aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorSøren Schmidt <sos@FreeBSD.org>1999-11-06 16:50:21 +0000
committerSøren Schmidt <sos@FreeBSD.org>1999-11-06 16:50:21 +0000
commit3de25e2f326e2fc278bc569bf26176fb5d761b87 (patch)
tree9bccc8d27f9829fbf70ec9f0e106fbde573004a7 /sys/dev/ata
parent8db34b3a11d2a0f0b243ac756cc7c192b52f9b54 (diff)
Notes
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-all.c50
-rw-r--r--sys/dev/ata/ata-all.h2
-rw-r--r--sys/dev/ata/ata-disk.c8
-rw-r--r--sys/dev/ata/ata-dma.c41
-rw-r--r--sys/dev/ata/atapi-all.c122
-rw-r--r--sys/dev/ata/atapi-all.h3
6 files changed, 148 insertions, 78 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index a136b6c6a8309..e6e10462655bc 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -243,6 +243,7 @@ ata_pciattach(device_t dev)
u_int32_t cmd;
int32_t iobase_1, iobase_2, altiobase_1, altiobase_2;
int32_t bmaddr_1 = 0, bmaddr_2 = 0, irq1, irq2;
+ struct resource *irq = NULL;
int32_t lun;
/* set up vendor-specific stuff */
@@ -324,7 +325,6 @@ ata_pciattach(device_t dev)
alpha_platform_setup_ide_intr(0, ataintr, scp);
#endif
else {
- struct resource *irq;
int rid = 0;
void *ih;
@@ -348,13 +348,14 @@ ata_pciattach(device_t dev)
alpha_platform_setup_ide_intr(1, ataintr, scp);
#endif
else {
- struct resource *irq;
int rid = 0;
void *ih;
- if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE)))
- printf("ata_pciattach: Unable to alloc interrupt\n");
+ if (irq1 != irq2 || irq == NULL) {
+ if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE)))
+ printf("ata_pciattach: Unable to alloc interrupt\n");
+ }
bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih);
}
printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
@@ -514,33 +515,37 @@ ataintr(void *data)
if (scp->flags & ATA_DMA_ACTIVE)
if (!(ata_dmastatus(scp) & ATA_BMSTAT_INTERRUPT))
return;
- if ((scp->status = inb(scp->ioaddr + ATA_STATUS)) == ATA_S_BUSY) /*XXX SOS*/
+ if ((scp->status = inb(scp->ioaddr + ATA_STATUS)) == ATA_S_BUSY)
return;
/* find & call the responsible driver to process this interrupt */
switch (scp->active) {
#if NATADISK > 0
case ATA_ACTIVE_ATA:
- if (scp->running && (ad_interrupt(scp->running) == ATA_OP_CONTINUES))
- return;
+ if (!scp->running)
+ return;
+ if (ad_interrupt(scp->running) == ATA_OP_CONTINUES)
+ return;
break;
#endif
#if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0
case ATA_ACTIVE_ATAPI:
- if (scp->running && (atapi_interrupt(scp->running) == ATA_OP_CONTINUES))
- return;
+ if (!scp->running)
+ return;
+ if (atapi_interrupt(scp->running) == ATA_OP_CONTINUES)
+ return;
break;
#endif
case ATA_WAIT_INTR:
wakeup((caddr_t)scp);
break;
+ case ATA_WAIT_READY:
+ break;
+
case ATA_REINITING:
return;
- case ATA_IGNORE_INTR:
- break;
-
default:
case ATA_IDLE:
#ifdef ATA_DEBUG
@@ -780,7 +785,7 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
switch (flags) {
case ATA_WAIT_INTR:
if (scp->active != ATA_IDLE)
- printf("DANGER wait_intr active=%s\n", active2str(scp->active));
+ printf("WARNING: WAIT_INTR active=%s\n", active2str(scp->active));
scp->active = ATA_WAIT_INTR;
outb(scp->ioaddr + ATA_CMD, command);
if (tsleep((caddr_t)scp, PRIBIO, "atacmd", 500)) {
@@ -790,12 +795,17 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
}
break;
- case ATA_IGNORE_INTR:
+ case ATA_WAIT_READY:
if (scp->active != ATA_IDLE && scp->active != ATA_REINITING)
- printf("DANGER ignore_intr active=%s\n", active2str(scp->active));
- if (scp->active != ATA_REINITING)
- scp->active = ATA_IGNORE_INTR;
+ printf("WARNING: WAIT_READY active=%s\n", active2str(scp->active));
+ scp->active = ATA_WAIT_READY;
outb(scp->ioaddr + ATA_CMD, command);
+ if (ata_wait(scp, device, ATA_S_READY) < 0) {
+ printf("ata%d-%s: timeout waiting for command=%02x s=%02x e=%02x\n",
+ scp->lun, device ? "slave" : "master", command,
+ scp->status, scp->error);
+ return -1;
+ }
break;
case ATA_IMMEDIATE:
@@ -803,7 +813,7 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
break;
default:
- printf("DANGER illegal interrupt flag=%s\n", active2str(flags));
+ printf("DANGER: illegal interrupt flag=%s\n", active2str(flags));
}
#ifdef ATA_DEBUG
printf("ata_command: leaving\n");
@@ -838,8 +848,6 @@ active2str(int32_t active)
return("ATA_IDLE");
case ATA_WAIT_INTR:
return("ATA_WAIT_INTR");
- case ATA_IGNORE_INTR:
- return("ATA_IGNORE_INTR");
case ATA_ACTIVE_ATA:
return("ATA_ACTIVE_ATA");
case ATA_ACTIVE_ATAPI:
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index c14c98f781531..f91b21c70a591 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -155,7 +155,7 @@ struct ata_softc {
#define ATA_IDLE 0x0
#define ATA_IMMEDIATE 0x0
#define ATA_WAIT_INTR 0x1
-#define ATA_IGNORE_INTR 0x2
+#define ATA_WAIT_READY 0x2
#define ATA_ACTIVE_ATA 0x3
#define ATA_ACTIVE_ATAPI 0x4
#define ATA_REINITING 0x5
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 62bd58f0a3aa5..9f4bba5d7561e 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -322,6 +322,7 @@ addump(dev_t dev)
adp->flags &= ~AD_F_DMA_ENABLED;
while (count > 0) {
+ DELAY(1000);
if (is_physical_memory(addr))
pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
trunc_page(addr), VM_PROT_READ, TRUE);
@@ -416,7 +417,11 @@ ad_transfer(struct ad_request *request)
if (request->donecount == 0) {
/* start timeout for this transfer */
- request->timeout_handle = timeout((timeout_t*)ad_timeout, request, 3*hz);
+ if (panicstr)
+ request->timeout_handle.callout = NULL;
+ else
+ request->timeout_handle =
+ timeout((timeout_t*)ad_timeout, request, 3*hz);
/* setup transfer parameters */
count = howmany(request->bytecount, DEV_BSIZE);
@@ -614,6 +619,7 @@ ad_timeout(struct ad_request *request)
{
struct ad_softc *adp = request->device;
+ adp->controller->running = NULL;
printf("ata%d-%s: ad_timeout: lost disk contact - resetting\n",
adp->controller->lun,
(adp->unit == ATA_MASTER) ? "master" : "slave");
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 28e5970df47ea..ab46df445698a 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -100,7 +100,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
int32_t mask48, new48;
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up UDMA2 mode on PIIX4 chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -139,7 +139,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
pci_write_config(scp->dev, 0x44, new44, 4);
}
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up WDMA2 mode on PIIX4 chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -212,7 +212,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
int32_t word54 = pci_read_config(scp->dev, 0x54, 4);
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up UDMA2 mode on Aladdin chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -228,7 +228,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
}
else if (wdmamode >= 2 && apiomode >= 4) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up WDMA2 mode on Aladdin chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -248,9 +248,24 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
break;
devno = (scp->unit << 1) + ((device == ATA_MASTER) ? 0 : 1);
+ if (udmamode >=4 && type == 0x4d38105a &&
+ !(pci_read_config(scp->dev, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
+ error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
+ ATA_UDMA4, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
+ if (bootverbose)
+ printf("ata%d: %s: %s setting up UDMA4 mode on Promise chip\n",
+ scp->lun, (device == ATA_MASTER) ? "master" : "slave",
+ (error) ? "failed" : "success");
+ if (error)
+ break;
+ outb(scp->bmaddr + 0x11, inl(scp->bmaddr + 0x11) | scp->unit ? 8:2);
+ pci_write_config(scp->dev, 0x60 + (devno << 2), 0x004127f3, 4);
+ scp->mode[(device == ATA_MASTER) ? 0 : 1] = ATA_MODE_UDMA4;
+ return 0;
+ }
if (udmamode >=2) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up UDMA2 mode on Promise chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -263,7 +278,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
}
else if (wdmamode >= 2 && apiomode >= 4) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up WDMA2 mode on Promise chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -291,7 +306,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
devno = (device == ATA_MASTER) ? 0 : 1;
if (udmamode >=4 && !(pci_read_config(scp->dev, 0x5a, 1) & 0x2)) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_UDMA4, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_UDMA4, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up UDMA4 mode on HPT366 chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -302,9 +317,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
scp->mode[(device == ATA_MASTER) ? 0 : 1] = ATA_MODE_UDMA4;
return 0;
}
- else if (udmamode >=3) {
+ if (udmamode >=3 && !(pci_read_config(scp->dev, 0x5a, 1) & 0x2)) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_UDMA3, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_UDMA3, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up UDMA3 mode on HPT366 chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -315,9 +330,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
scp->mode[(device == ATA_MASTER) ? 0 : 1] = ATA_MODE_UDMA3;
return 0;
}
- else if (udmamode >=2) {
+ if (udmamode >=2) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up UDMA2 mode on HPT366 chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -330,7 +345,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
}
else if (wdmamode >= 2 && apiomode >= 4) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up WDMA2 mode on HPT366 chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
@@ -361,7 +376,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
((device == ATA_MASTER) ?
ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
- ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_IGNORE_INTR);
+ ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY);
if (bootverbose)
printf("ata%d: %s: %s setting up WDMA2 mode on generic chip\n",
scp->lun, (device == ATA_MASTER) ? "master" : "slave",
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index 3368f783af13a..fc4bec8a08990 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.c
@@ -49,6 +49,8 @@
/* prototypes */
static void atapi_attach(void *);
static int32_t atapi_getparam(struct atapi_softc *);
+static void atapi_read(struct atapi_request *, int32_t);
+static void atapi_write(struct atapi_request *, int32_t);
static void atapi_timeout(struct atapi_request *request);
static int8_t *atapi_type(int32_t);
static int8_t *atapi_cmd2str(u_int8_t);
@@ -135,6 +137,7 @@ atapi_attach(void *notused)
udmamode(atp->atapi_parm),
atp->atapi_parm->dmaflag);
+#ifdef ATA_ENABLE_ATAPI_DMA
if (!(atp->atapi_parm->drqtype == ATAPI_DRQT_INTR) &&
!ata_dmainit(atp->controller, atp->unit,
(apiomode(atp->atapi_parm) < 0) ?
@@ -145,6 +148,7 @@ atapi_attach(void *notused)
wdmamode(atp->atapi_parm),
udmamode(atp->atapi_parm)))
atp->flags |= ATAPI_F_DMA_ENABLED;
+#endif
switch (atp->atapi_parm->device_type) {
#if NATAPICD > 0
@@ -245,14 +249,16 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
TAILQ_INSERT_TAIL(&atp->controller->atapi_queue, request, chain);
if (atp->controller->active == ATA_IDLE)
ata_start(atp->controller);
- splx(s);
/* if callback used, then just return, gets called from interrupt context */
- if (callback)
+ if (callback) {
+ splx(s);
return 0;
+ }
/* wait for request to complete */
tsleep((caddr_t)request, PRIBIO, "atprq", 0);
+ splx(s);
#ifdef ATAPI_DEBUG
printf("atapi: phew, got back from tsleep\n");
@@ -370,7 +376,7 @@ atapi_interrupt(struct atapi_request *request)
{
struct atapi_softc *atp = request->device;
int8_t **buffer = (int8_t **)&request->data;
- int32_t length, reason, resid, dma_stat = 0;
+ int32_t length, reason, dma_stat = 0;
if (request->ccb[0] == ATAPI_REQUEST_SENSE)
*buffer = (int8_t *)&request->sense;
@@ -432,25 +438,7 @@ atapi_interrupt(struct atapi_request *request)
atapi_cmd2str(atp->cmd));
goto op_finished;
}
- if (request->bytecount < length) {
- printf("atapi_interrupt: write data underrun %d/%d\n",
- length, request->bytecount);
-#ifdef ATA_16BIT_ONLY
- outsw(atp->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
-#else
- outsl(atp->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int32_t));
-#endif
- for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
- outw(atp->controller->ioaddr + ATA_DATA, 0);
- }
- else {
- outsw(atp->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
- }
- request->bytecount -= length;
- *buffer += length;
+ atapi_write(request, length);
return ATA_OP_CONTINUES;
case ATAPI_P_READ:
@@ -462,27 +450,20 @@ atapi_interrupt(struct atapi_request *request)
atapi_cmd2str(atp->cmd));
goto op_finished;
}
- if (request->bytecount < length) {
- printf("atapi_interrupt: read data overrun %d/%d\n",
- length, request->bytecount);
-#ifdef ATA_16BIT_ONLY
- insw(atp->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
-#else
- insl(atp->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int32_t));
-#endif
- for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
- inw(atp->controller->ioaddr + ATA_DATA);
- }
- else {
- insw(atp->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
- }
- request->bytecount -= length;
- *buffer += length;
+ atapi_read(request, length);
return ATA_OP_CONTINUES;
+ case ATAPI_P_DONEDRQ:
+ printf("ata%d-%s: %s DONEDRQ\n",
+ atp->controller->lun,
+ (atp->unit == ATA_MASTER) ? "master" : "slave",
+ atapi_cmd2str(atp->cmd));
+ if (request->flags & A_READ)
+ atapi_read(request, length);
+ else
+ atapi_write(request, length);
+ /* FALLTHROUGH */
+
case ATAPI_P_ABORT:
case ATAPI_P_DONE:
if (atp->controller->status & (ATA_S_ERROR | ATA_S_DWF))
@@ -590,11 +571,70 @@ atapi_dump(int8_t *label, void *data, int32_t len)
printf ("\n");
}
+static void
+atapi_read(struct atapi_request *request, int32_t length)
+{
+ int8_t **buffer = (int8_t **)&request->data;
+ int32_t resid;
+
+ if (request->ccb[0] == ATAPI_REQUEST_SENSE)
+ *buffer = (int8_t *)&request->sense;
+
+ if (request->bytecount < length) {
+ printf("atapi_interrupt: read data overrun %d/%d\n",
+ length, request->bytecount);
+#ifdef ATA_16BIT_ONLY
+ insw(request->device->controller->ioaddr + ATA_DATA,
+ (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
+#else
+ insl(request->device->controller->ioaddr + ATA_DATA,
+ (void *)((uintptr_t)*buffer), length / sizeof(int32_t));
+#endif
+ for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
+ inw(request->device->controller->ioaddr + ATA_DATA);
+ }
+ else
+ insw(request->device->controller->ioaddr + ATA_DATA,
+ (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
+ request->bytecount -= length;
+ *buffer += length;
+}
+
+static void
+atapi_write(struct atapi_request *request, int32_t length)
+{
+ int8_t **buffer = (int8_t **)&request->data;
+ int32_t resid;
+
+ if (request->ccb[0] == ATAPI_REQUEST_SENSE)
+ *buffer = (int8_t *)&request->sense;
+
+ if (request->bytecount < length) {
+ printf("atapi_interrupt: write data underrun %d/%d\n",
+ length, request->bytecount);
+#ifdef ATA_16BIT_ONLY
+ outsw(request->device->controller->ioaddr + ATA_DATA,
+ (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
+#else
+ outsl(request->device->controller->ioaddr + ATA_DATA,
+ (void *)((uintptr_t)*buffer), length / sizeof(int32_t));
+#endif
+ for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
+ outw(request->device->controller->ioaddr + ATA_DATA, 0);
+ }
+ else
+ outsw(request->device->controller->ioaddr + ATA_DATA,
+ (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
+ request->bytecount -= length;
+ *buffer += length;
+}
+
static void
atapi_timeout(struct atapi_request *request)
{
struct atapi_softc *atp = request->device;
+ atp->controller->running = NULL;
printf("ata%d-%s: atapi_timeout: cmd=%s - resetting\n",
atp->controller->lun, (atp->unit == ATA_MASTER) ? "master" : "slave",
atapi_cmd2str(request->ccb[0]));
diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h
index 29cc3ceca796c..6ef75c34e0229 100644
--- a/sys/dev/ata/atapi-all.h
+++ b/sys/dev/ata/atapi-all.h
@@ -34,8 +34,9 @@
#define ATAPI_P_READ (ATA_S_DRQ | ATA_I_IN)
#define ATAPI_P_WRITE (ATA_S_DRQ)
#define ATAPI_P_CMDOUT (ATA_S_DRQ | ATA_I_CMD)
+#define ATAPI_P_DONEDRQ (ATA_S_DRQ | ATA_I_CMD | ATA_I_IN)
+#define ATAPI_P_DONE (ATA_I_CMD | ATA_I_IN)
#define ATAPI_P_ABORT 0
-#define ATAPI_P_DONE (ATA_I_IN | ATA_I_CMD)
/* error register bits */
#define ATAPI_E_MASK 0x0f /* error mask */