From 9def48ad2e7ef77665a09724536d4f456405b64c Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 28 Nov 2012 21:26:18 +0100 Subject: [PATCH] Implement B_GET_DEVICE_NAME in usb_disk returning SCSI info. The SCSI inquiry vendor and product information is concatenated into a single string to form the device name. Multiple spaces are then collapsed to make the string more readable. The space padding is quite common as the fields are fixed size in the inquiry block. --- .../drivers/disk/usb/usb_disk/usb_disk.cpp | 55 +++++++++++++++++++ .../drivers/disk/usb/usb_disk/usb_disk.h | 4 ++ 2 files changed, 59 insertions(+) diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index b01e828cca..31cf38afdb 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -573,6 +573,16 @@ usb_disk_inquiry(device_lun *lun) parameter.product_identification); TRACE_ALWAYS("product_revision_level \"%.4s\"\n", parameter.product_revision_level); + + memcpy(lun->vendor_name, parameter.vendor_identification, + MIN(sizeof(lun->vendor_name), sizeof(parameter.vendor_identification))); + memcpy(lun->product_name, parameter.product_identification, + MIN(sizeof(lun->product_name), + sizeof(parameter.product_identification))); + memcpy(lun->product_revision, parameter.product_revision_level, + MIN(sizeof(lun->product_revision), + sizeof(parameter.product_revision_level))); + lun->device_type = parameter.peripherial_device_type; /* 1:1 mapping */ lun->removable = (parameter.removable_medium == 1); return B_OK; @@ -774,6 +784,11 @@ usb_disk_device_added(usb_device newDevice, void **cookie) lun->should_sync = false; lun->media_present = true; lun->media_changed = true; + + memset(lun->vendor_name, 0, sizeof(lun->vendor_name)); + memset(lun->product_name, 0, sizeof(lun->product_name)); + memset(lun->product_revision, 0, sizeof(lun->product_revision)); + usb_disk_reset_capacity(lun); // initialize this lun @@ -1034,6 +1049,27 @@ usb_disk_free(void *cookie) } +static inline void +normalize_name(char *name, size_t nameLength) +{ + bool wasSpace = false; + size_t insertIndex = 0; + for (size_t i = 0; i < nameLength; i++) { + bool isSpace = name[i] == ' '; + if (isSpace && wasSpace) + continue; + + name[insertIndex++] = name[i]; + wasSpace = isSpace; + } + + if (insertIndex > 0 && name[insertIndex - 1] == ' ') + insertIndex--; + + name[insertIndex] = 0; +} + + static status_t usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) { @@ -1128,6 +1164,25 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) result = user_memcpy(buffer, &iconData, sizeof(device_icon)); break; } + + case B_GET_DEVICE_NAME: + { + size_t nameLength = sizeof(lun->vendor_name) + + sizeof(lun->product_name) + sizeof(lun->product_revision) + 3; + + char name[nameLength]; + snprintf(name, nameLength, "%.8s %.16s %.4s", lun->vendor_name, + lun->product_name, lun->product_revision); + + normalize_name(name, nameLength); + + result = user_strlcpy((char *)buffer, name, length); + if (result > 0) + result = B_OK; + + TRACE_ALWAYS("got device name: \"%s\" = %s\n", name, strerror(result)); + break; + } #endif default: diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.h b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.h index d41c30582c..143a535d68 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.h +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.h @@ -74,6 +74,10 @@ struct device_lun_s { uint8 device_type; bool removable; bool write_protected; + + char vendor_name[8]; + char product_name[16]; + char product_revision[4]; };