PERFORCE change 162820 for review
Alexander Motin
mav at FreeBSD.org
Tue May 26 21:39:46 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=162820
Change 162820 by mav at 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;
More information about the p4-projects
mailing list