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>