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

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
Loading
Loading
Loading
Loading
+53 −70
Original line number Diff line number Diff line
@@ -47,8 +47,8 @@ MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types);
MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR);

struct visordisk_info {
	struct scsi_device *sdev;
	u32 valid;
	u32 channel, id, lun;	/* Disk Path */
	atomic_t ios_threshold;
	atomic_t error_count;
	struct visordisk_info *next;
@@ -101,12 +101,6 @@ struct visorhba_devices_open {
	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
 *	@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.
 */
static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
				    struct scsi_cmnd *scsicmd)
				    struct scsi_device *scsidev)
{
	struct uiscmdrsp *cmdrsp;
	struct scsi_device *scsidev = scsicmd->device;
	struct visorhba_devdata *devdata =
		(struct visorhba_devdata *)scsidev->host->hostdata;
	int notifyresult = 0xffff;
@@ -347,12 +340,6 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
	dev_dbg(&scsidev->sdev_gendev,
		"visorhba: taskmgmt type=%d success; result=0x%x\n",
		 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);
	return SUCCESS;

@@ -376,17 +363,20 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd)
	/* issue TASK_MGMT_ABORT_TASK */
	struct scsi_device *scsidev;
	struct visordisk_info *vdisk;
	struct visorhba_devdata *devdata;
	int rtn;

	scsidev = scsicmd->device;
	devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
	for_each_vdisk_match(vdisk, devdata, scsidev) {
	vdisk = scsidev->hostdata;
	if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
		atomic_inc(&vdisk->error_count);
	else
		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 */
	struct scsi_device *scsidev;
	struct visordisk_info *vdisk;
	struct visorhba_devdata *devdata;
	int rtn;

	scsidev = scsicmd->device;
	devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
	for_each_vdisk_match(vdisk, devdata, scsidev) {
	vdisk = scsidev->hostdata;
	if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
		atomic_inc(&vdisk->error_count);
	else
		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 visordisk_info *vdisk;
	struct visorhba_devdata *devdata;
	int rtn;

	scsidev = scsicmd->device;
	devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
	for_each_vdisk_match(vdisk, devdata, scsidev) {
	shost_for_each_device(scsidev, scsidev->host) {
		vdisk = scsidev->hostdata;
		if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
			atomic_inc(&vdisk->error_count);
		else
			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.
	 */
	struct visordisk_info *vdisk;
	struct visordisk_info *tmpvdisk;
	struct visorhba_devdata *devdata;
	struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;

	if (scsidev->hostdata)
		return 0; /* already allocated return success */

	devdata = (struct visorhba_devdata *)scsihost->hostdata;
	if (!devdata)
		return 0; /* even though we errored, treat as success */

	for_each_vdisk_match(vdisk, devdata, scsidev)
		return 0; /* already allocated return success */

	tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
	if (!tmpvdisk)
	vdisk = kzalloc(sizeof(*vdisk), GFP_ATOMIC);
	if (!vdisk)
		return -ENOMEM;

	tmpvdisk->channel = scsidev->channel;
	tmpvdisk->id = scsidev->id;
	tmpvdisk->lun = scsidev->lun;
	vdisk->next = tmpvdisk;
	vdisk->sdev = scsidev;
	scsidev->hostdata = vdisk;
	return 0;
}

@@ -603,17 +598,11 @@ static void visorhba_slave_destroy(struct scsi_device *scsidev)
	/* midlevel calls this after device has been quiesced and
	 * before it is to be deleted.
	 */
	struct visordisk_info *vdisk, *delvdisk;
	struct visorhba_devdata *devdata;
	struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
	struct visordisk_info *vdisk;

	devdata = (struct visorhba_devdata *)scsihost->hostdata;
	for_each_vdisk_match(vdisk, devdata, scsidev) {
		delvdisk = vdisk->next;
		vdisk->next = delvdisk->next;
		kfree(delvdisk);
		return;
	}
	vdisk = scsidev->hostdata;
	scsidev->hostdata = NULL;
	kfree(vdisk);
}

static struct scsi_host_template visorhba_driver_template = {
@@ -787,7 +776,6 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata)
static void
do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
{
	struct visorhba_devdata *devdata;
	struct visordisk_info *vdisk;
	struct scsi_device *scsidev;

@@ -800,14 +788,12 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
	    (cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT))
		return;
	/* Okay see what our error_count is here.... */
	devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
	for_each_vdisk_match(vdisk, devdata, scsidev) {
	vdisk = scsidev->hostdata;
	if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) {
		atomic_inc(&vdisk->error_count);
		atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
	}
}
}

static int set_no_disk_inquiry_result(unsigned char *buf,
				      size_t len, bool is_lun0)
@@ -846,7 +832,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
	char *this_page_orig;
	int bufind = 0;
	struct visordisk_info *vdisk;
	struct visorhba_devdata *devdata;

	scsidev = scsicmd->device;
	if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
@@ -883,8 +868,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
		}
		kfree(buf);
	} else {
		devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
		for_each_vdisk_match(vdisk, devdata, scsidev) {
		vdisk = scsidev->hostdata;
		if (atomic_read(&vdisk->ios_threshold) > 0) {
			atomic_dec(&vdisk->ios_threshold);
			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