From 51d76425033b27609fb4e206c7c9610cd4c4a653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 13 Jan 2011 19:41:01 +0000 Subject: [PATCH] * Added a new B_GET_DEVICE_NAME ioctl - this should be implemented by all drivers in the future, such that NetworkStatus and similar software can show nice names for the devices. The device manager should implement this and return the B_DEVICE_PRETTY_NAME of the device (and in turn, new style drivers should actually set this). * Implemented handling of this ioctl in the scsi_periph to return the vendor/ product strings. * Implemented this in the ATA bus manager to return the model from the info block. * KDiskDevice now fills in the partition_data::name if the B_GET_DEVICE_NAME succeeds. * As a side effect, at least BootManager now shows the drive name; maybe DriveSetup does as well for the raw device. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40231 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/Drivers.h | 4 +- .../kernel/bus_managers/ata/ATAChannel.cpp | 10 ++++ .../kernel/bus_managers/ata/ATADevice.cpp | 22 +++++++++ .../kernel/bus_managers/ata/ATAModule.cpp | 4 +- .../kernel/bus_managers/ata/ATAPrivate.h | 3 ++ src/add-ons/kernel/generic/scsi_periph/io.cpp | 46 ++++++++++++++++--- .../disk_device_manager/KDiskDevice.cpp | 4 ++ 7 files changed, 83 insertions(+), 10 deletions(-) diff --git a/headers/os/drivers/Drivers.h b/headers/os/drivers/Drivers.h index 904f33279c..3484dbfdf7 100644 --- a/headers/os/drivers/Drivers.h +++ b/headers/os/drivers/Drivers.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008, Haiku Inc. All Rights Reserved. + * Copyright 2002-2011, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _DRIVERS_DRIVERS_H @@ -105,6 +105,7 @@ enum { B_GET_PATH_FOR_DEVICE, /* get the absolute path of the device */ B_GET_ICON_NAME, /* get an icon name identifier */ B_GET_VECTOR_ICON, /* retrieves the device's vector icon */ + B_GET_DEVICE_NAME, /* get name, string buffer */ B_GET_NEXT_OPEN_DEVICE = 1000, /* obsolete, will be removed */ B_ADD_FIXED_DRIVER, /* obsolete, will be removed */ @@ -172,4 +173,5 @@ typedef struct { } #endif + #endif /* _DRIVERS_DRIVERS_H */ diff --git a/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp b/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp index 8ff706023d..969ed2b328 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp +++ b/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp @@ -338,6 +338,16 @@ ATAChannel::ExecuteIO(scsi_ccb *ccb) } +status_t +ATAChannel::Control(uint8 targetID, uint32 opcode, void *buffer, size_t length) +{ + if (targetID < fDeviceCount && fDevices[targetID] != NULL) + return fDevices[targetID]->Control(opcode, buffer, length); + + return B_BAD_VALUE; +} + + status_t ATAChannel::SelectDevice(uint8 device) { diff --git a/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp b/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp index ce67d0bcd4..e8d509cba7 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp +++ b/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp @@ -369,6 +369,28 @@ ATADevice::GetRestrictions(bool *noAutoSense, uint32 *maxBlocks) } +status_t +ATADevice::Control(uint32 opcode, void *buffer, size_t length) +{ + if (opcode == B_GET_DEVICE_NAME) { + // Swap words + char name[sizeof(fInfoBlock.model_number)]; + memcpy(name, fInfoBlock.model_number, sizeof(name)); + swap_words(name, sizeof(name)); + + // Remove trailing spaces + int32 nameLength = sizeof(name) - 2; + while (nameLength > 0 && name[nameLength - 1] == ' ') + nameLength--; + + // TODO: make string prettier, ie. "WDC" -> "Western Digital", ... + return user_strlcpy((char*)buffer, name, + min_c((size_t)nameLength + 1, length)) >= 0 ? B_OK : B_BAD_ADDRESS; + } + return B_BAD_VALUE; +} + + status_t ATADevice::Select() { diff --git a/src/add-ons/kernel/bus_managers/ata/ATAModule.cpp b/src/add-ons/kernel/bus_managers/ata/ATAModule.cpp index 8e7021ae32..82d6fae452 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATAModule.cpp +++ b/src/add-ons/kernel/bus_managers/ata/ATAModule.cpp @@ -157,8 +157,8 @@ static status_t ata_sim_control(scsi_sim_cookie cookie, uchar targetID, uint32 op, void *buffer, size_t length) { - // TODO implement - return B_BAD_VALUE; + ATAChannel *channel = (ATAChannel *)cookie; + return channel->Control(targetID, op, buffer, length); } diff --git a/src/add-ons/kernel/bus_managers/ata/ATAPrivate.h b/src/add-ons/kernel/bus_managers/ata/ATAPrivate.h index 8f01a4fba7..59cb14a8d5 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATAPrivate.h +++ b/src/add-ons/kernel/bus_managers/ata/ATAPrivate.h @@ -76,6 +76,8 @@ public: void GetRestrictions(uint8 targetID, bool *isATAPI, bool *noAutoSense, uint32 *maxBlocks); status_t ExecuteIO(scsi_ccb *ccb); + status_t Control(uint8 targetID, uint32 op, void *buffer, + size_t length); // ATA stuff status_t SelectDevice(uint8 index); @@ -181,6 +183,7 @@ public: void GetRestrictions(bool *noAutoSense, uint32 *maxBlocks); + status_t Control(uint32 op, void *buffer, size_t length); // ATA stuff virtual bool IsATAPI() const { return false; } diff --git a/src/add-ons/kernel/generic/scsi_periph/io.cpp b/src/add-ons/kernel/generic/scsi_periph/io.cpp index 98348f47d1..c110e9dbcd 100644 --- a/src/add-ons/kernel/generic/scsi_periph/io.cpp +++ b/src/add-ons/kernel/generic/scsi_periph/io.cpp @@ -1,6 +1,6 @@ /* - * Copyright 2004-2010, Haiku, Inc. All Rights Reserved. - * Copyright 2002/03, Thomas Kurschel. All rights reserved. + * Copyright 2004-2011, Haiku, Inc. All Rights Reserved. + * Copyright 2002-03, Thomas Kurschel. All rights reserved. * * Distributed under the terms of the MIT License. */ @@ -272,18 +272,50 @@ periph_ioctl(scsi_periph_handle_info *handle, int op, void *buffer, size_t length) { switch (op) { - case B_GET_MEDIA_STATUS: { - status_t res = B_OK; + case B_GET_MEDIA_STATUS: + { + status_t status = B_OK; if (handle->device->removable) - res = periph_get_media_status(handle); + status = periph_get_media_status(handle); - SHOW_FLOW(2, "%s", strerror(res)); + SHOW_FLOW(2, "%s", strerror(status)); - *(status_t *)buffer = res; + *(status_t *)buffer = status; return B_OK; } + case B_GET_DEVICE_NAME: + { + // TODO: this should be written as an attribute to the node + // Try driver further up first + if (handle->device->scsi->ioctl != NULL) { + status_t status = handle->device->scsi->ioctl( + handle->device->scsi_device, op, buffer, length); + if (status == B_OK) + return B_OK; + } + + // If that fails, get SCSI vendor/product + const char* vendor; + if (gDeviceManager->get_attr_string(handle->device->node, + SCSI_DEVICE_VENDOR_ITEM, &vendor, true) == B_OK) { + char name[B_FILE_NAME_LENGTH]; + strlcpy(name, vendor, sizeof(name)); + + const char* product; + if (gDeviceManager->get_attr_string(handle->device->node, + SCSI_DEVICE_PRODUCT_ITEM, &product, true) == B_OK) { + strlcat(name, " ", sizeof(name)); + strlcat(name, product, sizeof(name)); + } + + return user_strlcpy((char*)buffer, name, length) >= 0 + ? B_OK : B_BAD_ADDRESS; + } + return B_ERROR; + } + case B_SCSI_INQUIRY: return inquiry(handle->device, (scsi_inquiry *)buffer); diff --git a/src/system/kernel/disk_device_manager/KDiskDevice.cpp b/src/system/kernel/disk_device_manager/KDiskDevice.cpp index 7f704d68c4..b074b4d1c0 100644 --- a/src/system/kernel/disk_device_manager/KDiskDevice.cpp +++ b/src/system/kernel/disk_device_manager/KDiskDevice.cpp @@ -397,6 +397,10 @@ KDiskDevice::_InitPartitionData() * fDeviceData.geometry.cylinder_count * fDeviceData.geometry.head_count; fPartitionData.flags |= B_PARTITION_IS_DEVICE; + + char name[B_FILE_NAME_LENGTH]; + if (ioctl(fFD, B_GET_DEVICE_NAME, name, sizeof(name)) == B_OK) + fPartitionData.name = strdup(name); }