diff options
Diffstat (limited to 'drivers/scsi/gdth.c')
-rw-r--r-- | drivers/scsi/gdth.c | 511 |
1 files changed, 236 insertions, 275 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 9b918fd43bf5..e720bb017c1e 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -4,9 +4,9 @@ | |||
4 | * Intel Corporation: Storage RAID Controllers * | 4 | * Intel Corporation: Storage RAID Controllers * |
5 | * * | 5 | * * |
6 | * gdth.c * | 6 | * gdth.c * |
7 | * Copyright (C) 1995-04 ICP vortex GmbH, Achim Leubner * | 7 | * Copyright (C) 1995-06 ICP vortex GmbH, Achim Leubner * |
8 | * Copyright (C) 2002-04 Intel Corporation * | 8 | * Copyright (C) 2002-04 Intel Corporation * |
9 | * Copyright (C) 2003-04 Adaptec Inc. * | 9 | * Copyright (C) 2003-06 Adaptec Inc. * |
10 | * <achim_leubner@adaptec.com> * | 10 | * <achim_leubner@adaptec.com> * |
11 | * * | 11 | * * |
12 | * Additions/Fixes: * | 12 | * Additions/Fixes: * |
@@ -27,9 +27,14 @@ | |||
27 | * along with this kernel; if not, write to the Free Software * | 27 | * along with this kernel; if not, write to the Free Software * |
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | 28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * |
29 | * * | 29 | * * |
30 | * Linux kernel 2.2.x, 2.4.x, 2.6.x supported * | 30 | * Linux kernel 2.4.x, 2.6.x supported * |
31 | * * | 31 | * * |
32 | * $Log: gdth.c,v $ | 32 | * $Log: gdth.c,v $ |
33 | * Revision 1.74 2006/04/10 13:44:47 achim | ||
34 | * Community changes for 2.6.x | ||
35 | * Kernel 2.2.x no longer supported | ||
36 | * scsi_request interface removed, thanks to Christoph Hellwig | ||
37 | * | ||
33 | * Revision 1.73 2004/03/31 13:33:03 achim | 38 | * Revision 1.73 2004/03/31 13:33:03 achim |
34 | * Special command 0xfd implemented to detect 64-bit DMA support | 39 | * Special command 0xfd implemented to detect 64-bit DMA support |
35 | * | 40 | * |
@@ -94,7 +99,7 @@ | |||
94 | * Bugfix free_irq() | 99 | * Bugfix free_irq() |
95 | * | 100 | * |
96 | * Revision 1.56 2001/08/09 11:19:39 achim | 101 | * Revision 1.56 2001/08/09 11:19:39 achim |
97 | * struct scsi_host_template changes | 102 | * Scsi_Host_Template changes |
98 | * | 103 | * |
99 | * Revision 1.55 2001/08/09 10:11:28 achim | 104 | * Revision 1.55 2001/08/09 10:11:28 achim |
100 | * Command HOST_UNFREEZE_IO before cache service init. | 105 | * Command HOST_UNFREEZE_IO before cache service init. |
@@ -388,7 +393,13 @@ | |||
388 | #include <linux/proc_fs.h> | 393 | #include <linux/proc_fs.h> |
389 | #include <linux/time.h> | 394 | #include <linux/time.h> |
390 | #include <linux/timer.h> | 395 | #include <linux/timer.h> |
396 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) | ||
391 | #include <linux/dma-mapping.h> | 397 | #include <linux/dma-mapping.h> |
398 | #else | ||
399 | #define DMA_32BIT_MASK 0x00000000ffffffffULL | ||
400 | #define DMA_64BIT_MASK 0xffffffffffffffffULL | ||
401 | #endif | ||
402 | |||
392 | #ifdef GDTH_RTC | 403 | #ifdef GDTH_RTC |
393 | #include <linux/mc146818rtc.h> | 404 | #include <linux/mc146818rtc.h> |
394 | #endif | 405 | #endif |
@@ -408,8 +419,8 @@ | |||
408 | 419 | ||
409 | #include "scsi.h" | 420 | #include "scsi.h" |
410 | #include <scsi/scsi_host.h> | 421 | #include <scsi/scsi_host.h> |
411 | #include "gdth.h" | ||
412 | #include "gdth_kcompat.h" | 422 | #include "gdth_kcompat.h" |
423 | #include "gdth.h" | ||
413 | 424 | ||
414 | static void gdth_delay(int milliseconds); | 425 | static void gdth_delay(int milliseconds); |
415 | static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); | 426 | static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); |
@@ -464,6 +475,8 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
464 | 475 | ||
465 | static void gdth_flush(int hanum); | 476 | static void gdth_flush(int hanum); |
466 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); | 477 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); |
478 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); | ||
479 | static void gdth_scsi_done(struct scsi_cmnd *scp); | ||
467 | 480 | ||
468 | #ifdef DEBUG_GDTH | 481 | #ifdef DEBUG_GDTH |
469 | static unchar DebugState = DEBUG_GDTH; | 482 | static unchar DebugState = DEBUG_GDTH; |
@@ -643,6 +656,7 @@ static int probe_eisa_isa = 0; | |||
643 | static int force_dma32 = 0; | 656 | static int force_dma32 = 0; |
644 | 657 | ||
645 | /* parameters for modprobe/insmod */ | 658 | /* parameters for modprobe/insmod */ |
659 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) | ||
646 | module_param_array(irq, int, NULL, 0); | 660 | module_param_array(irq, int, NULL, 0); |
647 | module_param(disable, int, 0); | 661 | module_param(disable, int, 0); |
648 | module_param(reserve_mode, int, 0); | 662 | module_param(reserve_mode, int, 0); |
@@ -655,6 +669,20 @@ module_param(virt_ctr, int, 0); | |||
655 | module_param(shared_access, int, 0); | 669 | module_param(shared_access, int, 0); |
656 | module_param(probe_eisa_isa, int, 0); | 670 | module_param(probe_eisa_isa, int, 0); |
657 | module_param(force_dma32, int, 0); | 671 | module_param(force_dma32, int, 0); |
672 | #else | ||
673 | MODULE_PARM(irq, "i"); | ||
674 | MODULE_PARM(disable, "i"); | ||
675 | MODULE_PARM(reserve_mode, "i"); | ||
676 | MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i"); | ||
677 | MODULE_PARM(reverse_scan, "i"); | ||
678 | MODULE_PARM(hdr_channel, "i"); | ||
679 | MODULE_PARM(max_ids, "i"); | ||
680 | MODULE_PARM(rescan, "i"); | ||
681 | MODULE_PARM(virt_ctr, "i"); | ||
682 | MODULE_PARM(shared_access, "i"); | ||
683 | MODULE_PARM(probe_eisa_isa, "i"); | ||
684 | MODULE_PARM(force_dma32, "i"); | ||
685 | #endif | ||
658 | MODULE_AUTHOR("Achim Leubner"); | 686 | MODULE_AUTHOR("Achim Leubner"); |
659 | MODULE_LICENSE("GPL"); | 687 | MODULE_LICENSE("GPL"); |
660 | 688 | ||
@@ -683,6 +711,91 @@ static void gdth_delay(int milliseconds) | |||
683 | } | 711 | } |
684 | } | 712 | } |
685 | 713 | ||
714 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
715 | static void gdth_scsi_done(struct scsi_cmnd *scp) | ||
716 | { | ||
717 | TRACE2(("gdth_scsi_done()\n")); | ||
718 | |||
719 | if (scp->sc_request) | ||
720 | complete((struct completion *)scp->sc_request); | ||
721 | } | ||
722 | |||
723 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | ||
724 | int timeout, u32 *info) | ||
725 | { | ||
726 | Scsi_Cmnd *scp; | ||
727 | DECLARE_COMPLETION(wait); | ||
728 | int rval; | ||
729 | |||
730 | scp = kmalloc(sizeof(*scp), GFP_KERNEL); | ||
731 | if (!scp) | ||
732 | return -ENOMEM; | ||
733 | memset(scp, 0, sizeof(*scp)); | ||
734 | scp->device = sdev; | ||
735 | /* use sc_request field to save the ptr. to completion struct. */ | ||
736 | scp->sc_request = (struct scsi_request *)&wait; | ||
737 | scp->timeout_per_command = timeout*HZ; | ||
738 | scp->request_buffer = gdtcmd; | ||
739 | scp->cmd_len = 12; | ||
740 | memcpy(scp->cmnd, cmnd, 12); | ||
741 | scp->SCp.this_residual = IOCTL_PRI; /* priority */ | ||
742 | scp->done = gdth_scsi_done; /* some fn. test this */ | ||
743 | gdth_queuecommand(scp, gdth_scsi_done); | ||
744 | wait_for_completion(&wait); | ||
745 | |||
746 | rval = scp->SCp.Status; | ||
747 | if (info) | ||
748 | *info = scp->SCp.Message; | ||
749 | kfree(scp); | ||
750 | return rval; | ||
751 | } | ||
752 | #else | ||
753 | static void gdth_scsi_done(Scsi_Cmnd *scp) | ||
754 | { | ||
755 | TRACE2(("gdth_scsi_done()\n")); | ||
756 | |||
757 | scp->request.rq_status = RQ_SCSI_DONE; | ||
758 | if (scp->request.waiting) | ||
759 | complete(scp->request.waiting); | ||
760 | } | ||
761 | |||
762 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | ||
763 | int timeout, u32 *info) | ||
764 | { | ||
765 | Scsi_Cmnd *scp = scsi_allocate_device(sdev, 1, FALSE); | ||
766 | unsigned bufflen = gdtcmd ? sizeof(gdth_cmd_str) : 0; | ||
767 | DECLARE_COMPLETION(wait); | ||
768 | int rval; | ||
769 | |||
770 | if (!scp) | ||
771 | return -ENOMEM; | ||
772 | scp->cmd_len = 12; | ||
773 | scp->use_sg = 0; | ||
774 | scp->SCp.this_residual = IOCTL_PRI; /* priority */ | ||
775 | scp->request.rq_status = RQ_SCSI_BUSY; | ||
776 | scp->request.waiting = &wait; | ||
777 | scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); | ||
778 | wait_for_completion(&wait); | ||
779 | |||
780 | rval = scp->SCp.Status; | ||
781 | if (info) | ||
782 | *info = scp->SCp.Message; | ||
783 | |||
784 | scsi_release_command(scp); | ||
785 | return rval; | ||
786 | } | ||
787 | #endif | ||
788 | |||
789 | int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, | ||
790 | int timeout, u32 *info) | ||
791 | { | ||
792 | struct scsi_device *sdev = scsi_get_host_dev(shost); | ||
793 | int rval = __gdth_execute(sdev, gdtcmd, cmnd, timeout, info); | ||
794 | |||
795 | scsi_free_host_dev(sdev); | ||
796 | return rval; | ||
797 | } | ||
798 | |||
686 | static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs) | 799 | static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs) |
687 | { | 800 | { |
688 | *cyls = size /HEADS/SECS; | 801 | *cyls = size /HEADS/SECS; |
@@ -773,7 +886,7 @@ static struct pci_device_id gdthtable[] __attribute_used__ = { | |||
773 | MODULE_DEVICE_TABLE(pci,gdthtable); | 886 | MODULE_DEVICE_TABLE(pci,gdthtable); |
774 | 887 | ||
775 | static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | 888 | static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, |
776 | ushort vendor, ushort device) | 889 | ushort vendor, ushort device) |
777 | { | 890 | { |
778 | ulong base0, base1, base2; | 891 | ulong base0, base1, base2; |
779 | struct pci_dev *pdev; | 892 | struct pci_dev *pdev; |
@@ -2248,14 +2361,16 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) | |||
2248 | ha = HADATA(gdth_ctr_tab[hanum]); | 2361 | ha = HADATA(gdth_ctr_tab[hanum]); |
2249 | spin_lock_irqsave(&ha->smp_lock, flags); | 2362 | spin_lock_irqsave(&ha->smp_lock, flags); |
2250 | 2363 | ||
2251 | scp->SCp.this_residual = (int)priority; | 2364 | if (scp->done != gdth_scsi_done) { |
2252 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; | 2365 | scp->SCp.this_residual = (int)priority; |
2253 | t = scp->device->id; | 2366 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum:scp->device->channel; |
2254 | if (priority >= DEFAULT_PRI) { | 2367 | t = scp->device->id; |
2255 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || | 2368 | if (priority >= DEFAULT_PRI) { |
2256 | (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) { | 2369 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || |
2257 | TRACE2(("gdth_putq(): locked IO -> update_timeout()\n")); | 2370 | (b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) { |
2258 | scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); | 2371 | TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); |
2372 | scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); | ||
2373 | } | ||
2259 | } | 2374 | } |
2260 | } | 2375 | } |
2261 | 2376 | ||
@@ -2309,14 +2424,18 @@ static void gdth_next(int hanum) | |||
2309 | for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { | 2424 | for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { |
2310 | if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) | 2425 | if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) |
2311 | pscp = (Scsi_Cmnd *)pscp->SCp.ptr; | 2426 | pscp = (Scsi_Cmnd *)pscp->SCp.ptr; |
2312 | b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel; | 2427 | if (nscp->done != gdth_scsi_done) { |
2313 | t = nscp->device->id; | 2428 | b = virt_ctr ? |
2314 | l = nscp->device->lun; | 2429 | NUMDATA(nscp->device->host)->busnum : nscp->device->channel; |
2315 | if (nscp->SCp.this_residual >= DEFAULT_PRI) { | 2430 | t = nscp->device->id; |
2316 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || | 2431 | l = nscp->device->lun; |
2317 | (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) | 2432 | if (nscp->SCp.this_residual >= DEFAULT_PRI) { |
2318 | continue; | 2433 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || |
2319 | } | 2434 | (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) |
2435 | continue; | ||
2436 | } | ||
2437 | } else | ||
2438 | b = t = l = 0; | ||
2320 | 2439 | ||
2321 | if (firsttime) { | 2440 | if (firsttime) { |
2322 | if (gdth_test_busy(hanum)) { /* controller busy ? */ | 2441 | if (gdth_test_busy(hanum)) { /* controller busy ? */ |
@@ -2331,7 +2450,7 @@ static void gdth_next(int hanum) | |||
2331 | firsttime = FALSE; | 2450 | firsttime = FALSE; |
2332 | } | 2451 | } |
2333 | 2452 | ||
2334 | if (nscp->done != gdth_scsi_done || nscp->cmnd[0] != 0xff) { | 2453 | if (nscp->done != gdth_scsi_done) { |
2335 | if (nscp->SCp.phase == -1) { | 2454 | if (nscp->SCp.phase == -1) { |
2336 | nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ | 2455 | nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ |
2337 | if (nscp->cmnd[0] == TEST_UNIT_READY) { | 2456 | if (nscp->cmnd[0] == TEST_UNIT_READY) { |
@@ -2394,7 +2513,7 @@ static void gdth_next(int hanum) | |||
2394 | else | 2513 | else |
2395 | nscp->scsi_done(nscp); | 2514 | nscp->scsi_done(nscp); |
2396 | } | 2515 | } |
2397 | } else if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) { | 2516 | } else if (nscp->done == gdth_scsi_done) { |
2398 | if (!(cmd_index=gdth_special_cmd(hanum,nscp))) | 2517 | if (!(cmd_index=gdth_special_cmd(hanum,nscp))) |
2399 | this_cmd = FALSE; | 2518 | this_cmd = FALSE; |
2400 | next_cmd = FALSE; | 2519 | next_cmd = FALSE; |
@@ -2548,7 +2667,7 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, | |||
2548 | if (scp->use_sg) { | 2667 | if (scp->use_sg) { |
2549 | sl = (struct scatterlist *)scp->request_buffer; | 2668 | sl = (struct scatterlist *)scp->request_buffer; |
2550 | for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) { | 2669 | for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) { |
2551 | unsigned long flags; | 2670 | unsigned long flags; |
2552 | cpnow = (ushort)sl->length; | 2671 | cpnow = (ushort)sl->length; |
2553 | TRACE(("copy_internal() now %d sum %d count %d %d\n", | 2672 | TRACE(("copy_internal() now %d sum %d count %d %d\n", |
2554 | cpnow,cpsum,cpcount,(ushort)scp->bufflen)); | 2673 | cpnow,cpsum,cpcount,(ushort)scp->bufflen)); |
@@ -2560,12 +2679,19 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, | |||
2560 | hanum); | 2679 | hanum); |
2561 | return; | 2680 | return; |
2562 | } | 2681 | } |
2563 | local_irq_save(flags); | 2682 | local_irq_save(flags); |
2564 | address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; | 2683 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
2684 | address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; | ||
2685 | memcpy(address,buffer,cpnow); | ||
2686 | flush_dcache_page(sl->page); | ||
2687 | kunmap_atomic(address, KM_BIO_SRC_IRQ); | ||
2688 | #else | ||
2689 | address = kmap_atomic(sl->page, KM_BH_IRQ) + sl->offset; | ||
2565 | memcpy(address,buffer,cpnow); | 2690 | memcpy(address,buffer,cpnow); |
2566 | flush_dcache_page(sl->page); | 2691 | flush_dcache_page(sl->page); |
2567 | kunmap_atomic(address, KM_BIO_SRC_IRQ); | 2692 | kunmap_atomic(address, KM_BH_IRQ); |
2568 | local_irq_restore(flags); | 2693 | #endif |
2694 | local_irq_restore(flags); | ||
2569 | if (cpsum == cpcount) | 2695 | if (cpsum == cpcount) |
2570 | break; | 2696 | break; |
2571 | buffer += cpnow; | 2697 | buffer += cpnow; |
@@ -2946,9 +3072,9 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
2946 | offset = (ulong)scp->sense_buffer & ~PAGE_MASK; | 3072 | offset = (ulong)scp->sense_buffer & ~PAGE_MASK; |
2947 | sense_paddr = pci_map_page(ha->pdev,page,offset, | 3073 | sense_paddr = pci_map_page(ha->pdev,page,offset, |
2948 | 16,PCI_DMA_FROMDEVICE); | 3074 | 16,PCI_DMA_FROMDEVICE); |
2949 | scp->SCp.buffer = (struct scatterlist *)((ulong32)sense_paddr); | 3075 | *(ulong32 *)&scp->SCp.buffer = (ulong32)sense_paddr; |
2950 | /* high part, if 64bit */ | 3076 | /* high part, if 64bit */ |
2951 | scp->host_scribble = (char *)(ulong32)((ulong64)sense_paddr >> 32); | 3077 | *(ulong32 *)&scp->host_scribble = (ulong32)((ulong64)sense_paddr >> 32); |
2952 | cmdp->OpCode = GDT_WRITE; /* always */ | 3078 | cmdp->OpCode = GDT_WRITE; /* always */ |
2953 | cmdp->BoardNode = LOCALBOARD; | 3079 | cmdp->BoardNode = LOCALBOARD; |
2954 | if (mode64) { | 3080 | if (mode64) { |
@@ -3022,7 +3148,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3022 | } | 3148 | } |
3023 | #endif | 3149 | #endif |
3024 | 3150 | ||
3025 | } else { | 3151 | } else if (scp->request_bufflen) { |
3026 | scp->SCp.Status = GDTH_MAP_SINGLE; | 3152 | scp->SCp.Status = GDTH_MAP_SINGLE; |
3027 | scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; | 3153 | scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; |
3028 | page = virt_to_page(scp->request_buffer); | 3154 | page = virt_to_page(scp->request_buffer); |
@@ -3309,7 +3435,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) | |||
3309 | } | 3435 | } |
3310 | 3436 | ||
3311 | if (!gdth_polling) | 3437 | if (!gdth_polling) |
3312 | spin_lock_irqsave(&ha2->smp_lock, flags); | 3438 | spin_lock_irqsave(&ha2->smp_lock, flags); |
3313 | wait_index = 0; | 3439 | wait_index = 0; |
3314 | 3440 | ||
3315 | /* search controller */ | 3441 | /* search controller */ |
@@ -3642,9 +3768,10 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3642 | scp->request_bufflen,scp->SCp.Message); | 3768 | scp->request_bufflen,scp->SCp.Message); |
3643 | if (scp->SCp.buffer) { | 3769 | if (scp->SCp.buffer) { |
3644 | dma_addr_t addr; | 3770 | dma_addr_t addr; |
3645 | addr = (dma_addr_t)(ulong32)scp->SCp.buffer; | 3771 | addr = (dma_addr_t)*(ulong32 *)&scp->SCp.buffer; |
3646 | if (scp->host_scribble) | 3772 | if (scp->host_scribble) |
3647 | addr += (dma_addr_t)((ulong64)(ulong32)scp->host_scribble << 32); | 3773 | addr += (dma_addr_t) |
3774 | ((ulong64)(*(ulong32 *)&scp->host_scribble) << 32); | ||
3648 | pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); | 3775 | pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); |
3649 | } | 3776 | } |
3650 | 3777 | ||
@@ -4154,7 +4281,11 @@ int __init option_setup(char *str) | |||
4154 | return 1; | 4281 | return 1; |
4155 | } | 4282 | } |
4156 | 4283 | ||
4284 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
4157 | static int __init gdth_detect(struct scsi_host_template *shtp) | 4285 | static int __init gdth_detect(struct scsi_host_template *shtp) |
4286 | #else | ||
4287 | static int __init gdth_detect(Scsi_Host_Template *shtp) | ||
4288 | #endif | ||
4158 | { | 4289 | { |
4159 | struct Scsi_Host *shp; | 4290 | struct Scsi_Host *shp; |
4160 | gdth_pci_str pcistr[MAXHA]; | 4291 | gdth_pci_str pcistr[MAXHA]; |
@@ -4188,7 +4319,7 @@ static int __init gdth_detect(struct scsi_host_template *shtp) | |||
4188 | return 0; | 4319 | return 0; |
4189 | } | 4320 | } |
4190 | 4321 | ||
4191 | printk("GDT-HA: Storage RAID Controller Driver. Version: %s \n",GDTH_VERSION_STR); | 4322 | printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n",GDTH_VERSION_STR); |
4192 | /* initializations */ | 4323 | /* initializations */ |
4193 | gdth_polling = TRUE; b = 0; | 4324 | gdth_polling = TRUE; b = 0; |
4194 | gdth_clear_events(); | 4325 | gdth_clear_events(); |
@@ -4751,7 +4882,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | |||
4751 | gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS, | 4882 | gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS, |
4752 | BUS_L2P(ha,b), 0, 0); | 4883 | BUS_L2P(ha,b), 0, 0); |
4753 | gdth_polling = FALSE; | 4884 | gdth_polling = FALSE; |
4754 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4885 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
4755 | } | 4886 | } |
4756 | return SUCCESS; | 4887 | return SUCCESS; |
4757 | } | 4888 | } |
@@ -4819,7 +4950,9 @@ static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) | |||
4819 | priority = DEFAULT_PRI; | 4950 | priority = DEFAULT_PRI; |
4820 | if (scp->done == gdth_scsi_done) | 4951 | if (scp->done == gdth_scsi_done) |
4821 | priority = scp->SCp.this_residual; | 4952 | priority = scp->SCp.this_residual; |
4822 | gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); | 4953 | else |
4954 | gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); | ||
4955 | |||
4823 | gdth_putq( hanum, scp, priority ); | 4956 | gdth_putq( hanum, scp, priority ); |
4824 | gdth_next( hanum ); | 4957 | gdth_next( hanum ); |
4825 | return 0; | 4958 | return 0; |
@@ -4922,11 +5055,7 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) | |||
4922 | gdth_cmd_str cmd; | 5055 | gdth_cmd_str cmd; |
4923 | int hanum; | 5056 | int hanum; |
4924 | gdth_ha_str *ha; | 5057 | gdth_ha_str *ha; |
4925 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5058 | int rval; |
4926 | Scsi_Request *srp; | ||
4927 | #else | ||
4928 | Scsi_Cmnd *scp; | ||
4929 | #endif | ||
4930 | 5059 | ||
4931 | if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || | 5060 | if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || |
4932 | res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) | 5061 | res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) |
@@ -4943,25 +5072,11 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) | |||
4943 | cmd.u.cache64.DeviceNo = res.number; | 5072 | cmd.u.cache64.DeviceNo = res.number; |
4944 | else | 5073 | else |
4945 | cmd.u.cache.DeviceNo = res.number; | 5074 | cmd.u.cache.DeviceNo = res.number; |
4946 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5075 | |
4947 | srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); | 5076 | rval = __gdth_execute(ha->sdev, &cmd, cmnd, 30, NULL); |
4948 | if (!srp) | 5077 | if (rval < 0) |
4949 | return -ENOMEM; | 5078 | return rval; |
4950 | srp->sr_cmd_len = 12; | 5079 | res.status = rval; |
4951 | srp->sr_use_sg = 0; | ||
4952 | gdth_do_req(srp, &cmd, cmnd, 30); | ||
4953 | res.status = (ushort)srp->sr_command->SCp.Status; | ||
4954 | scsi_release_request(srp); | ||
4955 | #else | ||
4956 | scp = scsi_allocate_device(ha->sdev, 1, FALSE); | ||
4957 | if (!scp) | ||
4958 | return -ENOMEM; | ||
4959 | scp->cmd_len = 12; | ||
4960 | scp->use_sg = 0; | ||
4961 | gdth_do_cmd(scp, &cmd, cmnd, 30); | ||
4962 | res.status = (ushort)scp->SCp.Status; | ||
4963 | scsi_release_command(scp); | ||
4964 | #endif | ||
4965 | 5080 | ||
4966 | if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset))) | 5081 | if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset))) |
4967 | return -EFAULT; | 5082 | return -EFAULT; |
@@ -4974,12 +5089,8 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
4974 | char *buf = NULL; | 5089 | char *buf = NULL; |
4975 | ulong64 paddr; | 5090 | ulong64 paddr; |
4976 | int hanum; | 5091 | int hanum; |
4977 | gdth_ha_str *ha; | 5092 | gdth_ha_str *ha; |
4978 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5093 | int rval; |
4979 | Scsi_Request *srp; | ||
4980 | #else | ||
4981 | Scsi_Cmnd *scp; | ||
4982 | #endif | ||
4983 | 5094 | ||
4984 | if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || | 5095 | if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || |
4985 | gen.ionode >= gdth_ctr_count) | 5096 | gen.ionode >= gdth_ctr_count) |
@@ -5071,27 +5182,10 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
5071 | } | 5182 | } |
5072 | } | 5183 | } |
5073 | 5184 | ||
5074 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5185 | rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info); |
5075 | srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); | 5186 | if (rval < 0) |
5076 | if (!srp) | 5187 | return rval; |
5077 | return -ENOMEM; | 5188 | gen.status = rval; |
5078 | srp->sr_cmd_len = 12; | ||
5079 | srp->sr_use_sg = 0; | ||
5080 | gdth_do_req(srp, &gen.command, cmnd, gen.timeout); | ||
5081 | gen.status = srp->sr_command->SCp.Status; | ||
5082 | gen.info = srp->sr_command->SCp.Message; | ||
5083 | scsi_release_request(srp); | ||
5084 | #else | ||
5085 | scp = scsi_allocate_device(ha->sdev, 1, FALSE); | ||
5086 | if (!scp) | ||
5087 | return -ENOMEM; | ||
5088 | scp->cmd_len = 12; | ||
5089 | scp->use_sg = 0; | ||
5090 | gdth_do_cmd(scp, &gen.command, cmnd, gen.timeout); | ||
5091 | gen.status = scp->SCp.Status; | ||
5092 | gen.info = scp->SCp.Message; | ||
5093 | scsi_release_command(scp); | ||
5094 | #endif | ||
5095 | 5189 | ||
5096 | if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, | 5190 | if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, |
5097 | gen.data_len + gen.sense_len)) { | 5191 | gen.data_len + gen.sense_len)) { |
@@ -5114,40 +5208,22 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) | |||
5114 | gdth_ha_str *ha; | 5208 | gdth_ha_str *ha; |
5115 | unchar i; | 5209 | unchar i; |
5116 | int hanum, rc = -ENOMEM; | 5210 | int hanum, rc = -ENOMEM; |
5117 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5211 | u32 cluster_type = 0; |
5118 | Scsi_Request *srp; | 5212 | |
5119 | #else | ||
5120 | Scsi_Cmnd *scp; | ||
5121 | #endif | ||
5122 | |||
5123 | rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); | 5213 | rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); |
5124 | cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); | 5214 | cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); |
5125 | if (!rsc || !cmd) | 5215 | if (!rsc || !cmd) |
5126 | goto free_fail; | 5216 | goto free_fail; |
5127 | 5217 | ||
5128 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || | 5218 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || |
5129 | rsc->ionode >= gdth_ctr_count) { | 5219 | rsc->ionode >= gdth_ctr_count) { |
5130 | rc = -EFAULT; | 5220 | rc = -EFAULT; |
5131 | goto free_fail; | 5221 | goto free_fail; |
5132 | } | 5222 | } |
5133 | hanum = rsc->ionode; | 5223 | hanum = rsc->ionode; |
5134 | ha = HADATA(gdth_ctr_tab[hanum]); | 5224 | ha = HADATA(gdth_ctr_tab[hanum]); |
5135 | memset(cmd, 0, sizeof(gdth_cmd_str)); | 5225 | memset(cmd, 0, sizeof(gdth_cmd_str)); |
5136 | 5226 | ||
5137 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5138 | srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); | ||
5139 | if (!srp) | ||
5140 | goto free_fail; | ||
5141 | srp->sr_cmd_len = 12; | ||
5142 | srp->sr_use_sg = 0; | ||
5143 | #else | ||
5144 | scp = scsi_allocate_device(ha->sdev, 1, FALSE); | ||
5145 | if (!scp) | ||
5146 | goto free_fail; | ||
5147 | scp->cmd_len = 12; | ||
5148 | scp->use_sg = 0; | ||
5149 | #endif | ||
5150 | |||
5151 | for (i = 0; i < MAX_HDRIVES; ++i) { | 5227 | for (i = 0; i < MAX_HDRIVES; ++i) { |
5152 | if (!ha->hdr[i].present) { | 5228 | if (!ha->hdr[i].present) { |
5153 | rsc->hdr_list[i].bus = 0xff; | 5229 | rsc->hdr_list[i].bus = 0xff; |
@@ -5164,27 +5240,15 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) | |||
5164 | cmd->u.cache64.DeviceNo = i; | 5240 | cmd->u.cache64.DeviceNo = i; |
5165 | else | 5241 | else |
5166 | cmd->u.cache.DeviceNo = i; | 5242 | cmd->u.cache.DeviceNo = i; |
5167 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5243 | if (__gdth_execute(ha->sdev, cmd, cmnd, 30, &cluster_type) == S_OK) |
5168 | gdth_do_req(srp, cmd, cmnd, 30); | 5244 | rsc->hdr_list[i].cluster_type = cluster_type; |
5169 | if (srp->sr_command->SCp.Status == S_OK) | ||
5170 | rsc->hdr_list[i].cluster_type = srp->sr_command->SCp.Message; | ||
5171 | #else | ||
5172 | gdth_do_cmd(scp, cmd, cmnd, 30); | ||
5173 | if (scp->SCp.Status == S_OK) | ||
5174 | rsc->hdr_list[i].cluster_type = scp->SCp.Message; | ||
5175 | #endif | ||
5176 | } | 5245 | } |
5177 | } | 5246 | } |
5178 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5247 | |
5179 | scsi_release_request(srp); | ||
5180 | #else | ||
5181 | scsi_release_command(scp); | ||
5182 | #endif | ||
5183 | |||
5184 | if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) | 5248 | if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) |
5185 | rc = -EFAULT; | 5249 | rc = -EFAULT; |
5186 | else | 5250 | else |
5187 | rc = 0; | 5251 | rc = 0; |
5188 | 5252 | ||
5189 | free_fail: | 5253 | free_fail: |
5190 | kfree(rsc); | 5254 | kfree(rsc); |
@@ -5202,40 +5266,21 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5202 | int rc = -ENOMEM; | 5266 | int rc = -ENOMEM; |
5203 | ulong flags; | 5267 | ulong flags; |
5204 | gdth_ha_str *ha; | 5268 | gdth_ha_str *ha; |
5205 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5206 | Scsi_Request *srp; | ||
5207 | #else | ||
5208 | Scsi_Cmnd *scp; | ||
5209 | #endif | ||
5210 | 5269 | ||
5211 | rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); | 5270 | rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); |
5212 | cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); | 5271 | cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); |
5213 | if (!cmd || !rsc) | 5272 | if (!cmd || !rsc) |
5214 | goto free_fail; | 5273 | goto free_fail; |
5215 | 5274 | ||
5216 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || | 5275 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || |
5217 | rsc->ionode >= gdth_ctr_count) { | 5276 | rsc->ionode >= gdth_ctr_count) { |
5218 | rc = -EFAULT; | 5277 | rc = -EFAULT; |
5219 | goto free_fail; | 5278 | goto free_fail; |
5220 | } | 5279 | } |
5221 | hanum = rsc->ionode; | 5280 | hanum = rsc->ionode; |
5222 | ha = HADATA(gdth_ctr_tab[hanum]); | 5281 | ha = HADATA(gdth_ctr_tab[hanum]); |
5223 | memset(cmd, 0, sizeof(gdth_cmd_str)); | 5282 | memset(cmd, 0, sizeof(gdth_cmd_str)); |
5224 | 5283 | ||
5225 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5226 | srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); | ||
5227 | if (!srp) | ||
5228 | goto free_fail; | ||
5229 | srp->sr_cmd_len = 12; | ||
5230 | srp->sr_use_sg = 0; | ||
5231 | #else | ||
5232 | scp = scsi_allocate_device(ha->sdev, 1, FALSE); | ||
5233 | if (!scp) | ||
5234 | goto free_fail; | ||
5235 | scp->cmd_len = 12; | ||
5236 | scp->use_sg = 0; | ||
5237 | #endif | ||
5238 | |||
5239 | if (rsc->flag == 0) { | 5284 | if (rsc->flag == 0) { |
5240 | /* old method: re-init. cache service */ | 5285 | /* old method: re-init. cache service */ |
5241 | cmd->Service = CACHESERVICE; | 5286 | cmd->Service = CACHESERVICE; |
@@ -5246,19 +5291,8 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5246 | cmd->OpCode = GDT_INIT; | 5291 | cmd->OpCode = GDT_INIT; |
5247 | cmd->u.cache.DeviceNo = LINUX_OS; | 5292 | cmd->u.cache.DeviceNo = LINUX_OS; |
5248 | } | 5293 | } |
5249 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5294 | |
5250 | gdth_do_req(srp, cmd, cmnd, 30); | 5295 | status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); |
5251 | status = (ushort)srp->sr_command->SCp.Status; | ||
5252 | info = (ulong32)srp->sr_command->SCp.Message; | ||
5253 | #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) | ||
5254 | gdth_do_cmd(scp, cmd, cmnd, 30); | ||
5255 | status = (ushort)scp->SCp.Status; | ||
5256 | info = (ulong32)scp->SCp.Message; | ||
5257 | #else | ||
5258 | gdth_do_cmd(&scp, cmd, cmnd, 30); | ||
5259 | status = (ushort)scp.SCp.Status; | ||
5260 | info = (ulong32)scp.SCp.Message; | ||
5261 | #endif | ||
5262 | i = 0; | 5296 | i = 0; |
5263 | hdr_cnt = (status == S_OK ? (ushort)info : 0); | 5297 | hdr_cnt = (status == S_OK ? (ushort)info : 0); |
5264 | } else { | 5298 | } else { |
@@ -5273,15 +5307,9 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5273 | cmd->u.cache64.DeviceNo = i; | 5307 | cmd->u.cache64.DeviceNo = i; |
5274 | else | 5308 | else |
5275 | cmd->u.cache.DeviceNo = i; | 5309 | cmd->u.cache.DeviceNo = i; |
5276 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5310 | |
5277 | gdth_do_req(srp, cmd, cmnd, 30); | 5311 | status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); |
5278 | status = (ushort)srp->sr_command->SCp.Status; | 5312 | |
5279 | info = (ulong32)srp->sr_command->SCp.Message; | ||
5280 | #else | ||
5281 | gdth_do_cmd(scp, cmd, cmnd, 30); | ||
5282 | status = (ushort)scp->SCp.Status; | ||
5283 | info = (ulong32)scp->SCp.Message; | ||
5284 | #endif | ||
5285 | spin_lock_irqsave(&ha->smp_lock, flags); | 5313 | spin_lock_irqsave(&ha->smp_lock, flags); |
5286 | rsc->hdr_list[i].bus = ha->virt_bus; | 5314 | rsc->hdr_list[i].bus = ha->virt_bus; |
5287 | rsc->hdr_list[i].target = i; | 5315 | rsc->hdr_list[i].target = i; |
@@ -5313,15 +5341,9 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5313 | cmd->u.cache64.DeviceNo = i; | 5341 | cmd->u.cache64.DeviceNo = i; |
5314 | else | 5342 | else |
5315 | cmd->u.cache.DeviceNo = i; | 5343 | cmd->u.cache.DeviceNo = i; |
5316 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5344 | |
5317 | gdth_do_req(srp, cmd, cmnd, 30); | 5345 | status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); |
5318 | status = (ushort)srp->sr_command->SCp.Status; | 5346 | |
5319 | info = (ulong32)srp->sr_command->SCp.Message; | ||
5320 | #else | ||
5321 | gdth_do_cmd(scp, cmd, cmnd, 30); | ||
5322 | status = (ushort)scp->SCp.Status; | ||
5323 | info = (ulong32)scp->SCp.Message; | ||
5324 | #endif | ||
5325 | spin_lock_irqsave(&ha->smp_lock, flags); | 5347 | spin_lock_irqsave(&ha->smp_lock, flags); |
5326 | ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0); | 5348 | ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0); |
5327 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 5349 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
@@ -5332,15 +5354,9 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5332 | cmd->u.cache64.DeviceNo = i; | 5354 | cmd->u.cache64.DeviceNo = i; |
5333 | else | 5355 | else |
5334 | cmd->u.cache.DeviceNo = i; | 5356 | cmd->u.cache.DeviceNo = i; |
5335 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5357 | |
5336 | gdth_do_req(srp, cmd, cmnd, 30); | 5358 | status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); |
5337 | status = (ushort)srp->sr_command->SCp.Status; | 5359 | |
5338 | info = (ulong32)srp->sr_command->SCp.Message; | ||
5339 | #else | ||
5340 | gdth_do_cmd(scp, cmd, cmnd, 30); | ||
5341 | status = (ushort)scp->SCp.Status; | ||
5342 | info = (ulong32)scp->SCp.Message; | ||
5343 | #endif | ||
5344 | spin_lock_irqsave(&ha->smp_lock, flags); | 5360 | spin_lock_irqsave(&ha->smp_lock, flags); |
5345 | ha->hdr[i].cluster_type = | 5361 | ha->hdr[i].cluster_type = |
5346 | ((status == S_OK && !shared_access) ? (ushort)info : 0); | 5362 | ((status == S_OK && !shared_access) ? (ushort)info : 0); |
@@ -5353,29 +5369,18 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5353 | cmd->u.cache64.DeviceNo = i; | 5369 | cmd->u.cache64.DeviceNo = i; |
5354 | else | 5370 | else |
5355 | cmd->u.cache.DeviceNo = i; | 5371 | cmd->u.cache.DeviceNo = i; |
5356 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5372 | |
5357 | gdth_do_req(srp, cmd, cmnd, 30); | 5373 | status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); |
5358 | status = (ushort)srp->sr_command->SCp.Status; | 5374 | |
5359 | info = (ulong32)srp->sr_command->SCp.Message; | ||
5360 | #else | ||
5361 | gdth_do_cmd(scp, cmd, cmnd, 30); | ||
5362 | status = (ushort)scp->SCp.Status; | ||
5363 | info = (ulong32)scp->SCp.Message; | ||
5364 | #endif | ||
5365 | spin_lock_irqsave(&ha->smp_lock, flags); | 5375 | spin_lock_irqsave(&ha->smp_lock, flags); |
5366 | ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0); | 5376 | ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0); |
5367 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 5377 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5368 | } | 5378 | } |
5369 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5370 | scsi_release_request(srp); | ||
5371 | #else | ||
5372 | scsi_release_command(scp); | ||
5373 | #endif | ||
5374 | 5379 | ||
5375 | if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) | 5380 | if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) |
5376 | rc = -EFAULT; | 5381 | rc = -EFAULT; |
5377 | else | 5382 | else |
5378 | rc = 0; | 5383 | rc = 0; |
5379 | 5384 | ||
5380 | free_fail: | 5385 | free_fail: |
5381 | kfree(rsc); | 5386 | kfree(rsc); |
@@ -5515,17 +5520,18 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5515 | hanum = res.ionode; | 5520 | hanum = res.ionode; |
5516 | ha = HADATA(gdth_ctr_tab[hanum]); | 5521 | ha = HADATA(gdth_ctr_tab[hanum]); |
5517 | 5522 | ||
5518 | /* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.6.x */ | ||
5519 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5523 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
5520 | scp = scsi_get_command(ha->sdev, GFP_KERNEL); | 5524 | scp = kmalloc(sizeof(*scp), GFP_KERNEL); |
5521 | if (!scp) | 5525 | if (!scp) |
5522 | return -ENOMEM; | 5526 | return -ENOMEM; |
5527 | memset(scp, 0, sizeof(*scp)); | ||
5528 | scp->device = ha->sdev; | ||
5523 | scp->cmd_len = 12; | 5529 | scp->cmd_len = 12; |
5524 | scp->use_sg = 0; | 5530 | scp->use_sg = 0; |
5525 | scp->device->channel = virt_ctr ? 0 : res.number; | 5531 | scp->device->channel = virt_ctr ? 0 : res.number; |
5526 | rval = gdth_eh_bus_reset(scp); | 5532 | rval = gdth_eh_bus_reset(scp); |
5527 | res.status = (rval == SUCCESS ? S_OK : S_GENERR); | 5533 | res.status = (rval == SUCCESS ? S_OK : S_GENERR); |
5528 | scsi_put_command(scp); | 5534 | kfree(scp); |
5529 | #else | 5535 | #else |
5530 | scp = scsi_allocate_device(ha->sdev, 1, FALSE); | 5536 | scp = scsi_allocate_device(ha->sdev, 1, FALSE); |
5531 | if (!scp) | 5537 | if (!scp) |
@@ -5558,34 +5564,12 @@ static void gdth_flush(int hanum) | |||
5558 | int i; | 5564 | int i; |
5559 | gdth_ha_str *ha; | 5565 | gdth_ha_str *ha; |
5560 | gdth_cmd_str gdtcmd; | 5566 | gdth_cmd_str gdtcmd; |
5561 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5562 | Scsi_Request *srp; | ||
5563 | #else | ||
5564 | Scsi_Cmnd *scp; | ||
5565 | #endif | ||
5566 | struct scsi_device *sdev; | ||
5567 | char cmnd[MAX_COMMAND_SIZE]; | 5567 | char cmnd[MAX_COMMAND_SIZE]; |
5568 | memset(cmnd, 0xff, MAX_COMMAND_SIZE); | 5568 | memset(cmnd, 0xff, MAX_COMMAND_SIZE); |
5569 | 5569 | ||
5570 | TRACE2(("gdth_flush() hanum %d\n",hanum)); | 5570 | TRACE2(("gdth_flush() hanum %d\n",hanum)); |
5571 | ha = HADATA(gdth_ctr_tab[hanum]); | 5571 | ha = HADATA(gdth_ctr_tab[hanum]); |
5572 | 5572 | ||
5573 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5574 | sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); | ||
5575 | srp = scsi_allocate_request(sdev, GFP_KERNEL); | ||
5576 | if (!srp) | ||
5577 | return; | ||
5578 | srp->sr_cmd_len = 12; | ||
5579 | srp->sr_use_sg = 0; | ||
5580 | #else | ||
5581 | sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); | ||
5582 | scp = scsi_allocate_device(sdev, 1, FALSE); | ||
5583 | if (!scp) | ||
5584 | return; | ||
5585 | scp->cmd_len = 12; | ||
5586 | scp->use_sg = 0; | ||
5587 | #endif | ||
5588 | |||
5589 | for (i = 0; i < MAX_HDRIVES; ++i) { | 5573 | for (i = 0; i < MAX_HDRIVES; ++i) { |
5590 | if (ha->hdr[i].present) { | 5574 | if (ha->hdr[i].present) { |
5591 | gdtcmd.BoardNode = LOCALBOARD; | 5575 | gdtcmd.BoardNode = LOCALBOARD; |
@@ -5601,20 +5585,10 @@ static void gdth_flush(int hanum) | |||
5601 | gdtcmd.u.cache.sg_canz = 0; | 5585 | gdtcmd.u.cache.sg_canz = 0; |
5602 | } | 5586 | } |
5603 | TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); | 5587 | TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); |
5604 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5588 | |
5605 | gdth_do_req(srp, &gdtcmd, cmnd, 30); | 5589 | gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 30, NULL); |
5606 | #else | ||
5607 | gdth_do_cmd(scp, &gdtcmd, cmnd, 30); | ||
5608 | #endif | ||
5609 | } | 5590 | } |
5610 | } | 5591 | } |
5611 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5612 | scsi_release_request(srp); | ||
5613 | scsi_free_host_dev(sdev); | ||
5614 | #else | ||
5615 | scsi_release_command(scp); | ||
5616 | scsi_free_host_dev(sdev); | ||
5617 | #endif | ||
5618 | } | 5592 | } |
5619 | 5593 | ||
5620 | /* shutdown routine */ | 5594 | /* shutdown routine */ |
@@ -5623,18 +5597,11 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5623 | int hanum; | 5597 | int hanum; |
5624 | #ifndef __alpha__ | 5598 | #ifndef __alpha__ |
5625 | gdth_cmd_str gdtcmd; | 5599 | gdth_cmd_str gdtcmd; |
5626 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5627 | Scsi_Request *srp; | ||
5628 | struct scsi_device *sdev; | ||
5629 | #else | ||
5630 | Scsi_Cmnd *scp; | ||
5631 | struct scsi_device *sdev; | ||
5632 | #endif | ||
5633 | char cmnd[MAX_COMMAND_SIZE]; | 5600 | char cmnd[MAX_COMMAND_SIZE]; |
5634 | #endif | 5601 | #endif |
5635 | 5602 | ||
5636 | if (notifier_disabled) | 5603 | if (notifier_disabled) |
5637 | return NOTIFY_OK; | 5604 | return NOTIFY_OK; |
5638 | 5605 | ||
5639 | TRACE2(("gdth_halt() event %d\n",(int)event)); | 5606 | TRACE2(("gdth_halt() event %d\n",(int)event)); |
5640 | if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) | 5607 | if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) |
@@ -5652,31 +5619,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5652 | gdtcmd.Service = CACHESERVICE; | 5619 | gdtcmd.Service = CACHESERVICE; |
5653 | gdtcmd.OpCode = GDT_RESET; | 5620 | gdtcmd.OpCode = GDT_RESET; |
5654 | TRACE2(("gdth_halt(): reset controller %d\n", hanum)); | 5621 | TRACE2(("gdth_halt(): reset controller %d\n", hanum)); |
5655 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 5622 | gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 10, NULL); |
5656 | sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); | ||
5657 | srp = scsi_allocate_request(sdev, GFP_KERNEL); | ||
5658 | if (!srp) { | ||
5659 | unregister_reboot_notifier(&gdth_notifier); | ||
5660 | return NOTIFY_OK; | ||
5661 | } | ||
5662 | srp->sr_cmd_len = 12; | ||
5663 | srp->sr_use_sg = 0; | ||
5664 | gdth_do_req(srp, &gdtcmd, cmnd, 10); | ||
5665 | scsi_release_request(srp); | ||
5666 | scsi_free_host_dev(sdev); | ||
5667 | #else | ||
5668 | sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); | ||
5669 | scp = scsi_allocate_device(sdev, 1, FALSE); | ||
5670 | if (!scp) { | ||
5671 | unregister_reboot_notifier(&gdth_notifier); | ||
5672 | return NOTIFY_OK; | ||
5673 | } | ||
5674 | scp->cmd_len = 12; | ||
5675 | scp->use_sg = 0; | ||
5676 | gdth_do_cmd(scp, &gdtcmd, cmnd, 10); | ||
5677 | scsi_release_command(scp); | ||
5678 | scsi_free_host_dev(sdev); | ||
5679 | #endif | ||
5680 | #endif | 5623 | #endif |
5681 | } | 5624 | } |
5682 | printk("Done.\n"); | 5625 | printk("Done.\n"); |
@@ -5687,7 +5630,22 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5687 | return NOTIFY_OK; | 5630 | return NOTIFY_OK; |
5688 | } | 5631 | } |
5689 | 5632 | ||
5633 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5634 | /* configure lun */ | ||
5635 | static int gdth_slave_configure(struct scsi_device *sdev) | ||
5636 | { | ||
5637 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); | ||
5638 | sdev->skip_ms_page_3f = 1; | ||
5639 | sdev->skip_ms_page_8 = 1; | ||
5640 | return 0; | ||
5641 | } | ||
5642 | #endif | ||
5643 | |||
5644 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5690 | static struct scsi_host_template driver_template = { | 5645 | static struct scsi_host_template driver_template = { |
5646 | #else | ||
5647 | static Scsi_Host_Template driver_template = { | ||
5648 | #endif | ||
5691 | .proc_name = "gdth", | 5649 | .proc_name = "gdth", |
5692 | .proc_info = gdth_proc_info, | 5650 | .proc_info = gdth_proc_info, |
5693 | .name = "GDT SCSI Disk Array Controller", | 5651 | .name = "GDT SCSI Disk Array Controller", |
@@ -5698,6 +5656,9 @@ static struct scsi_host_template driver_template = { | |||
5698 | .eh_bus_reset_handler = gdth_eh_bus_reset, | 5656 | .eh_bus_reset_handler = gdth_eh_bus_reset, |
5699 | .bios_param = gdth_bios_param, | 5657 | .bios_param = gdth_bios_param, |
5700 | .can_queue = GDTH_MAXCMDS, | 5658 | .can_queue = GDTH_MAXCMDS, |
5659 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5660 | .slave_configure = gdth_slave_configure, | ||
5661 | #endif | ||
5701 | .this_id = -1, | 5662 | .this_id = -1, |
5702 | .sg_tablesize = GDTH_MAXSG, | 5663 | .sg_tablesize = GDTH_MAXSG, |
5703 | .cmd_per_lun = GDTH_MAXC_P_L, | 5664 | .cmd_per_lun = GDTH_MAXC_P_L, |