Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Apr 2010 17:06:31 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 177029 for review
Message-ID:  <201004171706.o3HH6VMl061033@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@177029?ac=10

Change 177029 by mav@mav_mavtest on 2010/04/17 17:05:49

	Make ATAPI work (in PIO mode for now).
	Fix 8-port adapters support.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#3 edit
.. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#3 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#3 (text+ko) ====

@@ -162,6 +162,15 @@
 	ctlr->quirks = mvs_ids[i].quirks;
 	resource_int_value(device_get_name(dev),
 	    device_get_unit(dev), "ccc", &ctlr->ccc);
+	ctlr->cccc = 8;
+	resource_int_value(device_get_name(dev),
+	    device_get_unit(dev), "cccc", &ctlr->cccc);
+	if (ctlr->ccc == 0 || ctlr->cccc == 0) {
+		ctlr->ccc = 0;
+		ctlr->cccc = 0;
+	}
+	if (ctlr->ccc > 100)
+		ctlr->ccc = 100;
 	/* We should have a memory BAR(0). */
 	ctlr->r_rid = PCIR_BAR(0);
 	if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
@@ -253,24 +262,19 @@
 	for (i = 0; i < ctlr->channels / 4; i++)
 		ATA_OUTL(ctlr->r_mem, HC_BASE(i) + HC_IC, 0x00000000);
 	/* Configure CCC */
-/*
+#if 0
 	if (ctlr->ccc) {
-		ATA_OUTL(ctlr->r_mem, MVS_CCCP, ATA_INL(ctlr->r_mem, MVS_PI));
-		ATA_OUTL(ctlr->r_mem, MVS_CCCC,
-		    (ctlr->ccc << MVS_CCCC_TV_SHIFT) |
-		    (4 << MVS_CCCC_CC_SHIFT) |
-		    MVS_CCCC_EN);
-		ctlr->cccv = (ATA_INL(ctlr->r_mem, MVS_CCCC) &
-		    MVS_CCCC_INT_MASK) >> MVS_CCCC_INT_SHIFT;
+		ATA_OUTL(ctlr->r_mem, HC_ICT, ctlr->cccc & HC_ICT_SAICOALT_MASK);
+		ATA_OUTL(ctlr->r_mem, HC_ITT, (ctlr->ccc * 150000) & HC_ITT_SAITMTH_MASK);
 		if (bootverbose) {
 			device_printf(dev,
-			    "CCC with %dms/4cmd enabled on vector %d\n",
-			    ctlr->ccc, ctlr->cccv);
+			    "CCC with %dms/%dcmd enabled\n",
+			    ctlr->ccc, ctlr->cccc);
 		}
 	}
-*/
+#endif
 	/* Enable chip interrupts */
-	ATA_OUTL(ctlr->r_mem, CHIP_MIM, IC_HC0 | IC_HC1 | IC_ALL_PORTS_COAL_DONE);
+	ATA_OUTL(ctlr->r_mem, CHIP_MIM, IC_HC0 | IC_HC1 /*| IC_ALL_PORTS_COAL_DONE*/);
 	/* Enable PCI interrupts */
 	ATA_OUTL(ctlr->r_mem, CHIP_PCIIM, 0x007fffff);
 	return (0);
@@ -356,6 +360,7 @@
 				ic >>= 1;
 			if ((ic & IC_HC0) == 0) {
 				p += 3;
+				ic >>= 8;
 				continue;
 			}
 			aic = 0;
@@ -525,7 +530,7 @@
 	for (i = 0; i < 16; i++) {
 		ch->user[i].revision = sata_rev;
 		ch->user[i].mode = 0;
-		ch->user[i].bytecount = 8192;
+		ch->user[i].bytecount = (ch->quirks & MVS_Q_GENIIE) ? 8192 : 2048;
 		ch->user[i].tags = MVS_MAX_SLOTS;
 		ch->curr[i] = ch->user[i];
 	}
@@ -837,6 +842,7 @@
 	}
 	ch->curr_mode = mode;
 	ch->fbs_enabled = 0;
+	ch->fake_busy = 0;
 	if (mode == MVS_EDMA_OFF)
 		return;
 	/* Configure new mode. */
@@ -1141,77 +1147,196 @@
 #endif
 }
 
+static uint8_t
+mvs_getstatus(device_t dev, int clear)
+{
+	struct mvs_channel *ch = device_get_softc(dev);
+	uint8_t status = ATA_INB(ch->r_mem, clear ? ATA_STATUS : ATA_ALTSTAT);
+
+	if (ch->fake_busy) {
+		if (status & (ATA_S_BUSY | ATA_S_DRQ | ATA_S_ERROR))
+			ch->fake_busy = 0;
+		else
+			status |= ATA_S_BUSY;
+	}
+	return (status);
+}
+
 static void
 mvs_legacy_intr(device_t dev)
 {
 	struct mvs_channel *ch = device_get_softc(dev);
 	union ccb *ccb = ch->slot[0].ccb;
 	enum mvs_err_type et = MVS_ERR_NONE;
-	uint8_t status;
+	int port = ccb->ccb_h.target_id & 0x0f;
+	u_int length;
+	uint8_t status, ireason;
 
 	/* clear interrupt and get status */
-	status = ATA_INB(ch->r_mem, ATA_STATUS);
-
+	status = mvs_getstatus(dev, 1);
 //	device_printf(dev, "Legacy intr status %02x\n",
-//	    ccb->ataio.res.status);
-	    
+//	    status);
 	if (ch->slot[0].state < MVS_SLOT_RUNNING) {
 //	    device_printf(dev, "Stray irq\n");
 	    return;
 	}
-	ccb->ataio.res.status = status;
-
+	/* Wait a bit for late !BUSY status update. */
+	if (status & ATA_S_BUSY) {
+		DELAY(100);
+		if ((status = mvs_getstatus(dev, 1)) & ATA_S_BUSY) {
+			DELAY(200);
+			if ((status = mvs_getstatus(dev, 1)) & ATA_S_BUSY) {
+device_printf(dev, "device busy on intr, Status %02x\n", status);
+				return;
+			}
+		}
+	}
 	/* if we got an error we are done with the HW */
-	if (ccb->ataio.res.status & ATA_S_ERROR) {
+	if (status & ATA_S_ERROR) {
 		et = MVS_ERR_TFE;
 		goto end_finished;
 	}
-
-	/* are we moving data ? */
-	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
-	    /* if read data get it */
-	    if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
-		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;
-		    goto end_finished;
-		}
-		ATA_INSW_STRM(ch->r_mem, ATA_DATA,
-		   (uint16_t *)(ccb->ataio.data_ptr + ch->donecount),
-		   ch->transfersize / 2);
-//		device_printf(dev, "After read %d status %02x\n",
-//		    ch->transfersize, ATA_INB(ch->r_mem, ATA_ALTSTAT));
-	    }
-
-	    /* update how far we've gotten */
-	    ch->donecount += ch->transfersize;
-
-	    /* do we need a scoop more ? */
-	    if (ccb->ataio.dxfer_len > ch->donecount) {
-
-		/* set this transfer size according to HW capabilities */
-		ch->transfersize = min(ccb->ataio.dxfer_len - ch->donecount,
-		    ch->curr[ccb->ccb_h.target_id].bytecount);
-
-		/* if data write command, output the data */
-		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
+	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
+		ccb->ataio.res.status = status;
+		/* are we moving data ? */
+		if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
+		    /* if read data get it */
+		    if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
 			if (mvs_wait(dev, ATA_S_DRQ, ATA_S_BUSY, 1000) < 0) {
-			    device_printf(dev, "timeout waiting for write DRQ\n");
+			    device_printf(dev, "timeout waiting for read DRQ\n");
 			    et = MVS_ERR_TIMEOUT;
 			    goto end_finished;
 			}
-			ATA_OUTSW_STRM(ch->r_mem, ATA_DATA,
+			ATA_INSW_STRM(ch->r_mem, ATA_DATA,
 			   (uint16_t *)(ccb->ataio.data_ptr + ch->donecount),
 			   ch->transfersize / 2);
-//			device_printf(dev, "After write %d status %02x\n",
+//			device_printf(dev, "After read %d status %02x\n",
 //			    ch->transfersize, ATA_INB(ch->r_mem, ATA_ALTSTAT));
-			return;
+		    }
+
+		    /* update how far we've gotten */
+		    ch->donecount += ch->transfersize;
+
+		    /* do we need a scoop more ? */
+		    if (ccb->ataio.dxfer_len > ch->donecount) {
+
+			/* set this transfer size according to HW capabilities */
+			ch->transfersize = min(ccb->ataio.dxfer_len - ch->donecount,
+			    ch->curr[ccb->ccb_h.target_id].bytecount);
+
+			/* if data write command, output the data */
+			if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
+				if (mvs_wait(dev, ATA_S_DRQ, ATA_S_BUSY, 1000) < 0) {
+				    device_printf(dev, "timeout waiting for write DRQ\n");
+				    et = MVS_ERR_TIMEOUT;
+				    goto end_finished;
+				}
+				ATA_OUTSW_STRM(ch->r_mem, ATA_DATA,
+				   (uint16_t *)(ccb->ataio.data_ptr + ch->donecount),
+				   ch->transfersize / 2);
+//				device_printf(dev, "After write %d status %02x\n",
+//				    ch->transfersize, ATA_INB(ch->r_mem, ATA_ALTSTAT));
+				return;
+			}
+
+			/* if data read command, return & wait for interrupt */
+			if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
+				return;
+		    }
 		}
+	} else {
+		length = ATA_INB(ch->r_mem,ATA_CYL_LSB) | (ATA_INB(ch->r_mem,ATA_CYL_MSB) << 8);
+		ireason = ATA_INB(ch->r_mem,ATA_IREASON);
+//device_printf(dev, "status %02x, ireason %02x, length %d\n", status, ireason, length);
+		switch ((ireason & (ATA_I_CMD | ATA_I_IN)) |
+			(status & ATA_S_DRQ)) {
+
+		case ATAPI_P_CMDOUT:
+device_printf(dev, "ATAPI CMDOUT\n");
+		    /* this seems to be needed for some (slow) devices */
+		    DELAY(10);
+
+		    if (!(status & ATA_S_DRQ)) {
+			device_printf(dev, "command interrupt without DRQ\n");
+			et = MVS_ERR_TFE;
+			goto end_finished;
+		    }
+		    ATA_OUTSW_STRM(ch->r_mem, ATA_DATA,
+			(uint16_t *)((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+			 ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes),
+			ch->curr[port].atapi / 2);
+		    /* return wait for interrupt */
+		    return;
+
+		case ATAPI_P_WRITE:
+//device_printf(dev, "ATAPI WRITE\n");
+		    if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
+			device_printf(dev, "trying to write on read buffer\n");
+			et = MVS_ERR_TFE;
+			goto end_finished;
+			break;
+		    }
+		    ATA_OUTSW_STRM(ch->r_mem, ATA_DATA,
+			(uint16_t *)(ccb->csio.data_ptr + ch->donecount),
+			length / 2);
+		    ch->donecount += length;
+
+		    /* set next transfer size according to HW capabilities */
+		    ch->transfersize = min(ccb->csio.dxfer_len - ch->donecount,
+			    ch->curr[ccb->ccb_h.target_id].bytecount);
+		    /* return wait for interrupt */
+		    return;
+
+		case ATAPI_P_READ:
+//device_printf(dev, "ATAPI READ\n");
+		    if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
+			device_printf(dev, "trying to read on write buffer\n");
+			et = MVS_ERR_TFE;
+			goto end_finished;
+		    }
+		    ATA_INSW_STRM(ch->r_mem, ATA_DATA,
+			(uint16_t *)(ccb->csio.data_ptr + ch->donecount),
+			length / 2);
+		    ch->donecount += length;
+
+		    /* set next transfer size according to HW capabilities */
+		    ch->transfersize = min(ccb->csio.dxfer_len - ch->donecount,
+			    ch->curr[ccb->ccb_h.target_id].bytecount);
+		    /* return wait for interrupt */
+		    return;
+
+		case ATAPI_P_DONEDRQ:
+device_printf(dev, "ATAPI DONEDRQ\n");
+		    device_printf(dev,
+			  "WARNING - DONEDRQ non conformant device\n");
+		    if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
+			ATA_INSW_STRM(ch->r_mem, ATA_DATA,
+			    (uint16_t *)(ccb->csio.data_ptr + ch->donecount),
+			    length / 2);
+			ch->donecount += length;
+		    }
+		    else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
+			ATA_OUTSW_STRM(ch->r_mem, ATA_DATA,
+			    (uint16_t *)(ccb->csio.data_ptr + ch->donecount),
+			    length / 2);
+			ch->donecount += length;
+		    }
+		    else
+			et = MVS_ERR_TFE;
+		    /* FALLTHROUGH */
+
+		case ATAPI_P_ABORT:
+		case ATAPI_P_DONE:
+//device_printf(dev, "ATAPI ABORT/DONE\n");
+		    if (status & (ATA_S_ERROR | ATA_S_DWF))
+			et = MVS_ERR_TFE;
+		    goto end_finished;
 
-		/* if data read command, return & wait for interrupt */
-		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
-			return;
-	    }
+		default:
+		    device_printf(dev, "unknown transfer phase (status %02x, ireason %02x)\n",
+			status, ireason);
+		    et = MVS_ERR_TFE;
+		}
 	}
 
 end_finished:
@@ -1297,6 +1422,10 @@
 			if (ch->numrslots != 0)
 				return (1);
 		}
+	} else { /* ATAPI */
+		/* ATAPI goes without EDMA, so can't mix it with anything. */
+		if (ch->numrslots != 0)
+			return (1);
 	}
 	/* We have some atomic command running. */
 	if (ch->aslots != 0)
@@ -1399,6 +1528,8 @@
 		    (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT)) {
 			ch->aslots |= (1 << slot->slot);
 		}
+	} else {
+		ch->numpslots++;
 	}
 	if (ch->numpslots == 0) {
 		void *buf;
@@ -1428,40 +1559,81 @@
 	struct mvs_channel *ch = device_get_softc(dev);
 	union ccb *ccb = slot->ccb;
 	int port = ccb->ccb_h.target_id & 0x0f;
+	int timeout;
 
-	device_printf(dev, "%d Legacy command %02x size %d\n",
-	    port, ccb->ataio.cmd.command, ccb->ataio.dxfer_len);
 	slot->state = MVS_SLOT_RUNNING;
 	ch->rslots |= (1 << slot->slot);
 	ATA_OUTB(ch->r_mem, SATA_SATAICTL, port << SATA_SATAICTL_PMPTX_SHIFT);
-	mvs_tfd_write(dev, ccb);
-	/* device reset doesn't interrupt */
-	if (ccb->ataio.cmd.command == ATA_DEVICE_RESET) {
-		int timeout = 1000000;
-		do {
-		    DELAY(10);
-		    ccb->ataio.res.status = ATA_INB(ch->r_mem, ATA_STATUS);
-		} while (ccb->ataio.res.status & ATA_S_BUSY && timeout--);
-		mvs_legacy_intr(dev);
-		return;
-	}
-	ch->donecount = 0;
-	ch->transfersize = min(ccb->ataio.dxfer_len,
-	    ch->curr[ccb->ccb_h.target_id].bytecount);
-//	device_printf(dev, "After command (status %02x)\n",
-//	    ATA_INB(ch->r_mem, ATA_ALTSTAT));
-	/* if write command output the data */
-	if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
-		if (mvs_wait(dev, ATA_S_DRQ, ATA_S_BUSY, 1000) < 0) {
-		    device_printf(dev, "timeout waiting for write DRQ\n");
-//		    request->result = EIO;
-//		    goto begin_finished;
+	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
+		device_printf(dev, "%d Legacy command %02x size %d\n",
+		    port, ccb->ataio.cmd.command, ccb->ataio.dxfer_len);
+		mvs_tfd_write(dev, ccb);
+		/* device reset doesn't interrupt */
+		if (ccb->ataio.cmd.command == ATA_DEVICE_RESET) {
+			int timeout = 1000000;
+			do {
+			    DELAY(10);
+			    ccb->ataio.res.status = ATA_INB(ch->r_mem, ATA_STATUS);
+			} while (ccb->ataio.res.status & ATA_S_BUSY && timeout--);
+			mvs_legacy_intr(dev);
+			return;
+		}
+		ch->donecount = 0;
+		ch->transfersize = min(ccb->ataio.dxfer_len,
+		    ch->curr[port].bytecount);
+		if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
+			ch->fake_busy = 1;
+		/* if write command output the data */
+		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
+			if (mvs_wait(dev, ATA_S_DRQ, ATA_S_BUSY, 1000) < 0) {
+				device_printf(dev, "timeout waiting for write DRQ\n");
+				mvs_end_transaction(slot, MVS_ERR_TIMEOUT);
+				return;
+			}
+			ATA_OUTSW_STRM(ch->r_mem, ATA_DATA,
+			   (uint16_t *)(ccb->ataio.data_ptr + ch->donecount),
+			   ch->transfersize / 2);
+		}
+	} else {
+		device_printf(dev, "%d ATAPI command %02x size %d\n",
+		    port, ccb->csio.cdb_io.cdb_bytes[0], ccb->csio.dxfer_len);
+		ch->donecount = 0;
+		ch->transfersize = min(ccb->csio.dxfer_len,
+		    ch->curr[port].bytecount);
+		ATA_OUTB(ch->r_mem, ATA_FEATURE, 0);
+		ATA_OUTB(ch->r_mem, ATA_CYL_LSB, ch->transfersize);
+	    	ATA_OUTB(ch->r_mem, ATA_CYL_MSB, ch->transfersize >> 8);
+		ATA_OUTB(ch->r_mem, ATA_COMMAND, ATA_PACKET_CMD);
+		ch->fake_busy = 1;
+		/* 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");
+			mvs_end_transaction(slot, MVS_ERR_TIMEOUT);
+			return;
+		}
+		timeout = 5000;
+		while (timeout--) {
+		    int reason = ATA_INB(ch->r_mem, ATA_IREASON);
+		    int status = ATA_INB(ch->r_mem, ATA_STATUS);
+
+		    if (((reason & (ATA_I_CMD | ATA_I_IN)) |
+			 (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT)
+			break;
+		    DELAY(20);
+		}
+		if (timeout <= 0) {
+			device_printf(dev, "timeout waiting for ATAPI command ready\n");
+			mvs_end_transaction(slot, MVS_ERR_TIMEOUT);
+			return;
 		}
+		DELAY(20);
 		ATA_OUTSW_STRM(ch->r_mem, ATA_DATA,
-		   (uint16_t *)(ccb->ataio.data_ptr + ch->donecount),
-		   ch->transfersize / 2);
-//		device_printf(dev, "After write %d status %02x\n",
-//		    ch->transfersize, ATA_INB(ch->r_mem, ATA_ALTSTAT));
+		   (uint16_t *)((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+		    ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes),
+		   ch->curr[port].atapi / 2);
+		if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
+			ch->fake_busy = 1;
+		DELAY(10);
 	}
 }
 
@@ -1828,7 +2000,8 @@
 		} else {
 			ch->numpslots--;
 		}
-	}
+	} else
+		ch->numpslots--;
 	/* If it was our READ LOG command - process it. */
 	if (ch->readlog) {
 		mvs_process_read_log(dev, ccb);
@@ -1973,18 +2146,17 @@
 static int
 mvs_wait(device_t dev, u_int s, u_int c, int t)
 {
-	struct mvs_channel *ch = device_get_softc(dev);
 	int timeout = 0;
 	uint8_t st;
 
-	while (((st = ATA_INB(ch->r_mem, ATA_ALTSTAT)) & (s | c)) != s) {
+	while (((st =  mvs_getstatus(dev, 0)) & (s | c)) != s) {
 		DELAY(1000);
 		if (timeout++ > t) {
 			device_printf(dev, "Wait status %02x\n", st);
 			return (-1);
 		}
 	} 
-	device_printf(dev, "Wait status %02x\n", st);
+//	device_printf(dev, "Wait status %02x\n", st);
 	return (timeout);
 }
 
@@ -2208,8 +2380,10 @@
 			d->revision = cts->xport_specific.sata.revision;
 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE)
 			d->mode = cts->xport_specific.sata.mode;
-		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
-			d->bytecount = min(8192, cts->xport_specific.sata.bytecount);
+		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) {
+			d->bytecount = min((ch->quirks & MVS_Q_GENIIE) ? 8192 : 2048,
+			    cts->xport_specific.sata.bytecount);
+		}
 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS)
 			d->tags = min(MVS_MAX_SLOTS, cts->xport_specific.sata.tags);
 		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM)

==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#3 (text+ko) ====

@@ -206,6 +206,12 @@
 #define         ATA_A_4BIT               0x08	/* 4 head bits */
 #define         ATA_A_HOB                0x80	/* High Order Byte enable */
 #define ATA_ALTSTAT                     0x120	/* (R) alternate status */
+#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
 
 /* Basic DMA Registers */
 #define DMA_C				0x224	/* Basic DMA Command */
@@ -530,6 +536,7 @@
 	int			in_idx;		/* Next read CRPB */
 	u_int			transfersize;	/* PIO transfer size */
 	u_int			donecount;	/* PIO bytes sent/received */
+	u_int			fake_busy;	/* Fake busy bit after command submission */
 	union ccb		*frozen;	/* Frozen command */
 	struct callout		pm_timer;	/* Power management events */
 
@@ -551,7 +558,7 @@
 	int			quirks;
 	int			channels;
 	int			ccc;		/* CCC timeout */
-	int			cccv;		/* CCC vector */
+	int			cccc;		/* CCC commands */
 	struct {
 		void			(*function)(void *);
 		void			*argument;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004171706.o3HH6VMl061033>