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.
This commit is contained in:
Michael Lotz
2012-11-28 21:30:00 +01:00
parent f125673c3f
commit 9def48ad2e
2 changed files with 59 additions and 0 deletions
@@ -573,6 +573,16 @@ usb_disk_inquiry(device_lun *lun)
parameter.product_identification); parameter.product_identification);
TRACE_ALWAYS("product_revision_level \"%.4s\"\n", TRACE_ALWAYS("product_revision_level \"%.4s\"\n",
parameter.product_revision_level); 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->device_type = parameter.peripherial_device_type; /* 1:1 mapping */
lun->removable = (parameter.removable_medium == 1); lun->removable = (parameter.removable_medium == 1);
return B_OK; return B_OK;
@@ -774,6 +784,11 @@ usb_disk_device_added(usb_device newDevice, void **cookie)
lun->should_sync = false; lun->should_sync = false;
lun->media_present = true; lun->media_present = true;
lun->media_changed = 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); usb_disk_reset_capacity(lun);
// initialize this 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 static status_t
usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) 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)); result = user_memcpy(buffer, &iconData, sizeof(device_icon));
break; 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 #endif
default: default:
@@ -74,6 +74,10 @@ struct device_lun_s {
uint8 device_type; uint8 device_type;
bool removable; bool removable;
bool write_protected; bool write_protected;
char vendor_name[8];
char product_name[16];
char product_revision[4];
}; };