From 6f3b9849ccedb6b3e4a9c2c6b577d9ce5fd41552 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 18 Jun 2009 23:59:19 -0700 Subject: [PATCH] SILI - Minor fixes and adjustments. * Aligned scratch space for READ LOG * Better exclusivity code. Minor fix to only copy-back the rfis if the CCB was on-chip, instead of unconditionally. * Probe all ports reported by the PM, we'll have to adjust for 'fake' disks at the end of the PM port chain more specifically. --- sys/dev/disk/sili/sili.c | 35 +++++++++++++++++++---------------- sys/dev/disk/sili/sili.h | 7 +++---- sys/dev/disk/sili/sili_pm.c | 1 - 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/sys/dev/disk/sili/sili.c b/sys/dev/disk/sili/sili.c index f824341..0e5280f 100644 --- a/sys/dev/disk/sili/sili.c +++ b/sys/dev/disk/sili/sili.c @@ -126,6 +126,7 @@ sili_port_alloc(struct sili_softc *sc, u_int port) int i; ap = kmalloc(sizeof(*ap), M_DEVBUF, M_WAITOK | M_ZERO); + ap->ap_err_scratch = kmalloc(512, M_DEVBUF, M_WAITOK | M_ZERO); ksnprintf(ap->ap_name, sizeof(ap->ap_name), "%s%d.%d", device_get_name(sc->sc_dev), @@ -708,6 +709,10 @@ sili_port_free(struct sili_softc *sc, u_int port) kfree(ap->ap_ata, M_DEVBUF); ap->ap_ata = NULL; } + if (ap->ap_err_scratch) { + kfree(ap->ap_err_scratch, M_DEVBUF); + ap->ap_err_scratch = NULL; + } /* bus_space(9) says we dont free the subregions handle */ @@ -1513,16 +1518,14 @@ sili_issue_pending_commands(struct sili_port *ap, struct sili_ccb *ccb) if (ap->ap_active & ~ap->ap_expired) { /* * There may be multiple ccb's already running, - * but there will only be one if it is exclusive. - * We can't queue a new command in that case. + * if any are running and ap_run_flags sets + * one of these flags then we know only one is + * running. * * XXX Current AUTOSENSE code forces exclusivity * to simplify the code. */ - KKASSERT(ap->ap_last_ccb); - KKASSERT(ap->ap_active & - (1 << ap->ap_last_ccb->ccb_slot)); - if (ap->ap_last_ccb->ccb_xa.flags & + if (ap->ap_run_flags & (ATA_F_EXCLUSIVE | ATA_F_AUTOSENSE)) { break; } @@ -1545,7 +1548,7 @@ sili_issue_pending_commands(struct sili_port *ap, struct sili_ccb *ccb) ccb->ccb_xa.state = ATA_S_ONCHIP; ap->ap_active |= 1 << ccb->ccb_slot; ap->ap_active_cnt++; - ap->ap_last_ccb = ccb; + ap->ap_run_flags = ccb->ccb_xa.flags; /* * We can't use the CMD_FIFO method because it requires us @@ -1939,15 +1942,16 @@ fatal: ccb->ccb_done(ccb); ccb->ccb_xa.complete(&ccb->ccb_xa); } else { - if (ccb->ccb_xa.flags & ATA_F_AUTOSENSE) { - memcpy(ccb->ccb_xa.rfis, - &ccb->ccb_prb_lram->prb_d2h, - sizeof(ccb->ccb_prb_lram->prb_d2h)); - if (ccb->ccb_xa.state == ATA_S_TIMEOUT) - ccb->ccb_xa.state = ATA_S_ERROR; - } - if (ccb->ccb_xa.state == ATA_S_ONCHIP) + if (ccb->ccb_xa.state == ATA_S_ONCHIP) { ccb->ccb_xa.state = ATA_S_COMPLETE; + if (ccb->ccb_xa.flags & ATA_F_AUTOSENSE) { + memcpy(ccb->ccb_xa.rfis, + &ccb->ccb_prb_lram->prb_d2h, + sizeof(ccb->ccb_prb_lram->prb_d2h)); + if (ccb->ccb_xa.state == ATA_S_TIMEOUT) + ccb->ccb_xa.state = ATA_S_ERROR; + } + } ccb->ccb_done(ccb); } } @@ -2188,7 +2192,6 @@ sili_port_read_ncq_error(struct sili_port *ap, int target) } else { kprintf("%s: read NCQ error page slot=%d, " "slot does not match any cmds\n", - ATANAME(ccb->ccb_port, ccb->ccb_xa.at), err_slot ); diff --git a/sys/dev/disk/sili/sili.h b/sys/dev/disk/sili/sili.h index 54c4519..063322e 100644 --- a/sys/dev/disk/sili/sili.h +++ b/sys/dev/disk/sili/sili.h @@ -771,7 +771,7 @@ struct sili_port { u_int32_t ap_expired; /* deferred expired bmask */ struct sili_ccb *ap_ccbs; struct sili_ccb *ap_err_ccb; /* used to read LOG page */ - struct sili_ccb *ap_last_ccb; /* used to check excl mode*/ + int ap_run_flags; /* used to check excl mode */ TAILQ_HEAD(, sili_ccb) ap_ccb_free; TAILQ_HEAD(, sili_ccb) ap_ccb_pending; @@ -789,8 +789,7 @@ struct sili_port { #ifdef DIAGNOSTIC int ap_err_busy; #endif - int ap_filler; - u_int8_t ap_err_scratch[512]; + u_int8_t *ap_err_scratch; char ap_name[16]; }; @@ -886,8 +885,8 @@ void sili_ata_put_xfer(struct ata_xfer *xa); int sili_ata_cmd(struct ata_xfer *xa); int sili_pm_port_probe(struct sili_port *ap, int); -int sili_pm_identify(struct sili_port *ap); int sili_pm_port_init(struct sili_port *ap, struct ata_port *at); +int sili_pm_identify(struct sili_port *ap); int sili_pm_set_feature(struct sili_port *ap, int feature, int enable); int sili_pm_hardreset(struct sili_port *ap, int target, int hard); int sili_pm_softreset(struct sili_port *ap, int target); diff --git a/sys/dev/disk/sili/sili_pm.c b/sys/dev/disk/sili/sili_pm.c index 45883bf..fb308f6 100644 --- a/sys/dev/disk/sili/sili_pm.c +++ b/sys/dev/disk/sili/sili_pm.c @@ -171,7 +171,6 @@ sili_pm_identify(struct sili_port *ap) if (sili_pm_read(ap, 15, 2, &nports)) goto err; nports &= 0x0000000F; /* only the low 4 bits */ - --nports; ap->ap_probe = ATA_PROBE_GOOD; kprintf("%s: Port multiplier: chip=%08x rev=0x%b nports=%d\n", PORTNAME(ap), -- 1.7.7.2