summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam')
-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
3 files changed, 31 insertions, 2 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
OpenPOWER on IntegriCloud