PERFORCE change 177212 for review
Alexander Motin
mav at FreeBSD.org
Thu Apr 22 13:18:39 UTC 2010
http://p4web.freebsd.org/@@177212?ac=10
Change 177212 by mav at mav_mavtest on 2010/04/22 13:18:08
Improve Asynchronous Notifications support.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#9 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#9 (text+ko) ====
@@ -232,12 +232,21 @@
mvs_ch_resume(device_t dev)
{
struct mvs_channel *ch = device_get_softc(dev);
+ uint32_t reg;
/* Disable port interrupts */
ATA_OUTL(ch->r_mem, EDMA_IEM, 0);
/* Stop EDMA */
ch->curr_mode = MVS_EDMA_UNKNOWN;
mvs_set_edma_mode(dev, MVS_EDMA_OFF);
+ /* Clear and configure FIS interrupts. */
+ ATA_OUTL(ch->r_mem, SATA_FISIC, 0);
+ reg = ATA_INL(ch->r_mem, SATA_FISC);
+ reg |= SATA_FISC_FISWAIT4HOSTRDYEN_B1;
+ ATA_OUTL(ch->r_mem, SATA_FISC, reg);
+ reg = ATA_INL(ch->r_mem, SATA_FISIM);
+ reg |= SATA_FISC_FISWAIT4HOSTRDYEN_B1;
+ ATA_OUTL(ch->r_mem, SATA_FISC, reg);
/* Clear SATA error register. */
ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff);
/* Clear any outstanding error interrupts. */
@@ -534,22 +543,24 @@
}
static void
-mvs_notify_events(device_t dev, u_int32_t status)
+mvs_notify_events(device_t dev)
{
struct mvs_channel *ch = device_get_softc(dev);
struct cam_path *dpath;
- int i;
+ uint32_t fis;
+ int d;
+ fis = ATA_INL(ch->r_mem, SATA_FISDW0);
+ if ((fis & 0x80ff) == 0x80a1)
+ d = (fis & 0x0f00) >> 8;
+ else
+ d = ch->pm_present ? 15 : 0;
if (bootverbose)
- device_printf(dev, "SNTF 0x%04x\n", status);
- for (i = 0; i < 16; i++) {
- if ((status & (1 << i)) == 0)
- continue;
- if (xpt_create_path(&dpath, NULL,
- xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) {
- xpt_async(AC_SCSI_AEN, dpath, NULL);
- xpt_free_path(dpath);
- }
+ device_printf(dev, "SNTF %d\n", d);
+ if (xpt_create_path(&dpath, NULL,
+ xpt_path_path_id(ch->path), d, 0) == CAM_REQ_CMP) {
+ xpt_async(AC_SCSI_AEN, dpath, NULL);
+ xpt_free_path(dpath);
}
}
@@ -592,7 +603,7 @@
struct mvs_channel *ch = device_get_softc(dev);
uint32_t iec, serr = 0, fisic = 0;
enum mvs_err_type et;
- int i, ccs, port = -1;
+ int i, ccs, port = -1, selfdis = 0;
int edma = (ch->numtslots != 0 || ch->numdslots != 0);
//device_printf(dev, "irq cause %02x EDMA %d IEC %08x\n",
@@ -608,12 +619,19 @@
ATA_OUTL(ch->r_mem, SATA_SE, serr);
device_printf(dev, "SERR %08x\n", serr);
}
+ if (iec & EDMA_IE_ESELFDIS)
+ selfdis = 1;
if (iec & EDMA_IE_ETRANSINT) {
- fisic = ATA_INL(ch->r_mem, SATA_FISIC);
-device_printf(dev, "FISC %08x\n", ATA_INL(ch->r_mem, SATA_FISC));
+ if (ch->quirks & MVS_Q_GENI)
+ selfdis = 1;
+ else if (ch->quirks & MVS_Q_GENII)
+ fisic = SATA_FISC_FISWAIT4HOSTRDYEN_B1;
+ else
+ fisic = ATA_INL(ch->r_mem, SATA_FISIC);
device_printf(dev, "FISIC %08x\n", fisic);
-device_printf(dev, "FISIM %08x\n", ATA_INL(ch->r_mem, SATA_FISIM));
}
+ if (selfdis)
+ ch->curr_mode = MVS_EDMA_OFF;
ATA_OUTL(ch->r_mem, EDMA_IEC, ~iec);
/* Interface errors or Device error. */
if (iec & (0xfc1e9000 | EDMA_IE_EDEVERR)) {
@@ -641,7 +659,7 @@
/* If several ports were active and EDMA still enabled -
* other ports are probably unaffected and may continue.
*/
- if (port == -2 && (iec & EDMA_IE_ESELFDIS) == 0) {
+ if (port == -2 && !selfdis) {
uint16_t p = ATA_INL(ch->r_mem, SATA_SATAITC) >> 16;
port = ffs(p) - 1;
if (port != (fls(p) - 1))
@@ -684,15 +702,13 @@
mvs_end_transaction(&ch->slot[i], et);
}
}
+ if (fisic & SATA_FISC_FISWAIT4HOSTRDYEN_B1)
+ mvs_notify_events(dev);
if (fisic)
ATA_OUTL(ch->r_mem, SATA_FISIC, ~fisic);
- if (iec & EDMA_IE_ESELFDIS)
- ch->curr_mode = MVS_EDMA_OFF;
if ((iec & (EDMA_IE_EDEVDIS | EDMA_IE_EDEVCON)) ||
(serr & ATA_SE_PHY_CHANGED))
mvs_phy_check_events(dev, serr);
- if (fisic & SATA_FISC_FISWAIT4HOSTRDYEN_B1)
- mvs_notify_events(dev, ch->pm_present ? 0x8000 : 0x0001);
}
if ((arg->cause & 2) && !edma)
mvs_legacy_intr(dev);
More information about the p4-projects
mailing list