Ensure consistent target IDs for direct-attached devices.

Sponsored by: Intel
Reported by: sbruno, <rpokala at panasas dot com>
Tested by: <rpokala at panasas dot com>
Reviewed by: scottl
Approved by: scottl
MFC after: 3 days
This commit is contained in:
Jim Harris 2012-03-28 18:38:13 +00:00
parent a6e69b92e6
commit 47c3b89324
3 changed files with 32 additions and 9 deletions

View file

@ -89,10 +89,10 @@ struct ISCI_REMOTE_DEVICE {
};
struct ISCI_DOMAIN {
struct ISCI_CONTROLLER *controller;
SCI_DOMAIN_HANDLE_T sci_object;
uint8_t index;
struct ISCI_CONTROLLER *controller;
SCI_DOMAIN_HANDLE_T sci_object;
uint8_t index;
struct ISCI_REMOTE_DEVICE *da_remote_device;
};
struct ISCI_MEMORY

View file

@ -430,7 +430,18 @@ int isci_controller_allocate_memory(struct ISCI_CONTROLLER *controller)
remote_device->frozen_lun_mask = 0;
sci_fast_list_element_init(remote_device,
&remote_device->pending_device_reset_element);
sci_pool_put(controller->remote_device_pool, remote_device);
/*
* For the first SCI_MAX_DOMAINS device objects, do not put
* them in the pool, rather assign them to each domain. This
* ensures that any device attached directly to port "i" will
* always get CAM target id "i".
*/
if (i < SCI_MAX_DOMAINS)
controller->domain[i].da_remote_device = remote_device;
else
sci_pool_put(controller->remote_device_pool,
remote_device);
remote_device_memory_ptr += remote_device_size;
}

View file

@ -202,10 +202,14 @@ scif_cb_domain_da_device_added(SCI_CONTROLLER_HANDLE_T controller,
struct ISCI_REMOTE_DEVICE *remote_device;
struct ISCI_DOMAIN *isci_domain =
(struct ISCI_DOMAIN *)sci_object_get_association(domain);
struct ISCI_CONTROLLER *isci_controller =
(struct ISCI_CONTROLLER *)sci_object_get_association(controller);
sci_pool_get(isci_controller->remote_device_pool, remote_device);
/*
* For direct-attached devices, do not pull the device object from
* the pool. Rather, use the one stored in the domain object which
* will ensure that we always get consistent target ids for direct
* attached devices.
*/
remote_device = isci_domain->da_remote_device;
scif_remote_device_construct(domain,
(uint8_t*)remote_device + sizeof(struct ISCI_REMOTE_DEVICE),
@ -287,6 +291,8 @@ scif_cb_domain_device_removed(SCI_CONTROLLER_HANDLE_T controller,
{
struct ISCI_REMOTE_DEVICE *isci_remote_device =
(struct ISCI_REMOTE_DEVICE *)sci_object_get_association(remote_device);
struct ISCI_DOMAIN *isci_domain =
(struct ISCI_DOMAIN *)sci_object_get_association(domain);
struct ISCI_CONTROLLER *isci_controller =
(struct ISCI_CONTROLLER *)sci_object_get_association(controller);
uint32_t path = cam_sim_path(isci_controller->sim);
@ -301,7 +307,13 @@ scif_cb_domain_device_removed(SCI_CONTROLLER_HANDLE_T controller,
scif_remote_device_destruct(remote_device);
sci_pool_put(isci_controller->remote_device_pool, isci_remote_device);
/*
* Only put the remote device back into the pool if it was an
* expander-attached device.
*/
if (isci_remote_device != isci_domain->da_remote_device)
sci_pool_put(isci_controller->remote_device_pool,
isci_remote_device);
}
void