Commit 7bc4e528 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Martin K. Petersen

scsi: visorhba: sanitze private device data allocation

There's no need to keep the private data for a device in a separate
list; better to store it in ->hostdata and do away with the additional
list.
Signed-off-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarDavid Kershner <david.kershner@unisys.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 6d415342
...@@ -47,8 +47,8 @@ MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types); ...@@ -47,8 +47,8 @@ MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types);
MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR); MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR);
struct visordisk_info { struct visordisk_info {
struct scsi_device *sdev;
u32 valid; u32 valid;
u32 channel, id, lun; /* Disk Path */
atomic_t ios_threshold; atomic_t ios_threshold;
atomic_t error_count; atomic_t error_count;
struct visordisk_info *next; struct visordisk_info *next;
...@@ -101,12 +101,6 @@ struct visorhba_devices_open { ...@@ -101,12 +101,6 @@ struct visorhba_devices_open {
struct visorhba_devdata *devdata; struct visorhba_devdata *devdata;
}; };
#define for_each_vdisk_match(iter, list, match) \
for (iter = &list->head; iter->next; iter = iter->next) \
if ((iter->channel == match->channel) && \
(iter->id == match->id) && \
(iter->lun == match->lun))
/* /*
* visor_thread_start - starts a thread for the device * visor_thread_start - starts a thread for the device
* @threadfn: Function the thread starts * @threadfn: Function the thread starts
...@@ -296,10 +290,9 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable, ...@@ -296,10 +290,9 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable,
* Returns whether the command was queued successfully or not. * Returns whether the command was queued successfully or not.
*/ */
static int forward_taskmgmt_command(enum task_mgmt_types tasktype, static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
struct scsi_cmnd *scsicmd) struct scsi_device *scsidev)
{ {
struct uiscmdrsp *cmdrsp; struct uiscmdrsp *cmdrsp;
struct scsi_device *scsidev = scsicmd->device;
struct visorhba_devdata *devdata = struct visorhba_devdata *devdata =
(struct visorhba_devdata *)scsidev->host->hostdata; (struct visorhba_devdata *)scsidev->host->hostdata;
int notifyresult = 0xffff; int notifyresult = 0xffff;
...@@ -347,12 +340,6 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, ...@@ -347,12 +340,6 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
dev_dbg(&scsidev->sdev_gendev, dev_dbg(&scsidev->sdev_gendev,
"visorhba: taskmgmt type=%d success; result=0x%x\n", "visorhba: taskmgmt type=%d success; result=0x%x\n",
tasktype, notifyresult); tasktype, notifyresult);
if (tasktype == TASK_MGMT_ABORT_TASK)
scsicmd->result = DID_ABORT << 16;
else
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp); cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp);
return SUCCESS; return SUCCESS;
...@@ -376,17 +363,20 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd) ...@@ -376,17 +363,20 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd)
/* issue TASK_MGMT_ABORT_TASK */ /* issue TASK_MGMT_ABORT_TASK */
struct scsi_device *scsidev; struct scsi_device *scsidev;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata; int rtn;
scsidev = scsicmd->device; scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) { if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) atomic_inc(&vdisk->error_count);
atomic_inc(&vdisk->error_count); else
else atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); rtn = forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_ABORT << 16;
scsicmd->scsi_done(scsicmd);
} }
return forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsicmd); return rtn;
} }
/* /*
...@@ -400,17 +390,20 @@ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd) ...@@ -400,17 +390,20 @@ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd)
/* issue TASK_MGMT_LUN_RESET */ /* issue TASK_MGMT_LUN_RESET */
struct scsi_device *scsidev; struct scsi_device *scsidev;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata; int rtn;
scsidev = scsicmd->device; scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) { if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) atomic_inc(&vdisk->error_count);
atomic_inc(&vdisk->error_count); else
else atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); rtn = forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
} }
return forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsicmd); return rtn;
} }
/* /*
...@@ -424,17 +417,22 @@ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd) ...@@ -424,17 +417,22 @@ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd)
{ {
struct scsi_device *scsidev; struct scsi_device *scsidev;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata; int rtn;
scsidev = scsicmd->device; scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; shost_for_each_device(scsidev, scsidev->host) {
for_each_vdisk_match(vdisk, devdata, scsidev) { vdisk = scsidev->hostdata;
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count); atomic_inc(&vdisk->error_count);
else else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
} }
return forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsicmd); rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
}
return rtn;
} }
/* /*
...@@ -569,25 +567,22 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev) ...@@ -569,25 +567,22 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev)
* LLD can alloc any struct & do init if needed. * LLD can alloc any struct & do init if needed.
*/ */
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visordisk_info *tmpvdisk;
struct visorhba_devdata *devdata; struct visorhba_devdata *devdata;
struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
if (scsidev->hostdata)
return 0; /* already allocated return success */
devdata = (struct visorhba_devdata *)scsihost->hostdata; devdata = (struct visorhba_devdata *)scsihost->hostdata;
if (!devdata) if (!devdata)
return 0; /* even though we errored, treat as success */ return 0; /* even though we errored, treat as success */
for_each_vdisk_match(vdisk, devdata, scsidev) vdisk = kzalloc(sizeof(*vdisk), GFP_ATOMIC);
return 0; /* already allocated return success */ if (!vdisk)
tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
if (!tmpvdisk)
return -ENOMEM; return -ENOMEM;
tmpvdisk->channel = scsidev->channel; vdisk->sdev = scsidev;
tmpvdisk->id = scsidev->id; scsidev->hostdata = vdisk;
tmpvdisk->lun = scsidev->lun;
vdisk->next = tmpvdisk;
return 0; return 0;
} }
...@@ -603,17 +598,11 @@ static void visorhba_slave_destroy(struct scsi_device *scsidev) ...@@ -603,17 +598,11 @@ static void visorhba_slave_destroy(struct scsi_device *scsidev)
/* midlevel calls this after device has been quiesced and /* midlevel calls this after device has been quiesced and
* before it is to be deleted. * before it is to be deleted.
*/ */
struct visordisk_info *vdisk, *delvdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
devdata = (struct visorhba_devdata *)scsihost->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) { scsidev->hostdata = NULL;
delvdisk = vdisk->next; kfree(vdisk);
vdisk->next = delvdisk->next;
kfree(delvdisk);
return;
}
} }
static struct scsi_host_template visorhba_driver_template = { static struct scsi_host_template visorhba_driver_template = {
...@@ -787,7 +776,6 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata) ...@@ -787,7 +776,6 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata)
static void static void
do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
{ {
struct visorhba_devdata *devdata;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct scsi_device *scsidev; struct scsi_device *scsidev;
...@@ -800,12 +788,10 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) ...@@ -800,12 +788,10 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
(cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT)) (cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT))
return; return;
/* Okay see what our error_count is here.... */ /* Okay see what our error_count is here.... */
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) { if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) {
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) { atomic_inc(&vdisk->error_count);
atomic_inc(&vdisk->error_count); atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
}
} }
} }
...@@ -846,7 +832,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) ...@@ -846,7 +832,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
char *this_page_orig; char *this_page_orig;
int bufind = 0; int bufind = 0;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
scsidev = scsicmd->device; scsidev = scsicmd->device;
if ((cmdrsp->scsi.cmnd[0] == INQUIRY) && if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
...@@ -883,13 +868,11 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) ...@@ -883,13 +868,11 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
} }
kfree(buf); kfree(buf);
} else { } else {
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) { if (atomic_read(&vdisk->ios_threshold) > 0) {
if (atomic_read(&vdisk->ios_threshold) > 0) { atomic_dec(&vdisk->ios_threshold);
atomic_dec(&vdisk->ios_threshold); if (atomic_read(&vdisk->ios_threshold) == 0)
if (atomic_read(&vdisk->ios_threshold) == 0) atomic_set(&vdisk->error_count, 0);
atomic_set(&vdisk->error_count, 0);
}
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment