diff options
Diffstat (limited to 'drivers/scsi/gdth.c')
| -rw-r--r-- | drivers/scsi/gdth.c | 517 |
1 files changed, 239 insertions, 278 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index d5740bbdef3e..76071a158306 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; |
| @@ -556,8 +569,8 @@ static struct timer_list gdth_timer; | |||
| 556 | #endif | 569 | #endif |
| 557 | 570 | ||
| 558 | #define PTR2USHORT(a) (ushort)(ulong)(a) | 571 | #define PTR2USHORT(a) (ushort)(ulong)(a) |
| 559 | #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) | 572 | #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) |
| 560 | #define INDEX_OK(i,t) ((i)<sizeof(t)/sizeof((t)[0])) | 573 | #define INDEX_OK(i,t) ((i)<ARRAY_SIZE(t)) |
| 561 | 574 | ||
| 562 | #define NUMDATA(a) ( (gdth_num_str *)((a)->hostdata)) | 575 | #define NUMDATA(a) ( (gdth_num_str *)((a)->hostdata)) |
| 563 | #define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext) | 576 | #define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext) |
| @@ -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->request) | ||
| 720 | complete((struct completion *)scp->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 request field to save the ptr. to completion struct. */ | ||
| 736 | scp->request = (struct 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; |
| @@ -2542,13 +2661,13 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, | |||
| 2542 | gdth_ha_str *ha; | 2661 | gdth_ha_str *ha; |
| 2543 | char *address; | 2662 | char *address; |
| 2544 | 2663 | ||
| 2545 | cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen; | 2664 | cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen; |
| 2546 | ha = HADATA(gdth_ctr_tab[hanum]); | 2665 | ha = HADATA(gdth_ctr_tab[hanum]); |
| 2547 | 2666 | ||
| 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, |
