aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mvs
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2011-04-13 16:20:54 +0000
committerAlexander Motin <mav@FreeBSD.org>2011-04-13 16:20:54 +0000
commit8d169381e427bddf2b46c862fb721fa76ffac8f3 (patch)
tree50152a120489fd01d6729de29dac3161f46fd826 /sys/dev/mvs
parent235ab70e0a6c67b0529450bfd7717cd99bcf09eb (diff)
downloadsrc-8d169381e427bddf2b46c862fb721fa76ffac8f3.tar.gz
src-8d169381e427bddf2b46c862fb721fa76ffac8f3.zip
Improve SATA Asynchronous Notification feature support in CAM:
- make SATA SIMs announce capabilities to handle SDB with Notification bit; - make PMP driver honor this SIMs capability; - make SATA XPT to negotiate and enable this feature for ATAPI devices. This feature allows supporting SATA ATAPI devices to inform system about some events happened, that may require attention. In my case this allows LG GH22LS50 SATA DVR-RW drive to report tray open/close events. Events reported to CAM in form of AC_SCSI_AEN async. Further they could be used as a hints for checking device status and reporting media change to upper layers, for example, via spoiling mechanism of GEOM.
Notes
Notes: svn path=/head/; revision=220602
Diffstat (limited to 'sys/dev/mvs')
-rw-r--r--sys/dev/mvs/mvs.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/dev/mvs/mvs.c b/sys/dev/mvs/mvs.c
index 304813fbab5f..9a84e82c6d2a 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;