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: Hannes Reinecke <hare@suse.com> Reviewed-by: David Kershner <david.kershner@unisys.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Родитель
6d415342ad
Коммит
7bc4e528d9
|
@ -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 {
|
||||||
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,
|
||||||
* 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,
|
||||||
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)
|
||||||
/* 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)
|
||||||
/* 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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
* 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)
|
||||||
/* 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)
|
||||||
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,14 +788,12 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static int set_no_disk_inquiry_result(unsigned char *buf,
|
static int set_no_disk_inquiry_result(unsigned char *buf,
|
||||||
size_t len, bool is_lun0)
|
size_t len, bool is_lun0)
|
||||||
|
@ -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,8 +868,7 @@ 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)
|
||||||
|
@ -892,7 +876,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* complete_scsi_command - complete a scsi command
|
* complete_scsi_command - complete a scsi command
|
||||||
|
|
Загрузка…
Ссылка в новой задаче