@@ -332,10 +332,9 @@ static void gdth_scsi_done(struct scsi_cmnd *scp)
scp->scsi_done(scp);
}
-static int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd,
- char *cmnd, int timeout, u32 *info)
+int gdth_execute(gdth_ha_str *ha, gdth_cmd_str *gdtcmd, char *cmnd,
+ int timeout, u32 *info)
{
- gdth_ha_str *ha = shost_priv(sdev->host);
struct scsi_cmnd *scp;
struct gdth_cmndinfo cmndinfo;
DECLARE_COMPLETION_ONSTACK(wait);
@@ -351,7 +350,7 @@ static int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd,
return -ENOMEM;
}
- scp->device = sdev;
+ scp->device = ha->sdev;
memset(&cmndinfo, 0, sizeof(cmndinfo));
/* use request field to save the ptr. to completion struct. */
@@ -375,16 +374,6 @@ static int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd,
return rval;
}
-int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
- int timeout, u32 *info)
-{
- struct scsi_device *sdev = scsi_get_host_dev(shost);
- int rval = __gdth_execute(sdev, gdtcmd, cmnd, timeout, info);
-
- scsi_free_host_dev(sdev);
- return rval;
-}
-
static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs)
{
*cyls = size /HEADS/SECS;
@@ -3446,15 +3435,6 @@ static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
static int gdth_open(struct inode *inode, struct file *filep)
{
- gdth_ha_str *ha;
-
- mutex_lock(&gdth_mutex);
- list_for_each_entry(ha, &gdth_instances, list) {
- if (!ha->sdev)
- ha->sdev = scsi_get_host_dev(ha->shost);
- }
- mutex_unlock(&gdth_mutex);
-
TRACE(("gdth_open()\n"));
return 0;
}
@@ -3558,7 +3538,7 @@ static int ioc_resetdrv(void __user *arg, char *cmnd)
else
cmd.u.cache.DeviceNo = res.number;
- rval = __gdth_execute(ha->sdev, &cmd, cmnd, 30, NULL);
+ rval = gdth_execute(ha, &cmd, cmnd, 30, NULL);
if (rval < 0)
return rval;
res.status = rval;
@@ -3690,8 +3670,8 @@ static int ioc_general(void __user *arg, char *cmnd)
goto out_free_buf;
}
- rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout,
- &gen.info);
+ rval = gdth_execute(ha, &gen.command, cmnd, gen.timeout,
+ &gen.info);
if (rval < 0)
goto out_free_buf;
gen.status = rval;
@@ -3749,7 +3729,8 @@ static int ioc_hdrlist(void __user *arg, char *cmnd)
cmd->u.cache64.DeviceNo = i;
else
cmd->u.cache.DeviceNo = i;
- if (__gdth_execute(ha->sdev, cmd, cmnd, 30, &cluster_type) == S_OK)
+ if (gdth_execute(ha, cmd, cmnd, 30,
+ &cluster_type) == S_OK)
rsc->hdr_list[i].cluster_type = cluster_type;
}
}
@@ -3799,7 +3780,7 @@ static int ioc_rescan(void __user *arg, char *cmnd)
cmd->u.cache.DeviceNo = LINUX_OS;
}
- status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
+ status = gdth_execute(ha, cmd, cmnd, 30, &info);
i = 0;
hdr_cnt = (status == S_OK ? (u16)info : 0);
} else {
@@ -3815,7 +3796,7 @@ static int ioc_rescan(void __user *arg, char *cmnd)
else
cmd->u.cache.DeviceNo = i;
- status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
+ status = gdth_execute(ha, cmd, cmnd, 30, &info);
spin_lock_irqsave(&ha->smp_lock, flags);
rsc->hdr_list[i].bus = ha->virt_bus;
@@ -3849,7 +3830,7 @@ static int ioc_rescan(void __user *arg, char *cmnd)
else
cmd->u.cache.DeviceNo = i;
- status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
+ status = gdth_execute(ha, cmd, cmnd, 30, &info);
spin_lock_irqsave(&ha->smp_lock, flags);
ha->hdr[i].devtype = (status == S_OK ? (u16)info : 0);
@@ -3862,7 +3843,7 @@ static int ioc_rescan(void __user *arg, char *cmnd)
else
cmd->u.cache.DeviceNo = i;
- status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
+ status = gdth_execute(ha, cmd, cmnd, 30, &info);
spin_lock_irqsave(&ha->smp_lock, flags);
ha->hdr[i].cluster_type =
@@ -3877,7 +3858,7 @@ static int ioc_rescan(void __user *arg, char *cmnd)
else
cmd->u.cache.DeviceNo = i;
- status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
+ status = gdth_execute(ha, cmd, cmnd, 30, &info);
spin_lock_irqsave(&ha->smp_lock, flags);
ha->hdr[i].rw_attribs = (status == S_OK ? (u16)info : 0);
@@ -4070,7 +4051,7 @@ static void gdth_flush(gdth_ha_str *ha)
TRACE2(("gdth_flush(): flush ha %d drive %d\n",
ha->hanum, i));
- gdth_execute(ha->shost, &gdtcmd, cmnd, 30, NULL);
+ gdth_execute(ha, &gdtcmd, cmnd, 30, NULL);
}
}
}
@@ -4208,6 +4189,9 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
goto out_free_pmsg;
list_add_tail(&ha->list, &gdth_instances);
+ ha->sdev = scsi_get_host_dev(shp);
+ if (!ha->sdev)
+ goto out_unlink;
pci_set_drvdata(ha->pdev, ha);
gdth_timer_init();
@@ -4217,6 +4201,8 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
return 0;
+ out_unlink:
+ list_del_init(&ha->list);
out_free_pmsg:
dma_free_coherent(&ha->pdev->dev, sizeof(gdth_msg_str),
ha->pmsg, ha->msg_phys);
@@ -71,7 +71,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
gdtcmd.u.cache.BlockNo = 1;
}
- gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
+ gdth_execute(ha, &gdtcmd, cmnd, 30, NULL);
}
}
if (!found)
@@ -134,7 +134,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
pcpar->write_back = wb_mode==1 ? 0:1;
- gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
+ gdth_execute(ha, &gdtcmd, cmnd, 30, NULL);
spin_lock_irqsave(&ha->smp_lock, flags);
ha->scratch_busy = FALSE;
@@ -254,7 +254,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
if (pds->entries > cnt)
pds->entries = cnt;
- if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK)
+ if (gdth_execute(ha, gdtcmd, cmnd, 30, NULL) != S_OK)
pds->count = 0;
/* other IOCTLs must fit into area GDTH_SCRATCH/4 */
@@ -271,7 +271,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
gdtcmd->u.ioctl.channel =
ha->raw[i].address | ha->raw[i].id_list[j];
- if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
+ if (gdth_execute(ha, gdtcmd, cmnd, 30, NULL) == S_OK) {
strncpy(hrec,pdi->vendor,8);
strncpy(hrec+8,pdi->product,16);
strncpy(hrec+24,pdi->revision,4);
@@ -318,7 +318,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
ha->raw[i].address | ha->raw[i].id_list[j];
pdef->sddc_type = 0x08;
- if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
+ if (gdth_execute(ha, gdtcmd, cmnd, 30, NULL) == S_OK) {
seq_printf(m,
" Grown Defects:\t%d\n",
pdef->sddc_cnt);
@@ -350,7 +350,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO;
gdtcmd->u.ioctl.channel = drv_no;
- if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK)
+ if (gdth_execute(ha, gdtcmd, cmnd, 30, NULL) != S_OK)
break;
pcdi->ld_dtype >>= 16;
j++;
@@ -427,7 +427,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str);
gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
gdtcmd->u.ioctl.channel = i;
- if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
+ if (gdth_execute(ha, gdtcmd, cmnd, 30, NULL) == S_OK) {
if (pai->ai_state == 0)
strcpy(hrec, "idle");
else if (pai->ai_state == 2)
@@ -486,7 +486,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
gdtcmd->u.ioctl.channel = i;
phg->entries = MAX_HDRIVES;
phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]);
- if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
+ if (gdth_execute(ha, gdtcmd, cmnd, 30, NULL) == S_OK) {
ha->hdr[i].ldr_no = i;
ha->hdr[i].rw_attribs = 0;
ha->hdr[i].start_sec = 0;
@@ -6,7 +6,7 @@
* $Id: gdth_proc.h,v 1.16 2004/01/14 13:09:01 achim Exp $
*/
-int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
+int gdth_execute(gdth_ha_str *ha, gdth_cmd_str *gdtcmd, char *cmnd,
int timeout, u32 *info);
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
gdth_execute() is just a wrapper around __gdth_execute(), which tries to allocate the host device, too. But the host device is required for other code paths, too, so we should allocate it during pci init, kill the original gdth_execute() and rename __gdth_execute() to gdth_execute(). Signed-off-by: Hannes Reinecke <hare@suse.de> --- drivers/scsi/gdth.c | 52 ++++++++++++++++++------------------------------ drivers/scsi/gdth_proc.c | 16 +++++++-------- drivers/scsi/gdth_proc.h | 2 +- 3 files changed, 28 insertions(+), 42 deletions(-)