diff --git a/headers/os/drivers/bus/SCSI.h b/headers/os/drivers/bus/SCSI.h index ed4b616387..af91138c56 100644 --- a/headers/os/drivers/bus/SCSI.h +++ b/headers/os/drivers/bus/SCSI.h @@ -288,6 +288,8 @@ typedef struct { // maximum targets on scsi bus #define SCSI_DEVICE_MAX_TARGET_COUNT "scsi/max_target_count" +// maximum luns on scsi bus +#define SCSI_DEVICE_MAX_LUN_COUNT "scsi/max_lun_count" // directory containing links to peripheral drivers #define SCSI_PERIPHERAL_DRIVERS_DIR "scsi" diff --git a/src/add-ons/kernel/bus_managers/scsi/busses.cpp b/src/add-ons/kernel/bus_managers/scsi/busses.cpp index d5a17d4c3c..934cf3215e 100644 --- a/src/add-ons/kernel/bus_managers/scsi/busses.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/busses.cpp @@ -101,6 +101,15 @@ scsi_create_bus(device_node *node, uint8 path_id) if (pnp->get_attr_uint32(node, SCSI_DEVICE_MAX_TARGET_COUNT, &bus->max_target_count, true) != B_OK) bus->max_target_count = MAX_TARGET_ID + 1; + if (pnp->get_attr_uint32(node, SCSI_DEVICE_MAX_LUN_COUNT, &bus->max_lun_count, true) != B_OK) + bus->max_lun_count = MAX_LUN_ID + 1; + + // our scsi_ccb only has a uchar for target_id + if (bus->max_target_count > 256) + bus->max_target_count = 256; + // our scsi_ccb only has a uchar for target_lun + if (bus->max_lun_count > 256) + bus->max_lun_count = 256; bus->node = node; bus->lock_count = bus->blocked[0] = bus->blocked[1] = 0; diff --git a/src/add-ons/kernel/bus_managers/scsi/device_scan.cpp b/src/add-ons/kernel/bus_managers/scsi/device_scan.cpp index 99c39ce488..bb0ffe83b5 100644 --- a/src/add-ons/kernel/bus_managers/scsi/device_scan.cpp +++ b/src/add-ons/kernel/bus_managers/scsi/device_scan.cpp @@ -251,18 +251,16 @@ err: status_t scsi_scan_bus(scsi_bus_info *bus) { - int initiator_id, target_id; scsi_path_inquiry inquiry; - uchar res; SHOW_FLOW0( 3, "" ); // get ID of initiator (i.e. controller) - res = scsi_inquiry_path(bus, &inquiry); + uchar res = scsi_inquiry_path(bus, &inquiry); if (res != SCSI_REQ_CMP) return B_ERROR; - initiator_id = inquiry.initiator_id; + uint initiator_id = inquiry.initiator_id; SHOW_FLOW(3, "initiator_id=%d", initiator_id); @@ -270,9 +268,7 @@ scsi_scan_bus(scsi_bus_info *bus) // as this function is optional for SIM, we ignore its result bus->interface->scan_bus(bus->sim_cookie); - for (target_id = 0; target_id < (int)bus->max_target_count; ++target_id) { - int lun; - + for (uint target_id = 0; target_id < bus->max_target_count; ++target_id) { SHOW_FLOW(3, "target: %d", target_id); if (target_id == initiator_id) @@ -281,12 +277,10 @@ scsi_scan_bus(scsi_bus_info *bus) // TODO: there are a lot of devices out there that go mad if you probe // anything but LUN 0, so we should probably add a black-list // or something - for (lun = 0; lun <= MAX_LUN_ID; ++lun) { - status_t status; - + for (uint lun = 0; lun < bus->max_lun_count; ++lun) { SHOW_FLOW(3, "lun: %d", lun); - status = scsi_scan_lun(bus, target_id, lun); + status_t status = scsi_scan_lun(bus, target_id, lun); // if there is no device at lun 0, there's probably no device at all if (lun == 0 && status != B_OK) diff --git a/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h b/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h index 1c4fd70635..d12d7dba48 100644 --- a/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h +++ b/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h @@ -90,6 +90,7 @@ typedef struct scsi_bus_info { uchar path_id; // SCSI path id uint32 max_target_count; // maximum count of target_ids on the bus + uint32 max_lun_count; // maximum count of lun_ids on the bus thread_id service_thread; // service thread sem_id start_service; // released whenever service thread has work to do diff --git a/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.cpp b/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.cpp index 5bf798d361..cd092a9c12 100644 --- a/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.cpp +++ b/src/add-ons/kernel/busses/scsi/virtio/virtio_scsi.cpp @@ -205,6 +205,7 @@ virtio_scsi_register_device(device_node *parent) return status; uint32 max_targets = config.max_target + 1; + uint32 max_luns = config.max_lun + 1; uint32 max_blocks = 0x10000; if (config.max_sectors != 0) max_blocks = config.max_sectors; @@ -212,6 +213,8 @@ virtio_scsi_register_device(device_node *parent) device_attr attrs[] = { { SCSI_DEVICE_MAX_TARGET_COUNT, B_UINT32_TYPE, { ui32: max_targets }}, + { SCSI_DEVICE_MAX_LUN_COUNT, B_UINT32_TYPE, + { ui32: max_luns }}, { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: VIRTIO_SCSI_BRIDGE_PRETTY_NAME }},