ahci: Improve emulated SCSI vendor/model info
* Make some educated gusses on SCSI vendor/model information vs just blasting it across the fields. * Should resolve a lot of the weird split SCSI vendor and model information of AHCI backed devices.
This commit is contained in:
parent
05fc1277c4
commit
9be1b5a16f
@ -769,13 +769,29 @@ AHCIPort::ScsiInquiry(scsi_ccb* request)
|
||||
// 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));
|
||||
// ident and another 4 for product revision.
|
||||
size_t vendorLen = strcspn(modelNumber, " ");
|
||||
if (vendorLen >= sizeof(scsiData.vendor_ident))
|
||||
vendorLen = strcspn(modelNumber, "-");
|
||||
if (vendorLen < sizeof(scsiData.vendor_ident)) {
|
||||
// First we try to break things apart smartly.
|
||||
snprintf(scsiData.vendor_ident, vendorLen + 1, "%s", modelNumber);
|
||||
size_t modelRemain = (sizeof(modelNumber) - vendorLen);
|
||||
if (modelRemain > sizeof(scsiData.product_ident))
|
||||
modelRemain = sizeof(scsiData.product_ident);
|
||||
memcpy(scsiData.product_ident, modelNumber + (vendorLen + 1),
|
||||
modelRemain);
|
||||
} else {
|
||||
// If we're unable to smartly break apart the vendor and model, just
|
||||
// dumbly squeeze as much in as possible.
|
||||
memcpy(scsiData.vendor_ident, modelNumber, sizeof(scsiData.vendor_ident));
|
||||
memcpy(scsiData.product_ident, modelNumber + 8,
|
||||
sizeof(scsiData.product_ident));
|
||||
}
|
||||
// Take the last 4 digits of the serial number as product rev
|
||||
size_t serialLen = sizeof(scsiData.product_rev);
|
||||
size_t serialOff = sizeof(serialNumber) - serialLen;
|
||||
memcpy(scsiData.product_rev, serialNumber + serialOff, serialLen);
|
||||
|
||||
if (sg_memcpy(request->sg_list, request->sg_count, &scsiData,
|
||||
sizeof(scsiData)) < B_OK) {
|
||||
|
Loading…
Reference in New Issue
Block a user