aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/gdth.c109
1 files changed, 51 insertions, 58 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 11796e61a76b..4248b041c9b5 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -290,8 +290,7 @@ static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */
290#endif 290#endif
291static unchar gdth_polling; /* polling if TRUE */ 291static unchar gdth_polling; /* polling if TRUE */
292static int gdth_ctr_count = 0; /* controller count */ 292static int gdth_ctr_count = 0; /* controller count */
293static struct Scsi_Host *gdth_ctr_tab[MAXHA]; /* controller table */ 293static LIST_HEAD(gdth_instances); /* controller list */
294static LIST_HEAD(gdth_instances);
295static unchar gdth_write_through = FALSE; /* write through */ 294static unchar gdth_write_through = FALSE; /* write through */
296static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ 295static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */
297static int elastidx; 296static int elastidx;
@@ -384,6 +383,17 @@ static struct notifier_block gdth_notifier = {
384}; 383};
385static int notifier_disabled = 0; 384static int notifier_disabled = 0;
386 385
386static gdth_ha_str *gdth_find_ha(int hanum)
387{
388 gdth_ha_str *ha;
389
390 list_for_each_entry(ha, &gdth_instances, list)
391 if (hanum == ha->hanum)
392 return ha;
393
394 return NULL;
395}
396
387static void gdth_delay(int milliseconds) 397static void gdth_delay(int milliseconds)
388{ 398{
389 if (milliseconds == 0) { 399 if (milliseconds == 0) {
@@ -3755,7 +3765,7 @@ static void gdth_timeout(ulong data)
3755 gdth_ha_str *ha; 3765 gdth_ha_str *ha;
3756 ulong flags; 3766 ulong flags;
3757 3767
3758 ha = shost_priv(gdth_ctr_tab[0]); 3768 ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
3759 spin_lock_irqsave(&ha->smp_lock, flags); 3769 spin_lock_irqsave(&ha->smp_lock, flags);
3760 3770
3761 for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) 3771 for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i)
@@ -4015,12 +4025,10 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
4015static int gdth_open(struct inode *inode, struct file *filep) 4025static int gdth_open(struct inode *inode, struct file *filep)
4016{ 4026{
4017 gdth_ha_str *ha; 4027 gdth_ha_str *ha;
4018 int i;
4019 4028
4020 for (i = 0; i < gdth_ctr_count; i++) { 4029 list_for_each_entry(ha, &gdth_instances, list) {
4021 ha = shost_priv(gdth_ctr_tab[i]);
4022 if (!ha->sdev) 4030 if (!ha->sdev)
4023 ha->sdev = scsi_get_host_dev(gdth_ctr_tab[i]); 4031 ha->sdev = scsi_get_host_dev(ha->shost);
4024 } 4032 }
4025 4033
4026 TRACE(("gdth_open()\n")); 4034 TRACE(("gdth_open()\n"));
@@ -4039,10 +4047,11 @@ static int ioc_event(void __user *arg)
4039 gdth_ha_str *ha; 4047 gdth_ha_str *ha;
4040 ulong flags; 4048 ulong flags;
4041 4049
4042 if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)) || 4050 if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)))
4043 evt.ionode >= gdth_ctr_count) 4051 return -EFAULT;
4052 ha = gdth_find_ha(evt.ionode);
4053 if (!ha)
4044 return -EFAULT; 4054 return -EFAULT;
4045 ha = shost_priv(gdth_ctr_tab[evt.ionode]);
4046 4055
4047 if (evt.erase == 0xff) { 4056 if (evt.erase == 0xff) {
4048 if (evt.event.event_source == ES_TEST) 4057 if (evt.event.event_source == ES_TEST)
@@ -4076,11 +4085,12 @@ static int ioc_lockdrv(void __user *arg)
4076 ulong flags; 4085 ulong flags;
4077 gdth_ha_str *ha; 4086 gdth_ha_str *ha;
4078 4087
4079 if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)) || 4088 if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)))
4080 ldrv.ionode >= gdth_ctr_count)
4081 return -EFAULT; 4089 return -EFAULT;
4082 ha = shost_priv(gdth_ctr_tab[ldrv.ionode]); 4090 ha = gdth_find_ha(ldrv.ionode);
4083 4091 if (!ha)
4092 return -EFAULT;
4093
4084 for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { 4094 for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) {
4085 j = ldrv.drives[i]; 4095 j = ldrv.drives[i];
4086 if (j >= MAX_HDRIVES || !ha->hdr[j].present) 4096 if (j >= MAX_HDRIVES || !ha->hdr[j].present)
@@ -4110,9 +4120,11 @@ static int ioc_resetdrv(void __user *arg, char *cmnd)
4110 int rval; 4120 int rval;
4111 4121
4112 if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || 4122 if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) ||
4113 res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) 4123 res.number >= MAX_HDRIVES)
4124 return -EFAULT;
4125 ha = gdth_find_ha(res.ionode);
4126 if (!ha)
4114 return -EFAULT; 4127 return -EFAULT;
4115 ha = shost_priv(gdth_ctr_tab[res.ionode]);
4116 4128
4117 if (!ha->hdr[res.number].present) 4129 if (!ha->hdr[res.number].present)
4118 return 0; 4130 return 0;
@@ -4141,11 +4153,12 @@ static int ioc_general(void __user *arg, char *cmnd)
4141 ulong64 paddr; 4153 ulong64 paddr;
4142 gdth_ha_str *ha; 4154 gdth_ha_str *ha;
4143 int rval; 4155 int rval;
4144 4156
4145 if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || 4157 if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)))
4146 gen.ionode >= gdth_ctr_count) 4158 return -EFAULT;
4159 ha = gdth_find_ha(gen.ionode);
4160 if (!ha)
4147 return -EFAULT; 4161 return -EFAULT;
4148 ha = shost_priv(gdth_ctr_tab[gen.ionode]);
4149 if (gen.data_len + gen.sense_len != 0) { 4162 if (gen.data_len + gen.sense_len != 0) {
4150 if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, 4163 if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len,
4151 FALSE, &paddr))) 4164 FALSE, &paddr)))
@@ -4265,11 +4278,10 @@ static int ioc_hdrlist(void __user *arg, char *cmnd)
4265 goto free_fail; 4278 goto free_fail;
4266 4279
4267 if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || 4280 if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) ||
4268 rsc->ionode >= gdth_ctr_count) { 4281 (NULL == (ha = gdth_find_ha(rsc->ionode)))) {
4269 rc = -EFAULT; 4282 rc = -EFAULT;
4270 goto free_fail; 4283 goto free_fail;
4271 } 4284 }
4272 ha = shost_priv(gdth_ctr_tab[rsc->ionode]);
4273 memset(cmd, 0, sizeof(gdth_cmd_str)); 4285 memset(cmd, 0, sizeof(gdth_cmd_str));
4274 4286
4275 for (i = 0; i < MAX_HDRIVES; ++i) { 4287 for (i = 0; i < MAX_HDRIVES; ++i) {
@@ -4321,11 +4333,10 @@ static int ioc_rescan(void __user *arg, char *cmnd)
4321 goto free_fail; 4333 goto free_fail;
4322 4334
4323 if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || 4335 if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) ||
4324 rsc->ionode >= gdth_ctr_count) { 4336 (NULL == (ha = gdth_find_ha(rsc->ionode)))) {
4325 rc = -EFAULT; 4337 rc = -EFAULT;
4326 goto free_fail; 4338 goto free_fail;
4327 } 4339 }
4328 ha = shost_priv(gdth_ctr_tab[rsc->ionode]);
4329 memset(cmd, 0, sizeof(gdth_cmd_str)); 4340 memset(cmd, 0, sizeof(gdth_cmd_str));
4330 4341
4331 if (rsc->flag == 0) { 4342 if (rsc->flag == 0) {
@@ -4482,9 +4493,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
4482 gdth_ioctl_ctrtype ctrt; 4493 gdth_ioctl_ctrtype ctrt;
4483 4494
4484 if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || 4495 if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) ||
4485 ctrt.ionode >= gdth_ctr_count) 4496 (NULL == (ha = gdth_find_ha(ctrt.ionode))))
4486 return -EFAULT; 4497 return -EFAULT;
4487 ha = shost_priv(gdth_ctr_tab[ctrt.ionode]); 4498
4488 if (ha->type == GDT_ISA || ha->type == GDT_EISA) { 4499 if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
4489 ctrt.type = (unchar)((ha->stype>>20) - 0x10); 4500 ctrt.type = (unchar)((ha->stype>>20) - 0x10);
4490 } else { 4501 } else {
@@ -4523,10 +4534,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
4523 unchar i, j; 4534 unchar i, j;
4524 4535
4525 if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || 4536 if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) ||
4526 lchn.ionode >= gdth_ctr_count) 4537 (NULL == (ha = gdth_find_ha(lchn.ionode))))
4527 return -EFAULT; 4538 return -EFAULT;
4528 ha = shost_priv(gdth_ctr_tab[lchn.ionode]); 4539
4529
4530 i = lchn.channel; 4540 i = lchn.channel;
4531 if (i < ha->bus_cnt) { 4541 if (i < ha->bus_cnt) {
4532 if (lchn.lock) { 4542 if (lchn.lock) {
@@ -4562,9 +4572,8 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
4562 int rval;