aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/gdth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/gdth.c')
-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; 4572 int rval;
4563 4573
4564 if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || 4574 if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) ||
4565 res.ionode >= gdth_ctr_count) 4575 (NULL == (ha = gdth_find_ha(res.ionode))))
4566 return -EFAULT; 4576 return -EFAULT;
4567 ha = shost_priv(gdth_ctr_tab[res.ionode]);
4568 4577
4569 scp = kzalloc(sizeof(*scp), GFP_KERNEL); 4578 scp = kzalloc(sizeof(*scp), GFP_KERNEL);
4570 if (!scp) 4579 if (!scp)
@@ -4626,7 +4635,7 @@ static void gdth_flush(gdth_ha_str *ha)
4626/* shutdown routine */ 4635/* shutdown routine */
4627static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) 4636static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
4628{ 4637{
4629 int hanum; 4638 gdth_ha_str *ha;
4630#ifndef __alpha__ 4639#ifndef __alpha__
4631 gdth_cmd_str gdtcmd; 4640 gdth_cmd_str gdtcmd;
4632 char cmnd[MAX_COMMAND_SIZE]; 4641 char cmnd[MAX_COMMAND_SIZE];
@@ -4641,8 +4650,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
4641 4650
4642 notifier_disabled = 1; 4651 notifier_disabled = 1;
4643 printk("GDT-HA: Flushing all host drives .. "); 4652 printk("GDT-HA: Flushing all host drives .. ");
4644 for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { 4653 list_for_each_entry(ha, &gdth_instances, list) {
4645 gdth_ha_str *ha = shost_priv(gdth_ctr_tab[hanum]);
4646 gdth_flush(ha); 4654 gdth_flush(ha);
4647 4655
4648#ifndef __alpha__ 4656#ifndef __alpha__
@@ -4695,7 +4703,7 @@ static int gdth_isa_probe_one(ulong32 isa_bios)
4695 struct Scsi_Host *shp; 4703 struct Scsi_Host *shp;
4696 gdth_ha_str *ha; 4704 gdth_ha_str *ha;
4697 dma_addr_t scratch_dma_handle = 0; 4705 dma_addr_t scratch_dma_handle = 0;
4698 int error, hanum, i; 4706 int error, i;
4699 4707
4700 if (!gdth_search_isa(isa_bios)) 4708 if (!gdth_search_isa(isa_bios))
4701 return -ENXIO; 4709 return -ENXIO;
@@ -4730,10 +4738,8 @@ static int gdth_isa_probe_one(ulong32 isa_bios)
4730 shp->unchecked_isa_dma = 1; 4738 shp->unchecked_isa_dma = 1;
4731 shp->irq = ha->irq; 4739 shp->irq = ha->irq;
4732 shp->dma_channel = ha->drq; 4740 shp->dma_channel = ha->drq;
4733 hanum = gdth_ctr_count;
4734 gdth_ctr_tab[gdth_ctr_count++] = shp;
4735 4741
4736 ha->hanum = (ushort)hanum; 4742 ha->hanum = gdth_ctr_count++;
4737 ha->shost = shp; 4743 ha->shost = shp;
4738 4744
4739 ha->pccb = &ha->cmdext; 4745 ha->pccb = &ha->cmdext;
@@ -4825,7 +4831,7 @@ static int gdth_eisa_probe_one(ushort eisa_slot)
4825 struct Scsi_Host *shp; 4831 struct Scsi_Host *shp;
4826 gdth_ha_str *ha; 4832 gdth_ha_str *ha;
4827 dma_addr_t scratch_dma_handle = 0; 4833 dma_addr_t scratch_dma_handle = 0;
4828 int error, hanum, i; 4834 int error, i;
4829 4835
4830 if (!gdth_search_eisa(eisa_slot)) 4836 if (!gdth_search_eisa(eisa_slot))
4831 return -ENXIO; 4837 return -ENXIO;
@@ -4852,10 +4858,8 @@ static int gdth_eisa_probe_one(ushort eisa_slot)
4852 shp->unchecked_isa_dma = 0; 4858 shp->unchecked_isa_dma = 0;
4853 shp->irq = ha->irq; 4859 shp->irq = ha->irq;
4854 shp->dma_channel = 0xff; 4860 shp->dma_channel = 0xff;
4855 hanum = gdth_ctr_count;
4856 gdth_ctr_tab[gdth_ctr_count++] = shp;
4857 4861
4858 ha->hanum = (ushort)hanum; 4862 ha->hanum = gdth_ctr_count++;
4859 ha->shost = shp; 4863 ha->shost = shp;
4860 4864
4861 TRACE2(("EISA detect Bus 0: hanum %d\n", ha->hanum)); 4865 TRACE2(("EISA detect Bus 0: hanum %d\n", ha->hanum));
@@ -4956,7 +4960,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
4956 struct Scsi_Host *shp; 4960 struct Scsi_Host *shp;
4957 gdth_ha_str *ha; 4961 gdth_ha_str *ha;
4958 dma_addr_t scratch_dma_handle = 0; 4962 dma_addr_t scratch_dma_handle = 0;
4959 int error, hanum, i; 4963 int error, i;
4960 4964
4961 shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); 4965 shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
4962 if (!shp) 4966 if (!shp)
@@ -4983,10 +4987,8 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
4983 shp->unchecked_isa_dma = 0; 4987 shp->unchecked_isa_dma = 0;
4984 shp->irq = ha->irq; 4988 shp->irq = ha->irq;
4985 shp->dma_channel = 0xff; 4989 shp->dma_channel = 0xff;
4986 hanum = gdth_ctr_count;
4987 gdth_ctr_tab[gdth_ctr_count++] = shp;
4988 4990
4989 ha->hanum = (ushort)hanum; 4991 ha->hanum = gdth_ctr_count++;
4990 ha->shost = shp; 4992 ha->shost = shp;
4991 4993
4992 ha->pccb = &ha->cmdext; 4994 ha->pccb = &ha->cmdext;
@@ -5147,21 +5149,15 @@ static int __init gdth_init(void)
5147#ifdef CONFIG_ISA 5149#ifdef CONFIG_ISA
5148 ulong32 isa_bios; 5150 ulong32 isa_bios;
5149 for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL; 5151 for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL;
5150 isa_bios += 0x8000UL) { 5152 isa_bios += 0x8000UL)
5151 if (gdth_ctr_count >= MAXHA)
5152 break;
5153 gdth_isa_probe_one(isa_bios); 5153 gdth_isa_probe_one(isa_bios);
5154 }
5155#endif 5154#endif
5156#ifdef CONFIG_EISA 5155#ifdef CONFIG_EISA
5157 { 5156 {
5158 ushort eisa_slot; 5157 ushort eisa_slot;
5159 for (eisa_slot = 0x1000; eisa_slot <= 0x8000; 5158 for (eisa_slot = 0x1000; eisa_slot <= 0x8000;
5160 eisa_slot += 0x1000) { 5159 eisa_slot += 0x1000)
5161 if (gdth_ctr_count >= MAXHA)
5162 break;
5163 gdth_eisa_probe_one(eisa_slot); 5160 gdth_eisa_probe_one(eisa_slot);
5164 }
5165 } 5161 }
5166#endif 5162#endif
5167 } 5163 }
@@ -5175,11 +5171,8 @@ static int __init gdth_init(void)
5175 cnt = gdth_search_pci(pcistr); 5171 cnt = gdth_search_pci(pcistr);
5176 printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt); 5172 printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt);
5177 gdth_sort_pci(pcistr,cnt); 5173 gdth_sort_pci(pcistr,cnt);
5178 for (ctr = 0; ctr < cnt; ++ctr) { 5174 for (ctr = 0; ctr < cnt; ++ctr)
5179 if (gdth_ctr_count >= MAXHA)
5180 break;
5181 gdth_pci_probe_one(pcistr, ctr); 5175 gdth_pci_probe_one(pcistr, ctr);
5182 }
5183 } 5176 }
5184#endif /* CONFIG_PCI */ 5177#endif /* CONFIG_PCI */
5185 5178