summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/cam/ata/ata_pmp.c7
-rw-r--r--sys/cam/ata/ata_xpt.c25
-rw-r--r--sys/cam/cam_ccb.h1
-rw-r--r--sys/dev/ahci/ahci.c4
-rw-r--r--sys/dev/mvs/mvs.c15
-rw-r--r--sys/dev/siis/siis.c5
-rw-r--r--sys/sys/ata.h1
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
OpenPOWER on IntegriCloud