X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fgdth.c;fp=drivers%2Fscsi%2Fgdth.c;h=f6d44b6f1fb618a24e29641e3b88cd8acea1197e;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=5c0c92716cb3ffcd1da3cfdce78fb4ec6594fb32;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 5c0c92716..f6d44b6f1 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -4,9 +4,9 @@ * Intel Corporation: Storage RAID Controllers * * * * gdth.c * - * Copyright (C) 1995-06 ICP vortex GmbH, Achim Leubner * + * Copyright (C) 1995-04 ICP vortex GmbH, Achim Leubner * * Copyright (C) 2002-04 Intel Corporation * - * Copyright (C) 2003-06 Adaptec Inc. * + * Copyright (C) 2003-04 Adaptec Inc. * * * * * * Additions/Fixes: * @@ -27,14 +27,9 @@ * along with this kernel; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * - * Linux kernel 2.4.x, 2.6.x supported * + * Linux kernel 2.2.x, 2.4.x, 2.6.x supported * * * * $Log: gdth.c,v $ - * Revision 1.74 2006/04/10 13:44:47 achim - * Community changes for 2.6.x - * Kernel 2.2.x no longer supported - * scsi_request interface removed, thanks to Christoph Hellwig - * * Revision 1.73 2004/03/31 13:33:03 achim * Special command 0xfd implemented to detect 64-bit DMA support * @@ -99,7 +94,7 @@ * Bugfix free_irq() * * Revision 1.56 2001/08/09 11:19:39 achim - * Scsi_Host_Template changes + * struct scsi_host_template changes * * Revision 1.55 2001/08/09 10:11:28 achim * Command HOST_UNFREEZE_IO before cache service init. @@ -393,13 +388,6 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) -#include -#else -#define DMA_32BIT_MASK 0x00000000ffffffffULL -#define DMA_64BIT_MASK 0xffffffffffffffffULL -#endif - #ifdef GDTH_RTC #include #endif @@ -419,8 +407,8 @@ #include "scsi.h" #include -#include "gdth_kcompat.h" #include "gdth.h" +#include "gdth_kcompat.h" static void gdth_delay(int milliseconds); static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); @@ -475,8 +463,6 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, static void gdth_flush(int hanum); static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); -static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); -static void gdth_scsi_done(struct scsi_cmnd *scp); #ifdef DEBUG_GDTH static unchar DebugState = DEBUG_GDTH; @@ -569,8 +555,8 @@ static struct timer_list gdth_timer; #endif #define PTR2USHORT(a) (ushort)(ulong)(a) -#define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) -#define INDEX_OK(i,t) ((i)b) +#define INDEX_OK(i,t) ((i)hostdata)) #define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext) @@ -656,7 +642,6 @@ static int probe_eisa_isa = 0; static int force_dma32 = 0; /* parameters for modprobe/insmod */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) module_param_array(irq, int, NULL, 0); module_param(disable, int, 0); module_param(reserve_mode, int, 0); @@ -669,23 +654,8 @@ module_param(virt_ctr, int, 0); module_param(shared_access, int, 0); module_param(probe_eisa_isa, int, 0); module_param(force_dma32, int, 0); -#else -MODULE_PARM(irq, "i"); -MODULE_PARM(disable, "i"); -MODULE_PARM(reserve_mode, "i"); -MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i"); -MODULE_PARM(reverse_scan, "i"); -MODULE_PARM(hdr_channel, "i"); -MODULE_PARM(max_ids, "i"); -MODULE_PARM(rescan, "i"); -MODULE_PARM(virt_ctr, "i"); -MODULE_PARM(shared_access, "i"); -MODULE_PARM(probe_eisa_isa, "i"); -MODULE_PARM(force_dma32, "i"); -#endif MODULE_AUTHOR("Achim Leubner"); MODULE_LICENSE("GPL"); -MODULE_VERSION(GDTH_VERSION_STR); /* ioctl interface */ static struct file_operations gdth_fops = { @@ -701,7 +671,7 @@ static struct file_operations gdth_fops = { static struct notifier_block gdth_notifier = { gdth_halt, NULL, 0 }; -static int notifier_disabled = 0; + static void gdth_delay(int milliseconds) { @@ -712,91 +682,6 @@ static void gdth_delay(int milliseconds) } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -static void gdth_scsi_done(struct scsi_cmnd *scp) -{ - TRACE2(("gdth_scsi_done()\n")); - - if (scp->request) - complete((struct completion *)scp->request); -} - -int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info) -{ - Scsi_Cmnd *scp; - DECLARE_COMPLETION_ONSTACK(wait); - int rval; - - scp = kmalloc(sizeof(*scp), GFP_KERNEL); - if (!scp) - return -ENOMEM; - memset(scp, 0, sizeof(*scp)); - scp->device = sdev; - /* use request field to save the ptr. to completion struct. */ - scp->request = (struct request *)&wait; - scp->timeout_per_command = timeout*HZ; - scp->request_buffer = gdtcmd; - scp->cmd_len = 12; - memcpy(scp->cmnd, cmnd, 12); - scp->SCp.this_residual = IOCTL_PRI; /* priority */ - scp->done = gdth_scsi_done; /* some fn. test this */ - gdth_queuecommand(scp, gdth_scsi_done); - wait_for_completion(&wait); - - rval = scp->SCp.Status; - if (info) - *info = scp->SCp.Message; - kfree(scp); - return rval; -} -#else -static void gdth_scsi_done(Scsi_Cmnd *scp) -{ - TRACE2(("gdth_scsi_done()\n")); - - scp->request.rq_status = RQ_SCSI_DONE; - if (scp->request.waiting) - complete(scp->request.waiting); -} - -int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, - int timeout, u32 *info) -{ - Scsi_Cmnd *scp = scsi_allocate_device(sdev, 1, FALSE); - unsigned bufflen = gdtcmd ? sizeof(gdth_cmd_str) : 0; - DECLARE_COMPLETION_ONSTACK(wait); - int rval; - - if (!scp) - return -ENOMEM; - scp->cmd_len = 12; - scp->use_sg = 0; - scp->SCp.this_residual = IOCTL_PRI; /* priority */ - scp->request.rq_status = RQ_SCSI_BUSY; - scp->request.waiting = &wait; - scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); - wait_for_completion(&wait); - - rval = scp->SCp.Status; - if (info) - *info = scp->SCp.Message; - - scsi_release_command(scp); - return rval; -} -#endif - -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(ulong32 size, ulong32 *cyls, int *heads, int *secs) { *cyls = size /HEADS/SECS; @@ -887,7 +772,7 @@ static struct pci_device_id gdthtable[] __attribute_used__ = { MODULE_DEVICE_TABLE(pci,gdthtable); static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, - ushort vendor, ushort device) + ushort vendor, ushort device) { ulong base0, base1, base2; struct pci_dev *pdev; @@ -2362,16 +2247,14 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) ha = HADATA(gdth_ctr_tab[hanum]); spin_lock_irqsave(&ha->smp_lock, flags); - if (scp->done != gdth_scsi_done) { - scp->SCp.this_residual = (int)priority; - b = virt_ctr ? NUMDATA(scp->device->host)->busnum:scp->device->channel; - t = scp->device->id; - if (priority >= DEFAULT_PRI) { - if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || - (b==ha->virt_bus && thdr[t].lock)) { - TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); - scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); - } + scp->SCp.this_residual = (int)priority; + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + t = scp->device->id; + if (priority >= DEFAULT_PRI) { + if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || + (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) { + TRACE2(("gdth_putq(): locked IO -> update_timeout()\n")); + scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); } } @@ -2425,18 +2308,14 @@ static void gdth_next(int hanum) for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; - if (nscp->done != gdth_scsi_done) { - b = virt_ctr ? - NUMDATA(nscp->device->host)->busnum : nscp->device->channel; - t = nscp->device->id; - l = nscp->device->lun; - if (nscp->SCp.this_residual >= DEFAULT_PRI) { - if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || - (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) - continue; - } - } else - b = t = l = 0; + b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel; + t = nscp->device->id; + l = nscp->device->lun; + if (nscp->SCp.this_residual >= DEFAULT_PRI) { + if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || + (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) + continue; + } if (firsttime) { if (gdth_test_busy(hanum)) { /* controller busy ? */ @@ -2451,7 +2330,7 @@ static void gdth_next(int hanum) firsttime = FALSE; } - if (nscp->done != gdth_scsi_done) { + if (nscp->done != gdth_scsi_done || nscp->cmnd[0] != 0xff) { if (nscp->SCp.phase == -1) { nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ if (nscp->cmnd[0] == TEST_UNIT_READY) { @@ -2514,7 +2393,7 @@ static void gdth_next(int hanum) else nscp->scsi_done(nscp); } - } else if (nscp->done == gdth_scsi_done) { + } else if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) { if (!(cmd_index=gdth_special_cmd(hanum,nscp))) this_cmd = FALSE; next_cmd = FALSE; @@ -2662,13 +2541,13 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, gdth_ha_str *ha; char *address; - cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen; + cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen; ha = HADATA(gdth_ctr_tab[hanum]); if (scp->use_sg) { sl = (struct scatterlist *)scp->request_buffer; for (i=0,cpsum=0; iuse_sg; ++i,++sl) { - unsigned long flags; + unsigned long flags; cpnow = (ushort)sl->length; TRACE(("copy_internal() now %d sum %d count %d %d\n", cpnow,cpsum,cpcount,(ushort)scp->bufflen)); @@ -2680,19 +2559,12 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, hanum); return; } - local_irq_save(flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; - memcpy(address,buffer,cpnow); - flush_dcache_page(sl->page); - kunmap_atomic(address, KM_BIO_SRC_IRQ); -#else - address = kmap_atomic(sl->page, KM_BH_IRQ) + sl->offset; + local_irq_save(flags); + address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; memcpy(address,buffer,cpnow); - flush_dcache_page(sl->page); - kunmap_atomic(address, KM_BH_IRQ); -#endif - local_irq_restore(flags); + flush_dcache_page(sl->page); + kunmap_atomic(address, KM_BIO_SRC_IRQ); + local_irq_restore(flags); if (cpsum == cpcount) break; buffer += cpnow; @@ -3073,9 +2945,9 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) offset = (ulong)scp->sense_buffer & ~PAGE_MASK; sense_paddr = pci_map_page(ha->pdev,page,offset, 16,PCI_DMA_FROMDEVICE); - *(ulong32 *)&scp->SCp.buffer = (ulong32)sense_paddr; + scp->SCp.buffer = (struct scatterlist *)((ulong32)sense_paddr); /* high part, if 64bit */ - *(ulong32 *)&scp->host_scribble = (ulong32)((ulong64)sense_paddr >> 32); + scp->host_scribble = (char *)(ulong32)((ulong64)sense_paddr >> 32); cmdp->OpCode = GDT_WRITE; /* always */ cmdp->BoardNode = LOCALBOARD; if (mode64) { @@ -3149,7 +3021,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) } #endif - } else if (scp->request_bufflen) { + } else { scp->SCp.Status = GDTH_MAP_SINGLE; scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; page = virt_to_page(scp->request_buffer); @@ -3436,7 +3308,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) } if (!gdth_polling) - spin_lock_irqsave(&ha2->smp_lock, flags); + spin_lock_irqsave(&ha2->smp_lock, flags); wait_index = 0; /* search controller */ @@ -3532,7 +3404,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) IStatus &= ~0x80; #ifdef INT_COAL if (coalesced) - ha->status = pcs->ext_status && 0xffff; + ha->status = pcs->ext_status & 0xffff; else #endif ha->status = gdth_readw(&dp6m_ptr->i960r.status); @@ -3544,7 +3416,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) if (coalesced) { ha->info = pcs->info0; ha->info2 = pcs->info1; - ha->service = (pcs->ext_status >> 16) && 0xffff; + ha->service = (pcs->ext_status >> 16) & 0xffff; } else #endif { @@ -3769,10 +3641,9 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) scp->request_bufflen,scp->SCp.Message); if (scp->SCp.buffer) { dma_addr_t addr; - addr = (dma_addr_t)*(ulong32 *)&scp->SCp.buffer; + addr = (dma_addr_t)(ulong32)scp->SCp.buffer; if (scp->host_scribble) - addr += (dma_addr_t) - ((ulong64)(*(ulong32 *)&scp->host_scribble) << 32); + addr += (dma_addr_t)((ulong64)(ulong32)scp->host_scribble << 32); pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); } @@ -4282,11 +4153,7 @@ int __init option_setup(char *str) return 1; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int __init gdth_detect(struct scsi_host_template *shtp) -#else -static int __init gdth_detect(Scsi_Host_Template *shtp) -#endif { struct Scsi_Host *shp; gdth_pci_str pcistr[MAXHA]; @@ -4320,7 +4187,7 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) return 0; } - printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n",GDTH_VERSION_STR); + printk("GDT-HA: Storage RAID Controller Driver. Version: %s \n",GDTH_VERSION_STR); /* initializations */ gdth_polling = TRUE; b = 0; gdth_clear_events(); @@ -4351,7 +4218,7 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", isa_bios,ha->irq,ha->drq); - if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) { + if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth",ha)) { printk("GDT-ISA: Unable to allocate IRQ\n"); scsi_unregister(shp); continue; @@ -4477,7 +4344,7 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", eisa_slot>>12,ha->irq); - if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) { + if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth",ha)) { printk("GDT-EISA: Unable to allocate IRQ\n"); scsi_unregister(shp); continue; @@ -4604,7 +4471,7 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) pcistr[ctr].bus,PCI_SLOT(pcistr[ctr].device_fn),ha->irq); if (request_irq(ha->irq, gdth_interrupt, - IRQF_DISABLED|IRQF_SHARED, "gdth", ha)) + SA_INTERRUPT|SA_SHIRQ, "gdth", ha)) { printk("GDT-PCI: Unable to allocate IRQ\n"); scsi_unregister(shp); @@ -4660,15 +4527,15 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat &GDT_64BIT)|| /* 64-bit DMA only supported from FW >= x.43 */ (!ha->dma64_support)) { - if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { + if (pci_set_dma_mask(pcistr[ctr].pdev, 0xffffffff)) { printk(KERN_WARNING "GDT-PCI %d: Unable to set 32-bit DMA\n", hanum); err = TRUE; } } else { shp->max_cmd_len = 16; - if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { + if (!pci_set_dma_mask(pcistr[ctr].pdev, 0xffffffffffffffffULL)) { printk("GDT-PCI %d: 64-bit DMA enabled\n", hanum); - } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { + } else if (pci_set_dma_mask(pcistr[ctr].pdev, 0xffffffff)) { printk(KERN_WARNING "GDT-PCI %d: Unable to set 64/32-bit DMA\n", hanum); err = TRUE; } @@ -4728,13 +4595,13 @@ static int __init gdth_detect(Scsi_Host_Template *shtp) add_timer(&gdth_timer); #endif major = register_chrdev(0,"gdth",&gdth_fops); - notifier_disabled = 0; register_reboot_notifier(&gdth_notifier); } gdth_polling = FALSE; return gdth_ctr_vcount; } + static int gdth_release(struct Scsi_Host *shp) { int hanum; @@ -4883,7 +4750,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS, BUS_L2P(ha,b), 0, 0); gdth_polling = FALSE; - spin_unlock_irqrestore(&ha->smp_lock, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } return SUCCESS; } @@ -4951,9 +4818,7 @@ static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) priority = DEFAULT_PRI; if (scp->done == gdth_scsi_done) priority = scp->SCp.this_residual; - else - gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); - + gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); gdth_putq( hanum, scp, priority ); gdth_next( hanum ); return 0; @@ -5056,7 +4921,11 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) gdth_cmd_str cmd; int hanum; gdth_ha_str *ha; - int rval; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) @@ -5073,11 +4942,25 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) cmd.u.cache64.DeviceNo = res.number; else cmd.u.cache.DeviceNo = res.number; - - rval = __gdth_execute(ha->sdev, &cmd, cmnd, 30, NULL); - if (rval < 0) - return rval; - res.status = rval; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); + if (!srp) + return -ENOMEM; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; + gdth_do_req(srp, &cmd, cmnd, 30); + res.status = (ushort)srp->sr_command->SCp.Status; + scsi_release_request(srp); +#else + scp = scsi_allocate_device(ha->sdev, 1, FALSE); + if (!scp) + return -ENOMEM; + scp->cmd_len = 12; + scp->use_sg = 0; + gdth_do_cmd(scp, &cmd, cmnd, 30); + res.status = (ushort)scp->SCp.Status; + scsi_release_command(scp); +#endif if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset))) return -EFAULT; @@ -5090,8 +4973,12 @@ static int ioc_general(void __user *arg, char *cmnd) char *buf = NULL; ulong64 paddr; int hanum; - gdth_ha_str *ha; - int rval; + gdth_ha_str *ha; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || gen.ionode >= gdth_ctr_count) @@ -5183,10 +5070,27 @@ static int ioc_general(void __user *arg, char *cmnd) } } - rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info); - if (rval < 0) - return rval; - gen.status = rval; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); + if (!srp) + return -ENOMEM; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; + gdth_do_req(srp, &gen.command, cmnd, gen.timeout); + gen.status = srp->sr_command->SCp.Status; + gen.info = srp->sr_command->SCp.Message; + scsi_release_request(srp); +#else + scp = scsi_allocate_device(ha->sdev, 1, FALSE); + if (!scp) + return -ENOMEM; + scp->cmd_len = 12; + scp->use_sg = 0; + gdth_do_cmd(scp, &gen.command, cmnd, gen.timeout); + gen.status = scp->SCp.Status; + gen.info = scp->SCp.Message; + scsi_release_command(scp); +#endif if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, gen.data_len + gen.sense_len)) { @@ -5209,22 +5113,40 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) gdth_ha_str *ha; unchar i; int hanum, rc = -ENOMEM; - u32 cluster_type = 0; - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif + rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); if (!rsc || !cmd) - goto free_fail; + goto free_fail; if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || rsc->ionode >= gdth_ctr_count) { rc = -EFAULT; - goto free_fail; + goto free_fail; } hanum = rsc->ionode; ha = HADATA(gdth_ctr_tab[hanum]); memset(cmd, 0, sizeof(gdth_cmd_str)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); + if (!srp) + goto free_fail; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; +#else + scp = scsi_allocate_device(ha->sdev, 1, FALSE); + if (!scp) + goto free_fail; + scp->cmd_len = 12; + scp->use_sg = 0; +#endif + for (i = 0; i < MAX_HDRIVES; ++i) { if (!ha->hdr[i].present) { rsc->hdr_list[i].bus = 0xff; @@ -5241,15 +5163,27 @@ 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) - rsc->hdr_list[i].cluster_type = cluster_type; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + if (srp->sr_command->SCp.Status == S_OK) + rsc->hdr_list[i].cluster_type = srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + if (scp->SCp.Status == S_OK) + rsc->hdr_list[i].cluster_type = scp->SCp.Message; +#endif } } - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scsi_release_request(srp); +#else + scsi_release_command(scp); +#endif + if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) rc = -EFAULT; else - rc = 0; + rc = 0; free_fail: kfree(rsc); @@ -5267,21 +5201,40 @@ static int ioc_rescan(void __user *arg, char *cmnd) int rc = -ENOMEM; ulong flags; gdth_ha_str *ha; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd || !rsc) - goto free_fail; + goto free_fail; if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || rsc->ionode >= gdth_ctr_count) { - rc = -EFAULT; - goto free_fail; + rc = -EFAULT; + goto free_fail; } hanum = rsc->ionode; ha = HADATA(gdth_ctr_tab[hanum]); memset(cmd, 0, sizeof(gdth_cmd_str)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); + if (!srp) + goto free_fail; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; +#else + scp = scsi_allocate_device(ha->sdev, 1, FALSE); + if (!scp) + goto free_fail; + scp->cmd_len = 12; + scp->use_sg = 0; +#endif + if (rsc->flag == 0) { /* old method: re-init. cache service */ cmd->Service = CACHESERVICE; @@ -5292,8 +5245,19 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->OpCode = GDT_INIT; cmd->u.cache.DeviceNo = LINUX_OS; } - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#else + gdth_do_cmd(&scp, cmd, cmnd, 30); + status = (ushort)scp.SCp.Status; + info = (ulong32)scp.SCp.Message; +#endif i = 0; hdr_cnt = (status == S_OK ? (ushort)info : 0); } else { @@ -5308,9 +5272,15 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#endif spin_lock_irqsave(&ha->smp_lock, flags); rsc->hdr_list[i].bus = ha->virt_bus; rsc->hdr_list[i].target = i; @@ -5342,9 +5312,15 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#endif spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0); spin_unlock_irqrestore(&ha->smp_lock, flags); @@ -5355,9 +5331,15 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#endif spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].cluster_type = ((status == S_OK && !shared_access) ? (ushort)info : 0); @@ -5370,18 +5352,29 @@ static int ioc_rescan(void __user *arg, char *cmnd) cmd->u.cache64.DeviceNo = i; else cmd->u.cache.DeviceNo = i; - - status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, cmd, cmnd, 30); + status = (ushort)srp->sr_command->SCp.Status; + info = (ulong32)srp->sr_command->SCp.Message; +#else + gdth_do_cmd(scp, cmd, cmnd, 30); + status = (ushort)scp->SCp.Status; + info = (ulong32)scp->SCp.Message; +#endif spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0); spin_unlock_irqrestore(&ha->smp_lock, flags); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scsi_release_request(srp); +#else + scsi_release_command(scp); +#endif if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) rc = -EFAULT; else - rc = 0; + rc = 0; free_fail: kfree(rsc); @@ -5521,18 +5514,17 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, hanum = res.ionode; ha = HADATA(gdth_ctr_tab[hanum]); + /* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.6.x */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - scp = kmalloc(sizeof(*scp), GFP_KERNEL); + scp = scsi_get_command(ha->sdev, GFP_KERNEL); if (!scp) return -ENOMEM; - memset(scp, 0, sizeof(*scp)); - scp->device = ha->sdev; scp->cmd_len = 12; scp->use_sg = 0; scp->device->channel = virt_ctr ? 0 : res.number; rval = gdth_eh_bus_reset(scp); res.status = (rval == SUCCESS ? S_OK : S_GENERR); - kfree(scp); + scsi_put_command(scp); #else scp = scsi_allocate_device(ha->sdev, 1, FALSE); if (!scp) @@ -5565,12 +5557,34 @@ static void gdth_flush(int hanum) int i; gdth_ha_str *ha; gdth_cmd_str gdtcmd; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; +#else + Scsi_Cmnd *scp; +#endif + struct scsi_device *sdev; char cmnd[MAX_COMMAND_SIZE]; memset(cmnd, 0xff, MAX_COMMAND_SIZE); TRACE2(("gdth_flush() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + srp = scsi_allocate_request(sdev, GFP_KERNEL); + if (!srp) + return; + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; +#else + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + scp = scsi_allocate_device(sdev, 1, FALSE); + if (!scp) + return; + scp->cmd_len = 12; + scp->use_sg = 0; +#endif + for (i = 0; i < MAX_HDRIVES; ++i) { if (ha->hdr[i].present) { gdtcmd.BoardNode = LOCALBOARD; @@ -5586,10 +5600,20 @@ static void gdth_flush(int hanum) gdtcmd.u.cache.sg_canz = 0; } TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); - - gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 30, NULL); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + gdth_do_req(srp, &gdtcmd, cmnd, 30); +#else + gdth_do_cmd(scp, &gdtcmd, cmnd, 30); +#endif } } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + scsi_release_request(srp); + scsi_free_host_dev(sdev); +#else + scsi_release_command(scp); + scsi_free_host_dev(sdev); +#endif } /* shutdown routine */ @@ -5598,17 +5622,20 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) int hanum; #ifndef __alpha__ gdth_cmd_str gdtcmd; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + Scsi_Request *srp; + struct scsi_device *sdev; +#else + Scsi_Cmnd *scp; + struct scsi_device *sdev; +#endif char cmnd[MAX_COMMAND_SIZE]; #endif - if (notifier_disabled) - return NOTIFY_OK; - TRACE2(("gdth_halt() event %d\n",(int)event)); if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) return NOTIFY_DONE; - notifier_disabled = 1; printk("GDT-HA: Flushing all host drives .. "); for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { gdth_flush(hanum); @@ -5620,7 +5647,31 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) gdtcmd.Service = CACHESERVICE; gdtcmd.OpCode = GDT_RESET; TRACE2(("gdth_halt(): reset controller %d\n", hanum)); - gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 10, NULL); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + srp = scsi_allocate_request(sdev, GFP_KERNEL); + if (!srp) { + unregister_reboot_notifier(&gdth_notifier); + return NOTIFY_OK; + } + srp->sr_cmd_len = 12; + srp->sr_use_sg = 0; + gdth_do_req(srp, &gdtcmd, cmnd, 10); + scsi_release_request(srp); + scsi_free_host_dev(sdev); +#else + sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); + scp = scsi_allocate_device(sdev, 1, FALSE); + if (!scp) { + unregister_reboot_notifier(&gdth_notifier); + return NOTIFY_OK; + } + scp->cmd_len = 12; + scp->use_sg = 0; + gdth_do_cmd(scp, &gdtcmd, cmnd, 10); + scsi_release_command(scp); + scsi_free_host_dev(sdev); +#endif #endif } printk("Done.\n"); @@ -5628,25 +5679,11 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) #ifdef GDTH_STATISTICS del_timer(&gdth_timer); #endif + unregister_reboot_notifier(&gdth_notifier); return NOTIFY_OK; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -/* configure lun */ -static int gdth_slave_configure(struct scsi_device *sdev) -{ - scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); - sdev->skip_ms_page_3f = 1; - sdev->skip_ms_page_8 = 1; - return 0; -} -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static struct scsi_host_template driver_template = { -#else -static Scsi_Host_Template driver_template = { -#endif .proc_name = "gdth", .proc_info = gdth_proc_info, .name = "GDT SCSI Disk Array Controller", @@ -5657,9 +5694,6 @@ static Scsi_Host_Template driver_template = { .eh_bus_reset_handler = gdth_eh_bus_reset, .bios_param = gdth_bios_param, .can_queue = GDTH_MAXCMDS, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - .slave_configure = gdth_slave_configure, -#endif .this_id = -1, .sg_tablesize = GDTH_MAXSG, .cmd_per_lun = GDTH_MAXC_P_L,