diff options
-rw-r--r-- | sys/cam/ata/ata_pmp.c | 7 | ||||
-rw-r--r-- | sys/cam/ata/ata_xpt.c | 25 | ||||
-rw-r--r-- | sys/cam/cam_ccb.h | 1 | ||||
-rw-r--r-- | sys/dev/ahci/ahci.c | 4 | ||||
-rw-r--r-- | sys/dev/mvs/mvs.c | 15 | ||||
-rw-r--r-- | sys/dev/siis/siis.c | 5 | ||||
-rw-r--r-- | sys/sys/ata.h | 1 |
7 files changed, 55 insertions, 3 deletions
diff --git a/sys/cam/ata/ata_pmp.c b/sys/cam/ata/ata_pmp.c index 3520376..e6eb4a2 100644 --- a/sys/cam/ata/ata_pmp.c +++ b/sys/cam/ata/ata_pmp.c @@ -533,7 +533,8 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb) /*data_ptr*/NULL, /*dxfer_len*/0, pmp_default_timeout * 1000); - ata_pm_write_cmd(ataio, 0x60, 15, 0xf); + ata_pm_write_cmd(ataio, 0x60, 15, 0x07 | + ((softc->caps & CTS_SATA_CAPS_H_AN) ? 0x08 : 0)); break; default: break; @@ -672,7 +673,9 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb) cts.xport_specific.sata.revision = (res & 0x0f0) >> 4; cts.xport_specific.sata.valid = CTS_SATA_VALID_REVISION; cts.xport_specific.sata.caps = softc->caps & - (CTS_SATA_CAPS_H_PMREQ | CTS_SATA_CAPS_H_DMAAA); + (CTS_SATA_CAPS_H_PMREQ | + CTS_SATA_CAPS_H_DMAAA | + CTS_SATA_CAPS_H_AN); cts.xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; xpt_action((union ccb *)&cts); xpt_free_path(dpath); diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c index db45f8f..b836485 100644 --- a/sys/cam/ata/ata_xpt.c +++ b/sys/cam/ata/ata_xpt.c @@ -87,6 +87,7 @@ typedef enum { PROBE_SETPM, PROBE_SETAPST, PROBE_SETDMAAA, + PROBE_SETAN, PROBE_SET_MULTI, PROBE_INQUIRY, PROBE_FULL_INQUIRY, @@ -103,6 +104,7 @@ static char *probe_action_text[] = { "PROBE_SETPM", "PROBE_SETAPST", "PROBE_SETDMAAA", + "PROBE_SETAN", "PROBE_SET_MULTI", "PROBE_INQUIRY", "PROBE_FULL_INQUIRY", @@ -436,6 +438,19 @@ negotiate: (softc->caps & CTS_SATA_CAPS_H_DMAAA) ? 0x10 : 0x90, 0, 0x02); break; + case PROBE_SETAN: + cam_fill_ataio(ataio, + 1, + probedone, + CAM_DIR_NONE, + 0, + NULL, + 0, + 30*1000); + ata_28bit_cmd(ataio, ATA_SETFEATURES, + (softc->caps & CTS_SATA_CAPS_H_AN) ? 0x10 : 0x90, + 0, 0x05); + break; case PROBE_SET_MULTI: { u_int sectors, bytecount; @@ -1027,6 +1042,16 @@ noerror: } /* FALLTHROUGH */ case PROBE_SETDMAAA: + if ((ident_buf->satasupport & ATA_SUPPORT_ASYNCNOTIF) && + (!(softc->caps & CTS_SATA_CAPS_H_AN)) != + (!(ident_buf->sataenabled & ATA_SUPPORT_ASYNCNOTIF))) { + PROBE_SET_ACTION(softc, PROBE_SETAN); + xpt_release_ccb(done_ccb); + xpt_schedule(periph, priority); + return; + } + /* FALLTHROUGH */ + case PROBE_SETAN: notsata: if (path->device->protocol == PROTO_ATA) { PROBE_SET_ACTION(softc, PROBE_SET_MULTI); diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 9c1e3ab..bee07e8 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -889,6 +889,7 @@ struct ccb_trans_settings_sata { #define CTS_SATA_CAPS_H_PMREQ 0x00000001 #define CTS_SATA_CAPS_H_APST 0x00000002 #define CTS_SATA_CAPS_H_DMAAA 0x00000010 /* Auto-activation */ +#define CTS_SATA_CAPS_H_AN 0x00000020 /* Async. notification */ #define CTS_SATA_CAPS_D 0xffff0000 #define CTS_SATA_CAPS_D_PMREQ 0x00010000 #define CTS_SATA_CAPS_D_APST 0x00020000 diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 2bd4bb4..50780b8 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -914,7 +914,8 @@ ahci_ch_attach(device_t dev) CTS_SATA_CAPS_H_APST | CTS_SATA_CAPS_D_PMREQ | CTS_SATA_CAPS_D_APST; } - ch->user[i].caps |= CTS_SATA_CAPS_H_DMAAA; + ch->user[i].caps |= CTS_SATA_CAPS_H_DMAAA | + CTS_SATA_CAPS_H_AN; } rid = ch->unit; if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -2721,6 +2722,7 @@ ahciaction(struct cam_sim *sim, union ccb *ccb) if ((ch->caps & AHCI_CAP_SNCQ) && (ch->quirks & AHCI_Q_NOAA) == 0) cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_DMAAA; + cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_AN; cts->xport_specific.sata.caps &= ch->user[ccb->ccb_h.target_id].caps; cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c index 304813f..9a84e82 100644 --- a/sys/dev/mvs/mvs.c +++ b/sys/dev/mvs/mvs.c @@ -138,6 +138,7 @@ mvs_ch_attach(device_t dev) CTS_SATA_CAPS_H_APST | CTS_SATA_CAPS_D_PMREQ | CTS_SATA_CAPS_D_APST; } + ch->user[i].caps |= CTS_SATA_CAPS_H_AN; } rid = ch->unit; if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -861,6 +862,8 @@ mvs_legacy_intr(device_t dev) if (mvs_wait(dev, ATA_S_DRQ, ATA_S_BUSY, 1000) < 0) { device_printf(dev, "timeout waiting for read DRQ\n"); et = MVS_ERR_TIMEOUT; + xpt_freeze_simq(ch->sim, 1); + ch->toslots |= (1 << slot->slot); goto end_finished; } ATA_INSW_STRM(ch->r_mem, ATA_DATA, @@ -880,6 +883,8 @@ mvs_legacy_intr(device_t dev) device_printf(dev, "timeout waiting for write DRQ\n"); et = MVS_ERR_TIMEOUT; + xpt_freeze_simq(ch->sim, 1); + ch->toslots |= (1 << slot->slot); goto end_finished; } ATA_OUTSW_STRM(ch->r_mem, ATA_DATA, @@ -1325,6 +1330,8 @@ mvs_legacy_execute_transaction(struct mvs_slot *slot) if (mvs_wait(dev, ATA_S_DRQ, ATA_S_BUSY, 1000) < 0) { device_printf(dev, "timeout waiting for write DRQ\n"); + xpt_freeze_simq(ch->sim, 1); + ch->toslots |= (1 << slot->slot); mvs_end_transaction(slot, MVS_ERR_TIMEOUT); return; } @@ -1351,6 +1358,8 @@ mvs_legacy_execute_transaction(struct mvs_slot *slot) /* Wait for ready to write ATAPI command block */ if (mvs_wait(dev, 0, ATA_S_BUSY, 1000) < 0) { device_printf(dev, "timeout waiting for ATAPI !BUSY\n"); + xpt_freeze_simq(ch->sim, 1); + ch->toslots |= (1 << slot->slot); mvs_end_transaction(slot, MVS_ERR_TIMEOUT); return; } @@ -1367,6 +1376,8 @@ mvs_legacy_execute_transaction(struct mvs_slot *slot) if (timeout <= 0) { device_printf(dev, "timeout waiting for ATAPI command ready\n"); + xpt_freeze_simq(ch->sim, 1); + ch->toslots |= (1 << slot->slot); mvs_end_transaction(slot, MVS_ERR_TIMEOUT); return; } @@ -2205,6 +2216,7 @@ mvsaction(struct cam_sim *sim, union ccb *ccb) cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D; // if (ch->pm_level) // cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ; + cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_AN; cts->xport_specific.sata.caps &= ch->user[ccb->ccb_h.target_id].caps; cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; @@ -2212,6 +2224,9 @@ mvsaction(struct cam_sim *sim, union ccb *ccb) cts->xport_specific.sata.revision = d->revision; cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; cts->xport_specific.sata.caps = d->caps; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS/* && + (ch->quirks & MVS_Q_GENIIE) == 0*/) + cts->xport_specific.sata.caps &= ~CTS_SATA_CAPS_H_AN; cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; } cts->xport_specific.sata.mode = d->mode; diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index 03c6127..b974cf2 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -474,6 +474,7 @@ siis_ch_attach(device_t dev) ch->curr[i] = ch->user[i]; if (ch->pm_level) ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ; + ch->user[i].caps |= CTS_SATA_CAPS_H_AN; } mtx_init(&ch->mtx, "SIIS channel lock", NULL, MTX_DEF); rid = ch->unit; @@ -1869,6 +1870,7 @@ siisaction(struct cam_sim *sim, union ccb *ccb) cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D; if (ch->pm_level) cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ; + cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_AN; cts->xport_specific.sata.caps &= ch->user[ccb->ccb_h.target_id].caps; cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; @@ -1876,6 +1878,9 @@ siisaction(struct cam_sim *sim, union ccb *ccb) cts->xport_specific.sata.revision = d->revision; cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; cts->xport_specific.sata.caps = d->caps; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS && + (ch->quirks & SIIS_Q_SNTF) == 0) + cts->xport_specific.sata.caps &= ~CTS_SATA_CAPS_H_AN; cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; } cts->xport_specific.sata.mode = d->mode; diff --git a/sys/sys/ata.h b/sys/sys/ata.h index cacb1ea0..1d46dc1 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -135,6 +135,7 @@ struct ata_params { #define ATA_SUPPORT_AUTOACTIVATE 0x0004 #define ATA_SUPPORT_IFPWRMNGT 0x0008 #define ATA_SUPPORT_INORDERDATA 0x0010 +#define ATA_SUPPORT_ASYNCNOTIF 0x0020 #define ATA_SUPPORT_SOFTSETPRESERVE 0x0040 /*79*/ u_int16_t sataenabled; #define ATA_ENABLED_DAPST 0x0080 |