Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 May 2009 21:39:41 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 162820 for review
Message-ID:  <200905262139.n4QLdfmj050171@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=162820

Change 162820 by mav@mav_mavbook on 2009/05/26 21:38:43

	Most parts of ATAPI support. Error reporting still TBD,

Affected files ...

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

Differences ...

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

@@ -694,10 +694,18 @@
 
 	/* if request moves data setup and load SG list */
 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
-		if (bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map,
-		    ccb->ataio.data_ptr, ccb->ataio.dxfer_len,
-		    ahci_dmasetprd, slot, BUS_DMA_NOWAIT)) {
-			device_printf(dev, "FAILURE - load data\n");
+		if (ccb->ccb_h.func_code == XPT_ATA_IO) {
+			if (bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map,
+			    ccb->ataio.data_ptr, ccb->ataio.dxfer_len,
+			    ahci_dmasetprd, slot, BUS_DMA_NOWAIT)) {
+				device_printf(dev, "FAILURE - load data\n");
+			}
+		} else {
+			if (bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map,
+			    ccb->csio.data_ptr, ccb->csio.dxfer_len,
+			    ahci_dmasetprd, slot, BUS_DMA_NOWAIT)) {
+				device_printf(dev, "FAILURE - load data\n");
+			}
 		}
 		return;
 	}
@@ -772,8 +780,8 @@
 
 	clp->prd_length = slot->dma.nsegs;
 	clp->cmd_flags = (slot->ccb->ccb_h.flags & CAM_DIR_OUT ? AHCI_CMD_WRITE : 0) |
-		     /*(request->flags & ATA_R_ATAPI ?
-		      (AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH) : 0) |*/
+		     (slot->ccb->ccb_h.func_code == XPT_SCSI_IO ?
+		      (AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH) : 0) |
 		     (fis_size / sizeof(u_int32_t)) |
 		     (port << 12);
 	clp->bytecount = 0;
@@ -785,16 +793,17 @@
 //		 ATA_IDX_INL(ch, ATA_SACTIVE) & (1 << slot->slot));
 
 	/* set command type bit */
-/*    if (request->flags & ATA_R_ATAPI)
-	ATA_OUTL(ch->r_mem, AHCI_P_CMD,
-		 ATA_INL(ch->r_mem, AHCI_P_CMD) |
-		 AHCI_P_CMD_ATAPI);
-    else*/
+	if (slot->ccb->ccb_h.func_code == XPT_SCSI_IO) {
+		ATA_OUTL(ch->r_mem, AHCI_P_CMD,
+		    ATA_INL(ch->r_mem, AHCI_P_CMD) | AHCI_P_CMD_ATAPI);
+	} else {
 		ATA_OUTL(ch->r_mem, AHCI_P_CMD,
 		    ATA_INL(ch->r_mem, AHCI_P_CMD) & ~AHCI_P_CMD_ATAPI);
+	}
 
 	slot->state = AHCI_SLOT_RUNNING;
 	ch->rslots |= (1 << slot->slot);
+
 	/* issue command to controller */
 	ATA_OUTL(ch->r_mem, AHCI_P_CI, (1 << slot->slot));
 /*
@@ -810,30 +819,30 @@
     ATA_INL(ch->r_mem, AHCI_P_TFD),
     ATA_IDX_INL(ch, ATA_SERROR));
 */
-//    if (!(request->flags & ATA_R_ATAPI)) {
-	/* device reset doesn't interrupt */
-	if (slot->ccb->ataio.cmd.command == ATA_DEVICE_RESET) {
-	    u_int32_t tf_data;
-	    int timeout = 1000000;
+
+	if (slot->ccb->ccb_h.func_code == XPT_ATA_IO &&
+	    slot->ccb->ataio.cmd.command == ATA_DEVICE_RESET) {
+		/* device reset doesn't interrupt */
+		u_int32_t tf_data;
+		int timeout = 1000000;
 
-	    do {
-		DELAY(10);
-		tf_data = ATA_INL(ch->r_mem, AHCI_P_TFD + (ch->unit<<7));
-	    } while ((tf_data & ATA_S_BUSY) && timeout--);
-	    if (bootverbose)
-		device_printf(ch->dev, "device_reset timeout=%dus\n",
-			      (1000000-timeout)*10);
-	    slot->ccb->ataio.status = tf_data;
-//	    if (request->status & ATA_S_ERROR)
-//		request->error = tf_data >> 8;
-	    slot->ccb->ccb_h.status = CAM_REQ_CMP;
-	    xpt_done(slot->ccb);
-	    return;
+		do {
+			DELAY(10);
+			tf_data = ATA_INL(ch->r_mem, AHCI_P_TFD + (ch->unit<<7));
+		} while ((tf_data & ATA_S_BUSY) && timeout--);
+		if (bootverbose)
+			device_printf(ch->dev, "device_reset timeout=%dus\n",
+			    (1000000-timeout)*10);
+		slot->ccb->ataio.status = tf_data;
+//		if (request->status & ATA_S_ERROR)
+//			request->error = tf_data >> 8;
+		slot->ccb->ccb_h.status = CAM_REQ_CMP;
+		xpt_done(slot->ccb);
+		return;
 	}
-//    }
 
-    /* start the timeout */
-//    callout_reset(&request->callout, request->timeout * hz,
+	/* start the timeout */
+//	callout_reset(&request->callout, request->timeout * hz,
 //		  (timeout_t*)ata_timeout, request);
 	return;
 }
@@ -1425,49 +1434,48 @@
 ahci_setup_fis(struct ahci_cmd_tab *ctp, union ccb *ccb)
 {
 	u_int8_t *fis = &ctp->cfis[0];
+
 	bzero(ctp->cfis, 64);
-//	if (request->flags & ATA_R_ATAPI) {
-//		bzero(ctp->acmd, 32);
-//		bcopy(request->u.atapi.ccb, ctp->acmd, 16);
-//	}
-#if 0
-    if (request->flags & ATA_R_ATAPI) {
-	fis[0] = 0x27;  		/* host to device */
-	fis[1] = 0x80 | (atadev->unit & 0x0f);
-	fis[2] = ATA_PACKET_CMD;
-	if (request->flags & (ATA_R_READ | ATA_R_WRITE))
-	    fis[3] = ATA_F_DMA;
-	else {
-	    fis[5] = request->transfersize;
-	    fis[6] = request->transfersize >> 8;
+	if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
+		bzero(ctp->acmd, 32);
+		bcopy((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+		    ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes,
+		    ctp->acmd, ccb->csio.cdb_len);
+		fis[0] = 0x27;  		/* host to device */
+//		fis[1] = 0x80 | (atadev->unit & 0x0f);
+		fis[1] = 0x80 | (0 & 0x0f);
+		fis[2] = ATA_PACKET_CMD;
+		if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
+			fis[3] = ATA_F_DMA;
+		else {
+			fis[5] = ccb->csio.dxfer_len;
+		        fis[6] = ccb->csio.dxfer_len >> 8;
+		}
+		fis[7] = ATA_D_LBA;
+		fis[15] = ATA_A_4BIT;
+		return 20;
+	} else {
+//		ata_modify_if_48bit(request);
+		fis[0] = 0x27;			/* host to device */
+//		fis[1] = 0x80 | (atadev->unit & 0x0f);
+		fis[1] = 0x80 | (0 & 0x0f);
+		fis[2] = ccb->ataio.cmd.command;
+		fis[3] = ccb->ataio.cmd.feature;
+		fis[4] = ccb->ataio.cmd.lba;
+		fis[5] = ccb->ataio.cmd.lba >> 8;
+		fis[6] = ccb->ataio.cmd.lba >> 16;
+		fis[7] = ATA_D_LBA;
+//		if (!(atadev->flags & ATA_D_48BIT_ACTIVE))
+			fis[7] |= (ATA_D_IBM | (ccb->ataio.cmd.lba >> 24 & 0x0f));
+		fis[8] = ccb->ataio.cmd.lba >> 24;
+		fis[9] = ccb->ataio.cmd.lba >> 32; 
+		fis[10] = ccb->ataio.cmd.lba >> 40; 
+		fis[11] = ccb->ataio.cmd.feature >> 8;
+		fis[12] = ccb->ataio.cmd.count;
+		fis[13] = ccb->ataio.cmd.count >> 8;
+		fis[15] = ATA_A_4BIT;
+		return 20;
 	}
-	fis[7] = ATA_D_LBA;
-	fis[15] = ATA_A_4BIT;
-	return 20;
-    }
-    else {
-#endif
-//	ata_modify_if_48bit(request);
-	fis[0] = 0x27;			/* host to device */
-//	fis[1] = 0x80 | (atadev->unit & 0x0f);
-	fis[1] = 0x80 | (0 & 0x0f);
-	fis[2] = ccb->ataio.cmd.command;
-	fis[3] = ccb->ataio.cmd.feature;
-	fis[4] = ccb->ataio.cmd.lba;
-	fis[5] = ccb->ataio.cmd.lba >> 8;
-	fis[6] = ccb->ataio.cmd.lba >> 16;
-	fis[7] = ATA_D_LBA;
-//	if (!(atadev->flags & ATA_D_48BIT_ACTIVE))
-	    fis[7] |= (ATA_D_IBM | (ccb->ataio.cmd.lba >> 24 & 0x0f));
-	fis[8] = ccb->ataio.cmd.lba >> 24;
-	fis[9] = ccb->ataio.cmd.lba >> 32; 
-	fis[10] = ccb->ataio.cmd.lba >> 40; 
-	fis[11] = ccb->ataio.cmd.feature >> 8;
-	fis[12] = ccb->ataio.cmd.count;
-	fis[13] = ccb->ataio.cmd.count >> 8;
-	fis[15] = ATA_A_4BIT;
-	return 20;
-//    }
 }
 
 static int
@@ -1556,154 +1564,9 @@
 	switch (ccb->ccb_h.func_code) {
 	/* Common cases first */
 	case XPT_ATA_IO:	/* Execute the requested I/O operation */
+	case XPT_SCSI_IO:
 		ahci_begin_transaction(ch->dev, ccb);
 		break;
-#if 0
-	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
-	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */	{
-		struct	aha_ccb	*accb;
-		struct	aha_hccb *hccb;
-
-		/*
-		 * Get an accb to use.
-		 */
-		if ((accb = ahagetccb(aha)) == NULL) {
-			s = splcam();
-			aha->resource_shortage = TRUE;
-			splx(s);
-			xpt_freeze_simq(aha->sim, /*count*/1);
-			ccb->ccb_h.status = CAM_REQUEUE_REQ;
-			xpt_done(ccb);
-			return;
-		}
-		hccb = &accb->hccb;
-
-		/*
-		 * So we can find the ACCB when an abort is requested
-		 */
-		accb->ccb = ccb;
-		ccb->ccb_h.ccb_accb_ptr = accb;
-		ccb->ccb_h.ccb_aha_ptr = aha;
-
-		/*
-		 * Put all the arguments for the xfer in the accb
-		 */
-		hccb->target = ccb->ccb_h.target_id;
-		hccb->lun = ccb->ccb_h.target_lun;
-		hccb->ahastat = 0;
-		hccb->sdstat = 0;
-
-		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
-			struct ccb_scsiio *csio;
-			struct ccb_hdr *ccbh;
-
-			csio = &ccb->csio;
-			ccbh = &csio->ccb_h;
-			hccb->opcode = aha->ccb_ccb_opcode;
-			hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0;
-			hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0;
-			hccb->cmd_len = csio->cdb_len;
-			if (hccb->cmd_len > sizeof(hccb->scsi_cdb)) {
-				ccb->ccb_h.status = CAM_REQ_INVALID;
-				ahafreeccb(aha, accb);
-				xpt_done(ccb);
-				return;
-			}
-			hccb->sense_len = csio->sense_len;
-			if ((ccbh->flags & CAM_CDB_POINTER) != 0) {
-				if ((ccbh->flags & CAM_CDB_PHYS) == 0) {
-					bcopy(csio->cdb_io.cdb_ptr,
-					      hccb->scsi_cdb, hccb->cmd_len);
-				} else {
-					/* I guess I could map it in... */
-					ccbh->status = CAM_REQ_INVALID;
-					ahafreeccb(aha, accb);
-					xpt_done(ccb);
-					return;
-				}
-			} else {
-				bcopy(csio->cdb_io.cdb_bytes,
-				      hccb->scsi_cdb, hccb->cmd_len);
-			}
-			/*
-			 * If we have any data to send with this command,
-			 * map it into bus space.
-			 */
-		        /* Only use S/G if there is a transfer */
-			if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
-				if ((ccbh->flags & CAM_SCATTER_VALID) == 0) {
-					/*
-					 * We've been given a pointer
-					 * to a single buffer.
-					 */
-					if ((ccbh->flags & CAM_DATA_PHYS)==0) {
-						int error;
-
-						s = splsoftvm();
-						error = bus_dmamap_load(
-						    aha->buffer_dmat,
-						    accb->dmamap,
-						    csio->data_ptr,
-						    csio->dxfer_len,
-						    ahaexecuteccb,
-						    accb,
-						    /*flags*/0);
-						if (error == EINPROGRESS) {
-							/*
-							 * So as to maintain
-							 * ordering, freeze the
-							 * controller queue
-							 * until our mapping is
-							 * returned.
-							 */
-							xpt_freeze_simq(aha->sim,
-									1);
-							csio->ccb_h.status |=
-							    CAM_RELEASE_SIMQ;
-						}
-						splx(s);
-					} else {
-						struct bus_dma_segment seg;
-
-						/* Pointer to physical buffer */
-						seg.ds_addr =
-						    (bus_addr_t)csio->data_ptr;
-						seg.ds_len = csio->dxfer_len;
-						ahaexecuteccb(accb, &seg, 1, 0);
-					}
-				} else {
-					struct bus_dma_segment *segs;
-
-					if ((ccbh->flags & CAM_DATA_PHYS) != 0)
-						panic("ahaaction - Physical "
-						      "segment pointers "
-						      "unsupported");
-
-					if ((ccbh->flags&CAM_SG_LIST_PHYS)==0)
-						panic("ahaaction - Virtual "
-						      "segment addresses "
-						      "unsupported");
-
-					/* Just use the segments provided */
-					segs = (struct bus_dma_segment *)
-					    csio->data_ptr;
-					ahaexecuteccb(accb, segs,
-						     csio->sglist_cnt, 0);
-				}
-			} else {
-				ahaexecuteccb(accb, NULL, 0, 0);
-			}
-		} else {
-			hccb->opcode = INITIATOR_BUS_DEV_RESET;
-			/* No data transfer */
-			hccb->datain = TRUE;
-			hccb->dataout = TRUE;
-			hccb->cmd_len = 0;
-			hccb->sense_len = 0;
-			ahaexecuteccb(accb, NULL, 0, 0);
-		}
-		break;
-	}
 	case XPT_EN_LUN:		/* Enable LUN as a target */
 	case XPT_TARGET_IO:		/* Execute target I/O request */
 	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
@@ -1718,7 +1581,6 @@
 		ccb->ccb_h.status = CAM_PROVIDE_FAIL;
 		xpt_done(ccb);
 		break;
-#endif
 	case XPT_GET_TRAN_SETTINGS:
 	/* Get default/user set transfer settings for the target */
 	{
@@ -1780,7 +1642,8 @@
 		struct ccb_pathinq *cpi = &ccb->cpi;
 
 		if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD ||
-		    ((ATA_ATA_MASTER << (ccb->ccb_h.target_id - 1)) & ch->devices)) {
+		    (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) <<
+			(ccb->ccb_h.target_id - 1)) & ch->devices)) {
 
 		cpi->version_num = 1; /* XXX??? */
 		cpi->hba_inquiry = PI_SDTR_ABLE;
@@ -1796,10 +1659,13 @@
 		strncpy(cpi->hba_vid, "AHCI", HBA_IDLEN);
 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 		cpi->unit_number = cam_sim_unit(sim);
-                cpi->transport = XPORT_ATA;
-                cpi->transport_version = 2;
-                cpi->protocol = PROTO_ATA;
-                cpi->protocol_version = SCSI_REV_2;
+		cpi->transport = XPORT_ATA;
+		cpi->transport_version = 2;
+		if ((ATA_ATA_MASTER << (ccb->ccb_h.target_id - 1)) & ch->devices)
+			cpi->protocol = PROTO_ATA;
+		else
+			cpi->protocol = PROTO_SCSI;
+		cpi->protocol_version = SCSI_REV_2;
 		cpi->ccb_h.status = CAM_REQ_CMP;
 		} else {
 		    ccb->ccb_h.status = CAM_REQ_INVALID;



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