void AHCIPort::ScsiReadCapacity(scsi_ccb *request) { TRACE("AHCIPort::ScsiReadCapacity port %d\n", fIndex); const scsi_cmd_read_capacity *cmd = (const scsi_cmd_read_capacity *)request->cdb; scsi_res_read_capacity scsiData; if (cmd->pmi || cmd->lba || request->data_length < sizeof(scsiData)) { TRACE("invalid request\n"); request->subsys_status = SCSI_REQ_ABORTED; gSCSI->finished(request, 1); return; } TRACE("SectorSize %" B_PRIu32 ", SectorCount 0x%" B_PRIx64 "\n", fSectorSize, fSectorCount); scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize); if (fSectorCount <= 0xffffffff) scsiData.lba = B_HOST_TO_BENDIAN_INT32(fSectorCount - 1); else scsiData.lba = 0xffffffff; if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) { request->subsys_status = SCSI_DATA_RUN_ERR; } else { request->subsys_status = SCSI_REQ_CMP; request->data_resid = request->data_length - sizeof(scsiData); } gSCSI->finished(request, 1); }
void AHCIPort::ScsiReadCapacity(scsi_ccb *request) { TRACE("AHCIPort::ScsiReadCapacity port %d\n", fIndex); scsi_cmd_read_capacity *cmd = (scsi_cmd_read_capacity *)request->cdb; scsi_res_read_capacity scsiData; if (cmd->pmi || cmd->lba || request->data_length < sizeof(scsiData)) { TRACE("invalid request\n"); return; } TRACE("SectorSize %lu, SectorCount 0x%llx\n", fSectorSize, fSectorCount); if (fSectorCount > 0xffffffff) panic("ahci: SCSI emulation doesn't support harddisks larger than 2TB"); scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize); scsiData.lba = B_HOST_TO_BENDIAN_INT32(fSectorCount - 1); if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) { request->subsys_status = SCSI_DATA_RUN_ERR; } else { request->subsys_status = SCSI_REQ_CMP; request->data_resid = request->data_length - sizeof(scsiData); } gSCSI->finished(request, 1); }
void AHCIPort::ScsiReadCapacity16(scsi_ccb* request) { TRACE("AHCIPort::ScsiReadCapacity16 port %d\n", fIndex); scsi_res_read_capacity_long scsiData; TRACE("SectorSize %" B_PRIu32 ", SectorCount 0x%" B_PRIx64 "\n", fSectorSize, fSectorCount); scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize); scsiData.lba = B_HOST_TO_BENDIAN_INT64(fSectorCount - 1); if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) { request->subsys_status = SCSI_DATA_RUN_ERR; } else { request->subsys_status = SCSI_REQ_CMP; request->data_resid = request->data_length - sizeof(scsiData); } gSCSI->finished(request, 1); }
void AHCIPort::ScsiInquiry(scsi_ccb *request) { TRACE("AHCIPort::ScsiInquiry port %d\n", fIndex); const scsi_cmd_inquiry *cmd = (const scsi_cmd_inquiry *)request->cdb; scsi_res_inquiry scsiData; ata_device_infoblock ataData; ASSERT(sizeof(ataData) == 512); if (cmd->evpd || cmd->page_code || request->data_length < sizeof(scsiData)) { TRACE("invalid request\n"); request->subsys_status = SCSI_REQ_ABORTED; gSCSI->finished(request, 1); return; } sata_request sreq; sreq.set_data(&ataData, sizeof(ataData)); sreq.set_ata_cmd(fIsATAPI ? 0xa1 : 0xec); // Identify (Packet) Device ExecuteSataRequest(&sreq); sreq.wait_for_completion(); if (sreq.completion_status() & ATA_ERR) { TRACE("identify device failed\n"); request->subsys_status = SCSI_REQ_CMP_ERR; gSCSI->finished(request, 1); return; } /* uint8 *data = (uint8*) &ataData; for (int i = 0; i < 512; i += 8) { TRACE(" %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]); } */ scsiData.device_type = fIsATAPI ? ataData.word_0.atapi.command_packet_set : scsi_dev_direct_access; scsiData.device_qualifier = scsi_periph_qual_connected; scsiData.device_type_modifier = 0; scsiData.removable_medium = ataData.word_0.ata.removable_media_device; scsiData.ansi_version = 2; scsiData.ecma_version = 0; scsiData.iso_version = 0; scsiData.response_data_format = 2; scsiData.term_iop = false; scsiData.additional_length = sizeof(scsi_res_inquiry) - 4; scsiData.soft_reset = false; scsiData.cmd_queue = false; scsiData.linked = false; scsiData.sync = false; scsiData.write_bus16 = true; scsiData.write_bus32 = false; scsiData.relative_address = false; if (!fIsATAPI) { fSectorCount = ataData.SectorCount(fUse48BitCommands, true); fSectorSize = ataData.SectorSize(); fTrim = ataData.data_set_management_support; TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %" B_PRIu32 ", sectors48 %" B_PRIu64 ", size %" B_PRIu64 "\n", ataData.dma_supported != 0, ataData.lba48_supported != 0, fUse48BitCommands, ataData.lba_sector_count, ataData.lba48_sector_count, fSectorCount * fSectorSize); } #if 0 if (fSectorCount < 0x0fffffff) { TRACE("disabling 48 bit commands\n"); fUse48BitCommands = 0; } #endif char modelNumber[sizeof(ataData.model_number) + 1]; char serialNumber[sizeof(ataData.serial_number) + 1]; char firmwareRev[sizeof(ataData.firmware_revision) + 1]; strlcpy(modelNumber, ataData.model_number, sizeof(modelNumber)); strlcpy(serialNumber, ataData.serial_number, sizeof(serialNumber)); strlcpy(firmwareRev, ataData.firmware_revision, sizeof(firmwareRev)); swap_words(modelNumber, sizeof(modelNumber) - 1); swap_words(serialNumber, sizeof(serialNumber) - 1); swap_words(firmwareRev, sizeof(firmwareRev) - 1); TRACE("model number: %s\n", modelNumber); TRACE("serial number: %s\n", serialNumber); TRACE("firmware rev.: %s\n", firmwareRev); TRACE("trim support: %s\n", fTrim ? "yes" : "no"); // There's not enough space to fit all of the data in. ATA has 40 bytes for // the model number, 20 for the serial number and another 8 for the // firmware revision. SCSI has room for 8 for vendor ident, 16 for product // ident and another 4 for product revision. We just try and fit in as much // as possible of the model number into the vendor and product ident fields // and put a little of the serial number into the product revision field. memcpy(scsiData.vendor_ident, modelNumber, sizeof(scsiData.vendor_ident)); memcpy(scsiData.product_ident, modelNumber + 8, sizeof(scsiData.product_ident)); memcpy(scsiData.product_rev, serialNumber, sizeof(scsiData.product_rev)); if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) { request->subsys_status = SCSI_DATA_RUN_ERR; } else { request->subsys_status = SCSI_REQ_CMP; request->data_resid = request->data_length - sizeof(scsiData); } gSCSI->finished(request, 1); }
void AHCIPort::ScsiInquiry(scsi_ccb *request) { TRACE("AHCIPort::ScsiInquiry port %d\n", fIndex); scsi_cmd_inquiry *cmd = (scsi_cmd_inquiry *)request->cdb; scsi_res_inquiry scsiData; ata_res_identify_device ataData; ASSERT(sizeof(ataData) == 512); if (cmd->evpd || cmd->page_code || request->data_length < sizeof(scsiData)) { TRACE("invalid request\n"); request->subsys_status = SCSI_REQ_ABORTED; gSCSI->finished(request, 1); return; } sata_request sreq; sreq.set_data(&ataData, sizeof(ataData)); sreq.set_ata_cmd(fIsATAPI ? 0xa1 : 0xec); // Identify (Packet) Device ExecuteSataRequest(&sreq); sreq.wait_for_completition(); if (sreq.completition_status() & ATA_ERR) { TRACE("identify device failed\n"); request->subsys_status = SCSI_REQ_CMP_ERR; gSCSI->finished(request, 1); return; } /* uint8 *data = (uint8*) &ataData; for (int i = 0; i < 512; i += 8) { TRACE(" %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]); } */ scsiData.device_type = fIsATAPI ? scsi_dev_CDROM : scsi_dev_direct_access; scsiData.device_qualifier = scsi_periph_qual_connected; scsiData.device_type_modifier = 0; scsiData.removable_medium = fIsATAPI; scsiData.ansi_version = 2; scsiData.ecma_version = 0; scsiData.iso_version = 0; scsiData.response_data_format = 2; scsiData.term_iop = false; scsiData.additional_length = sizeof(scsiData) - 4; scsiData.soft_reset = false; scsiData.cmd_queue = false; scsiData.linked = false; scsiData.sync = false; scsiData.write_bus16 = true; scsiData.write_bus32 = false; scsiData.relative_address = false; memcpy(scsiData.vendor_ident, ataData.model_number, sizeof(scsiData.vendor_ident)); memcpy(scsiData.product_ident, ataData.model_number + 8, sizeof(scsiData.product_ident)); memcpy(scsiData.product_rev, ataData.serial_number, sizeof(scsiData.product_rev)); if (!fIsATAPI) { bool lba = (ataData.words[49] & (1 << 9)) != 0; bool lba48 = (ataData.words[83] & (1 << 10)) != 0; uint32 sectors = *(uint32*)&ataData.words[60]; uint64 sectors48 = *(uint64*)&ataData.words[100]; fUse48BitCommands = lba && lba48; fSectorSize = 512; fSectorCount = !(lba || sectors) ? 0 : lba48 ? sectors48 : sectors; TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %lu, " "sectors48 %llu, size %llu\n", lba, lba48, fUse48BitCommands, sectors, sectors48, fSectorCount * fSectorSize); } #if 0 if (fSectorCount < 0x0fffffff) { TRACE("disabling 48 bit commands\n"); fUse48BitCommands = 0; } #endif char modelNumber[sizeof(ataData.model_number) + 1]; char serialNumber[sizeof(ataData.serial_number) + 1]; char firmwareRev[sizeof(ataData.firmware_revision) + 1]; strlcpy(modelNumber, ataData.model_number, sizeof(modelNumber)); strlcpy(serialNumber, ataData.serial_number, sizeof(serialNumber)); strlcpy(firmwareRev, ataData.firmware_revision, sizeof(firmwareRev)); swap_words(modelNumber, sizeof(modelNumber) - 1); swap_words(serialNumber, sizeof(serialNumber) - 1); swap_words(firmwareRev, sizeof(firmwareRev) - 1); TRACE("model number: %s\n", modelNumber); TRACE("serial number: %s\n", serialNumber); TRACE("firmware rev.: %s\n", firmwareRev); if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) { request->subsys_status = SCSI_DATA_RUN_ERR; } else { request->subsys_status = SCSI_REQ_CMP; request->data_resid = request->data_length - sizeof(scsiData); } gSCSI->finished(request, 1); }
template<class T> SGNDArray<T> SGNDArray<T>::clone() const { SGNDArray<T> array_clone(get_dimensions()); sg_memcpy(array_clone.array, array, sizeof(T)*len_array); return array_clone; }