diff --git a/[refs] b/[refs] index 74d5e16b9196..0bcf136d0818 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4f7a307dc6e4d8bfeb56f7cf7231b08cb845687c +refs/heads/master: af7cd373b01ccb8191dc16c77fff4cf2b11def50 diff --git a/trunk/Documentation/scsi/aacraid.txt b/trunk/Documentation/scsi/aacraid.txt index 2368e7e4a8cf..dc8e44fc650f 100644 --- a/trunk/Documentation/scsi/aacraid.txt +++ b/trunk/Documentation/scsi/aacraid.txt @@ -37,11 +37,7 @@ Supported Cards/Chipsets 9005:0286:9005:029d Adaptec 2420SA (Intruder HP release) 9005:0286:9005:02ac Adaptec 1800 (Typhoon44) 9005:0285:9005:02b5 Adaptec 5445 (Voodoo44) - 9005:0285:15d9:02b5 SMC AOC-USAS-S4i - 9005:0285:15d9:02c9 SMC AOC-USAS-S4iR 9005:0285:9005:02b6 Adaptec 5805 (Voodoo80) - 9005:0285:15d9:02b6 SMC AOC-USAS-S8i - 9005:0285:15d9:02ca SMC AOC-USAS-S8iR 9005:0285:9005:02b7 Adaptec 5085 (Voodoo08) 9005:0285:9005:02bb Adaptec 3405 (Marauder40LP) 9005:0285:9005:02bc Adaptec 3805 (Marauder80LP) @@ -97,9 +93,6 @@ Supported Cards/Chipsets 9005:0286:9005:02ae (Aurora Lite ARK) 9005:0285:9005:02b0 (Sunrise Lake ARK) 9005:0285:9005:02b1 Adaptec (Voodoo 8 internal 8 external) - 9005:0285:108e:7aac SUN STK RAID REM (Voodoo44 Coyote) - 9005:0285:108e:0286 SUN SG-XPCIESAS-R-IN (Cougar) - 9005:0285:108e:0287 SUN SG-XPCIESAS-R-EX (Prometheus) People ------------------------- diff --git a/trunk/Documentation/scsi/ncr53c8xx.txt b/trunk/Documentation/scsi/ncr53c8xx.txt index 88ef88b949f7..caf10b155185 100644 --- a/trunk/Documentation/scsi/ncr53c8xx.txt +++ b/trunk/Documentation/scsi/ncr53c8xx.txt @@ -562,6 +562,11 @@ if only one has a flaw for some SCSI feature, you can disable the support by the driver of this feature at linux start-up and enable this feature after boot-up only for devices that support it safely. +CONFIG_SCSI_NCR53C8XX_PROFILE_SUPPORT (default answer: n) + This option must be set for profiling information to be gathered + and printed out through the proc file system. This features may + impact performances. + CONFIG_SCSI_NCR53C8XX_IOMAPPED (default answer: n) Answer "y" if you suspect your mother board to not allow memory mapped I/O. May slow down performance a little. This option is required by diff --git a/trunk/arch/i386/kernel/i8253.c b/trunk/arch/i386/kernel/i8253.c index f8a3c4054c70..10cef5ca8a5b 100644 --- a/trunk/arch/i386/kernel/i8253.c +++ b/trunk/arch/i386/kernel/i8253.c @@ -110,7 +110,7 @@ void __init setup_pit_timer(void) * Start pit with the boot cpu mask and make it global after the * IO_APIC has been initialized. */ - pit_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); + pit_clockevent.cpumask = cpumask_of_cpu(0); pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 32); pit_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFF, &pit_clockevent); diff --git a/trunk/arch/i386/mach-voyager/setup.c b/trunk/arch/i386/mach-voyager/setup.c index 447bb105cf58..cfa16c151c8f 100644 --- a/trunk/arch/i386/mach-voyager/setup.c +++ b/trunk/arch/i386/mach-voyager/setup.c @@ -40,16 +40,10 @@ void __init trap_init_hook(void) { } -static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING, - .mask = CPU_MASK_NONE, - .name = "timer" -}; +static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init_hook(void) { - irq0.mask = cpumask_of_cpu(safe_smp_processor_id()); setup_irq(0, &irq0); } diff --git a/trunk/arch/i386/mach-voyager/voyager_cat.c b/trunk/arch/i386/mach-voyager/voyager_cat.c index 26a2d4c54b68..943a9473b138 100644 --- a/trunk/arch/i386/mach-voyager/voyager_cat.c +++ b/trunk/arch/i386/mach-voyager/voyager_cat.c @@ -1111,7 +1111,7 @@ voyager_cat_do_common_interrupt(void) printk(KERN_ERR "Voyager front panel switch turned off\n"); voyager_status.switch_off = 1; voyager_status.request_from_kernel = 1; - wake_up_process(voyager_thread); + up(&kvoyagerd_sem); } /* Tell the hardware we're taking care of the * shutdown, otherwise it will power the box off @@ -1157,7 +1157,7 @@ voyager_cat_do_common_interrupt(void) outb(VOYAGER_CAT_END, CAT_CMD); voyager_status.power_fail = 1; voyager_status.request_from_kernel = 1; - wake_up_process(voyager_thread); + up(&kvoyagerd_sem); } diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index fe0ed393294c..74aeedf277f4 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -536,6 +536,15 @@ do_boot_cpu(__u8 cpu) & ~( voyager_extended_vic_processors & voyager_allowed_boot_processors); + /* For the 486, we can't use the 4Mb page table trick, so + * must map a region of memory */ +#ifdef CONFIG_M486 + int i; + unsigned long *page_table_copies = (unsigned long *) + __get_free_page(GFP_KERNEL); +#endif + pgd_t orig_swapper_pg_dir0; + /* This is an area in head.S which was used to set up the * initial kernel stack. We need to alter this to give the * booting CPU a new stack (taken from its idle process) */ @@ -564,8 +573,6 @@ do_boot_cpu(__u8 cpu) hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF; cpucount++; - alternatives_smp_switch(1); - idle = fork_idle(cpu); if(IS_ERR(idle)) panic("failed fork for CPU%d", cpu); @@ -588,11 +595,24 @@ do_boot_cpu(__u8 cpu) VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, (unsigned long)hijack_source.val, hijack_source.idt.Segment, hijack_source.idt.Offset, stack_start.esp)); - - /* init lowmem identity mapping */ - clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, - min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); - flush_tlb_all(); + /* set the original swapper_pg_dir[0] to map 0 to 4Mb transparently + * (so that the booting CPU can find start_32 */ + orig_swapper_pg_dir0 = swapper_pg_dir[0]; +#ifdef CONFIG_M486 + if(page_table_copies == NULL) + panic("No free memory for 486 page tables\n"); + for(i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++) + page_table_copies[i] = (i * PAGE_SIZE) + | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; + + ((unsigned long *)swapper_pg_dir)[0] = + ((virt_to_phys(page_table_copies)) & PAGE_MASK) + | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; +#else + ((unsigned long *)swapper_pg_dir)[0] = + (virt_to_phys(pg0) & PAGE_MASK) + | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; +#endif if(quad_boot) { printk("CPU %d: non extended Quad boot\n", cpu); @@ -635,7 +655,11 @@ do_boot_cpu(__u8 cpu) udelay(100); } /* reset the page table */ - zap_low_mappings(); + swapper_pg_dir[0] = orig_swapper_pg_dir0; + local_flush_tlb(); +#ifdef CONFIG_M486 + free_page((unsigned long)page_table_copies); +#endif if (cpu_booted_map) { VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n", @@ -1058,11 +1082,20 @@ smp_call_function_interrupt(void) } } -static int -__smp_call_function_mask (void (*func) (void *info), void *info, int retry, - int wait, __u32 mask) +/* Call this function on all CPUs using the function_interrupt above + The function to run. This must be fast and non-blocking. + An arbitrary pointer to pass to the function. + If true, keep retrying until ready. + If true, wait until function has completed on other CPUs. + [RETURNS] 0 on success, else a negative status code. Does not return until + remote CPUs are nearly ready to execute <> or are or have executed. +*/ +int +smp_call_function (void (*func) (void *info), void *info, int retry, + int wait) { struct call_data_struct data; + __u32 mask = cpus_addr(cpu_online_map)[0]; mask &= ~(1< The function to run. This must be fast and non-blocking. - An arbitrary pointer to pass to the function. - If true, keep retrying until ready. - If true, wait until function has completed on other CPUs. - [RETURNS] 0 on success, else a negative status code. Does not return until - remote CPUs are nearly ready to execute <> or are or have executed. -*/ -int -smp_call_function(void (*func) (void *info), void *info, int retry, - int wait) -{ - __u32 mask = cpus_addr(cpu_online_map)[0]; - - return __smp_call_function_mask(func, info, retry, wait, mask); -} EXPORT_SYMBOL(smp_call_function); -/* - * smp_call_function_single - Run a function on another CPU - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @nonatomic: Currently unused. - * @wait: If true, wait until function has completed on other CPUs. - * - * Retrurns 0 on success, else a negative status code. - * - * Does not return until the remote CPU is nearly ready to execute - * or is or has executed. - */ - -int -smp_call_function_single(int cpu, void (*func) (void *info), void *info, - int nonatomic, int wait) -{ - __u32 mask = 1 << cpu; - - return __smp_call_function_mask(func, info, nonatomic, wait, mask); -} -EXPORT_SYMBOL(smp_call_function_single); - /* Sorry about the name. In an APIC based system, the APICs * themselves are programmed to send a timer interrupt. This is used * by linux to reschedule the processor. Voyager doesn't have this, diff --git a/trunk/arch/i386/mach-voyager/voyager_thread.c b/trunk/arch/i386/mach-voyager/voyager_thread.c index fdc1d926fb2a..f39887359e8e 100644 --- a/trunk/arch/i386/mach-voyager/voyager_thread.c +++ b/trunk/arch/i386/mach-voyager/voyager_thread.c @@ -24,16 +24,33 @@ #include #include #include -#include #include #include #include #include #include +#define THREAD_NAME "kvoyagerd" -struct task_struct *voyager_thread; -static __u8 set_timeout; +/* external variables */ +int kvoyagerd_running = 0; +DECLARE_MUTEX_LOCKED(kvoyagerd_sem); + +static int thread(void *); + +static __u8 set_timeout = 0; + +/* Start the machine monitor thread. Return 1 if OK, 0 if fail */ +static int __init +voyager_thread_start(void) +{ + if(kernel_thread(thread, NULL, CLONE_KERNEL) < 0) { + /* This is serious, but not fatal */ + printk(KERN_ERR "Voyager: Failed to create system monitor thread!!!\n"); + return 1; + } + return 0; +} static int execute(const char *string) @@ -93,15 +110,31 @@ check_continuing_condition(void) } } +static void +wakeup(unsigned long unused) +{ + up(&kvoyagerd_sem); +} + static int thread(void *unused) { - printk(KERN_NOTICE "Voyager starting monitor thread\n"); + struct timer_list wakeup_timer; + + kvoyagerd_running = 1; - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT); + daemonize(THREAD_NAME); + set_timeout = 0; + + init_timer(&wakeup_timer); + + sigfillset(¤t->blocked); + + printk(KERN_NOTICE "Voyager starting monitor thread\n"); + + for(;;) { + down_interruptible(&kvoyagerd_sem); VDEBUG(("Voyager Daemon awoken\n")); if(voyager_status.request_from_kernel == 0) { /* probably awoken from timeout */ @@ -110,26 +143,20 @@ thread(void *unused) check_from_kernel(); voyager_status.request_from_kernel = 0; } + if(set_timeout) { + del_timer(&wakeup_timer); + wakeup_timer.expires = HZ + jiffies; + wakeup_timer.function = wakeup; + add_timer(&wakeup_timer); + } } } -static int __init -voyager_thread_start(void) -{ - voyager_thread = kthread_run(thread, NULL, "kvoyagerd"); - if (IS_ERR(voyager_thread)) { - printk(KERN_ERR "Voyager: Failed to create system monitor thread.\n"); - return PTR_ERR(voyager_thread); - } - return 0; -} - - static void __exit voyager_thread_stop(void) { - kthread_stop(voyager_thread); + /* FIXME: do nothing at the moment */ } module_init(voyager_thread_start); -module_exit(voyager_thread_stop); +//module_exit(voyager_thread_stop); diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 5873861e1dbb..123003a90477 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -1925,8 +1925,6 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS); blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); - q->sg_reserved_size = INT_MAX; - /* * all done */ diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index e83f1dbf7c29..65c6a3cba6d6 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -78,9 +78,7 @@ static int sg_set_timeout(request_queue_t *q, int __user *p) static int sg_get_reserved_size(request_queue_t *q, int __user *p) { - unsigned val = min(q->sg_reserved_size, q->max_sectors << 9); - - return put_user(val, p); + return put_user(q->sg_reserved_size, p); } static int sg_set_reserved_size(request_queue_t *q, int __user *p) diff --git a/trunk/drivers/ide/cris/ide-cris.c b/trunk/drivers/ide/cris/ide-cris.c index 5e8efc89255a..556455fbfa2b 100644 --- a/trunk/drivers/ide/cris/ide-cris.c +++ b/trunk/drivers/ide/cris/ide-cris.c @@ -730,7 +730,7 @@ static int speed_cris_ide(ide_drive_t *drive, u8 speed) if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) { tune_cris_ide(drive, speed - XFER_PIO_0); - return ide_config_drive_speed(drive, speed); + return 0; } switch(speed) @@ -760,8 +760,7 @@ static int speed_cris_ide(ide_drive_t *drive, u8 speed) hold = ATA_DMA2_HOLD; break; default: - BUG(); - break; + return 0; } if (speed >= XFER_UDMA_0) @@ -769,7 +768,7 @@ static int speed_cris_ide(ide_drive_t *drive, u8 speed) else cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); - return ide_config_drive_speed(drive, speed); + return 0; } void __init @@ -822,6 +821,7 @@ init_e100_ide (void) hwif->udma_four = 0; hwif->ultra_mask = cris_ultra_mask; hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ + hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */ hwif->autodma = 1; hwif->drives[0].autodma = 1; hwif->drives[1].autodma = 1; @@ -1010,6 +1010,7 @@ static int cris_config_drive_for_dma (ide_drive_t *drive) return 0; speed_cris_ide(drive, speed); + ide_config_drive_speed(drive, speed); return ide_dma_enable(drive); } diff --git a/trunk/drivers/ide/legacy/ide-cs.c b/trunk/drivers/ide/legacy/ide-cs.c index c6522a64d7ec..b08c37c9f956 100644 --- a/trunk/drivers/ide/legacy/ide-cs.c +++ b/trunk/drivers/ide/legacy/ide-cs.c @@ -401,7 +401,6 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), - PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), diff --git a/trunk/drivers/ide/pci/aec62xx.c b/trunk/drivers/ide/pci/aec62xx.c index 73bdf64dbbfc..990eafe5ea11 100644 --- a/trunk/drivers/ide/pci/aec62xx.c +++ b/trunk/drivers/ide/pci/aec62xx.c @@ -1,8 +1,7 @@ /* - * linux/drivers/ide/pci/aec62xx.c Version 0.21 Apr 21, 2007 + * linux/drivers/ide/pci/aec62xx.c Version 0.11 March 27, 2002 * * Copyright (C) 1999-2002 Andre Hedrick - * Copyright (C) 2007 MontaVista Software, Inc. * */ @@ -194,8 +193,18 @@ static int config_chipset_for_dma (ide_drive_t *drive) static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void) aec62xx_tune_chipset(drive, pio + XFER_PIO_0); + u8 speed = 0; + u8 new_pio = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + + switch(pio) { + case 5: speed = new_pio; break; + case 4: speed = XFER_PIO_4; break; + case 3: speed = XFER_PIO_3; break; + case 2: speed = XFER_PIO_2; break; + case 1: speed = XFER_PIO_1; break; + default: speed = XFER_PIO_0; break; + } + (void) aec62xx_tune_chipset(drive, speed); } static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) @@ -204,7 +213,7 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - aec62xx_tune_drive(drive, 255); + aec62xx_tune_drive(drive, 5); return -1; } @@ -279,10 +288,11 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate; hwif->ide_dma_lostirq = &aec62xx_irq_timeout; - + hwif->ide_dma_timeout = &aec62xx_irq_timeout; if (!noautodma) hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; diff --git a/trunk/drivers/ide/pci/alim15x3.c b/trunk/drivers/ide/pci/alim15x3.c index 946a12746cb5..83e0aa65a431 100644 --- a/trunk/drivers/ide/pci/alim15x3.c +++ b/trunk/drivers/ide/pci/alim15x3.c @@ -534,7 +534,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive) struct hd_driveid *id = drive->id; if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) - goto ata_pio; + goto no_dma_set; drive->init_speed = 0; @@ -555,19 +555,20 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive) (id->dma_1word & hwif->swdma_mask)) { /* Force if Capable regular DMA modes */ if (!config_chipset_for_dma(drive)) - goto ata_pio; + goto no_dma_set; } } else if (__ide_dma_good_drive(drive) && (id->eide_dma_time < 150)) { /* Consult the list of known "good" drives */ if (!config_chipset_for_dma(drive)) - goto ata_pio; + goto no_dma_set; } else { goto ata_pio; } } else { ata_pio: hwif->tuneproc(drive, 255); +no_dma_set: return -1; } diff --git a/trunk/drivers/ide/pci/cmd64x.c b/trunk/drivers/ide/pci/cmd64x.c index 77f51ab6d439..561197f7b5bb 100644 --- a/trunk/drivers/ide/pci/cmd64x.c +++ b/trunk/drivers/ide/pci/cmd64x.c @@ -1,7 +1,10 @@ -/* - * linux/drivers/ide/pci/cmd64x.c Version 1.47 Mar 19, 2007 +/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 + * + * linux/drivers/ide/pci/cmd64x.c Version 1.42 Feb 8, 2007 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. + * Note, this driver is not used at all on other systems because + * there the "BIOS" has done all of the following already. * Due to massive hardware bugs, UltraDMA is only supported * on the 646U2 and not on the 646U. * @@ -36,12 +39,11 @@ * CMD64x specific registers definition. */ #define CFR 0x50 -#define CFR_INTR_CH0 0x04 +#define CFR_INTR_CH0 0x02 #define CNTRL 0x51 -#define CNTRL_ENA_1ST 0x04 -#define CNTRL_ENA_2ND 0x08 -#define CNTRL_DIS_RA0 0x40 -#define CNTRL_DIS_RA1 0x80 +#define CNTRL_DIS_RA0 0x40 +#define CNTRL_DIS_RA1 0x80 +#define CNTRL_ENA_2ND 0x08 #define CMDTIM 0x52 #define ARTTIM0 0x53 @@ -88,67 +90,86 @@ static int n_cmd_devs; static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index) { char *p = buf; + + u8 reg53 = 0, reg54 = 0, reg55 = 0, reg56 = 0; /* primary */ + u8 reg57 = 0, reg58 = 0, reg5b; /* secondary */ u8 reg72 = 0, reg73 = 0; /* primary */ u8 reg7a = 0, reg7b = 0; /* secondary */ - u8 reg50 = 1, reg51 = 1, reg57 = 0, reg71 = 0; /* extra */ - u8 rev = 0; + u8 reg50 = 0, reg71 = 0; /* extra */ p += sprintf(p, "\nController: %d\n", index); - p += sprintf(p, "PCI-%x Chipset.\n", dev->device); - + p += sprintf(p, "CMD%x Chipset.\n", dev->device); (void) pci_read_config_byte(dev, CFR, ®50); - (void) pci_read_config_byte(dev, CNTRL, ®51); - (void) pci_read_config_byte(dev, ARTTIM23, ®57); + (void) pci_read_config_byte(dev, ARTTIM0, ®53); + (void) pci_read_config_byte(dev, DRWTIM0, ®54); + (void) pci_read_config_byte(dev, ARTTIM1, ®55); + (void) pci_read_config_byte(dev, DRWTIM1, ®56); + (void) pci_read_config_byte(dev, ARTTIM2, ®57); + (void) pci_read_config_byte(dev, DRWTIM2, ®58); + (void) pci_read_config_byte(dev, DRWTIM3, ®5b); (void) pci_read_config_byte(dev, MRDMODE, ®71); (void) pci_read_config_byte(dev, BMIDESR0, ®72); (void) pci_read_config_byte(dev, UDIDETCR0, ®73); (void) pci_read_config_byte(dev, BMIDESR1, ®7a); (void) pci_read_config_byte(dev, UDIDETCR1, ®7b); - /* PCI0643/6 originally didn't have the primary channel enable bit */ - (void) pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - if ((dev->device == PCI_DEVICE_ID_CMD_643) || - (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 3)) - reg51 |= CNTRL_ENA_1ST; - - p += sprintf(p, "---------------- Primary Channel " - "---------------- Secondary Channel ------------\n"); - p += sprintf(p, " %s %s\n", - (reg51 & CNTRL_ENA_1ST) ? "enabled " : "disabled", - (reg51 & CNTRL_ENA_2ND) ? "enabled " : "disabled"); - p += sprintf(p, "---------------- drive0 --------- drive1 " - "-------- drive0 --------- drive1 ------\n"); - p += sprintf(p, "DMA enabled: %s %s" - " %s %s\n", - (reg72 & 0x20) ? "yes" : "no ", (reg72 & 0x40) ? "yes" : "no ", - (reg7a & 0x20) ? "yes" : "no ", (reg7a & 0x40) ? "yes" : "no "); - p += sprintf(p, "UltraDMA mode: %s (%c) %s (%c)", - ( reg73 & 0x01) ? " on" : "off", - ((reg73 & 0x30) == 0x30) ? ((reg73 & 0x04) ? '3' : '0') : - ((reg73 & 0x30) == 0x20) ? ((reg73 & 0x04) ? '3' : '1') : - ((reg73 & 0x30) == 0x10) ? ((reg73 & 0x04) ? '4' : '2') : - ((reg73 & 0x30) == 0x00) ? ((reg73 & 0x04) ? '5' : '2') : '?', - ( reg73 & 0x02) ? " on" : "off", - ((reg73 & 0xC0) == 0xC0) ? ((reg73 & 0x08) ? '3' : '0') : - ((reg73 & 0xC0) == 0x80) ? ((reg73 & 0x08) ? '3' : '1') : - ((reg73 & 0xC0) == 0x40) ? ((reg73 & 0x08) ? '4' : '2') : - ((reg73 & 0xC0) == 0x00) ? ((reg73 & 0x08) ? '5' : '2') : '?'); - p += sprintf(p, " %s (%c) %s (%c)\n", - ( reg7b & 0x01) ? " on" : "off", - ((reg7b & 0x30) == 0x30) ? ((reg7b & 0x04) ? '3' : '0') : - ((reg7b & 0x30) == 0x20) ? ((reg7b & 0x04) ? '3' : '1') : - ((reg7b & 0x30) == 0x10) ? ((reg7b & 0x04) ? '4' : '2') : - ((reg7b & 0x30) == 0x00) ? ((reg7b & 0x04) ? '5' : '2') : '?', - ( reg7b & 0x02) ? " on" : "off", - ((reg7b & 0xC0) == 0xC0) ? ((reg7b & 0x08) ? '3' : '0') : - ((reg7b & 0xC0) == 0x80) ? ((reg7b & 0x08) ? '3' : '1') : - ((reg7b & 0xC0) == 0x40) ? ((reg7b & 0x08) ? '4' : '2') : - ((reg7b & 0xC0) == 0x00) ? ((reg7b & 0x08) ? '5' : '2') : '?'); - p += sprintf(p, "Interrupt: %s, %s %s, %s\n", - (reg71 & MRDMODE_BLK_CH0 ) ? "blocked" : "enabled", - (reg50 & CFR_INTR_CH0 ) ? "pending" : "clear ", - (reg71 & MRDMODE_BLK_CH1 ) ? "blocked" : "enabled", - (reg57 & ARTTIM23_INTR_CH1) ? "pending" : "clear "); + p += sprintf(p, "--------------- Primary Channel " + "---------------- Secondary Channel " + "-------------\n"); + p += sprintf(p, " %sabled " + " %sabled\n", + (reg72&0x80)?"dis":" en", + (reg7a&0x80)?"dis":" en"); + p += sprintf(p, "--------------- drive0 " + "--------- drive1 -------- drive0 " + "---------- drive1 ------\n"); + p += sprintf(p, "DMA enabled: %s %s" + " %s %s\n", + (reg72&0x20)?"yes":"no ", (reg72&0x40)?"yes":"no ", + (reg7a&0x20)?"yes":"no ", (reg7a&0x40)?"yes":"no "); + + p += sprintf(p, "DMA Mode: %s(%s) %s(%s)", + (reg72&0x20)?((reg73&0x01)?"UDMA":" DMA"):" PIO", + (reg72&0x20)?( + ((reg73&0x30)==0x30)?(((reg73&0x35)==0x35)?"3":"0"): + ((reg73&0x20)==0x20)?(((reg73&0x25)==0x25)?"3":"1"): + ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"): + ((reg73&0x00)==0x00)?(((reg73&0x05)==0x05)?"5":"2"): + "X"):"?", + (reg72&0x40)?((reg73&0x02)?"UDMA":" DMA"):" PIO", + (reg72&0x40)?( + ((reg73&0xC0)==0xC0)?(((reg73&0xC5)==0xC5)?"3":"0"): + ((reg73&0x80)==0x80)?(((reg73&0x85)==0x85)?"3":"1"): + ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"): + ((reg73&0x00)==0x00)?(((reg73&0x0A)==0x0A)?"5":"2"): + "X"):"?"); + p += sprintf(p, " %s(%s) %s(%s)\n", + (reg7a&0x20)?((reg7b&0x01)?"UDMA":" DMA"):" PIO", + (reg7a&0x20)?( + ((reg7b&0x30)==0x30)?(((reg7b&0x35)==0x35)?"3":"0"): + ((reg7b&0x20)==0x20)?(((reg7b&0x25)==0x25)?"3":"1"): + ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"): + ((reg7b&0x00)==0x00)?(((reg7b&0x05)==0x05)?"5":"2"): + "X"):"?", + (reg7a&0x40)?((reg7b&0x02)?"UDMA":" DMA"):" PIO", + (reg7a&0x40)?( + ((reg7b&0xC0)==0xC0)?(((reg7b&0xC5)==0xC5)?"3":"0"): + ((reg7b&0x80)==0x80)?(((reg7b&0x85)==0x85)?"3":"1"): + ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"): + ((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"): + "X"):"?" ); + p += sprintf(p, "PIO Mode: %s %s" + " %s %s\n", + "?", "?", "?", "?"); + p += sprintf(p, " %s %s\n", + (reg50 & CFR_INTR_CH0) ? "interrupting" : "polling ", + (reg57 & ARTTIM23_INTR_CH1) ? "interrupting" : "polling"); + p += sprintf(p, " %s %s\n", + (reg71 & MRDMODE_INTR_CH0) ? "pending" : "clear ", + (reg71 & MRDMODE_INTR_CH1) ? "pending" : "clear"); + p += sprintf(p, " %s %s\n", + (reg71 & MRDMODE_BLK_CH0) ? "blocked" : "enabled", + (reg71 & MRDMODE_BLK_CH1) ? "blocked" : "enabled"); return (char *)p; } @@ -158,6 +179,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) char *p = buffer; int i; + p += sprintf(p, "\n"); for (i = 0; i < n_cmd_devs; i++) { struct pci_dev *dev = cmd_devs[i]; p = print_cmd64x_get_info(p, dev, i); @@ -173,103 +195,116 @@ static u8 quantize_timing(int timing, int quant) } /* - * This routine calculates active/recovery counts and then writes them into - * the chipset registers. + * This routine writes the prepared setup/active/recovery counts + * for a drive into the cmd646 chipset registers to active them. */ -static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time) +static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int clock_time = 1000 / system_bus_clock(); - u8 cycle_count, active_count, recovery_count, drwtim; - static const u8 recovery_values[] = + unsigned long flags; + struct pci_dev *dev = HWIF(drive)->pci_dev; + ide_drive_t *drives = HWIF(drive)->drives; + u8 temp_b; + static const u8 setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; + static const u8 recovery_counts[] = {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; - static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3}; - - cmdprintk("program_cycle_times parameters: total=%d, active=%d\n", - cycle_time, active_time); - - cycle_count = quantize_timing( cycle_time, clock_time); - active_count = quantize_timing(active_time, clock_time); - recovery_count = cycle_count - active_count; - + static const u8 arttim_regs[2][2] = { + { ARTTIM0, ARTTIM1 }, + { ARTTIM23, ARTTIM23 } + }; + static const u8 drwtim_regs[2][2] = { + { DRWTIM0, DRWTIM1 }, + { DRWTIM2, DRWTIM3 } + }; + int channel = (int) HWIF(drive)->channel; + int slave = (drives != drive); /* Is this really the best way to determine this?? */ + + cmdprintk("program_drive_count parameters = s(%d),a(%d),r(%d),p(%d)\n", + setup_count, active_count, recovery_count, drive->present); /* - * In case we've got too long recovery phase, try to lengthen - * the active phase + * Set up address setup count registers. + * Primary interface has individual count/timing registers for + * each drive. Secondary interface has one common set of registers, + * for address setup so we merge these timings, using the slowest + * value. */ - if (recovery_count > 16) { - active_count += recovery_count - 16; - recovery_count = 16; + if (channel) { + drive->drive_data = setup_count; + setup_count = max(drives[0].drive_data, + drives[1].drive_data); + cmdprintk("Secondary interface, setup_count = %d\n", + setup_count); } - if (active_count > 16) /* shouldn't actually happen... */ - active_count = 16; - - cmdprintk("Final counts: total=%d, active=%d, recovery=%d\n", - cycle_count, active_count, recovery_count); /* * Convert values to internal chipset representation */ - recovery_count = recovery_values[recovery_count]; - active_count &= 0x0f; + setup_count = (setup_count > 5) ? 0xc0 : (int) setup_counts[setup_count]; + active_count &= 0xf; /* Remember, max value is 16 */ + recovery_count = (int) recovery_counts[recovery_count]; - /* Program the active/recovery counts into the DRWTIM register */ - drwtim = (active_count << 4) | recovery_count; - (void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim); - cmdprintk("Write 0x%02x to reg 0x%x\n", drwtim, drwtim_regs[drive->dn]); + cmdprintk("Final values = %d,%d,%d\n", + setup_count, active_count, recovery_count); + + /* + * Now that everything is ready, program the new timings + */ + local_irq_save(flags); + /* + * Program the address_setup clocks into ARTTIM reg, + * and then the active/recovery counts into the DRWTIM reg + */ + (void) pci_read_config_byte(dev, arttim_regs[channel][slave], &temp_b); + (void) pci_write_config_byte(dev, arttim_regs[channel][slave], + ((u8) setup_count) | (temp_b & 0x3f)); + (void) pci_write_config_byte(dev, drwtim_regs[channel][slave], + (u8) ((active_count << 4) | recovery_count)); + cmdprintk ("Write %x to %x\n", + ((u8) setup_count) | (temp_b & 0x3f), + arttim_regs[channel][slave]); + cmdprintk ("Write %x to %x\n", + (u8) ((active_count << 4) | recovery_count), + drwtim_regs[channel][slave]); + local_irq_restore(flags); } /* - * This routine selects drive's best PIO mode and writes into the chipset - * registers setup/active/recovery timings. + * This routine selects drive's best PIO mode, calculates setup/active/recovery + * counts, and then writes them into the chipset registers. */ static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + int setup_time, active_time, cycle_time; + u8 cycle_count, setup_count, active_count, recovery_count; + u8 pio_mode; + int clock_time = 1000 / system_bus_clock(); ide_pio_data_t pio; - u8 pio_mode, setup_count, arttim = 0; - static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; - static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; - pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio); - - cmdprintk("%s: PIO mode wanted %d, selected %d (%d ns)%s\n", - drive->name, mode_wanted, pio_mode, pio.cycle_time, - pio.overridden ? " (overriding vendor mode)" : ""); - program_cycle_times(drive, pio.cycle_time, - ide_pio_timings[pio_mode].active_time); + pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio); + cycle_time = pio.cycle_time; - setup_count = quantize_timing(ide_pio_timings[pio_mode].setup_time, - 1000 / system_bus_clock()); + setup_time = ide_pio_timings[pio_mode].setup_time; + active_time = ide_pio_timings[pio_mode].active_time; - /* - * The primary channel has individual address setup timing registers - * for each drive and the hardware selects the slowest timing itself. - * The secondary channel has one common register and we have to select - * the slowest address setup timing ourselves. - */ - if (hwif->channel) { - ide_drive_t *drives = hwif->drives; + setup_count = quantize_timing( setup_time, clock_time); + cycle_count = quantize_timing( cycle_time, clock_time); + active_count = quantize_timing(active_time, clock_time); - drive->drive_data = setup_count; - setup_count = max(drives[0].drive_data, drives[1].drive_data); + recovery_count = cycle_count - active_count; + /* program_drive_counts() takes care of zero recovery cycles */ + if (recovery_count > 16) { + active_count += recovery_count - 16; + recovery_count = 16; } + if (active_count > 16) + active_count = 16; /* maximum allowed by cmd64x */ - if (setup_count > 5) /* shouldn't actually happen... */ - setup_count = 5; - cmdprintk("Final address setup count: %d\n", setup_count); + program_drive_counts (drive, setup_count, active_count, recovery_count); - /* - * Program the address setup clocks into the ARTTIM registers. - * Avoid clearing the secondary channel's interrupt bit. - */ - (void) pci_read_config_byte (dev, arttim_regs[drive->dn], &arttim); - if (hwif->channel) - arttim &= ~ARTTIM23_INTR_CH1; - arttim &= ~0xc0; - arttim |= setup_values[setup_count]; - (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); - cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]); + cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, " + "clocks=%d/%d/%d\n", + drive->name, mode_wanted, pio_mode, cycle_time, + pio.overridden ? " (overriding vendor mode)" : "", + setup_count, active_count, recovery_count); return pio_mode; } @@ -341,64 +376,61 @@ static u8 cmd64x_ratemask (ide_drive_t *drive) return mode; } -static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) +static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 unit = drive->dn & 0x01; - u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; - speed = ide_rate_filter(cmd64x_ratemask(drive), speed); + u8 unit = (drive->select.b.unit & 0x01); + u8 regU = 0, pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0; + u8 regD = 0, pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0; + + u8 speed = ide_rate_filter(cmd64x_ratemask(drive), xferspeed); if (speed >= XFER_SW_DMA_0) { + (void) pci_read_config_byte(dev, pciD, ®D); (void) pci_read_config_byte(dev, pciU, ®U); + regD &= ~(unit ? 0x40 : 0x20); regU &= ~(unit ? 0xCA : 0x35); + (void) pci_write_config_byte(dev, pciD, regD); + (void) pci_write_config_byte(dev, pciU, regU); + (void) pci_read_config_byte(dev, pciD, ®D); + (void) pci_read_config_byte(dev, pciU, ®U); } switch(speed) { - case XFER_UDMA_5: - regU |= unit ? 0x0A : 0x05; - break; - case XFER_UDMA_4: - regU |= unit ? 0x4A : 0x15; - break; - case XFER_UDMA_3: - regU |= unit ? 0x8A : 0x25; - break; - case XFER_UDMA_2: - regU |= unit ? 0x42 : 0x11; - break; - case XFER_UDMA_1: - regU |= unit ? 0x82 : 0x21; - break; - case XFER_UDMA_0: - regU |= unit ? 0xC2 : 0x31; - break; - case XFER_MW_DMA_2: - program_cycle_times(drive, 120, 70); - break; - case XFER_MW_DMA_1: - program_cycle_times(drive, 150, 80); - break; - case XFER_MW_DMA_0: - program_cycle_times(drive, 480, 215); - break; - case XFER_PIO_5: - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - (void) cmd64x_tune_pio(drive, speed - XFER_PIO_0); - break; - default: - return 1; + case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; + case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; + case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break; + case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break; + case XFER_UDMA_1: regU |= (unit ? 0x82 : 0x21); break; + case XFER_UDMA_0: regU |= (unit ? 0xC2 : 0x31); break; + case XFER_MW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; + case XFER_MW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; + case XFER_MW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; + case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; + case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; + case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; + case XFER_PIO_5: + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + (void) cmd64x_tune_pio(drive, speed - XFER_PIO_0); + break; + + default: + return 1; } - if (speed >= XFER_SW_DMA_0) + if (speed >= XFER_SW_DMA_0) { (void) pci_write_config_byte(dev, pciU, regU); + regD |= (unit ? 0x40 : 0x20); + (void) pci_write_config_byte(dev, pciD, regD); + } - return ide_config_drive_speed(drive, speed); + return (ide_config_drive_speed(drive, speed)); } static int config_chipset_for_dma (ide_drive_t *drive) @@ -425,80 +457,67 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) return -1; } -static int cmd648_ide_dma_end (ide_drive_t *drive) +static int cmd64x_alt_dma_status (struct pci_dev *dev) { - ide_hwif_t *hwif = HWIF(drive); - int err = __ide_dma_end(drive); - u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : - MRDMODE_INTR_CH0; - u8 mrdmode = inb(hwif->dma_master + 0x01); - - /* clear the interrupt bit */ - outb(mrdmode | irq_mask, hwif->dma_master + 0x01); - - return err; + switch(dev->device) { + case PCI_DEVICE_ID_CMD_648: + case PCI_DEVICE_ID_CMD_649: + return 1; + default: + break; + } + return 0; } static int cmd64x_ide_dma_end (ide_drive_t *drive) { + u8 dma_stat = 0, dma_cmd = 0; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - int irq_reg = hwif->channel ? ARTTIM23 : CFR; - u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : - CFR_INTR_CH0; - u8 irq_stat = 0; - int err = __ide_dma_end(drive); - - (void) pci_read_config_byte(dev, irq_reg, &irq_stat); - /* clear the interrupt bit */ - (void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask); - - return err; -} - -static int cmd648_ide_dma_test_irq (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : - MRDMODE_INTR_CH0; - u8 dma_stat = inb(hwif->dma_status); - u8 mrdmode = inb(hwif->dma_master + 0x01); - -#ifdef DEBUG - printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n", - drive->name, dma_stat, mrdmode, irq_mask); -#endif - if (!(mrdmode & irq_mask)) - return 0; - /* return 1 if INTR asserted */ - if (dma_stat & 4) - return 1; - - return 0; + drive->waiting_for_dma = 0; + /* read DMA command state */ + dma_cmd = inb(hwif->dma_command); + /* stop DMA */ + outb(dma_cmd & ~1, hwif->dma_command); + /* get DMA status */ + dma_stat = inb(hwif->dma_status); + /* clear the INTR & ERROR bits */ + outb(dma_stat | 6, hwif->dma_status); + if (cmd64x_alt_dma_status(dev)) { + u8 dma_intr = 0; + u8 dma_mask = (hwif->channel) ? ARTTIM23_INTR_CH1 : + CFR_INTR_CH0; + u8 dma_reg = (hwif->channel) ? ARTTIM2 : CFR; + (void) pci_read_config_byte(dev, dma_reg, &dma_intr); + /* clear the INTR bit */ + (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); + } + /* purge DMA mappings */ + ide_destroy_dmatable(drive); + /* verify good DMA status */ + return (dma_stat & 7) != 4; } static int cmd64x_ide_dma_test_irq (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - int irq_reg = hwif->channel ? ARTTIM23 : CFR; - u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : - CFR_INTR_CH0; - u8 dma_stat = inb(hwif->dma_status); - u8 irq_stat = 0; - - (void) pci_read_config_byte(dev, irq_reg, &irq_stat); + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u8 dma_alt_stat = 0, mask = (hwif->channel) ? MRDMODE_INTR_CH1 : + MRDMODE_INTR_CH0; + u8 dma_stat = inb(hwif->dma_status); + (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat); #ifdef DEBUG - printk("%s: dma_stat: 0x%02x irq_stat: 0x%02x irq_mask: 0x%02x\n", - drive->name, dma_stat, irq_stat, irq_mask); + printk("%s: dma_stat: 0x%02x dma_alt_stat: " + "0x%02x mask: 0x%02x\n", drive->name, + dma_stat, dma_alt_stat, mask); #endif - if (!(irq_stat & irq_mask)) + if (!(dma_alt_stat & mask)) return 0; /* return 1 if INTR asserted */ - if (dma_stat & 4) + if ((dma_stat & 4) == 4) return 1; return 0; @@ -646,6 +665,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; if (dev->device == PCI_DEVICE_ID_CMD_643) hwif->ultra_mask = 0x80; @@ -658,25 +678,17 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) if (!(hwif->udma_four)) hwif->udma_four = ata66_cmd64x(hwif); - switch(dev->device) { - case PCI_DEVICE_ID_CMD_648: - case PCI_DEVICE_ID_CMD_649: - alt_irq_bits: - hwif->ide_dma_end = &cmd648_ide_dma_end; - hwif->ide_dma_test_irq = &cmd648_ide_dma_test_irq; - break; - case PCI_DEVICE_ID_CMD_646: + if (dev->device == PCI_DEVICE_ID_CMD_646) { hwif->chipset = ide_cmd646; if (class_rev == 0x01) { hwif->ide_dma_end = &cmd646_1_ide_dma_end; - break; - } else if (class_rev >= 0x03) - goto alt_irq_bits; - /* fall thru */ - default: - hwif->ide_dma_end = &cmd64x_ide_dma_end; - hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; - break; + } else { + hwif->ide_dma_end = &cmd64x_ide_dma_end; + hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; + } + } else { + hwif->ide_dma_end = &cmd64x_ide_dma_end; + hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; } @@ -686,75 +698,42 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) hwif->drives[1].autodma = hwif->autodma; } -static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d) -{ - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_cmd646(struct pci_dev *dev, ide_pci_device_t *d) -{ - u8 rev = 0; - - /* - * The original PCI0646 didn't have the primary channel enable bit, - * it appeared starting with PCI0646U (i.e. revision ID 3). - */ - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - if (rev < 3) - d->enablebits[0].reg = 0; - - return ide_setup_pci_device(dev, d); -} - static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { { /* 0 */ .name = "CMD643", - .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, },{ /* 1 */ .name = "CMD646", - .init_setup = init_setup_cmd646, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, + .enablebits = {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, .bootable = ON_BOARD, },{ /* 2 */ .name = "CMD648", - .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, },{ /* 3 */ .name = "CMD649", - .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, } }; -/* - * We may have to modify enablebits for PCI0646, so we'd better pass - * a local copy of the ide_pci_device_t structure down the call chain... - */ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t d = cmd64x_chipsets[id->driver_data]; - - return d.init_setup(dev, &d); + return ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]); } static struct pci_device_id cmd64x_pci_tbl[] = { diff --git a/trunk/drivers/ide/pci/hpt366.c b/trunk/drivers/ide/pci/hpt366.c index cf9d344d19f8..ab6fa271aeb3 100644 --- a/trunk/drivers/ide/pci/hpt366.c +++ b/trunk/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.03 May 4, 2007 + * linux/drivers/ide/pci/hpt366.c Version 1.02 Apr 18, 2007 * * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -1527,12 +1527,7 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) if (rev > 2) goto init_single; - /* - * HPT36x chips are single channel and - * do not seem to have the channel enable bit... - */ d->channels = 1; - d->enablebits[0].reg = 0; if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { u8 pin1 = 0, pin2 = 0; diff --git a/trunk/drivers/ide/pci/it821x.c b/trunk/drivers/ide/pci/it821x.c index 4e1254813ee0..a132767f7d90 100644 --- a/trunk/drivers/ide/pci/it821x.c +++ b/trunk/drivers/ide/pci/it821x.c @@ -1,9 +1,8 @@ /* - * linux/drivers/ide/pci/it821x.c Version 0.10 Mar 10 2007 + * linux/drivers/ide/pci/it821x.c Version 0.09 December 2004 * * Copyright (C) 2004 Red Hat - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public License * Based in part on the ITE vendor provided SCSI driver. @@ -105,7 +104,6 @@ static int it8212_noraid; /** * it821x_program - program the PIO/MWDMA registers * @drive: drive to tune - * @timing: timing info * * Program the PIO/MWDMA timing for this channel according to the * current clock. @@ -129,7 +127,6 @@ static void it821x_program(ide_drive_t *drive, u16 timing) /** * it821x_program_udma - program the UDMA registers * @drive: drive to tune - * @timing: timing info * * Program the UDMA timing for this drive according to the * current clock. @@ -156,9 +153,10 @@ static void it821x_program_udma(ide_drive_t *drive, u16 timing) } } + /** * it821x_clock_strategy - * @drive: drive to set up + * @hwif: hardware interface * * Select between the 50 and 66Mhz base clocks to get the best * results for this interface. @@ -184,11 +182,8 @@ static void it821x_clock_strategy(ide_drive_t *drive) altclock = itdev->want[0][1]; } - /* - * if both clocks can be used for the mode with the higher priority - * use the clock needed by the mode with the lower priority - */ - if (clock == ATA_ANY) + /* Master doesn't care does the slave ? */ + if(clock == ATA_ANY) clock = altclock; /* Nobody cares - keep the same clock */ @@ -245,56 +240,37 @@ static u8 it821x_ratemask (ide_drive_t *drive) } /** - * it821x_tunepio - tune a drive + * it821x_tuneproc - tune a drive * @drive: drive to tune - * @pio: the desired PIO mode + * @mode_wanted: the target operating mode + * + * Load the timing settings for this device mode into the + * controller. By the time we are called the mode has been + * modified as neccessary to handle the absence of seperate + * master/slave timers for MWDMA/PIO. * - * Try to tune the drive/host to the desired PIO mode taking into - * the consideration the maximum PIO mode supported by the other - * device on the cable. + * This code is only used in pass through mode. */ -static int it821x_tunepio(ide_drive_t *drive, u8 set_pio) +static void it821x_tuneproc (ide_drive_t *drive, byte mode_wanted) { ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); int unit = drive->select.b.unit; - ide_drive_t *pair = &hwif->drives[1 - unit]; /* Spec says 89 ref driver uses 88 */ static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; - /* - * Compute the best PIO mode we can for a given device. We must - * pick a speed that does not cause problems with the other device - * on the cable. - */ - if (pair) { - u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4, NULL); - /* trim PIO to the slowest of the master/slave */ - if (pair_pio < set_pio) - set_pio = pair_pio; - } - - if (itdev->smart) - goto set_drive_speed; + if(itdev->smart) + return; /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */ - itdev->want[unit][1] = pio_want[set_pio]; + itdev->want[unit][1] = pio_want[mode_wanted]; itdev->want[unit][0] = 1; /* PIO is lowest priority */ - itdev->pio[unit] = pio[set_pio]; + itdev->pio[unit] = pio[mode_wanted]; it821x_clock_strategy(drive); it821x_program(drive, itdev->pio[unit]); - -set_drive_speed: - return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio); -} - -static void it821x_tuneproc(ide_drive_t *drive, u8 pio) -{ - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void)it821x_tunepio(drive, pio); } /** @@ -377,6 +353,40 @@ static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted) } +/** + * config_it821x_chipset_for_pio - set drive timings + * @drive: drive to tune + * @speed we want + * + * Compute the best pio mode we can for a given device. We must + * pick a speed that does not cause problems with the other device + * on the cable. + */ + +static void config_it821x_chipset_for_pio (ide_drive_t *drive, byte set_speed) +{ + u8 unit = drive->select.b.unit; + ide_hwif_t *hwif = drive->hwif; + ide_drive_t *pair = &hwif->drives[1-unit]; + u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 255, 5, NULL); + u8 pair_pio; + + /* We have to deal with this mess in pairs */ + if(pair != NULL) { + pair_pio = ide_get_best_pio_mode(pair, 255, 5, NULL); + /* Trim PIO to the slowest of the master/slave */ + if(pair_pio < set_pio) + set_pio = pair_pio; + } + it821x_tuneproc(drive, set_pio); + speed = XFER_PIO_0 + set_pio; + /* XXX - We trim to the lowest of the pair so the other drive + will always be fine at this point until we do hotplug passthru */ + + if (set_speed) + (void) ide_config_drive_speed(drive, speed); +} + /** * it821x_dma_read - DMA hook * @drive: drive for DMA @@ -440,17 +450,15 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) struct it821x_dev *itdev = ide_get_hwifdata(hwif); u8 speed = ide_rate_filter(it821x_ratemask(drive), xferspeed); - switch (speed) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - return it821x_tunepio(drive, speed - XFER_PIO_0); - } - - if (itdev->smart == 0) { - switch (speed) { + if(!itdev->smart) { + switch(speed) { + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + it821x_tuneproc(drive, (speed - XFER_PIO_0)); + break; /* MWDMA tuning is really hard because our MWDMA and PIO timings are kept in the same place. We can switch in the host dma on/off callbacks */ @@ -490,12 +498,14 @@ static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, it821x_ratemask(drive)); - if (speed == 0) - return 0; + if (speed) { + config_it821x_chipset_for_pio(drive, 0); + it821x_tune_chipset(drive, speed); - it821x_tune_chipset(drive, speed); + return ide_dma_enable(drive); + } - return ide_dma_enable(drive); + return 0; } /** @@ -513,7 +523,7 @@ static int it821x_config_drive_for_dma (ide_drive_t *drive) if (ide_use_dma(drive) && config_chipset_for_dma(drive)) return 0; - it821x_tuneproc(drive, 255); + config_it821x_chipset_for_pio(drive, 1); return -1; } diff --git a/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index 2da5cbb53566..ace98929cc3d 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -255,6 +255,9 @@ static int config_chipset_for_dma(ide_drive_t *drive) printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); } + if (drive->media != ide_disk && drive->media != ide_cdrom) + return 0; + if (id->capability & 4) { /* * Set IORDY_EN & PREFETCH_EN (this seems to have diff --git a/trunk/drivers/ide/pci/siimage.c b/trunk/drivers/ide/pci/siimage.c index c0188de3cc66..71eccdf5f817 100644 --- a/trunk/drivers/ide/pci/siimage.c +++ b/trunk/drivers/ide/pci/siimage.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/siimage.c Version 1.12 Mar 10 2007 + * linux/drivers/ide/pci/siimage.c Version 1.11 Jan 27, 2007 * * Copyright (C) 2001-2002 Andre Hedrick * Copyright (C) 2003 Red Hat @@ -287,6 +287,11 @@ static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed) (void) ide_config_drive_speed(drive, speed); } +static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed) +{ + config_siimage_chipset_for_pio(drive, set_speed); +} + /** * siimage_tune_chipset - set controller timings * @drive: Drive to set up @@ -391,6 +396,8 @@ static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, siimage_ratemask(drive)); + config_chipset_for_pio(drive, !speed); + if (!speed) return 0; @@ -416,7 +423,7 @@ static int siimage_config_drive_for_dma (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - config_siimage_chipset_for_pio(drive, 1); + config_chipset_for_pio(drive, 1); return -1; } @@ -1008,6 +1015,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; if (!is_sata(hwif)) hwif->atapi_dma = 1; diff --git a/trunk/drivers/ide/pci/sl82c105.c b/trunk/drivers/ide/pci/sl82c105.c index fe3b4b91f854..3a8a76fc78c7 100644 --- a/trunk/drivers/ide/pci/sl82c105.c +++ b/trunk/drivers/ide/pci/sl82c105.c @@ -11,8 +11,6 @@ * Merge in Russell's HW workarounds, fix various problems * with the timing registers setup. * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org - * - * Copyright (C) 2006-2007 MontaVista Software, Inc. */ #include @@ -49,19 +47,25 @@ #define CTRL_P0EN (1 << 0) /* - * Convert a PIO mode and cycle time to the required on/off times - * for the interface. This has protection against runaway timings. + * Convert a PIO mode and cycle time to the required on/off + * times for the interface. This has protection against run-away + * timings. */ -static unsigned int get_pio_timings(ide_pio_data_t *p) +static unsigned int get_timing_sl82c105(ide_pio_data_t *p) { - unsigned int cmd_on, cmd_off; + unsigned int cmd_on; + unsigned int cmd_off; - cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; + cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30; + if (cmd_on > 32) + cmd_on = 32; if (cmd_on == 0) cmd_on = 1; + if (cmd_off > 32) + cmd_off = 32; if (cmd_off == 0) cmd_off = 1; @@ -69,59 +73,100 @@ static unsigned int get_pio_timings(ide_pio_data_t *p) } /* - * Configure the chipset for PIO mode. + * Configure the drive and chipset for PIO */ -static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) +static void config_for_pio(ide_drive_t *drive, int pio, int report, int chipset_only) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int reg = 0x44 + drive->dn * 4; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; ide_pio_data_t p; - u16 drv_ctrl; + u16 drv_ctrl = 0x909; + unsigned int xfer_mode, reg; - DBG(("sl82c105_tune_pio(drive:%s, pio:%u)\n", drive->name, pio)); + DBG(("config_for_pio(drive:%s, pio:%d, report:%d, chipset_only:%d)\n", + drive->name, pio, report, chipset_only)); + + reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); pio = ide_get_best_pio_mode(drive, pio, 5, &p); - drive->drive_data = drv_ctrl = get_pio_timings(&p); + xfer_mode = XFER_PIO_0 + pio; + + if (chipset_only || ide_config_drive_speed(drive, xfer_mode) == 0) { + drv_ctrl = get_timing_sl82c105(&p); + drive->pio_speed = xfer_mode; + } else + drive->pio_speed = XFER_PIO_0; - if (!drive->using_dma) { + if (drive->using_dma == 0) { /* * If we are actually using MW DMA, then we can not * reprogram the interface drive control register. */ - pci_write_config_word(dev, reg, drv_ctrl); - pci_read_config_word (dev, reg, &drv_ctrl); - } + pci_write_config_word(dev, reg, drv_ctrl); + pci_read_config_word(dev, reg, &drv_ctrl); - printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, - ide_xfer_verbose(pio + XFER_PIO_0), p.cycle_time, drv_ctrl); - - return pio; + if (report) { + printk("%s: selected %s (%dns) (%04X)\n", drive->name, + ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl); + } + } } /* - * Configure the drive for DMA. - * We'll program the chipset only when DMA is actually turned on. + * Configure the drive and the chipset for DMA */ -static int config_for_dma(ide_drive_t *drive) +static int config_for_dma (ide_drive_t *drive) { + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + unsigned int reg; + DBG(("config_for_dma(drive:%s)\n", drive->name)); + reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); + if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) - return 0; + return 1; - return ide_dma_enable(drive); + pci_write_config_word(dev, reg, 0x0240); + + return 0; } /* - * Check to see if the drive and chipset are capable of DMA mode. + * Check to see if the drive and + * chipset is capable of DMA mode */ -static int sl82c105_ide_dma_check(ide_drive_t *drive) + +static int sl82c105_check_drive (ide_drive_t *drive) { - DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); + ide_hwif_t *hwif = HWIF(drive); + + DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); + + do { + struct hd_driveid *id = drive->id; + + if (!drive->autodma) + break; + + if (!id || !(id->capability & 1)) + break; - if (ide_use_dma(drive) && config_for_dma(drive)) - return 0; + /* Consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) + break; + + if (id->field_valid & 2) { + if ((id->dma_mword & hwif->mwdma_mask) || + (id->dma_1word & hwif->swdma_mask)) + return 0; + } + + if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) + return 0; + } while (0); return -1; } @@ -150,14 +195,14 @@ static inline void sl82c105_reset_host(struct pci_dev *dev) * This function is called when the IDE timer expires, the drive * indicates that it is READY, and we were waiting for DMA to complete. */ -static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) +static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; - u8 dma_cmd; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; + unsigned long dma_base = hwif->dma_base; - printk("sl82c105: lost IRQ, resetting host\n"); + printk("sl82c105: lost IRQ: resetting host\n"); /* * Check the raw interrupt from the drive. @@ -170,15 +215,15 @@ static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) * Was DMA enabled? If so, disable it - we're resetting the * host. The IDE layer will be handling the drive for us. */ - dma_cmd = inb(hwif->dma_command); - if (dma_cmd & 1) { - outb(dma_cmd & ~1, hwif->dma_command); + val = inb(dma_base); + if (val & 1) { + outb(val & ~1, dma_base); printk("sl82c105: DMA was enabled\n"); } sl82c105_reset_host(dev); - /* __ide_dma_lostirq would return 1, so we do as well */ + /* ide_dmaproc would return 1, so we do as well */ return 1; } @@ -190,10 +235,10 @@ static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) * The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_dma_start(ide_drive_t *drive) +static void sl82c105_ide_dma_start(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; sl82c105_reset_host(dev); ide_dma_start(drive); @@ -201,8 +246,8 @@ static void sl82c105_dma_start(ide_drive_t *drive) static int sl82c105_ide_dma_timeout(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); @@ -210,32 +255,26 @@ static int sl82c105_ide_dma_timeout(ide_drive_t *drive) return __ide_dma_timeout(drive); } -static int sl82c105_ide_dma_on(ide_drive_t *drive) +static int sl82c105_ide_dma_on (ide_drive_t *drive) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int rc, reg = 0x44 + drive->dn * 4; - DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - rc = __ide_dma_on(drive); - if (rc == 0) { - pci_write_config_word(dev, reg, 0x0200); - - printk(KERN_INFO "%s: DMA enabled\n", drive->name); - } - return rc; + if (config_for_dma(drive)) + return 1; + printk(KERN_INFO "%s: DMA enabled\n", drive->name); + return __ide_dma_on(drive); } static void sl82c105_dma_off_quietly(ide_drive_t *drive) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int reg = 0x44 + drive->dn * 4; + u8 speed = XFER_PIO_0; DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); - pci_write_config_word(dev, reg, drive->drive_data); - ide_dma_off_quietly(drive); + if (drive->pio_speed) + speed = drive->pio_speed - XFER_PIO_0; + config_for_pio(drive, speed, 0, 1); } /* @@ -247,8 +286,8 @@ static void sl82c105_dma_off_quietly(ide_drive_t *drive) */ static void sl82c105_selectproc(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; u32 val, old, mask; //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); @@ -284,12 +323,18 @@ static void sl82c105_resetproc(ide_drive_t *drive) * We only deal with PIO mode here - DMA mode 'using_dma' is not * initialised at the point that this function is called. */ -static void sl82c105_tune_drive(ide_drive_t *drive, u8 pio) +static void tune_sl82c105(ide_drive_t *drive, u8 pio) { - DBG(("sl82c105_tune_drive(drive:%s, pio:%u)\n", drive->name, pio)); + DBG(("tune_sl82c105(drive:%s)\n", drive->name)); + + config_for_pio(drive, pio, 1, 0); - pio = sl82c105_tune_pio(drive, pio); - (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); + /* + * We support 32-bit I/O on this interface, and it + * doesn't have problems with interrupts. + */ + drive->io_32bit = 1; + drive->unmask = 1; } /* @@ -348,7 +393,7 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c } /* - * Initialise IDE channel + * Initialise the chip */ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { @@ -356,22 +401,24 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); - hwif->tuneproc = &sl82c105_tune_drive; - hwif->selectproc = &sl82c105_selectproc; - hwif->resetproc = &sl82c105_resetproc; - - /* - * We support 32-bit I/O on this interface, and - * it doesn't have problems with interrupts. - */ - hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1; - hwif->drives[0].unmask = hwif->drives[1].unmask = 1; + hwif->tuneproc = tune_sl82c105; + hwif->selectproc = sl82c105_selectproc; + hwif->resetproc = sl82c105_resetproc; /* + * Default to PIO 0 for fallback unless tuned otherwise. * We always autotune PIO, this is done before DMA is checked, * so there's no risk of accidentally disabling DMA */ - hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + hwif->drives[0].pio_speed = XFER_PIO_0; + hwif->drives[0].autotune = 1; + hwif->drives[1].pio_speed = XFER_PIO_0; + hwif->drives[1].autotune = 1; + + hwif->atapi_dma = 0; + hwif->mwdma_mask = 0; + hwif->swdma_mask = 0; + hwif->autodma = 0; if (!hwif->dma_base) return; @@ -382,27 +429,27 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) * Never ever EVER under any circumstances enable * DMA when the bridge is this old. */ - printk(" %s: Winbond W83C553 bridge revision %d, " - "BM-DMA disabled\n", hwif->name, rev); - return; + printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", + hwif->name, rev); + } else { + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; + + hwif->ide_dma_check = &sl82c105_check_drive; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->dma_start = &sl82c105_ide_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; + + if (hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; } - - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; - - hwif->ide_dma_check = &sl82c105_ide_dma_check; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->dma_off_quietly = &sl82c105_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq; - hwif->dma_start = &sl82c105_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; - - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; } static ide_pci_device_t sl82c105_chipset __devinitdata = { diff --git a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c index 3651072f6c1f..278fcbccc2d9 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c @@ -201,7 +201,7 @@ static int iser_post_receive_control(struct iscsi_conn *conn) * what's common for both schemes is that the connection is not started */ if (conn->c_stage != ISCSI_CONN_STARTED) - rx_data_size = ISCSI_DEF_MAX_RECV_SEG_LEN; + rx_data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; else /* FIXME till user space sets conn->max_recv_dlength correctly */ rx_data_size = 128; diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index 97471af4309c..083acfd91d8b 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -1531,7 +1531,6 @@ mpt_resume(struct pci_dev *pdev) MPT_ADAPTER *ioc = pci_get_drvdata(pdev); u32 device_state = pdev->current_state; int recovery_state; - int err; printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", @@ -1539,9 +1538,7 @@ mpt_resume(struct pci_dev *pdev) pci_set_power_state(pdev, 0); pci_restore_state(pdev); - err = pci_enable_device(pdev); - if (err) - return err; + pci_enable_device(pdev); /* enable interrupts */ CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); @@ -4742,8 +4739,12 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) } /** - * mpt_inactive_raid_list_free - This clears this link list. - * @ioc : pointer to per adapter structure + * mpt_inactive_raid_list_free + * + * This clears this link list. + * + * @ioc - pointer to per adapter structure + * **/ static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) @@ -4763,11 +4764,15 @@ mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) } /** - * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume + * mpt_inactive_raid_volumes + * + * This sets up link list of phy_disk_nums for devices belonging in an inactive volume + * + * @ioc - pointer to per adapter structure + * @channel - volume channel + * @id - volume target id + * * - * @ioc : pointer to per adapter structure - * @channel : volume channel - * @id : volume target id **/ static void mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) @@ -6658,7 +6663,7 @@ union loginfo_type { /** * mpt_iocstatus_info_config - IOCSTATUS information for config pages * @ioc: Pointer to MPT_ADAPTER structure - * @ioc_status: U32 IOCStatus word from IOC + * ioc_status: U32 IOCStatus word from IOC * @mf: Pointer to MPT request frame * * Refer to lsi/mpi.h. diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h index d25d3be8fcd2..e3a39272aad6 100644 --- a/trunk/drivers/message/fusion/mptbase.h +++ b/trunk/drivers/message/fusion/mptbase.h @@ -994,7 +994,6 @@ typedef struct _MPT_SCSI_HOST { int scandv_wait_done; long last_queue_full; u16 tm_iocstatus; - u16 spi_pending; struct list_head target_reset_list; } MPT_SCSI_HOST; diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c index fa0f7761652a..2a3e9e66d4ef 100644 --- a/trunk/drivers/message/fusion/mptscsih.c +++ b/trunk/drivers/message/fusion/mptscsih.c @@ -819,7 +819,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) sc->resid=0; case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ - sc->result = (DID_OK << 16) | scsi_status; + if (scsi_status == MPI_SCSI_STATUS_BUSY) + sc->result = (DID_BUS_BUSY << 16) | scsi_status; + else + sc->result = (DID_OK << 16) | scsi_status; if (scsi_state == 0) { ; } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { @@ -1185,7 +1188,20 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state) int mptscsih_resume(struct pci_dev *pdev) { - return mpt_resume(pdev); + MPT_ADAPTER *ioc = pci_get_drvdata(pdev); + struct Scsi_Host *host = ioc->sh; + MPT_SCSI_HOST *hd; + + mpt_resume(pdev); + + if(!host) + return 0; + + hd = (MPT_SCSI_HOST *)host->hostdata; + if(!hd) + return 0; + + return 0; } #endif @@ -1521,23 +1537,21 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptscsih_TMHandler - Generic handler for SCSI Task Management. - * @hd: Pointer to MPT SCSI HOST structure + * Fall through to mpt_HardResetHandler if: not operational, too many + * failed TM requests or handshake failure. + * + * @ioc: Pointer to MPT_ADAPTER structure * @type: Task Management type - * @channel: channel number for task management * @id: Logical Target ID for reset (if appropriate) * @lun: Logical Unit for reset (if appropriate) * @ctx2abort: Context for the task to be aborted (if appropriate) - * @timeout: timeout for task management control - * - * Fall through to mpt_HardResetHandler if: not operational, too many - * failed TM requests or handshake failure. * * Remark: Currently invoked from a non-interrupt thread (_bh). * * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC * will be active. * - * Returns 0 for SUCCESS, or %FAILED. + * Returns 0 for SUCCESS, or FAILED. **/ int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) @@ -1636,11 +1650,9 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c * mptscsih_IssueTaskMgmt - Generic send Task Management function. * @hd: Pointer to MPT_SCSI_HOST structure * @type: Task Management type - * @channel: channel number for task management * @id: Logical Target ID for reset (if appropriate) * @lun: Logical Unit for reset (if appropriate) * @ctx2abort: Context for the task to be aborted (if appropriate) - * @timeout: timeout for task management control * * Remark: _HardResetHandler can be invoked from an interrupt thread (timer) * or a non-interrupt thread. In the former, must not call schedule(). @@ -2010,7 +2022,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) /** * mptscsih_tm_wait_for_completion - wait for completion of TM task * @hd: Pointer to MPT host structure. - * @timeout: timeout value * * Returns {SUCCESS,FAILED}. */ diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c index d75f7ffbb02e..85f21b54cb7d 100644 --- a/trunk/drivers/message/fusion/mptspi.c +++ b/trunk/drivers/message/fusion/mptspi.c @@ -96,13 +96,14 @@ static int mptspiTaskCtx = -1; static int mptspiInternalCtx = -1; /* Used only for internal commands */ /** - * mptspi_setTargetNegoParms - Update the target negotiation parameters + * mptspi_setTargetNegoParms - Update the target negotiation + * parameters based on the the Inquiry data, adapter capabilities, + * and NVRAM settings + * * @hd: Pointer to a SCSI Host Structure - * @target: per target private data + * @vtarget: per target private data * @sdev: SCSI device * - * Update the target negotiation parameters based on the the Inquiry - * data, adapter capabilities, and NVRAM settings. **/ static void mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, @@ -233,7 +234,7 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, /** * mptspi_writeIOCPage4 - write IOC Page 4 * @hd: Pointer to a SCSI Host Structure - * @channel: channel number + * @channel: * @id: write IOC Page4 for this ID & Bus * * Return: -EAGAIN if unable to obtain a Message Frame @@ -445,7 +446,7 @@ static int mptspi_target_alloc(struct scsi_target *starget) return 0; } -static void +void mptspi_target_destroy(struct scsi_target *starget) { if (starget->hostdata) @@ -676,9 +677,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, return; } - hd->spi_pending |= (1 << sdev->id); spi_dv_device(sdev); - hd->spi_pending &= ~(1 << sdev->id); if (sdev->channel == 1 && mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0) @@ -1204,27 +1203,11 @@ mptspi_dv_renegotiate_work(struct work_struct *work) container_of(work, struct work_queue_wrapper, work); struct _MPT_SCSI_HOST *hd = wqw->hd; struct scsi_device *sdev; - struct scsi_target *starget; - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - u32 nego; kfree(wqw); - if (hd->spi_pending) { - shost_for_each_device(sdev, hd->ioc->sh) { - if (hd->spi_pending & (1 << sdev->id)) - continue; - starget = scsi_target(sdev); - nego = mptspi_getRP(starget); - pg1.RequestedParameters = cpu_to_le32(nego); - pg1.Reserved = 0; - pg1.Configuration = 0; - mptspi_write_spi_device_pg1(starget, &pg1); - } - } else { - shost_for_each_device(sdev, hd->ioc->sh) - mptspi_dv_device(hd, sdev); - } + shost_for_each_device(sdev, hd->ioc->sh) + mptspi_dv_device(hd, sdev); } static void @@ -1470,7 +1453,6 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) init_waitqueue_head(&hd->scandv_waitq); hd->scandv_wait_done = 0; hd->last_queue_full = 0; - hd->spi_pending = 0; /* Some versions of the firmware don't support page 0; without * that we can't get the parameters */ diff --git a/trunk/drivers/s390/scsi/zfcp_erp.c b/trunk/drivers/s390/scsi/zfcp_erp.c index c1f2d4b14c2b..421da1e7c0ea 100644 --- a/trunk/drivers/s390/scsi/zfcp_erp.c +++ b/trunk/drivers/s390/scsi/zfcp_erp.c @@ -186,7 +186,7 @@ void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) { fsf_req->timer.function = zfcp_fsf_request_timeout_handler; fsf_req->timer.data = (unsigned long) fsf_req->adapter; - fsf_req->timer.expires = jiffies + timeout; + fsf_req->timer.expires = timeout; add_timer(&fsf_req->timer); } diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c index 4c0a59afd5c8..ef16f7ca4bb1 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.c +++ b/trunk/drivers/s390/scsi/zfcp_fsf.c @@ -299,10 +299,9 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) } /* log additional information provided by FSF (if any) */ - if (likely(qtcb->header.log_length)) { + if (unlikely(qtcb->header.log_length)) { /* do not trust them ;-) */ - if (unlikely(qtcb->header.log_start > - sizeof(struct fsf_qtcb))) { + if (qtcb->header.log_start > sizeof(struct fsf_qtcb)) { ZFCP_LOG_NORMAL ("bug: ULP (FSF logging) log data starts " "beyond end of packet header. Ignored. " @@ -311,9 +310,8 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) sizeof(struct fsf_qtcb)); goto forget_log; } - if (unlikely((size_t) (qtcb->header.log_start + - qtcb->header.log_length) > - sizeof(struct fsf_qtcb))) { + if ((size_t) (qtcb->header.log_start + qtcb->header.log_length) + > sizeof(struct fsf_qtcb)) { ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends " "beyond end of packet header. Ignored. " "(start=%i, length=%i, size=%li)\n", diff --git a/trunk/drivers/scsi/BusLogic.c b/trunk/drivers/scsi/BusLogic.c index 96f4cab07614..e874b8944875 100644 --- a/trunk/drivers/scsi/BusLogic.c +++ b/trunk/drivers/scsi/BusLogic.c @@ -579,17 +579,17 @@ static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapt /* Append the list of standard BusLogic MultiMaster ISA I/O Addresses. */ - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe330) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x330); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe334) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x334); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe230) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x230); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe234) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x234); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe130) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x130); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe134) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x134); } @@ -795,9 +795,7 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd host adapters are probed. */ if (!BusLogic_ProbeOptions.NoProbeISA) - if (PrimaryProbeInfo->IO_Address == 0 && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe330)) { + if (PrimaryProbeInfo->IO_Address == 0 && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)) { PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; PrimaryProbeInfo->IO_Address = 0x330; @@ -807,25 +805,15 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd omitting the Primary I/O Address which has already been handled. */ if (!BusLogic_ProbeOptions.NoProbeISA) { - if (!StandardAddressSeen[1] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe334)) + if (!StandardAddressSeen[1] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x334); - if (!StandardAddressSeen[2] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe230)) + if (!StandardAddressSeen[2] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x230); - if (!StandardAddressSeen[3] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe234)) + if (!StandardAddressSeen[3] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x234); - if (!StandardAddressSeen[4] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe130)) + if (!StandardAddressSeen[4] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x130); - if (!StandardAddressSeen[5] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe134)) + if (!StandardAddressSeen[5] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x134); } /* @@ -2232,35 +2220,22 @@ static int __init BusLogic_init(void) HostAdapter->PCI_Device = ProbeInfo->PCI_Device; HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel; HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType]; - - /* - Make sure region is free prior to probing. - */ - if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, - "BusLogic")) - continue; /* Probe the Host Adapter. If unsuccessful, abort further initialization. */ - if (!BusLogic_ProbeHostAdapter(HostAdapter)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue; - } /* Hard Reset the Host Adapter. If unsuccessful, abort further initialization. */ - if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue; - } /* Check the Host Adapter. If unsuccessful, abort further initialization. */ - if (!BusLogic_CheckHostAdapter(HostAdapter)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!BusLogic_CheckHostAdapter(HostAdapter)) continue; - } /* Initialize the Driver Options field if provided. */ @@ -2271,6 +2246,16 @@ static int __init BusLogic_init(void) and Electronic Mail Address. */ BusLogic_AnnounceDriver(HostAdapter); + /* + Register usage of the I/O Address range. From this point onward, any + failure will be assumed to be due to a problem with the Host Adapter, + rather than due to having mistakenly identified this port as belonging + to a BusLogic Host Adapter. The I/O Address range will not be + released, thereby preventing it from being incorrectly identified as + any other type of Host Adapter. + */ + if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, "BusLogic")) + continue; /* Register the SCSI Host structure. */ @@ -2295,12 +2280,6 @@ static int __init BusLogic_init(void) Acquire the System Resources necessary to use the Host Adapter, then Create the Initial CCBs, Initialize the Host Adapter, and finally perform Target Device Inquiry. - - From this point onward, any failure will be assumed to be due to a - problem with the Host Adapter, rather than due to having mistakenly - identified this port as belonging to a BusLogic Host Adapter. The - I/O Address range will not be released, thereby preventing it from - being incorrectly identified as any other type of Host Adapter. */ if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) && BusLogic_ReportHostAdapterConfiguration(HostAdapter) && @@ -3619,7 +3598,6 @@ static void __exit BusLogic_exit(void) __setup("BusLogic=", BusLogic_Setup); -#ifdef MODULE static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -3629,7 +3607,6 @@ static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { } }; -#endif MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl); module_init(BusLogic_init); diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 58c811d20eb2..e1ebed0f0755 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -241,12 +241,6 @@ config SCSI_SCAN_ASYNC You can override this choice by specifying "scsi_mod.scan=sync" or async on the kernel's command line. -config SCSI_WAIT_SCAN - tristate - default m - depends on SCSI - depends on MODULES - menu "SCSI Transports" depends on SCSI @@ -1200,6 +1194,17 @@ config SCSI_NCR53C8XX_SYNC There is no safe option other than using good cabling, right terminations and SCSI conformant devices. +config SCSI_NCR53C8XX_PROFILE + bool "enable profiling" + depends on SCSI_ZALON || SCSI_NCR_Q720 + help + This option allows you to enable profiling information gathering. + These statistics are not very accurate due to the low frequency + of the kernel clock (100 Hz on i386) and have performance impact + on systems that use very fast devices. + + The normal answer therefore is N. + config SCSI_NCR53C8XX_NO_DISCONNECT bool "not allow targets to disconnect" depends on (SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0 @@ -1329,6 +1334,11 @@ config SCSI_SIM710 It currently supports Compaq EISA cards and NCR MCA cards +config 53C700_IO_MAPPED + bool + depends on SCSI_SIM710 + default y + config SCSI_SYM53C416 tristate "Symbios 53c416 SCSI support" depends on ISA && SCSI diff --git a/trunk/drivers/scsi/Makefile b/trunk/drivers/scsi/Makefile index 51e884fa10b0..70cff4c599d7 100644 --- a/trunk/drivers/scsi/Makefile +++ b/trunk/drivers/scsi/Makefile @@ -146,7 +146,7 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o # This goes last, so that "real" scsi devices probe earlier obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o -obj-$(CONFIG_SCSI_WAIT_SCAN) += scsi_wait_scan.o +obj-$(CONFIG_SCSI) += scsi_wait_scan.o scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ scsicam.o scsi_error.o scsi_lib.o \ diff --git a/trunk/drivers/scsi/aacraid/aachba.c b/trunk/drivers/scsi/aacraid/aachba.c index 1e82c69b36b0..d789e61bdc49 100644 --- a/trunk/drivers/scsi/aacraid/aachba.c +++ b/trunk/drivers/scsi/aacraid/aachba.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -172,30 +172,6 @@ MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. int expose_physicals = -1; module_param(expose_physicals, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on"); - - -static inline int aac_valid_context(struct scsi_cmnd *scsicmd, - struct fib *fibptr) { - struct scsi_device *device; - - if (unlikely(!scsicmd || !scsicmd->scsi_done )) { - dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n")) -; - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - return 0; - } - scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; - device = scsicmd->device; - if (unlikely(!device || !scsi_device_online(device))) { - dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n")); - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - return 0; - } - return 1; -} - /** * aac_get_config_status - check the adapter configuration * @common: adapter to query @@ -282,10 +258,13 @@ int aac_get_containers(struct aac_dev *dev) u32 index; int status = 0; struct fib * fibptr; + unsigned instance; struct aac_get_container_count *dinfo; struct aac_get_container_count_resp *dresp; int maximum_num_containers = MAXIMUM_NUM_CONTAINERS; + instance = dev->scsi_host_ptr->unique_id; + if (!(fibptr = aac_fib_alloc(dev))) return -ENOMEM; @@ -305,35 +284,88 @@ int aac_get_containers(struct aac_dev *dev) maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); aac_fib_complete(fibptr); } - aac_fib_free(fibptr); if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) maximum_num_containers = MAXIMUM_NUM_CONTAINERS; - fsa_dev_ptr = kmalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers, - GFP_KERNEL); - if (!fsa_dev_ptr) + fsa_dev_ptr = kmalloc( + sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL); + if (!fsa_dev_ptr) { + aac_fib_free(fibptr); return -ENOMEM; + } memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); dev->fsa_dev = fsa_dev_ptr; dev->maximum_num_containers = maximum_num_containers; - for (index = 0; index < dev->maximum_num_containers; ) { + for (index = 0; index < dev->maximum_num_containers; index++) { + struct aac_query_mount *dinfo; + struct aac_mount *dresp; + fsa_dev_ptr[index].devname[0] = '\0'; - status = aac_probe_container(dev, index); + aac_fib_init(fibptr); + dinfo = (struct aac_query_mount *) fib_data(fibptr); + + dinfo->command = cpu_to_le32(VM_NameServe); + dinfo->count = cpu_to_le32(index); + dinfo->type = cpu_to_le32(FT_FILESYS); - if (status < 0) { + status = aac_fib_send(ContainerCommand, + fibptr, + sizeof (struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL); + if (status < 0 ) { printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n"); break; } + dresp = (struct aac_mount *)fib_data(fibptr); + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { + dinfo->command = cpu_to_le32(VM_NameServe64); + dinfo->count = cpu_to_le32(index); + dinfo->type = cpu_to_le32(FT_FILESYS); + + if (aac_fib_send(ContainerCommand, + fibptr, + sizeof(struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL) < 0) + continue; + } else + dresp->mnt[0].capacityhigh = 0; + + dprintk ((KERN_DEBUG + "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%llu\n", + (int)index, (int)le32_to_cpu(dresp->status), + (int)le32_to_cpu(dresp->mnt[0].vol), + (int)le32_to_cpu(dresp->mnt[0].state), + ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32))); + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && + (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { + fsa_dev_ptr[index].valid = 1; + fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol); + fsa_dev_ptr[index].size + = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); + if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) + fsa_dev_ptr[index].ro = 1; + } + aac_fib_complete(fibptr); /* * If there are no more containers, then stop asking. */ - if (++index >= status) + if ((index + 1) >= le32_to_cpu(dresp->count)){ break; + } } + aac_fib_free(fibptr); return status; } @@ -350,9 +382,8 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne buf = scsicmd->request_buffer; transfer_len = min(scsicmd->request_bufflen, len + offset); } - transfer_len -= offset; - if (buf && transfer_len) - memcpy(buf + offset, data, transfer_len); + + memcpy(buf + offset, data, transfer_len - offset); if (scsicmd->use_sg) kunmap_atomic(buf - sg->offset, KM_IRQ0); @@ -365,9 +396,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr) struct scsi_cmnd * scsicmd; scsicmd = (struct scsi_cmnd *) context; - - if (!aac_valid_context(scsicmd, fibptr)) - return; + scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); BUG_ON(fibptr == NULL); @@ -402,7 +431,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr) /** * aac_get_container_name - get container name, none blocking. */ -static int aac_get_container_name(struct scsi_cmnd * scsicmd) +static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) { int status; struct aac_get_name *dinfo; @@ -419,7 +448,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) dinfo->command = cpu_to_le32(VM_ContainerConfig); dinfo->type = cpu_to_le32(CT_READ_NAME); - dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); + dinfo->cid = cpu_to_le32(cid); dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); status = aac_fib_send(ContainerCommand, @@ -444,192 +473,85 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) return -1; } -static int aac_probe_container_callback2(struct scsi_cmnd * scsicmd) -{ - struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; - - if (fsa_dev_ptr[scmd_id(scsicmd)].valid) - return aac_scsi_cmd(scsicmd); - - scsicmd->result = DID_NO_CONNECT << 16; - scsicmd->scsi_done(scsicmd); - return 0; -} - -static int _aac_probe_container2(void * context, struct fib * fibptr) +/** + * aac_probe_container - query a logical volume + * @dev: device to query + * @cid: container identifier + * + * Queries the controller about the given volume. The volume information + * is updated in the struct fsa_dev_info structure rather than returned. + */ + +int aac_probe_container(struct aac_dev *dev, int cid) { struct fsa_dev_info *fsa_dev_ptr; - int (*callback)(struct scsi_cmnd *); - struct scsi_cmnd * scsicmd = (struct scsi_cmnd *)context; - - if (!aac_valid_context(scsicmd, fibptr)) - return 0; - - fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; - - scsicmd->SCp.Status = 0; - if (fsa_dev_ptr) { - struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr); - fsa_dev_ptr += scmd_id(scsicmd); - - if ((le32_to_cpu(dresp->status) == ST_OK) && - (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && - (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { - fsa_dev_ptr->valid = 1; - fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol); - fsa_dev_ptr->size - = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + - (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); - fsa_dev_ptr->ro = ((le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) != 0); - } - if ((fsa_dev_ptr->valid & 1) == 0) - fsa_dev_ptr->valid = 0; - scsicmd->SCp.Status = le32_to_cpu(dresp->count); - } - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - callback = (int (*)(struct scsi_cmnd *))(scsicmd->SCp.ptr); - scsicmd->SCp.ptr = NULL; - return (*callback)(scsicmd); -} - -static int _aac_probe_container1(void * context, struct fib * fibptr) -{ - struct scsi_cmnd * scsicmd; - struct aac_mount * dresp; - struct aac_query_mount *dinfo; int status; + struct aac_query_mount *dinfo; + struct aac_mount *dresp; + struct fib * fibptr; + unsigned instance; - dresp = (struct aac_mount *) fib_data(fibptr); - dresp->mnt[0].capacityhigh = 0; - if ((le32_to_cpu(dresp->status) != ST_OK) || - (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) - return _aac_probe_container2(context, fibptr); - scsicmd = (struct scsi_cmnd *) context; - scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; + fsa_dev_ptr = dev->fsa_dev; + if (!fsa_dev_ptr) + return -ENOMEM; + instance = dev->scsi_host_ptr->unique_id; - if (!aac_valid_context(scsicmd, fibptr)) - return 0; + if (!(fibptr = aac_fib_alloc(dev))) + return -ENOMEM; aac_fib_init(fibptr); dinfo = (struct aac_query_mount *)fib_data(fibptr); - dinfo->command = cpu_to_le32(VM_NameServe64); - dinfo->count = cpu_to_le32(scmd_id(scsicmd)); + dinfo->command = cpu_to_le32(VM_NameServe); + dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); status = aac_fib_send(ContainerCommand, - fibptr, - sizeof(struct aac_query_mount), - FsaNormal, - 0, 1, - (fib_callback) _aac_probe_container2, - (void *) scsicmd); - /* - * Check that the command queued to the controller - */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; - return 0; - } + fibptr, + sizeof(struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL); if (status < 0) { - /* Inherit results from VM_NameServe, if any */ - dresp->status = cpu_to_le32(ST_OK); - return _aac_probe_container2(context, fibptr); + printk(KERN_WARNING "aacraid: aac_probe_container query failed.\n"); + goto error; } - return 0; -} - -static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(struct scsi_cmnd *)) -{ - struct fib * fibptr; - int status = -ENOMEM; - - if ((fibptr = aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) { - struct aac_query_mount *dinfo; - - aac_fib_init(fibptr); - dinfo = (struct aac_query_mount *)fib_data(fibptr); + dresp = (struct aac_mount *) fib_data(fibptr); - dinfo->command = cpu_to_le32(VM_NameServe); - dinfo->count = cpu_to_le32(scmd_id(scsicmd)); + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { + dinfo->command = cpu_to_le32(VM_NameServe64); + dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); - scsicmd->SCp.ptr = (char *)callback; - status = aac_fib_send(ContainerCommand, - fibptr, - sizeof(struct aac_query_mount), - FsaNormal, - 0, 1, - (fib_callback) _aac_probe_container1, - (void *) scsicmd); - /* - * Check that the command queued to the controller - */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; - return 0; - } - if (status < 0) { - scsicmd->SCp.ptr = NULL; - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - } - } - if (status < 0) { - struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; - if (fsa_dev_ptr) { - fsa_dev_ptr += scmd_id(scsicmd); - if ((fsa_dev_ptr->valid & 1) == 0) { - fsa_dev_ptr->valid = 0; - return (*callback)(scsicmd); - } - } - } - return status; -} + if (aac_fib_send(ContainerCommand, + fibptr, + sizeof(struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL) < 0) + goto error; + } else + dresp->mnt[0].capacityhigh = 0; -/** - * aac_probe_container - query a logical volume - * @dev: device to query - * @cid: container identifier - * - * Queries the controller about the given volume. The volume information - * is updated in the struct fsa_dev_info structure rather than returned. - */ -static int aac_probe_container_callback1(struct scsi_cmnd * scsicmd) -{ - scsicmd->device = NULL; - return 0; -} + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && + (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { + fsa_dev_ptr[cid].valid = 1; + fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol); + fsa_dev_ptr[cid].size + = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); + if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) + fsa_dev_ptr[cid].ro = 1; + } -int aac_probe_container(struct aac_dev *dev, int cid) -{ - struct scsi_cmnd *scsicmd = kmalloc(sizeof(*scsicmd), GFP_KERNEL); - struct scsi_device *scsidev = kmalloc(sizeof(*scsidev), GFP_KERNEL); - int status; +error: + aac_fib_complete(fibptr); + aac_fib_free(fibptr); - if (!scsicmd || !scsidev) { - kfree(scsicmd); - kfree(scsidev); - return -ENOMEM; - } - scsicmd->list.next = NULL; - scsicmd->scsi_done = (void (*)(struct scsi_cmnd*))_aac_probe_container1; - - scsicmd->device = scsidev; - scsidev->sdev_state = 0; - scsidev->id = cid; - scsidev->host = dev->scsi_host_ptr; - - if (_aac_probe_container(scsicmd, aac_probe_container_callback1) == 0) - while (scsicmd->device == scsidev) - schedule(); - kfree(scsidev); - status = scsicmd->SCp.Status; - kfree(scsicmd); return status; } @@ -1193,12 +1115,6 @@ int aac_get_adapter_info(struct aac_dev* dev) printk(KERN_INFO "%s%d: serial %x\n", dev->name, dev->id, le32_to_cpu(dev->adapter_info.serial[0])); - if (dev->supplement_adapter_info.VpdInfo.Tsid[0]) { - printk(KERN_INFO "%s%d: TSID %.*s\n", - dev->name, dev->id, - (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), - dev->supplement_adapter_info.VpdInfo.Tsid); - } } dev->nondasd_support = 0; @@ -1325,9 +1241,7 @@ static void io_callback(void *context, struct fib * fibptr) u32 cid; scsicmd = (struct scsi_cmnd *) context; - - if (!aac_valid_context(scsicmd, fibptr)) - return; + scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dev = (struct aac_dev *)scsicmd->device->host->hostdata; cid = scmd_id(scsicmd); @@ -1403,7 +1317,7 @@ static void io_callback(void *context, struct fib * fibptr) scsicmd->scsi_done(scsicmd); } -static int aac_read(struct scsi_cmnd * scsicmd) +static int aac_read(struct scsi_cmnd * scsicmd, int cid) { u64 lba; u32 count; @@ -1417,7 +1331,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) */ switch (scsicmd->cmnd[0]) { case READ_6: - dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid)); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; @@ -1427,7 +1341,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) count = 256; break; case READ_16: - dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 56) | ((u64)scsicmd->cmnd[3] << 48) | @@ -1441,7 +1355,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; break; case READ_12: - dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | @@ -1451,7 +1365,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; break; default: - dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | @@ -1491,7 +1405,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) return 0; } -static int aac_write(struct scsi_cmnd * scsicmd) +static int aac_write(struct scsi_cmnd * scsicmd, int cid) { u64 lba; u32 count; @@ -1510,7 +1424,7 @@ static int aac_write(struct scsi_cmnd * scsicmd) if (count == 0) count = 256; } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */ - dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 56) | ((u64)scsicmd->cmnd[3] << 48) | @@ -1522,14 +1436,14 @@ static int aac_write(struct scsi_cmnd * scsicmd) count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */ - dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; } else { - dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; } @@ -1574,9 +1488,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) struct scsi_cmnd *cmd; cmd = context; - - if (!aac_valid_context(cmd, fibptr)) - return; + cmd->SCp.phase = AAC_OWNER_MIDLEVEL; dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); @@ -1611,7 +1523,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) cmd->scsi_done(cmd); } -static int aac_synchronize(struct scsi_cmnd *scsicmd) +static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) { int status; struct fib *cmd_fibcontext; @@ -1656,7 +1568,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd) synchronizecmd = fib_data(cmd_fibcontext); synchronizecmd->command = cpu_to_le32(VM_ContainerConfig); synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE); - synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd)); + synchronizecmd->cid = cpu_to_le32(cid); synchronizecmd->count = cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data)); @@ -1734,12 +1646,29 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) case TEST_UNIT_READY: if (dev->in_reset) return -1; - return _aac_probe_container(scsicmd, - aac_probe_container_callback2); + spin_unlock_irq(host->host_lock); + aac_probe_container(dev, cid); + if ((fsa_dev_ptr[cid].valid & 1) == 0) + fsa_dev_ptr[cid].valid = 0; + spin_lock_irq(host->host_lock); + if (fsa_dev_ptr[cid].valid == 0) { + scsicmd->result = DID_NO_CONNECT << 16; + scsicmd->scsi_done(scsicmd); + return 0; + } default: break; } } + /* + * If the target container still doesn't exist, + * return failure + */ + if (fsa_dev_ptr[cid].valid == 0) { + scsicmd->result = DID_BAD_TARGET << 16; + scsicmd->scsi_done(scsicmd); + return 0; + } } else { /* check for physical non-dasd devices */ if ((dev->nondasd_support == 1) || expose_physicals) { if (dev->in_reset) @@ -1804,7 +1733,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); - return aac_get_container_name(scsicmd); + return aac_get_container_name(scsicmd, cid); } case SERVICE_ACTION_IN: if (!(dev->raw_io_interface) || @@ -1970,7 +1899,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) min(sizeof(fsa_dev_ptr[cid].devname), sizeof(scsicmd->request->rq_disk->disk_name) + 1)); - return aac_read(scsicmd); + return aac_read(scsicmd, cid); case WRITE_6: case WRITE_10: @@ -1978,11 +1907,11 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) case WRITE_16: if (dev->in_reset) return -1; - return aac_write(scsicmd); + return aac_write(scsicmd, cid); case SYNCHRONIZE_CACHE: /* Issue FIB to tell Firmware to flush it's cache */ - return aac_synchronize(scsicmd); + return aac_synchronize(scsicmd, cid); default: /* @@ -2129,10 +2058,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) struct scsi_cmnd *scsicmd; scsicmd = (struct scsi_cmnd *) context; - - if (!aac_valid_context(scsicmd, fibptr)) - return; - + scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dev = (struct aac_dev *)scsicmd->device->host->hostdata; BUG_ON(fibptr == NULL); diff --git a/trunk/drivers/scsi/aacraid/aacraid.h b/trunk/drivers/scsi/aacraid/aacraid.h index 45ca3e801619..39ecd0d22eb0 100644 --- a/trunk/drivers/scsi/aacraid/aacraid.h +++ b/trunk/drivers/scsi/aacraid/aacraid.h @@ -12,8 +12,8 @@ *----------------------------------------------------------------------------*/ #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 2437 -# define AAC_DRIVER_BRANCH "-mh4" +# define AAC_DRIVER_BUILD 2423 +# define AAC_DRIVER_BRANCH "-mh3" #endif #define MAXIMUM_NUM_CONTAINERS 32 @@ -48,13 +48,49 @@ struct diskparm /* - * Firmware constants + * DON'T CHANGE THE ORDER, this is set by the firmware */ #define CT_NONE 0 +#define CT_VOLUME 1 +#define CT_MIRROR 2 +#define CT_STRIPE 3 +#define CT_RAID5 4 +#define CT_SSRW 5 +#define CT_SSRO 6 +#define CT_MORPH 7 +#define CT_PASSTHRU 8 +#define CT_RAID4 9 +#define CT_RAID10 10 /* stripe of mirror */ +#define CT_RAID00 11 /* stripe of stripe */ +#define CT_VOLUME_OF_MIRRORS 12 /* volume of mirror */ +#define CT_PSEUDO_RAID 13 /* really raid4 */ +#define CT_LAST_VOLUME_TYPE 14 #define CT_OK 218 + +/* + * Types of objects addressable in some fashion by the client. + * This is a superset of those objects handled just by the filesystem + * and includes "raw" objects that an administrator would use to + * configure containers and filesystems. + */ + +#define FT_REG 1 /* regular file */ +#define FT_DIR 2 /* directory */ +#define FT_BLK 3 /* "block" device - reserved */ +#define FT_CHR 4 /* "character special" device - reserved */ +#define FT_LNK 5 /* symbolic link */ +#define FT_SOCK 6 /* socket */ +#define FT_FIFO 7 /* fifo */ #define FT_FILESYS 8 /* ADAPTEC's "FSA"(tm) filesystem */ #define FT_DRIVE 9 /* physical disk - addressable in scsi by bus/id/lun */ +#define FT_SLICE 10 /* virtual disk - raw volume - slice */ +#define FT_PARTITION 11 /* FSA partition - carved out of a slice - building block for containers */ +#define FT_VOLUME 12 /* Container - Volume Set */ +#define FT_STRIPE 13 /* Container - Stripe Set */ +#define FT_MIRROR 14 /* Container - Mirror Set */ +#define FT_RAID5 15 /* Container - Raid 5 Set */ +#define FT_DATABASE 16 /* Storage object with "foreign" content manager */ /* * Host side memory scatter gather list @@ -461,7 +497,6 @@ struct adapter_ops void (*adapter_enable_int)(struct aac_dev *dev); int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); int (*adapter_check_health)(struct aac_dev *dev); - int (*adapter_restart)(struct aac_dev *dev, int bled); /* Transport operations */ int (*adapter_ioremap)(struct aac_dev * dev, u32 size); irqreturn_t (*adapter_intr)(int irq, void *dev_id); @@ -798,7 +833,7 @@ struct fib { */ struct list_head fiblink; void *data; - struct hw_fib *hw_fib_va; /* Actual shared object */ + struct hw_fib *hw_fib; /* Actual shared object */ dma_addr_t hw_fib_pa; /* physical address of hw_fib*/ }; @@ -843,25 +878,10 @@ struct aac_supplement_adapter_info __le32 Version; __le32 FeatureBits; u8 SlotNumber; - u8 ReservedPad0[3]; + u8 ReservedPad0[0]; u8 BuildDate[12]; __le32 CurrentNumberPorts; - struct { - u8 AssemblyPn[8]; - u8 FruPn[8]; - u8 BatteryFruPn[8]; - u8 EcVersionString[8]; - u8 Tsid[12]; - } VpdInfo; - __le32 FlashFirmwareRevision; - __le32 FlashFirmwareBuild; - __le32 RaidTypeMorphOptions; - __le32 FlashFirmwareBootRevision; - __le32 FlashFirmwareBootBuild; - u8 MfgPcbaSerialNo[12]; - u8 MfgWWNName[8]; - __le32 MoreFeatureBits; - __le32 ReservedGrowth[1]; + __le32 ReservedGrowth[24]; }; #define AAC_FEATURE_FALCON 0x00000010 #define AAC_SIS_VERSION_V3 3 @@ -950,6 +970,7 @@ struct aac_dev struct fib *fibs; struct fib *free_fib; + struct fib *timeout_fib; spinlock_t fib_lock; struct aac_queue_block *queues; @@ -1039,9 +1060,6 @@ struct aac_dev #define aac_adapter_check_health(dev) \ (dev)->a_ops.adapter_check_health(dev) -#define aac_adapter_restart(dev,bled) \ - (dev)->a_ops.adapter_restart(dev,bled) - #define aac_adapter_ioremap(dev, size) \ (dev)->a_ops.adapter_ioremap(dev, size) @@ -1498,7 +1516,8 @@ struct aac_mntent { struct creation_info create_info; /* if applicable */ __le32 capacity; __le32 vol; /* substrate structure */ - __le32 obj; /* FT_FILESYS, etc. */ + __le32 obj; /* FT_FILESYS, + FT_DATABASE, etc. */ __le32 state; /* unready for mounting, readonly, etc. */ union aac_contentinfo fileinfo; /* Info specific to content @@ -1798,7 +1817,7 @@ int aac_fib_send(u16 command, struct fib * context, unsigned long size, int prio int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry); void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); int aac_fib_complete(struct fib * context); -#define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data) +#define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) struct aac_dev *aac_init_adapter(struct aac_dev *dev); int aac_get_config_status(struct aac_dev *dev, int commit_flag); int aac_get_containers(struct aac_dev *dev); @@ -1821,11 +1840,8 @@ struct aac_driver_ident* aac_get_driver_ident(int devtype); int aac_get_adapter_info(struct aac_dev* dev); int aac_send_shutdown(struct aac_dev *dev); int aac_probe_container(struct aac_dev *dev, int cid); -int _aac_rx_init(struct aac_dev *dev); -int aac_rx_select_comm(struct aac_dev *dev, int comm); extern int numacb; extern int acbsize; extern char aac_driver_version[]; extern int startup_timeout; extern int aif_timeout; -extern int expose_physicals; diff --git a/trunk/drivers/scsi/aacraid/commctrl.c b/trunk/drivers/scsi/aacraid/commctrl.c index 72b0393b4596..e21070f4eac1 100644 --- a/trunk/drivers/scsi/aacraid/commctrl.c +++ b/trunk/drivers/scsi/aacraid/commctrl.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,15 +64,12 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) unsigned size; int retval; - if (dev->in_reset) { - return -EBUSY; - } fibptr = aac_fib_alloc(dev); if(fibptr == NULL) { return -ENOMEM; } - kfib = fibptr->hw_fib_va; + kfib = fibptr->hw_fib; /* * First copy in the header so that we can check the size field. */ @@ -94,9 +91,9 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) goto cleanup; } /* Highjack the hw_fib */ - hw_fib = fibptr->hw_fib_va; + hw_fib = fibptr->hw_fib; hw_fib_pa = fibptr->hw_fib_pa; - fibptr->hw_fib_va = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); + fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); memcpy(kfib, hw_fib, dev->max_fib_size); } @@ -140,7 +137,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) if (hw_fib) { pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); fibptr->hw_fib_pa = hw_fib_pa; - fibptr->hw_fib_va = hw_fib; + fibptr->hw_fib = hw_fib; } if (retval != -EINTR) aac_fib_free(fibptr); @@ -285,15 +282,15 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg) fib = list_entry(entry, struct fib, fiblink); fibctx->count--; spin_unlock_irqrestore(&dev->fib_lock, flags); - if (copy_to_user(f.fib, fib->hw_fib_va, sizeof(struct hw_fib))) { - kfree(fib->hw_fib_va); + if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) { + kfree(fib->hw_fib); kfree(fib); return -EFAULT; } /* * Free the space occupied by this copy of the fib. */ - kfree(fib->hw_fib_va); + kfree(fib->hw_fib); kfree(fib); status = 0; } else { @@ -343,7 +340,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx) /* * Free the space occupied by this copy of the fib. */ - kfree(fib->hw_fib_va); + kfree(fib->hw_fib); kfree(fib); } /* @@ -391,8 +388,10 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg) /* * Extract the fibctx from the input parameters */ - if (fibctx->unique == (u32)(ptrdiff_t)arg) /* We found a winner */ + if (fibctx->unique == (u32)(unsigned long)arg) { + /* We found a winner */ break; + } entry = entry->next; fibctx = NULL; } @@ -466,20 +465,16 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) void *sg_list[32]; u32 sg_indx = 0; u32 byte_count = 0; - u32 actual_fibsize64, actual_fibsize = 0; + u32 actual_fibsize = 0; int i; - if (dev->in_reset) { - dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n")); - return -EBUSY; - } if (!capable(CAP_SYS_ADMIN)){ dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); return -EPERM; } /* - * Allocate and initialize a Fib then setup a SRB command + * Allocate and initialize a Fib then setup a BlockWrite command */ if (!(srbfib = aac_fib_alloc(dev))) { return -ENOMEM; @@ -546,183 +541,129 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) rcode = -EINVAL; goto cleanup; } - actual_fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) + - ((user_srbcmd->sg.count & 0xff) * sizeof(struct sgentry)); - actual_fibsize64 = actual_fibsize + (user_srbcmd->sg.count & 0xff) * - (sizeof(struct sgentry64) - sizeof(struct sgentry)); - /* User made a mistake - should not continue */ - if ((actual_fibsize != fibsize) && (actual_fibsize64 != fibsize)) { - dprintk((KERN_DEBUG"aacraid: Bad Size specified in " - "Raw SRB command calculated fibsize=%lu;%lu " - "user_srbcmd->sg.count=%d aac_srb=%lu sgentry=%lu;%lu " - "issued fibsize=%d\n", - actual_fibsize, actual_fibsize64, user_srbcmd->sg.count, - sizeof(struct aac_srb), sizeof(struct sgentry), - sizeof(struct sgentry64), fibsize)); - rcode = -EINVAL; - goto cleanup; - } - if ((data_dir == DMA_NONE) && user_srbcmd->sg.count) { - dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); - rcode = -EINVAL; - goto cleanup; - } - byte_count = 0; - if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) { + if (dev->dac_support == 1) { struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; + struct user_sgmap* usg; + byte_count = 0; /* * This should also catch if user used the 32 bit sgmap */ - if (actual_fibsize64 == fibsize) { - actual_fibsize = actual_fibsize64; - for (i = 0; i < upsg->count; i++) { - u64 addr; - void* p; - /* Does this really need to be GFP_DMA? */ - p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA); - if(p == 0) { - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - upsg->sg[i].count,i,upsg->count)); - rcode = -ENOMEM; - goto cleanup; - } - addr = (u64)upsg->sg[i].addr[0]; - addr += ((u64)upsg->sg[i].addr[1]) << 32; - sg_user[i] = (void __user *)(ptrdiff_t)addr; - sg_list[i] = p; // save so we can clean up later - sg_indx = i; - - if( flags & SRB_DataOut ){ - if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ - dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); - rcode = -EFAULT; - goto cleanup; - } - } - addr = pci_map_single(dev->pdev, p, upsg->sg[i].count, data_dir); + actual_fibsize = sizeof(struct aac_srb) - + sizeof(struct sgentry) + + ((upsg->count & 0xff) * + sizeof(struct sgentry)); + if(actual_fibsize != fibsize){ // User made a mistake - should not continue + dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); + rcode = -EINVAL; + goto cleanup; + } + usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) + + sizeof(struct sgmap), GFP_KERNEL); + if (!usg) { + dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); + rcode = -ENOMEM; + goto cleanup; + } + memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) + + sizeof(struct sgmap)); + actual_fibsize = sizeof(struct aac_srb) - + sizeof(struct sgentry) + ((usg->count & 0xff) * + sizeof(struct sgentry64)); + if ((data_dir == DMA_NONE) && upsg->count) { + kfree (usg); + dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); + rcode = -EINVAL; + goto cleanup; + } - psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); - psg->sg[i].addr[1] = cpu_to_le32(addr>>32); - byte_count += upsg->sg[i].count; - psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); - } - } else { - struct user_sgmap* usg; - usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) - + sizeof(struct sgmap), GFP_KERNEL); - if (!usg) { - dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); + for (i = 0; i < usg->count; i++) { + u64 addr; + void* p; + /* Does this really need to be GFP_DMA? */ + p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); + if(p == 0) { + kfree (usg); + dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + usg->sg[i].count,i,usg->count)); rcode = -ENOMEM; goto cleanup; } - memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) - + sizeof(struct sgmap)); - actual_fibsize = actual_fibsize64; - - for (i = 0; i < usg->count; i++) { - u64 addr; - void* p; - /* Does this really need to be GFP_DMA? */ - p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); - if(p == 0) { + sg_user[i] = (void __user *)(long)usg->sg[i].addr; + sg_list[i] = p; // save so we can clean up later + sg_indx = i; + + if( flags & SRB_DataOut ){ + if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ kfree (usg); - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - usg->sg[i].count,i,usg->count)); - rcode = -ENOMEM; + dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); + rcode = -EFAULT; goto cleanup; } - sg_user[i] = (void __user *)(ptrdiff_t)usg->sg[i].addr; - sg_list[i] = p; // save so we can clean up later - sg_indx = i; - - if( flags & SRB_DataOut ){ - if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ - kfree (usg); - dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); - rcode = -EFAULT; - goto cleanup; - } - } - addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); - - psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); - psg->sg[i].addr[1] = cpu_to_le32(addr>>32); - byte_count += usg->sg[i].count; - psg->sg[i].count = cpu_to_le32(usg->sg[i].count); } - kfree (usg); + addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); + + psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); + psg->sg[i].addr[1] = cpu_to_le32(addr>>32); + psg->sg[i].count = cpu_to_le32(usg->sg[i].count); + byte_count += usg->sg[i].count; } + kfree (usg); + srbcmd->count = cpu_to_le32(byte_count); psg->count = cpu_to_le32(sg_indx+1); status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); } else { struct user_sgmap* upsg = &user_srbcmd->sg; struct sgmap* psg = &srbcmd->sg; - - if (actual_fibsize64 == fibsize) { - struct user_sgmap64* usg = (struct user_sgmap64 *)upsg; - for (i = 0; i < upsg->count; i++) { - u64 addr; - void* p; - /* Does this really need to be GFP_DMA? */ - p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); - if(p == 0) { - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - usg->sg[i].count,i,usg->count)); - rcode = -ENOMEM; - goto cleanup; - } - addr = (u64)usg->sg[i].addr[0]; - addr += ((u64)usg->sg[i].addr[1]) << 32; - sg_user[i] = (void __user *)(ptrdiff_t)addr; - sg_list[i] = p; // save so we can clean up later - sg_indx = i; - - if( flags & SRB_DataOut ){ - if(copy_from_user(p,sg_user[i],usg->sg[i].count)){ - dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); - rcode = -EFAULT; - goto cleanup; - } - } - addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); - - psg->sg[i].addr = cpu_to_le32(addr & 0xffffffff); - byte_count += usg->sg[i].count; - psg->sg[i].count = cpu_to_le32(usg->sg[i].count); + byte_count = 0; + + actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); + if(actual_fibsize != fibsize){ // User made a mistake - should not continue + dprintk((KERN_DEBUG"aacraid: Bad Size specified in " + "Raw SRB command calculated fibsize=%d " + "user_srbcmd->sg.count=%d aac_srb=%d sgentry=%d " + "issued fibsize=%d\n", + actual_fibsize, user_srbcmd->sg.count, + sizeof(struct aac_srb), sizeof(struct sgentry), + fibsize)); + rcode = -EINVAL; + goto cleanup; + } + if ((data_dir == DMA_NONE) && upsg->count) { + dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); + rcode = -EINVAL; + goto cleanup; + } + for (i = 0; i < upsg->count; i++) { + dma_addr_t addr; + void* p; + p = kmalloc(upsg->sg[i].count, GFP_KERNEL); + if(p == 0) { + dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + upsg->sg[i].count, i, upsg->count)); + rcode = -ENOMEM; + goto cleanup; } - } else { - for (i = 0; i < upsg->count; i++) { - dma_addr_t addr; - void* p; - p = kmalloc(upsg->sg[i].count, GFP_KERNEL); - if(p == 0) { - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - upsg->sg[i].count, i, upsg->count)); - rcode = -ENOMEM; + sg_user[i] = (void __user *)(long)upsg->sg[i].addr; + sg_list[i] = p; // save so we can clean up later + sg_indx = i; + + if( flags & SRB_DataOut ){ + if(copy_from_user(p, sg_user[i], + upsg->sg[i].count)) { + dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); + rcode = -EFAULT; goto cleanup; } - sg_user[i] = (void __user *)(ptrdiff_t)upsg->sg[i].addr; - sg_list[i] = p; // save so we can clean up later - sg_indx = i; - - if( flags & SRB_DataOut ){ - if(copy_from_user(p, sg_user[i], - upsg->sg[i].count)) { - dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); - rcode = -EFAULT; - goto cleanup; - } - } - addr = pci_map_single(dev->pdev, p, - upsg->sg[i].count, data_dir); - - psg->sg[i].addr = cpu_to_le32(addr); - byte_count += upsg->sg[i].count; - psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); } + addr = pci_map_single(dev->pdev, p, + upsg->sg[i].count, data_dir); + + psg->sg[i].addr = cpu_to_le32(addr); + psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); + byte_count += upsg->sg[i].count; } srbcmd->count = cpu_to_le32(byte_count); psg->count = cpu_to_le32(sg_indx+1); @@ -741,8 +682,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) if( flags & SRB_DataIn ) { for(i = 0 ; i <= sg_indx; i++){ - byte_count = le32_to_cpu( - (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) + byte_count = le32_to_cpu((dev->dac_support == 1) ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count : srbcmd->sg.sg[i].count); if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ diff --git a/trunk/drivers/scsi/aacraid/comminit.c b/trunk/drivers/scsi/aacraid/comminit.c index 33682ce96a5d..ae34768987a4 100644 --- a/trunk/drivers/scsi/aacraid/comminit.c +++ b/trunk/drivers/scsi/aacraid/comminit.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -110,7 +110,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co /* * Align the beginning of Headers to commalign */ - align = (commalign - ((ptrdiff_t)(base) & (commalign - 1))); + align = (commalign - ((unsigned long)(base) & (commalign - 1))); base = base + align; phys = phys + align; /* diff --git a/trunk/drivers/scsi/aacraid/commsup.c b/trunk/drivers/scsi/aacraid/commsup.c index 5824a757a753..1b97f60652ba 100644 --- a/trunk/drivers/scsi/aacraid/commsup.c +++ b/trunk/drivers/scsi/aacraid/commsup.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -94,7 +94,7 @@ void aac_fib_map_free(struct aac_dev *dev) int aac_fib_setup(struct aac_dev * dev) { struct fib *fibptr; - struct hw_fib *hw_fib; + struct hw_fib *hw_fib_va; dma_addr_t hw_fib_pa; int i; @@ -106,24 +106,24 @@ int aac_fib_setup(struct aac_dev * dev) if (i<0) return -ENOMEM; - hw_fib = dev->hw_fib_va; + hw_fib_va = dev->hw_fib_va; hw_fib_pa = dev->hw_fib_pa; - memset(hw_fib, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); + memset(hw_fib_va, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); /* * Initialise the fibs */ for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++) { fibptr->dev = dev; - fibptr->hw_fib_va = hw_fib; - fibptr->data = (void *) fibptr->hw_fib_va->data; + fibptr->hw_fib = hw_fib_va; + fibptr->data = (void *) fibptr->hw_fib->data; fibptr->next = fibptr+1; /* Forward chain the fibs */ init_MUTEX_LOCKED(&fibptr->event_wait); spin_lock_init(&fibptr->event_lock); - hw_fib->header.XferState = cpu_to_le32(0xffffffff); - hw_fib->header.SenderSize = cpu_to_le16(dev->max_fib_size); + hw_fib_va->header.XferState = cpu_to_le32(0xffffffff); + hw_fib_va->header.SenderSize = cpu_to_le16(dev->max_fib_size); fibptr->hw_fib_pa = hw_fib_pa; - hw_fib = (struct hw_fib *)((unsigned char *)hw_fib + dev->max_fib_size); + hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + dev->max_fib_size); hw_fib_pa = hw_fib_pa + dev->max_fib_size; } /* @@ -166,7 +166,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) * Null out fields that depend on being zero at the start of * each I/O */ - fibptr->hw_fib_va->header.XferState = 0; + fibptr->hw_fib->header.XferState = 0; fibptr->callback = NULL; fibptr->callback_data = NULL; @@ -178,6 +178,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) * @fibptr: fib to free up * * Frees up a fib and places it on the appropriate queue + * (either free or timed out) */ void aac_fib_free(struct fib *fibptr) @@ -185,15 +186,19 @@ void aac_fib_free(struct fib *fibptr) unsigned long flags; spin_lock_irqsave(&fibptr->dev->fib_lock, flags); - if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) + if (fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT) { aac_config.fib_timeouts++; - if (fibptr->hw_fib_va->header.XferState != 0) { - printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", - (void*)fibptr, - le32_to_cpu(fibptr->hw_fib_va->header.XferState)); - } - fibptr->next = fibptr->dev->free_fib; - fibptr->dev->free_fib = fibptr; + fibptr->next = fibptr->dev->timeout_fib; + fibptr->dev->timeout_fib = fibptr; + } else { + if (fibptr->hw_fib->header.XferState != 0) { + printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", + (void*)fibptr, + le32_to_cpu(fibptr->hw_fib->header.XferState)); + } + fibptr->next = fibptr->dev->free_fib; + fibptr->dev->free_fib = fibptr; + } spin_unlock_irqrestore(&fibptr->dev->fib_lock, flags); } @@ -206,7 +211,7 @@ void aac_fib_free(struct fib *fibptr) void aac_fib_init(struct fib *fibptr) { - struct hw_fib *hw_fib = fibptr->hw_fib_va; + struct hw_fib *hw_fib = fibptr->hw_fib; hw_fib->header.StructType = FIB_MAGIC; hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); @@ -226,7 +231,7 @@ void aac_fib_init(struct fib *fibptr) static void fib_dealloc(struct fib * fibptr) { - struct hw_fib *hw_fib = fibptr->hw_fib_va; + struct hw_fib *hw_fib = fibptr->hw_fib; BUG_ON(hw_fib->header.StructType != FIB_MAGIC); hw_fib->header.XferState = 0; } @@ -381,7 +386,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, void *callback_data) { struct aac_dev * dev = fibptr->dev; - struct hw_fib * hw_fib = fibptr->hw_fib_va; + struct hw_fib * hw_fib = fibptr->hw_fib; unsigned long flags = 0; unsigned long qflags; @@ -425,7 +430,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, */ hw_fib->header.Command = cpu_to_le16(command); hw_fib->header.XferState |= cpu_to_le32(SentFromHost); - fibptr->hw_fib_va->header.Flags = 0; /* 0 the flags field - internal only*/ + fibptr->hw_fib->header.Flags = 0; /* 0 the flags field - internal only*/ /* * Set the size of the Fib we want to send to the adapter */ @@ -457,7 +462,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command))); dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command))); dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState))); - dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib_va)); + dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib)); dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); @@ -508,20 +513,22 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, } udelay(5); } - } else - (void)down_interruptible(&fibptr->event_wait); - spin_lock_irqsave(&fibptr->event_lock, flags); - if (fibptr->done == 0) { - fibptr->done = 2; /* Tell interrupt we aborted */ + } else if (down_interruptible(&fibptr->event_wait)) { + spin_lock_irqsave(&fibptr->event_lock, flags); + if (fibptr->done == 0) { + fibptr->done = 2; /* Tell interrupt we aborted */ + spin_unlock_irqrestore(&fibptr->event_lock, flags); + return -EINTR; + } spin_unlock_irqrestore(&fibptr->event_lock, flags); - return -EINTR; } - spin_unlock_irqrestore(&fibptr->event_lock, flags); BUG_ON(fibptr->done == 0); - if(unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) + if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ return -ETIMEDOUT; - return 0; + } else { + return 0; + } } /* * If the user does not want a response than return success otherwise @@ -617,7 +624,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) { - struct hw_fib * hw_fib = fibptr->hw_fib_va; + struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_dev * dev = fibptr->dev; struct aac_queue * q; unsigned long nointr = 0; @@ -681,7 +688,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) int aac_fib_complete(struct fib *fibptr) { - struct hw_fib * hw_fib = fibptr->hw_fib_va; + struct hw_fib * hw_fib = fibptr->hw_fib; /* * Check for a fib which has already been completed @@ -767,8 +774,9 @@ void aac_printf(struct aac_dev *dev, u32 val) #define AIF_SNIFF_TIMEOUT (30*HZ) static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) { - struct hw_fib * hw_fib = fibptr->hw_fib_va; + struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data; + int busy; u32 container; struct scsi_device *device; enum { @@ -980,6 +988,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) * behind you. */ + busy = 0; + + /* * Find the scsi_device associated with the SCSI address, * and mark it as changed, invalidating the cache. This deals @@ -1024,6 +1035,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) static int _aac_reset_adapter(struct aac_dev *aac) { int index, quirks; + u32 ret; int retval; struct Scsi_Host *host; struct scsi_device *dev; @@ -1047,29 +1059,35 @@ static int _aac_reset_adapter(struct aac_dev *aac) * If a positive health, means in a known DEAD PANIC * state and the adapter could be reset to `try again'. */ - retval = aac_adapter_restart(aac, aac_adapter_check_health(aac)); + retval = aac_adapter_check_health(aac); + if (retval == 0) + retval = aac_adapter_sync_cmd(aac, IOP_RESET_ALWAYS, + 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL); + if (retval) + retval = aac_adapter_sync_cmd(aac, IOP_RESET, + 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL); if (retval) goto out; + if (ret != 0x00000001) { + retval = -ENODEV; + goto out; + } /* * Loop through the fibs, close the synchronous FIBS */ - for (retval = 1, index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { + for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { struct fib *fib = &aac->fibs[index]; - if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && - (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) { + if (!(fib->hw_fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && + (fib->hw_fib->header.XferState & cpu_to_le32(ResponseExpected))) { unsigned long flagv; spin_lock_irqsave(&fib->event_lock, flagv); up(&fib->event_wait); spin_unlock_irqrestore(&fib->event_lock, flagv); schedule(); - retval = 0; } } - /* Give some extra time for ioctls to complete. */ - if (retval == 0) - ssleep(2); index = aac->cardtype; /* @@ -1230,7 +1248,7 @@ int aac_check_health(struct aac_dev * aac) memset(hw_fib, 0, sizeof(struct hw_fib)); memset(fib, 0, sizeof(struct fib)); - fib->hw_fib_va = hw_fib; + fib->hw_fib = hw_fib; fib->dev = aac; aac_fib_init(fib); fib->type = FSAFS_NTC_FIB_CONTEXT; @@ -1336,11 +1354,11 @@ int aac_command_thread(void *data) * do anything at this point since we don't have * anything defined for this thread to do. */ - hw_fib = fib->hw_fib_va; + hw_fib = fib->hw_fib; memset(fib, 0, sizeof(struct fib)); fib->type = FSAFS_NTC_FIB_CONTEXT; fib->size = sizeof( struct fib ); - fib->hw_fib_va = hw_fib; + fib->hw_fib = hw_fib; fib->data = hw_fib->data; fib->dev = dev; /* @@ -1467,7 +1485,7 @@ int aac_command_thread(void *data) */ memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib)); memcpy(newfib, fib, sizeof(struct fib)); - newfib->hw_fib_va = hw_newfib; + newfib->hw_fib = hw_newfib; /* * Put the FIB onto the * fibctx's fibs diff --git a/trunk/drivers/scsi/aacraid/dpcsup.c b/trunk/drivers/scsi/aacraid/dpcsup.c index 42c7dcda6d9b..66aeb57dcc2d 100644 --- a/trunk/drivers/scsi/aacraid/dpcsup.c +++ b/trunk/drivers/scsi/aacraid/dpcsup.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,7 +72,7 @@ unsigned int aac_response_normal(struct aac_queue * q) u32 index = le32_to_cpu(entry->addr); fast = index & 0x01; fib = &dev->fibs[index >> 2]; - hwfib = fib->hw_fib_va; + hwfib = fib->hw_fib; aac_consumer_free(dev, q, HostNormRespQueue); /* @@ -83,13 +83,11 @@ unsigned int aac_response_normal(struct aac_queue * q) * continue. The caller has already been notified that * the fib timed out. */ - dev->queues->queue[AdapNormCmdQueue].numpending--; - - if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { - spin_unlock_irqrestore(q->lock, flags); - aac_fib_complete(fib); - aac_fib_free(fib); - spin_lock_irqsave(q->lock, flags); + if (!(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) + dev->queues->queue[AdapNormCmdQueue].numpending--; + else { + printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); + printk(KERN_DEBUG"aacraid: hwfib=%p fib index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); continue; } spin_unlock_irqrestore(q->lock, flags); @@ -194,7 +192,7 @@ unsigned int aac_command_normal(struct aac_queue *q) INIT_LIST_HEAD(&fib->fiblink); fib->type = FSAFS_NTC_FIB_CONTEXT; fib->size = sizeof(struct fib); - fib->hw_fib_va = hw_fib; + fib->hw_fib = hw_fib; fib->data = hw_fib->data; fib->dev = dev; @@ -255,13 +253,12 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) return 1; } memset(hw_fib, 0, sizeof(struct hw_fib)); - memcpy(hw_fib, (struct hw_fib *)(((ptrdiff_t)(dev->regs.sa)) + - (index & ~0x00000002L)), sizeof(struct hw_fib)); + memcpy(hw_fib, (struct hw_fib *)(((unsigned long)(dev->regs.sa)) + (index & ~0x00000002L)), sizeof(struct hw_fib)); memset(fib, 0, sizeof(struct fib)); INIT_LIST_HEAD(&fib->fiblink); fib->type = FSAFS_NTC_FIB_CONTEXT; fib->size = sizeof(struct fib); - fib->hw_fib_va = hw_fib; + fib->hw_fib = hw_fib; fib->data = hw_fib->data; fib->dev = dev; @@ -273,7 +270,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) } else { int fast = index & 0x01; struct fib * fib = &dev->fibs[index >> 2]; - struct hw_fib * hwfib = fib->hw_fib_va; + struct hw_fib * hwfib = fib->hw_fib; /* * Remove this fib from the Outstanding I/O queue. @@ -283,14 +280,14 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) * continue. The caller has already been notified that * the fib timed out. */ - dev->queues->queue[AdapNormCmdQueue].numpending--; - - if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { - aac_fib_complete(fib); - aac_fib_free(fib); + if ((fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { + printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); + printk(KERN_DEBUG"aacraid: hwfib=%p index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); return 0; } + dev->queues->queue[AdapNormCmdQueue].numpending--; + if (fast) { /* * Doctor the fib diff --git a/trunk/drivers/scsi/aacraid/linit.c b/trunk/drivers/scsi/aacraid/linit.c index 350ea7feb61d..0f948c2fb609 100644 --- a/trunk/drivers/scsi/aacraid/linit.c +++ b/trunk/drivers/scsi/aacraid/linit.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -82,6 +82,8 @@ static LIST_HEAD(aac_devices); static int aac_cfg_major = -1; char aac_driver_version[] = AAC_DRIVER_FULL_VERSION; +extern int expose_physicals; + /* * Because of the way Linux names scsi devices, the order in this table has * become important. Check for on-board Raid first, add-in cards second. @@ -245,19 +247,7 @@ static struct aac_driver_ident aac_drivers[] = { static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { - struct Scsi_Host *host = cmd->device->host; - struct aac_dev *dev = (struct aac_dev *)host->hostdata; - u32 count = 0; cmd->scsi_done = done; - for (; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - struct fib * fib = &dev->fibs[count]; - struct scsi_cmnd * command; - if (fib->hw_fib_va->header.XferState && - ((command = fib->callback_data)) && - (command == cmd) && - (cmd->SCp.phase == AAC_OWNER_FIRMWARE)) - return 0; /* Already owned by Adapter */ - } cmd->SCp.phase = AAC_OWNER_LOWLEVEL; return (aac_scsi_cmd(cmd) ? FAILED : 0); } @@ -456,40 +446,6 @@ static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg) return aac_do_ioctl(dev, cmd, arg); } -static int aac_eh_abort(struct scsi_cmnd* cmd) -{ - struct scsi_device * dev = cmd->device; - struct Scsi_Host * host = dev->host; - struct aac_dev * aac = (struct aac_dev *)host->hostdata; - int count; - int ret = FAILED; - - printk(KERN_ERR "%s: Host adapter abort request (%d,%d,%d,%d)\n", - AAC_DRIVERNAME, - host->host_no, sdev_channel(dev), sdev_id(dev), dev->lun); - switch (cmd->cmnd[0]) { - case SERVICE_ACTION_IN: - if (!(aac->raw_io_interface) || - !(aac->raw_io_64) || - ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16)) - break; - case INQUIRY: - case READ_CAPACITY: - case TEST_UNIT_READY: - /* Mark associated FIB to not complete, eh handler does this */ - for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - struct fib * fib = &aac->fibs[count]; - if (fib->hw_fib_va->header.XferState && - (fib->callback_data == cmd)) { - fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; - cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; - ret = SUCCESS; - } - } - } - return ret; -} - /* * aac_eh_reset - Reset command handling * @scsi_cmd: SCSI command block causing the reset @@ -501,20 +457,12 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) struct Scsi_Host * host = dev->host; struct scsi_cmnd * command; int count; - struct aac_dev * aac = (struct aac_dev *)host->hostdata; + struct aac_dev * aac; unsigned long flags; - /* Mark the associated FIB to not complete, eh handler does this */ - for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - struct fib * fib = &aac->fibs[count]; - if (fib->hw_fib_va->header.XferState && - (fib->callback_data == cmd)) { - fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; - cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; - } - } printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVERNAME); + aac = (struct aac_dev *)host->hostdata; if ((count = aac_check_health(aac))) return count; @@ -548,7 +496,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) ssleep(1); } printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); - return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ + return -ETIMEDOUT; } /** @@ -848,7 +796,6 @@ static struct scsi_host_template aac_driver_template = { .bios_param = aac_biosparm, .shost_attrs = aac_attrs, .slave_configure = aac_slave_configure, - .eh_abort_handler = aac_eh_abort, .eh_host_reset_handler = aac_eh_reset, .can_queue = AAC_NUM_IO_FIB, .this_id = MAXIMUM_NUM_CONTAINERS, diff --git a/trunk/drivers/scsi/aacraid/nark.c b/trunk/drivers/scsi/aacraid/nark.c index a8ace5677813..c76b611b6afb 100644 --- a/trunk/drivers/scsi/aacraid/nark.c +++ b/trunk/drivers/scsi/aacraid/nark.c @@ -74,6 +74,9 @@ static int aac_nark_ioremap(struct aac_dev * dev, u32 size) int aac_nark_init(struct aac_dev * dev) { + extern int _aac_rx_init(struct aac_dev *dev); + extern int aac_rx_select_comm(struct aac_dev *dev, int comm); + /* * Fill in the function dispatch table. */ diff --git a/trunk/drivers/scsi/aacraid/rkt.c b/trunk/drivers/scsi/aacraid/rkt.c index 9c5fcfb398c2..d953c3fe998a 100644 --- a/trunk/drivers/scsi/aacraid/rkt.c +++ b/trunk/drivers/scsi/aacraid/rkt.c @@ -45,6 +45,7 @@ static int aac_rkt_select_comm(struct aac_dev *dev, int comm) { int retval; + extern int aac_rx_select_comm(struct aac_dev *dev, int comm); retval = aac_rx_select_comm(dev, comm); if (comm == AAC_COMM_MESSAGE) { /* @@ -96,6 +97,8 @@ static int aac_rkt_ioremap(struct aac_dev * dev, u32 size) int aac_rkt_init(struct aac_dev *dev) { + extern int _aac_rx_init(struct aac_dev *dev); + /* * Fill in the function dispatch table. */ diff --git a/trunk/drivers/scsi/aacraid/rx.c b/trunk/drivers/scsi/aacraid/rx.c index 0c71315cbf1a..d242e2611d67 100644 --- a/trunk/drivers/scsi/aacraid/rx.c +++ b/trunk/drivers/scsi/aacraid/rx.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,25 +57,25 @@ static irqreturn_t aac_rx_intr_producer(int irq, void *dev_id) * been enabled. * Check to see if this is our interrupt. If it isn't just return */ - if (likely(intstat & ~(dev->OIMR))) { + if (intstat & ~(dev->OIMR)) { bellbits = rx_readl(dev, OutboundDoorbellReg); - if (unlikely(bellbits & DoorBellPrintfReady)) { + if (bellbits & DoorBellPrintfReady) { aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5])); rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); } - else if (unlikely(bellbits & DoorBellAdapterNormCmdReady)) { + else if (bellbits & DoorBellAdapterNormCmdReady) { rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); } - else if (likely(bellbits & DoorBellAdapterNormRespReady)) { + else if (bellbits & DoorBellAdapterNormRespReady) { rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); aac_response_normal(&dev->queues->queue[HostNormRespQueue]); } - else if (unlikely(bellbits & DoorBellAdapterNormCmdNotFull)) { + else if (bellbits & DoorBellAdapterNormCmdNotFull) { rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); } - else if (unlikely(bellbits & DoorBellAdapterNormRespNotFull)) { + else if (bellbits & DoorBellAdapterNormRespNotFull) { rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); } @@ -88,11 +88,11 @@ static irqreturn_t aac_rx_intr_message(int irq, void *dev_id) { struct aac_dev *dev = dev_id; u32 Index = rx_readl(dev, MUnit.OutboundQueue); - if (unlikely(Index == 0xFFFFFFFFL)) + if (Index == 0xFFFFFFFFL) Index = rx_readl(dev, MUnit.OutboundQueue); - if (likely(Index != 0xFFFFFFFFL)) { + if (Index != 0xFFFFFFFFL) { do { - if (unlikely(aac_intr_normal(dev, Index))) { + if (aac_intr_normal(dev, Index)) { rx_writel(dev, MUnit.OutboundQueue, Index); rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); } @@ -204,7 +204,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, */ msleep(1); } - if (unlikely(ok != 1)) { + if (ok != 1) { /* * Restore interrupt mask even though we timed out */ @@ -294,7 +294,7 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) * Start up processing on an i960 based AAC adapter */ -static void aac_rx_start_adapter(struct aac_dev *dev) +void aac_rx_start_adapter(struct aac_dev *dev) { struct aac_init *init; @@ -319,12 +319,12 @@ static int aac_rx_check_health(struct aac_dev *dev) /* * Check to see if the board failed any self tests. */ - if (unlikely(status & SELF_TEST_FAILED)) + if (status & SELF_TEST_FAILED) return -1; /* * Check to see if the board panic'd. */ - if (unlikely(status & KERNEL_PANIC)) { + if (status & KERNEL_PANIC) { char * buffer; struct POSTSTATUS { __le32 Post_Command; @@ -333,15 +333,15 @@ static int aac_rx_check_health(struct aac_dev *dev) dma_addr_t paddr, baddr; int ret; - if (likely((status & 0xFF000000L) == 0xBC000000L)) + if ((status & 0xFF000000L) == 0xBC000000L) return (status >> 16) & 0xFF; buffer = pci_alloc_consistent(dev->pdev, 512, &baddr); ret = -2; - if (unlikely(buffer == NULL)) + if (buffer == NULL) return ret; post = pci_alloc_consistent(dev->pdev, sizeof(struct POSTSTATUS), &paddr); - if (unlikely(post == NULL)) { + if (post == NULL) { pci_free_consistent(dev->pdev, 512, buffer, baddr); return ret; } @@ -353,7 +353,7 @@ static int aac_rx_check_health(struct aac_dev *dev) NULL, NULL, NULL, NULL, NULL); pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), post, paddr); - if (likely((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X')))) { + if ((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X'))) { ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); ret <<= 4; ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); @@ -364,7 +364,7 @@ static int aac_rx_check_health(struct aac_dev *dev) /* * Wait for the adapter to be up and running. */ - if (unlikely(!(status & KERNEL_UP_AND_RUNNING))) + if (!(status & KERNEL_UP_AND_RUNNING)) return -3; /* * Everything is OK @@ -387,7 +387,7 @@ static int aac_rx_deliver_producer(struct fib * fib) unsigned long nointr = 0; spin_lock_irqsave(q->lock, qflags); - aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr); + aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib, 1, fib, &nointr); q->numpending++; *(q->headers.producer) = cpu_to_le32(Index + 1); @@ -419,9 +419,9 @@ static int aac_rx_deliver_message(struct fib * fib) spin_unlock_irqrestore(q->lock, qflags); for(;;) { Index = rx_readl(dev, MUnit.InboundQueue); - if (unlikely(Index == 0xFFFFFFFFL)) + if (Index == 0xFFFFFFFFL) Index = rx_readl(dev, MUnit.InboundQueue); - if (likely(Index != 0xFFFFFFFFL)) + if (Index != 0xFFFFFFFFL) break; if (--count == 0) { spin_lock_irqsave(q->lock, qflags); @@ -437,7 +437,7 @@ static int aac_rx_deliver_message(struct fib * fib) device += sizeof(u32); writel((u32)(addr >> 32), device); device += sizeof(u32); - writel(le16_to_cpu(fib->hw_fib_va->header.Size), device); + writel(le16_to_cpu(fib->hw_fib->header.Size), device); rx_writel(dev, MUnit.InboundQueue, Index); return 0; } @@ -460,34 +460,22 @@ static int aac_rx_ioremap(struct aac_dev * dev, u32 size) return 0; } -static int aac_rx_restart_adapter(struct aac_dev *dev, int bled) +static int aac_rx_restart_adapter(struct aac_dev *dev) { u32 var; - if (bled) - printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n", - dev->name, dev->id, bled); - else { - bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, - 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); - if (!bled && (var != 0x00000001)) - bled = -EINVAL; - } - if (bled && (bled != -ETIMEDOUT)) - bled = aac_adapter_sync_cmd(dev, IOP_RESET, - 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); - - if (bled && (bled != -ETIMEDOUT)) - return -EINVAL; - if (bled || (var == 0x3803000F)) { /* USE_OTHER_METHOD */ - rx_writel(dev, MUnit.reserved2, 3); - msleep(5000); /* Delay 5 seconds */ - var = 0x00000001; - } + printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", + dev->name, dev->id); + + if (aac_rx_check_health(dev) <= 0) + return 1; + if (rx_sync_cmd(dev, IOP_RESET, 0, 0, 0, 0, 0, 0, + &var, NULL, NULL, NULL, NULL)) + return 1; if (var != 0x00000001) - return -EINVAL; + return 1; if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) - return -ENODEV; + return 1; return 0; } @@ -529,29 +517,24 @@ int _aac_rx_init(struct aac_dev *dev) { unsigned long start; unsigned long status; - int restart = 0; - int instance = dev->id; - const char * name = dev->name; + int instance; + const char * name; + + instance = dev->id; + name = dev->name; if (aac_adapter_ioremap(dev, dev->base_size)) { printk(KERN_WARNING "%s: unable to map adapter.\n", name); goto error_iounmap; } - /* Failure to reset here is an option ... */ - dev->OIMR = status = rx_readb (dev, MUnit.OIMR); - if ((((status & 0xff) != 0xff) || reset_devices) && - !aac_rx_restart_adapter(dev, 0)) - ++restart; /* * Check to see if the board panic'd while booting. */ status = rx_readl(dev, MUnit.OMRx[0]); - if (status & KERNEL_PANIC) { - if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev))) + if (status & KERNEL_PANIC) + if (aac_rx_restart_adapter(dev)) goto error_iounmap; - ++restart; - } /* * Check to see if the board failed any self tests. */ @@ -573,23 +556,12 @@ int _aac_rx_init(struct aac_dev *dev) */ while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) { - if ((restart && - (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || - time_after(jiffies, start+HZ*startup_timeout)) { + if(time_after(jiffies, start+startup_timeout*HZ)) + { printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", dev->name, instance, status); goto error_iounmap; } - if (!restart && - ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) || - time_after(jiffies, start + HZ * - ((startup_timeout > 60) - ? (startup_timeout - 60) - : (startup_timeout / 2))))) { - if (likely(!aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))) - start = jiffies; - ++restart; - } msleep(1); } /* @@ -600,7 +572,6 @@ int _aac_rx_init(struct aac_dev *dev) dev->a_ops.adapter_notify = aac_rx_notify_adapter; dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_check_health = aac_rx_check_health; - dev->a_ops.adapter_restart = aac_rx_restart_adapter; /* * First clear out all interrupts. Then enable the one's that we diff --git a/trunk/drivers/scsi/aic7xxx/Kconfig.aic79xx b/trunk/drivers/scsi/aic7xxx/Kconfig.aic79xx index 5e6620f8dabc..911ea1756e55 100644 --- a/trunk/drivers/scsi/aic7xxx/Kconfig.aic79xx +++ b/trunk/drivers/scsi/aic7xxx/Kconfig.aic79xx @@ -57,6 +57,18 @@ config AIC79XX_BUILD_FIRMWARE or modify the assembler Makefile or the files it includes if your build environment is different than that of the author. +config AIC79XX_ENABLE_RD_STRM + bool "Enable Read Streaming for All Targets" + depends on SCSI_AIC79XX + default n + help + Read Streaming is a U320 protocol option that should enhance + performance. Early U320 drive firmware actually performs slower + with read streaming enabled so it is disabled by default. Read + Streaming can be configured in much the same way as tagged queueing + using the "rd_strm" command line option. See + drivers/scsi/aic7xxx/README.aic79xx for details. + config AIC79XX_DEBUG_ENABLE bool "Compile in Debugging Code" depends on SCSI_AIC79XX diff --git a/trunk/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/trunk/drivers/scsi/aic7xxx/Kconfig.aic7xxx index 88da670a7915..cd93f9a8611f 100644 --- a/trunk/drivers/scsi/aic7xxx/Kconfig.aic7xxx +++ b/trunk/drivers/scsi/aic7xxx/Kconfig.aic7xxx @@ -50,6 +50,16 @@ config AIC7XXX_RESET_DELAY_MS Default: 5000 (5 seconds) +config AIC7XXX_PROBE_EISA_VL + bool "Probe for EISA and VL AIC7XXX Adapters" + depends on SCSI_AIC7XXX && EISA + help + Probe for EISA and VLB Aic7xxx controllers. In many newer systems, + the invasive probes necessary to detect these controllers can cause + other devices to fail. For this reason, the non-PCI probe code is + disabled by default. The current value of this option can be "toggled" + via the no_probe kernel command line option. + config AIC7XXX_BUILD_FIRMWARE bool "Build Adapter Firmware with Kernel Build" depends on SCSI_AIC7XXX && !PREVENT_FIRMWARE_BUILD diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c index 6054881f21f1..2be03e975d97 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -363,8 +363,6 @@ static int ahd_linux_run_command(struct ahd_softc*, struct scsi_cmnd *); static void ahd_linux_setup_tag_info_global(char *p); static int aic79xx_setup(char *c); -static void ahd_freeze_simq(struct ahd_softc *ahd); -static void ahd_release_simq(struct ahd_softc *ahd); static int ahd_linux_unit; @@ -2018,13 +2016,13 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd) cmd->scsi_done(cmd); } -static void +void ahd_freeze_simq(struct ahd_softc *ahd) { scsi_block_requests(ahd->platform_data->host); } -static void +void ahd_release_simq(struct ahd_softc *ahd) { scsi_unblock_requests(ahd->platform_data->host); diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h index 9218f29314fa..147c83c456a5 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -837,6 +837,8 @@ int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); void ahd_platform_free(struct ahd_softc *ahd); void ahd_platform_init(struct ahd_softc *ahd); void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb); +void ahd_freeze_simq(struct ahd_softc *ahd); +void ahd_release_simq(struct ahd_softc *ahd); static __inline void ahd_freeze_scb(struct scb *scb) diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx.h b/trunk/drivers/scsi/aic7xxx/aic7xxx.h index e1bd57b9f23d..954c7c24501d 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx.h +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx.h @@ -1278,6 +1278,11 @@ typedef enum { AHC_QUEUE_TAGGED } ahc_queue_alg; +void ahc_set_tags(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + ahc_queue_alg alg); + /**************************** Target Mode *************************************/ #ifdef AHC_TARGET_MODE void ahc_send_lstate_events(struct ahc_softc *, diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c index 75733b09f27a..50ef785224de 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -2073,7 +2073,7 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, /* * Update the current state of tagged queuing for a given target. */ -static void +void ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd, struct ahc_devinfo *devinfo, ahc_queue_alg alg) { diff --git a/trunk/drivers/scsi/constants.c b/trunk/drivers/scsi/constants.c index 2a458d66b6ff..61f6024b61ba 100644 --- a/trunk/drivers/scsi/constants.c +++ b/trunk/drivers/scsi/constants.c @@ -202,29 +202,31 @@ static const char * get_sa_name(const struct value_name_pair * arr, } /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ -static void print_opcode_name(unsigned char * cdbp, int cdb_len) +static void print_opcode_name(unsigned char * cdbp, int cdb_len, + int start_of_line) { int sa, len, cdb0; const char * name; + const char * leadin = start_of_line ? KERN_INFO : ""; cdb0 = cdbp[0]; switch(cdb0) { case VARIABLE_LENGTH_CMD: len = cdbp[7] + 8; if (len < 10) { - printk("short variable length command, " - "len=%d ext_len=%d", len, cdb_len); + printk("%sshort variable length command, " + "len=%d ext_len=%d", leadin, len, cdb_len); break; } sa = (cdbp[8] << 8) + cdbp[9]; name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); if (name) { - printk("%s", name); + printk("%s%s", leadin, name); if ((cdb_len > 0) && (len != cdb_len)) printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); } else { - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); if ((cdb_len > 0) && (len != cdb_len)) printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); @@ -234,80 +236,83 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) sa = cdbp[1] & 0x1f; name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case MAINTENANCE_OUT: sa = cdbp[1] & 0x1f; name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case SERVICE_ACTION_IN_12: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case SERVICE_ACTION_OUT_12: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case SERVICE_ACTION_IN_16: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case SERVICE_ACTION_OUT_16: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; default: if (cdb0 < 0xc0) { name = cdb_byte0_names[cdb0]; if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x (reserved)", cdb0); + printk("%scdb[0]=0x%x (reserved)", + leadin, cdb0); } else - printk("cdb[0]=0x%x (vendor)", cdb0); + printk("%scdb[0]=0x%x (vendor)", leadin, cdb0); break; } } #else /* ifndef CONFIG_SCSI_CONSTANTS */ -static void print_opcode_name(unsigned char * cdbp, int cdb_len) +static void print_opcode_name(unsigned char * cdbp, int cdb_len, + int start_of_line) { int sa, len, cdb0; + const char * leadin = start_of_line ? KERN_INFO : ""; cdb0 = cdbp[0]; switch(cdb0) { case VARIABLE_LENGTH_CMD: len = cdbp[7] + 8; if (len < 10) { - printk("short opcode=0x%x command, len=%d " - "ext_len=%d", cdb0, len, cdb_len); + printk("%sshort opcode=0x%x command, len=%d " + "ext_len=%d", leadin, cdb0, len, cdb_len); break; } sa = (cdbp[8] << 8) + cdbp[9]; - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); if (len != cdb_len) printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); break; @@ -318,48 +323,49 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) case SERVICE_ACTION_IN_16: case SERVICE_ACTION_OUT_16: sa = cdbp[1] & 0x1f; - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; default: if (cdb0 < 0xc0) - printk("cdb[0]=0x%x", cdb0); + printk("%scdb[0]=0x%x", leadin, cdb0); else - printk("cdb[0]=0x%x (vendor)", cdb0); + printk("%scdb[0]=0x%x (vendor)", leadin, cdb0); break; } } #endif -void __scsi_print_command(unsigned char *cdb) +void __scsi_print_command(unsigned char *command) { int k, len; - print_opcode_name(cdb, 0); - if (VARIABLE_LENGTH_CMD == cdb[0]) - len = cdb[7] + 8; + print_opcode_name(command, 0, 1); + if (VARIABLE_LENGTH_CMD == command[0]) + len = command[7] + 8; else - len = COMMAND_SIZE(cdb[0]); + len = COMMAND_SIZE(command[0]); /* print out all bytes in cdb */ for (k = 0; k < len; ++k) - printk(" %02x", cdb[k]); + printk(" %02x", command[k]); printk("\n"); } EXPORT_SYMBOL(__scsi_print_command); -void scsi_print_command(struct scsi_cmnd *cmd) +/* This function (perhaps with the addition of peripheral device type) + * is more approriate than __scsi_print_command(). Perhaps that static + * can be dropped later if it replaces the __scsi_print_command version. + */ +static void scsi_print_cdb(unsigned char *cdb, int cdb_len, int start_of_line) { int k; - scmd_printk(KERN_INFO, cmd, "CDB: "); - print_opcode_name(cmd->cmnd, cmd->cmd_len); - + print_opcode_name(cdb, cdb_len, start_of_line); /* print out all bytes in cdb */ printk(":"); - for (k = 0; k < cmd->cmd_len; ++k) - printk(" %02x", cmd->cmnd[k]); + for (k = 0; k < cdb_len; ++k) + printk(" %02x", cdb[k]); printk("\n"); } -EXPORT_SYMBOL(scsi_print_command); /** * @@ -404,11 +410,7 @@ struct error_info { const char * text; }; -/* - * The canonical list of T10 Additional Sense Codes is available at: - * http://www.t10.org/lists/asc-num.txt - */ -static const struct error_info additional[] = +static struct error_info additional[] = { {0x0000, "No additional sense information"}, {0x0001, "Filemark detected"}, @@ -712,7 +714,6 @@ static const struct error_info additional[] = {0x2F00, "Commands cleared by another initiator"}, {0x2F01, "Commands cleared by power loss notification"}, - {0x2F02, "Commands cleared by device server"}, {0x3000, "Incompatible medium installed"}, {0x3001, "Cannot read medium - unknown format"}, @@ -1175,77 +1176,67 @@ scsi_extd_sense_format(unsigned char asc, unsigned char ascq) { } EXPORT_SYMBOL(scsi_extd_sense_format); -void +/* Print extended sense information; no leadin, no linefeed */ +static void scsi_show_extd_sense(unsigned char asc, unsigned char ascq) { - const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq); + const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq); if (extd_sense_fmt) { if (strstr(extd_sense_fmt, "%x")) { - printk("Add. Sense: "); + printk("Additional sense: "); printk(extd_sense_fmt, ascq); } else - printk("Add. Sense: %s", extd_sense_fmt); + printk("Additional sense: %s", extd_sense_fmt); } else { if (asc >= 0x80) - printk("<> ASC=0x%x ASCQ=0x%x", asc, - ascq); + printk("<> ASC=0x%x ASCQ=0x%x", asc, ascq); if (ascq >= 0x80) - printk("ASC=0x%x <> ASCQ=0x%x", asc, - ascq); + printk("ASC=0x%x <> ASCQ=0x%x", asc, ascq); else printk("ASC=0x%x ASCQ=0x%x", asc, ascq); } - - printk("\n"); } -EXPORT_SYMBOL(scsi_show_extd_sense); void -scsi_show_sense_hdr(struct scsi_sense_hdr *sshdr) +scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) { const char *sense_txt; + /* An example of deferred is when an earlier write to disk cache + * succeeded, but now the disk discovers that it cannot write the + * data to the magnetic media. + */ + const char *error = scsi_sense_is_deferred(sshdr) ? + "<>" : "Current"; + printk(KERN_INFO "%s: %s", name, error); + if (sshdr->response_code >= 0x72) + printk(" [descriptor]"); sense_txt = scsi_sense_key_string(sshdr->sense_key); if (sense_txt) - printk("Sense Key : %s ", sense_txt); + printk(": sense key: %s\n", sense_txt); else - printk("Sense Key : 0x%x ", sshdr->sense_key); - - printk("%s", scsi_sense_is_deferred(sshdr) ? "[deferred] " : - "[current] "); - - if (sshdr->response_code >= 0x72) - printk("[descriptor]"); - - printk("\n"); -} -EXPORT_SYMBOL(scsi_show_sense_hdr); - -/* - * Print normalized SCSI sense header with a prefix. - */ -void -scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) -{ - printk(KERN_INFO "%s: ", name); - scsi_show_sense_hdr(sshdr); - printk(KERN_INFO "%s: ", name); + printk(": sense key=0x%x\n", sshdr->sense_key); + printk(KERN_INFO " "); scsi_show_extd_sense(sshdr->asc, sshdr->ascq); + printk("\n"); } EXPORT_SYMBOL(scsi_print_sense_hdr); +/* Print sense information */ void -scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, - struct scsi_sense_hdr *sshdr) +__scsi_print_sense(const char *name, const unsigned char *sense_buffer, + int sense_len) { int k, num, res; + unsigned int info; + struct scsi_sense_hdr ssh; - res = scsi_normalize_sense(sense_buffer, sense_len, sshdr); + res = scsi_normalize_sense(sense_buffer, sense_len, &ssh); if (0 == res) { /* this may be SCSI-1 sense data */ num = (sense_len < 32) ? sense_len : 32; - printk("Unrecognized sense data (in hex):"); + printk(KERN_INFO "Unrecognized sense data (in hex):"); for (k = 0; k < num; ++k) { if (0 == (k % 16)) { printk("\n"); @@ -1256,20 +1247,11 @@ scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, printk("\n"); return; } -} - -void -scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, - struct scsi_sense_hdr *sshdr) -{ - int k, num, res; - - if (sshdr->response_code < 0x72) - { + scsi_print_sense_hdr(name, &ssh); + if (ssh.response_code < 0x72) { /* only decode extras for "fixed" format now */ char buff[80]; int blen, fixed_valid; - unsigned int info; fixed_valid = sense_buffer[0] & 0x80; info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) | @@ -1299,13 +1281,13 @@ scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, res += snprintf(buff + res, blen - res, "ILI"); } if (res > 0) - printk("%s\n", buff); - } else if (sshdr->additional_length > 0) { + printk(KERN_INFO "%s\n", buff); + } else if (ssh.additional_length > 0) { /* descriptor format with sense descriptors */ - num = 8 + sshdr->additional_length; + num = 8 + ssh.additional_length; num = (sense_len < num) ? sense_len : num; - printk("Descriptor sense data with sense descriptors " - "(in hex):"); + printk(KERN_INFO "Descriptor sense data with sense " + "descriptors (in hex):"); for (k = 0; k < num; ++k) { if (0 == (k % 16)) { printk("\n"); @@ -1313,42 +1295,29 @@ scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, } printk("%02x ", sense_buffer[k]); } - printk("\n"); } - } +EXPORT_SYMBOL(__scsi_print_sense); -/* Normalize and print sense buffer with name prefix */ -void __scsi_print_sense(const char *name, const unsigned char *sense_buffer, - int sense_len) +void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd) { - struct scsi_sense_hdr sshdr; - - printk(KERN_INFO "%s: ", name); - scsi_decode_sense_buffer(sense_buffer, sense_len, &sshdr); - scsi_show_sense_hdr(&sshdr); - scsi_decode_sense_extras(sense_buffer, sense_len, &sshdr); - printk(KERN_INFO "%s: ", name); - scsi_show_extd_sense(sshdr.asc, sshdr.ascq); + const char *name = devclass; + + if (cmd->request->rq_disk) + name = cmd->request->rq_disk->disk_name; + __scsi_print_sense(name, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); } -EXPORT_SYMBOL(__scsi_print_sense); +EXPORT_SYMBOL(scsi_print_sense); -/* Normalize and print sense buffer in SCSI command */ -void scsi_print_sense(char *name, struct scsi_cmnd *cmd) +void scsi_print_command(struct scsi_cmnd *cmd) { - struct scsi_sense_hdr sshdr; - - scmd_printk(KERN_INFO, cmd, ""); - scsi_decode_sense_buffer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, - &sshdr); - scsi_show_sense_hdr(&sshdr); - scsi_decode_sense_extras(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, - &sshdr); - scmd_printk(KERN_INFO, cmd, ""); - scsi_show_extd_sense(sshdr.asc, sshdr.ascq); + /* Assume appended output (i.e. not at start of line) */ + sdev_printk("", cmd->device, "\n"); + printk(KERN_INFO " command: "); + scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0); } -EXPORT_SYMBOL(scsi_print_sense); +EXPORT_SYMBOL(scsi_print_command); #ifdef CONFIG_SCSI_CONSTANTS @@ -1358,6 +1327,25 @@ static const char * const hostbyte_table[]={ "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"}; #define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) +void scsi_print_hostbyte(int scsiresult) +{ + int hb = host_byte(scsiresult); + + printk("Hostbyte=0x%02x", hb); + if (hb < NUM_HOSTBYTE_STRS) + printk("(%s) ", hostbyte_table[hb]); + else + printk("is invalid "); +} +#else +void scsi_print_hostbyte(int scsiresult) +{ + printk("Hostbyte=0x%02x ", host_byte(scsiresult)); +} +#endif + +#ifdef CONFIG_SCSI_CONSTANTS + static const char * const driverbyte_table[]={ "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; @@ -1368,35 +1356,19 @@ static const char * const driversuggest_table[]={"SUGGEST_OK", "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"}; #define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table) -void scsi_show_result(int result) +void scsi_print_driverbyte(int scsiresult) { - int hb = host_byte(result); - int db = (driver_byte(result) & DRIVER_MASK); - int su = ((driver_byte(result) & SUGGEST_MASK) >> 4); + int dr = (driver_byte(scsiresult) & DRIVER_MASK); + int su = ((driver_byte(scsiresult) & SUGGEST_MASK) >> 4); - printk("Result: hostbyte=%s driverbyte=%s,%s\n", - (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb] : "invalid"), - (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"), + printk("Driverbyte=0x%02x ", driver_byte(scsiresult)); + printk("(%s,%s) ", + (dr < NUM_DRIVERBYTE_STRS ? driverbyte_table[dr] : "invalid"), (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid")); } - #else - -void scsi_show_result(int result) +void scsi_print_driverbyte(int scsiresult) { - printk("Result: hostbyte=0x%02x driverbyte=0x%02x\n", - host_byte(result), driver_byte(result)); + printk("Driverbyte=0x%02x ", driver_byte(scsiresult)); } - #endif -EXPORT_SYMBOL(scsi_show_result); - - -void scsi_print_result(struct scsi_cmnd *cmd) -{ - scmd_printk(KERN_INFO, cmd, ""); - scsi_show_result(cmd->result); -} -EXPORT_SYMBOL(scsi_print_result); - - diff --git a/trunk/drivers/scsi/dpt/dpti_i2o.h b/trunk/drivers/scsi/dpt/dpti_i2o.h index 100b49baca7f..5a49216fe4cf 100644 --- a/trunk/drivers/scsi/dpt/dpti_i2o.h +++ b/trunk/drivers/scsi/dpt/dpti_i2o.h @@ -31,7 +31,7 @@ * Tunable parameters first */ -/* How many different OSM's are we allowing */ +/* How many different OSM's are we allowing */ #define MAX_I2O_MODULES 64 #define I2O_EVT_CAPABILITY_OTHER 0x01 @@ -63,7 +63,7 @@ struct i2o_message u16 size; u32 target_tid:12; u32 init_tid:12; - u32 function:8; + u32 function:8; u32 initiator_context; /* List follows */ }; @@ -77,7 +77,7 @@ struct i2o_device char dev_name[8]; /* linux /dev name if available */ i2o_lct_entry lct_data;/* Device LCT information */ - u32 flags; + u32 flags; struct proc_dir_entry* proc_entry; /* /proc dir */ struct adpt_device *owner; struct _adpt_hba *controller; /* Controlling IOP */ @@ -86,7 +86,7 @@ struct i2o_device /* * Each I2O controller has one of these objects */ - + struct i2o_controller { char name[16]; @@ -111,9 +111,9 @@ struct i2o_sys_tbl_entry u32 iop_id:12; u32 reserved2:20; u16 seg_num:12; - u16 i2o_version:4; - u8 iop_state; - u8 msg_type; + u16 i2o_version:4; + u8 iop_state; + u8 msg_type; u16 frame_size; u16 reserved3; u32 last_changed; @@ -124,14 +124,14 @@ struct i2o_sys_tbl_entry struct i2o_sys_tbl { - u8 num_entries; - u8 version; - u16 reserved1; + u8 num_entries; + u8 version; + u16 reserved1; u32 change_ind; u32 reserved2; u32 reserved3; struct i2o_sys_tbl_entry iops[0]; -}; +}; /* * I2O classes / subclasses @@ -146,7 +146,7 @@ struct i2o_sys_tbl /* Class code names * (from v1.5 Table 6-1 Class Code Assignments.) */ - + #define I2O_CLASS_EXECUTIVE 0x000 #define I2O_CLASS_DDM 0x001 #define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010 @@ -166,7 +166,7 @@ struct i2o_sys_tbl /* Rest of 0x092 - 0x09f reserved for peer-to-peer classes */ - + #define I2O_CLASS_MATCH_ANYCLASS 0xffffffff /* Subclasses @@ -175,7 +175,7 @@ struct i2o_sys_tbl #define I2O_SUBCLASS_i960 0x001 #define I2O_SUBCLASS_HDM 0x020 #define I2O_SUBCLASS_ISM 0x021 - + /* Operation functions */ #define I2O_PARAMS_FIELD_GET 0x0001 @@ -219,7 +219,7 @@ struct i2o_sys_tbl /* * Messaging API values */ - + #define I2O_CMD_ADAPTER_ASSIGN 0xB3 #define I2O_CMD_ADAPTER_READ 0xB2 #define I2O_CMD_ADAPTER_RELEASE 0xB5 @@ -284,16 +284,16 @@ struct i2o_sys_tbl #define I2O_PRIVATE_MSG 0xFF /* - * Init Outbound Q status + * Init Outbound Q status */ - + #define I2O_CMD_OUTBOUND_INIT_IN_PROGRESS 0x01 #define I2O_CMD_OUTBOUND_INIT_REJECTED 0x02 #define I2O_CMD_OUTBOUND_INIT_FAILED 0x03 #define I2O_CMD_OUTBOUND_INIT_COMPLETE 0x04 /* - * I2O Get Status State values + * I2O Get Status State values */ #define ADAPTER_STATE_INITIALIZING 0x01 @@ -303,7 +303,7 @@ struct i2o_sys_tbl #define ADAPTER_STATE_OPERATIONAL 0x08 #define ADAPTER_STATE_FAILED 0x10 #define ADAPTER_STATE_FAULTED 0x11 - + /* I2O API function return values */ #define I2O_RTN_NO_ERROR 0 @@ -321,9 +321,9 @@ struct i2o_sys_tbl /* Reply message status defines for all messages */ -#define I2O_REPLY_STATUS_SUCCESS 0x00 -#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01 -#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02 +#define I2O_REPLY_STATUS_SUCCESS 0x00 +#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01 +#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02 #define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03 #define I2O_REPLY_STATUS_ERROR_DIRTY 0x04 #define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05 @@ -338,7 +338,7 @@ struct i2o_sys_tbl #define I2O_PARAMS_STATUS_SUCCESS 0x00 #define I2O_PARAMS_STATUS_BAD_KEY_ABORT 0x01 -#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE 0x02 +#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE 0x02 #define I2O_PARAMS_STATUS_BUFFER_FULL 0x03 #define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL 0x04 #define I2O_PARAMS_STATUS_FIELD_UNREADABLE 0x05 @@ -390,7 +390,7 @@ struct i2o_sys_tbl #define I2O_CLAIM_MANAGEMENT 0x02000000 #define I2O_CLAIM_AUTHORIZED 0x03000000 #define I2O_CLAIM_SECONDARY 0x04000000 - + /* Message header defines for VersionOffset */ #define I2OVER15 0x0001 #define I2OVER20 0x0002 diff --git a/trunk/drivers/scsi/dpt/dpti_ioctl.h b/trunk/drivers/scsi/dpt/dpti_ioctl.h index cc784e8f6e9d..82d24864be0c 100644 --- a/trunk/drivers/scsi/dpt/dpti_ioctl.h +++ b/trunk/drivers/scsi/dpt/dpti_ioctl.h @@ -99,7 +99,7 @@ typedef struct { uCHAR eataVersion; /* EATA Version */ uLONG cpLength; /* EATA Command Packet Length */ uLONG spLength; /* EATA Status Packet Length */ - uCHAR drqNum; /* DRQ Index (0,5,6,7) */ + uCHAR drqNum; /* DRQ Index (0,5,6,7) */ uCHAR flag1; /* EATA Flags 1 (Byte 9) */ uCHAR flag2; /* EATA Flags 2 (Byte 30) */ } CtrlInfo; diff --git a/trunk/drivers/scsi/dpt/dptsig.h b/trunk/drivers/scsi/dpt/dptsig.h index 94bc894d1200..4bf447792129 100644 --- a/trunk/drivers/scsi/dpt/dptsig.h +++ b/trunk/drivers/scsi/dpt/dptsig.h @@ -145,8 +145,8 @@ typedef unsigned long sigLONG; #define FT_LOGGER 12 /* Event Logger */ #define FT_INSTALL 13 /* An Install Program */ #define FT_LIBRARY 14 /* Storage Manager Real-Mode Calls */ -#define FT_RESOURCE 15 /* Storage Manager Resource File */ -#define FT_MODEM_DB 16 /* Storage Manager Modem Database */ +#define FT_RESOURCE 15 /* Storage Manager Resource File */ +#define FT_MODEM_DB 16 /* Storage Manager Modem Database */ /* Filetype flags - sigBYTE dsFiletypeFlags; FLAG BITS */ /* ------------------------------------------------------------------ */ diff --git a/trunk/drivers/scsi/dpt_i2o.c b/trunk/drivers/scsi/dpt_i2o.c index f7b9dbd64a96..cd36e81b2d93 100644 --- a/trunk/drivers/scsi/dpt_i2o.c +++ b/trunk/drivers/scsi/dpt_i2o.c @@ -195,6 +195,8 @@ static int adpt_detect(struct scsi_host_template* sht) pci_dev_get(pDev); } } + if (pDev) + pci_dev_put(pDev); /* In INIT state, Activate IOPs */ for (pHba = hba_chain; pHba; pHba = pHba->next) { diff --git a/trunk/drivers/scsi/eata_generic.h b/trunk/drivers/scsi/eata_generic.h index 5016af5cf860..635c14861f86 100644 --- a/trunk/drivers/scsi/eata_generic.h +++ b/trunk/drivers/scsi/eata_generic.h @@ -18,6 +18,13 @@ * Misc. definitions * *********************************************/ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + #define R_LIMIT 0x20000 #define MAXISA 4 diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index b10eefe735c5..fbc1d5c3b0a7 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -85,7 +85,7 @@ static int max_id = 64; static int max_channel = 3; static int init_timeout = 5; -static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; +static int max_requests = 50; #define IBMVSCSI_VERSION "1.5.8" @@ -538,8 +538,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, int request_status; int rc; - /* If we have exhausted our request limit, just fail this request, - * unless it is for a reset or abort. + /* If we have exhausted our request limit, just fail this request. * Note that there are rare cases involving driver generated requests * (such as task management requests) that the mid layer may think we * can handle more requests (can_queue) when we actually can't @@ -552,30 +551,9 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, */ if (request_status < -1) goto send_error; - /* Otherwise, we may have run out of requests. */ - /* Abort and reset calls should make it through. - * Nothing except abort and reset should use the last two - * slots unless we had two or less to begin with. - */ - else if (request_status < 2 && - evt_struct->iu.srp.cmd.opcode != SRP_TSK_MGMT) { - /* In the case that we have less than two requests - * available, check the server limit as a combination - * of the request limit and the number of requests - * in-flight (the size of the send list). If the - * server limit is greater than 2, return busy so - * that the last two are reserved for reset and abort. - */ - int server_limit = request_status; - struct srp_event_struct *tmp_evt; - - list_for_each_entry(tmp_evt, &hostdata->sent, list) { - server_limit++; - } - - if (server_limit > 2) - goto send_busy; - } + /* Otherwise, if we have run out of requests */ + else if (request_status < 0) + goto send_busy; } /* Copy the IU into the transfer area */ @@ -594,7 +572,6 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, printk(KERN_ERR "ibmvscsi: send error %d\n", rc); - atomic_inc(&hostdata->request_limit); goto send_error; } @@ -604,8 +581,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); free_event_struct(&hostdata->pool, evt_struct); - atomic_inc(&hostdata->request_limit); - return SCSI_MLQUEUE_HOST_BUSY; + return SCSI_MLQUEUE_HOST_BUSY; send_error: unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); @@ -855,16 +831,23 @@ static void login_rsp(struct srp_event_struct *evt_struct) printk(KERN_INFO "ibmvscsi: SRP_LOGIN succeeded\n"); - if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta < 0) - printk(KERN_ERR "ibmvscsi: Invalid request_limit.\n"); + if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta > + (max_requests - 2)) + evt_struct->xfer_iu->srp.login_rsp.req_lim_delta = + max_requests - 2; - /* Now we know what the real request-limit is. - * This value is set rather than added to request_limit because - * request_limit could have been set to -1 by this client. - */ + /* Now we know what the real request-limit is */ atomic_set(&hostdata->request_limit, evt_struct->xfer_iu->srp.login_rsp.req_lim_delta); + hostdata->host->can_queue = + evt_struct->xfer_iu->srp.login_rsp.req_lim_delta - 2; + + if (hostdata->host->can_queue < 1) { + printk(KERN_ERR "ibmvscsi: Invalid request_limit_delta\n"); + return; + } + /* If we had any pending I/Os, kick them */ scsi_unblock_requests(hostdata->host); @@ -1354,27 +1337,6 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, return rc; } -/** - * ibmvscsi_slave_configure: Set the "allow_restart" flag for each disk. - * @sdev: struct scsi_device device to configure - * - * Enable allow_restart for a device if it is a disk. Adjust the - * queue_depth here also as is required by the documentation for - * struct scsi_host_template. - */ -static int ibmvscsi_slave_configure(struct scsi_device *sdev) -{ - struct Scsi_Host *shost = sdev->host; - unsigned long lock_flags = 0; - - spin_lock_irqsave(shost->host_lock, lock_flags); - if (sdev->type == TYPE_DISK) - sdev->allow_restart = 1; - scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun); - spin_unlock_irqrestore(shost->host_lock, lock_flags); - return 0; -} - /* ------------------------------------------------------------ * sysfs attributes */ @@ -1520,9 +1482,8 @@ static struct scsi_host_template driver_template = { .queuecommand = ibmvscsi_queuecommand, .eh_abort_handler = ibmvscsi_eh_abort_handler, .eh_device_reset_handler = ibmvscsi_eh_device_reset_handler, - .slave_configure = ibmvscsi_slave_configure, .cmd_per_lun = 16, - .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, + .can_queue = 1, /* Updated after SRP_LOGIN */ .this_id = -1, .sg_tablesize = SG_ALL, .use_clustering = ENABLE_CLUSTERING, @@ -1542,7 +1503,6 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) vdev->dev.driver_data = NULL; - driver_template.can_queue = max_requests; host = scsi_host_alloc(&driver_template, sizeof(*hostdata)); if (!host) { printk(KERN_ERR "ibmvscsi: couldn't allocate host data\n"); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.h b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.h index 77cc1d40f5bb..5c6d93582929 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -44,8 +44,6 @@ struct Scsi_Host; */ #define MAX_INDIRECT_BUFS 10 -#define IBMVSCSI_MAX_REQUESTS_DEFAULT 100 - /* ------------------------------------------------------------ * Data Structures */ diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c b/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c index 6d223dd76440..a39a478bb39a 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -35,7 +35,7 @@ #include "ibmvscsi.h" #define INITIAL_SRP_LIMIT 16 -#define DEFAULT_MAX_SECTORS 256 +#define DEFAULT_MAX_SECTORS 512 #define TGT_NAME "ibmvstgt" @@ -248,8 +248,8 @@ static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg, md[i].va + mdone); if (err != H_SUCCESS) { - eprintk("rdma error %d %d %ld\n", dir, slen, err); - return -EIO; + eprintk("rdma error %d %d\n", dir, slen); + goto out; } mlen -= slen; @@ -265,35 +265,45 @@ static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg, if (sidx > nsg) { eprintk("out of sg %p %d %d\n", iue, sidx, nsg); - return -EIO; + goto out; } } }; rest -= mlen; } +out: + return 0; } +static int ibmvstgt_transfer_data(struct scsi_cmnd *sc, + void (*done)(struct scsi_cmnd *)) +{ + struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; + int err; + + err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); + + done(sc); + + return err; +} + static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) { unsigned long flags; struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; struct srp_target *target = iue->target; - int err = 0; - - dprintk("%p %p %x %u\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0], - cmd->usg_sg); - if (sc->use_sg) - err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); + dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); spin_lock_irqsave(&target->lock, flags); list_del(&iue->ilist); spin_unlock_irqrestore(&target->lock, flags); - if (err|| sc->result != SAM_STAT_GOOD) { + if (sc->result != SAM_STAT_GOOD) { eprintk("operation failed %p %d %x\n", iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]); send_rsp(iue, sc, HARDWARE_ERROR, 0x00); @@ -493,8 +503,7 @@ static void process_iu(struct viosrp_crq *crq, struct srp_target *target) { struct vio_port *vport = target_to_port(target); struct iu_entry *iue; - long err; - int done = 1; + long err, done; iue = srp_iu_get(target); if (!iue) { @@ -509,6 +518,7 @@ static void process_iu(struct viosrp_crq *crq, struct srp_target *target) if (err != H_SUCCESS) { eprintk("%ld transferring data error %p\n", err, iue); + done = 1; goto out; } @@ -784,6 +794,7 @@ static struct scsi_host_template ibmvstgt_sht = { .use_clustering = DISABLE_CLUSTERING, .max_sectors = DEFAULT_MAX_SECTORS, .transfer_response = ibmvstgt_cmd_done, + .transfer_data = ibmvstgt_transfer_data, .eh_abort_handler = ibmvstgt_eh_abort_handler, .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, .shost_attrs = ibmvstgt_attrs, diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 2c7b77e833f9..e9bd29975db4 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -89,9 +89,10 @@ static unsigned int ipr_log_level = IPR_DEFAULT_LOG_LEVEL; static unsigned int ipr_max_speed = 1; static int ipr_testmode = 0; static unsigned int ipr_fastfail = 0; -static unsigned int ipr_transop_timeout = 0; +static unsigned int ipr_transop_timeout = IPR_OPERATIONAL_TIMEOUT; static unsigned int ipr_enable_cache = 1; static unsigned int ipr_debug = 0; +static int ipr_auto_create = 1; static DEFINE_SPINLOCK(ipr_driver_lock); /* This table describes the differences between DMA controller chips */ @@ -158,13 +159,15 @@ module_param_named(enable_cache, ipr_enable_cache, int, 0); MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); module_param_named(debug, ipr_debug, int, 0); MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); +module_param_named(auto_create, ipr_auto_create, int, 0); +MODULE_PARM_DESC(auto_create, "Auto-create single device RAID 0 arrays when initialized (default: 1)"); MODULE_LICENSE("GPL"); MODULE_VERSION(IPR_DRIVER_VERSION); /* A constant array of IOASCs/URCs/Error Messages */ static const struct ipr_error_table_t ipr_error_table[] = { - {0x00000000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x00000000, 1, 1, "8155: An unknown error was received"}, {0x00330000, 0, 0, "Soft underlength error"}, @@ -172,37 +175,37 @@ struct ipr_error_table_t ipr_error_table[] = { "Command to be cancelled not found"}, {0x00808000, 0, 0, "Qualified success"}, - {0x01080000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x01080000, 1, 1, "FFFE: Soft device bus error recovered by the IOA"}, - {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01088100, 0, 1, "4101: Soft device bus fabric error"}, - {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01170600, 0, 1, "FFF9: Device sector reassign successful"}, - {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01170900, 0, 1, "FFF7: Media error recovered by device rewrite procedures"}, - {0x01180200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01180200, 0, 1, "7001: IOA sector reassignment successful"}, - {0x01180500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01180500, 0, 1, "FFF9: Soft media error. Sector reassignment recommended"}, - {0x01180600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01180600, 0, 1, "FFF7: Media error recovered by IOA rewrite procedures"}, - {0x01418000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01418000, 0, 1, "FF3D: Soft PCI bus error recovered by the IOA"}, - {0x01440000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x01440000, 1, 1, "FFF6: Device hardware error recovered by the IOA"}, - {0x01448100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01448100, 0, 1, "FFF6: Device hardware error recovered by the device"}, - {0x01448200, 1, IPR_DEFAULT_LOG_LEVEL, + {0x01448200, 1, 1, "FF3D: Soft IOA error recovered by the IOA"}, - {0x01448300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01448300, 0, 1, "FFFA: Undefined device response recovered by the IOA"}, - {0x014A0000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x014A0000, 1, 1, "FFF6: Device bus error, message or command phase"}, - {0x014A8000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x014A8000, 0, 1, "FFFE: Task Management Function failed"}, - {0x015D0000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x015D0000, 0, 1, "FFF6: Failure prediction threshold exceeded"}, - {0x015D9200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x015D9200, 0, 1, "8009: Impending cache battery pack failure"}, {0x02040400, 0, 0, "34FF: Disk device format in progress"}, @@ -212,85 +215,85 @@ struct ipr_error_table_t ipr_error_table[] = { "No ready, IOA shutdown"}, {0x025A0000, 0, 0, "Not ready, IOA has been shutdown"}, - {0x02670100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x02670100, 0, 1, "3020: Storage subsystem configuration error"}, {0x03110B00, 0, 0, "FFF5: Medium error, data unreadable, recommend reassign"}, {0x03110C00, 0, 0, "7000: Medium error, data unreadable, do not reassign"}, - {0x03310000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x03310000, 0, 1, "FFF3: Disk media format bad"}, - {0x04050000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04050000, 0, 1, "3002: Addressed device failed to respond to selection"}, - {0x04080000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04080000, 1, 1, "3100: Device bus error"}, - {0x04080100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04080100, 0, 1, "3109: IOA timed out a device command"}, {0x04088000, 0, 0, "3120: SCSI bus is not operational"}, - {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04088100, 0, 1, "4100: Hard device bus fabric error"}, - {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04118000, 0, 1, "9000: IOA reserved area data check"}, - {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04118100, 0, 1, "9001: IOA reserved area invalid data pattern"}, - {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04118200, 0, 1, "9002: IOA reserved area LRC error"}, - {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04320000, 0, 1, "102E: Out of alternate sectors for disk storage"}, - {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04330000, 1, 1, "FFF4: Data transfer underlength error"}, - {0x04338000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04338000, 1, 1, "FFF4: Data transfer overlength error"}, - {0x043E0100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x043E0100, 0, 1, "3400: Logical unit failure"}, - {0x04408500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04408500, 0, 1, "FFF4: Device microcode is corrupt"}, - {0x04418000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04418000, 1, 1, "8150: PCI bus error"}, {0x04430000, 1, 0, "Unsupported device bus message received"}, - {0x04440000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04440000, 1, 1, "FFF4: Disk device problem"}, - {0x04448200, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04448200, 1, 1, "8150: Permanent IOA failure"}, - {0x04448300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04448300, 0, 1, "3010: Disk device returned wrong response to IOA"}, - {0x04448400, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04448400, 0, 1, "8151: IOA microcode error"}, {0x04448500, 0, 0, "Device bus status error"}, - {0x04448600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04448600, 0, 1, "8157: IOA error requiring IOA reset to recover"}, {0x04448700, 0, 0, "ATA device status error"}, {0x04490000, 0, 0, "Message reject received from the device"}, - {0x04449200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04449200, 0, 1, "8008: A permanent cache battery pack failure occurred"}, - {0x0444A000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x0444A000, 0, 1, "9090: Disk unit has been modified after the last known status"}, - {0x0444A200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x0444A200, 0, 1, "9081: IOA detected device error"}, - {0x0444A300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x0444A300, 0, 1, "9082: IOA detected device error"}, - {0x044A0000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x044A0000, 1, 1, "3110: Device bus error, message or command phase"}, - {0x044A8000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x044A8000, 1, 1, "3110: SAS Command / Task Management Function failed"}, - {0x04670400, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04670400, 0, 1, "9091: Incorrect hardware configuration change has been detected"}, - {0x04678000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04678000, 0, 1, "9073: Invalid multi-adapter configuration"}, - {0x04678100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04678100, 0, 1, "4010: Incorrect connection between cascaded expanders"}, - {0x04678200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04678200, 0, 1, "4020: Connections exceed IOA design limits"}, - {0x04678300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04678300, 0, 1, "4030: Incorrect multipath connection"}, - {0x04679000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04679000, 0, 1, "4110: Unsupported enclosure function"}, - {0x046E0000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x046E0000, 0, 1, "FFF4: Command to logical unit failed"}, {0x05240000, 1, 0, "Illegal request, invalid request type or request packet"}, @@ -310,103 +313,101 @@ struct ipr_error_table_t ipr_error_table[] = { "Illegal request, command sequence error"}, {0x052C8000, 1, 0, "Illegal request, dual adapter support not enabled"}, - {0x06040500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06040500, 0, 1, "9031: Array protection temporarily suspended, protection resuming"}, - {0x06040600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06040600, 0, 1, "9040: Array protection temporarily suspended, protection resuming"}, - {0x06288000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06288000, 0, 1, "3140: Device bus not ready to ready transition"}, - {0x06290000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06290000, 0, 1, "FFFB: SCSI bus was reset"}, {0x06290500, 0, 0, "FFFE: SCSI bus transition to single ended"}, {0x06290600, 0, 0, "FFFE: SCSI bus transition to LVD"}, - {0x06298000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06298000, 0, 1, "FFFB: SCSI bus was reset by another initiator"}, - {0x063F0300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x063F0300, 0, 1, "3029: A device replacement has occurred"}, - {0x064C8000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x064C8000, 0, 1, "9051: IOA cache data exists for a missing or failed device"}, - {0x064C8100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x064C8100, 0, 1, "9055: Auxiliary cache IOA contains cache data needed by the primary IOA"}, - {0x06670100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06670100, 0, 1, "9025: Disk unit is not supported at its physical location"}, - {0x06670600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06670600, 0, 1, "3020: IOA detected a SCSI bus configuration error"}, - {0x06678000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678000, 0, 1, "3150: SCSI bus configuration error"}, - {0x06678100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678100, 0, 1, "9074: Asymmetric advanced function disk configuration"}, - {0x06678300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678300, 0, 1, "4040: Incomplete multipath connection between IOA and enclosure"}, - {0x06678400, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678400, 0, 1, "4041: Incomplete multipath connection between enclosure and device"}, - {0x06678500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678500, 0, 1, "9075: Incomplete multipath connection between IOA and remote IOA"}, - {0x06678600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678600, 0, 1, "9076: Configuration error, missing remote IOA"}, - {0x06679100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06679100, 0, 1, "4050: Enclosure does not support a required multipath function"}, - {0x06690200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06690200, 0, 1, "9041: Array protection temporarily suspended"}, - {0x06698200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06698200, 0, 1, "9042: Corrupt array parity detected on specified device"}, - {0x066B0200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B0200, 0, 1, "9030: Array no longer protected due to missing or failed disk unit"}, - {0x066B8000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B8000, 0, 1, "9071: Link operational transition"}, - {0x066B8100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B8100, 0, 1, "9072: Link not operational transition"}, - {0x066B8200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B8200, 0, 1, "9032: Array exposed but still protected"}, - {0x066B8300, 0, IPR_DEFAULT_LOG_LEVEL + 1, - "70DD: Device forced failed by disrupt device command"}, - {0x066B9100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B9100, 0, 1, "4061: Multipath redundancy level got better"}, - {0x066B9200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B9200, 0, 1, "4060: Multipath redundancy level got worse"}, {0x07270000, 0, 0, "Failure due to other device"}, - {0x07278000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278000, 0, 1, "9008: IOA does not support functions expected by devices"}, - {0x07278100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278100, 0, 1, "9010: Cache data associated with attached devices cannot be found"}, - {0x07278200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278200, 0, 1, "9011: Cache data belongs to devices other than those attached"}, - {0x07278400, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278400, 0, 1, "9020: Array missing 2 or more devices with only 1 device present"}, - {0x07278500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278500, 0, 1, "9021: Array missing 2 or more devices with 2 or more devices present"}, - {0x07278600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278600, 0, 1, "9022: Exposed array is missing a required device"}, - {0x07278700, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278700, 0, 1, "9023: Array member(s) not at required physical locations"}, - {0x07278800, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278800, 0, 1, "9024: Array not functional due to present hardware configuration"}, - {0x07278900, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278900, 0, 1, "9026: Array not functional due to present hardware configuration"}, - {0x07278A00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278A00, 0, 1, "9027: Array is missing a device and parity is out of sync"}, - {0x07278B00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278B00, 0, 1, "9028: Maximum number of arrays already exist"}, - {0x07278C00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278C00, 0, 1, "9050: Required cache data cannot be located for a disk unit"}, - {0x07278D00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278D00, 0, 1, "9052: Cache data exists for a device that has been modified"}, - {0x07278F00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278F00, 0, 1, "9054: IOA resources not available due to previous problems"}, - {0x07279100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279100, 0, 1, "9092: Disk unit requires initialization before use"}, - {0x07279200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279200, 0, 1, "9029: Incorrect hardware configuration change has been detected"}, - {0x07279600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279600, 0, 1, "9060: One or more disk pairs are missing from an array"}, - {0x07279700, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279700, 0, 1, "9061: One or more disks are missing from an array"}, - {0x07279800, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279800, 0, 1, "9062: One or more disks are missing from an array"}, - {0x07279900, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279900, 0, 1, "9063: Maximum number of functional arrays has been exceeded"}, {0x0B260000, 0, 0, "Aborted command, invalid descriptor"}, @@ -480,16 +481,12 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) { struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; - dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); ioarcb->write_data_transfer_length = 0; ioarcb->read_data_transfer_length = 0; ioarcb->write_ioadl_len = 0; ioarcb->read_ioadl_len = 0; - ioarcb->write_ioadl_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; ioasa->ioasc = 0; ioasa->residual_data_len = 0; ioasa->u.gata.status = 0; @@ -1613,7 +1610,7 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, /* Set indication we have logged an error */ ioa_cfg->errors_logged++; - if (ioa_cfg->log_level < ipr_error_table[error_index].log_hcam) + if (ioa_cfg->log_level < IPR_DEFAULT_LOG_LEVEL) return; if (be32_to_cpu(hostrcb->hcam.length) > sizeof(hostrcb->hcam.u.raw)) hostrcb->hcam.length = cpu_to_be32(sizeof(hostrcb->hcam.u.raw)); @@ -3853,8 +3850,6 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { if (ipr_cmd->scsi_cmd) ipr_cmd->done = ipr_scsi_eh_done; - if (ipr_cmd->qc) - ipr_cmd->done = ipr_sata_eh_done; if (ipr_cmd->qc && !(ipr_cmd->qc->flags & ATA_QCFLAG_FAILED)) { ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT; ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED; @@ -4235,14 +4230,6 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, sglist = scsi_cmd->request_buffer; - if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) { - ioadl = ioarcb->add_data.u.ioadl; - ioarcb->write_ioadl_addr = - cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) + - offsetof(struct ipr_ioarcb, add_data)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; - } - for (i = 0; i < ipr_cmd->dma_use_sg; i++) { ioadl[i].flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(&sglist[i])); @@ -4273,11 +4260,6 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, scsi_cmd->sc_data_direction); if (likely(!pci_dma_mapping_error(ipr_cmd->dma_handle))) { - ioadl = ioarcb->add_data.u.ioadl; - ioarcb->write_ioadl_addr = - cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) + - offsetof(struct ipr_ioarcb, add_data)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; ipr_cmd->dma_use_sg = 1; ioadl[0].flags_and_data_len = cpu_to_be32(ioadl_flags | length | IPR_IOADL_FLAGS_LAST); @@ -4364,9 +4346,11 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) **/ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) { - struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; - dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); + struct ipr_ioarcb *ioarcb; + struct ipr_ioasa *ioasa; + + ioarcb = &ipr_cmd->ioarcb; + ioasa = &ipr_cmd->ioasa; memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); ioarcb->write_data_transfer_length = 0; @@ -4375,9 +4359,6 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) ioarcb->read_ioadl_len = 0; ioasa->ioasc = 0; ioasa->residual_data_len = 0; - ioarcb->write_ioadl_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; } /** @@ -4476,13 +4457,12 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, { int i; u16 data_len; - u32 ioasc, fd_ioasc; + u32 ioasc; struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; __be32 *ioasa_data = (__be32 *)ioasa; int error_index; ioasc = be32_to_cpu(ioasa->ioasc) & IPR_IOASC_IOASC_MASK; - fd_ioasc = be32_to_cpu(ioasa->fd_ioasc) & IPR_IOASC_IOASC_MASK; if (0 == ioasc) return; @@ -4490,19 +4470,13 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, if (ioa_cfg->log_level < IPR_DEFAULT_LOG_LEVEL) return; - if (ioasc == IPR_IOASC_BUS_WAS_RESET && fd_ioasc) - error_index = ipr_get_error(fd_ioasc); - else - error_index = ipr_get_error(ioasc); + error_index = ipr_get_error(ioasc); if (ioa_cfg->log_level < IPR_MAX_LOG_LEVEL) { /* Don't log an error if the IOA already logged one */ if (ioasa->ilid != 0) return; - if (!ipr_is_gscsi(res)) - return; - if (ipr_error_table[error_index].log_ioasa == 0) return; } @@ -4662,11 +4636,11 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, return; } - if (!ipr_is_gscsi(res)) + if (ipr_is_gscsi(res)) + ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); + else ipr_gen_sense(ipr_cmd); - ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); - switch (ioasc & IPR_IOASC_IOASC_MASK) { case IPR_IOASC_ABORTED_CMD_TERM_BY_HOST: if (ipr_is_naca_model(res)) @@ -5147,7 +5121,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) struct ipr_ioarcb_ata_regs *regs; if (unlikely(!ioa_cfg->allow_cmds || ioa_cfg->ioa_is_dead)) - return AC_ERR_SYSTEM; + return -EIO; ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ioarcb = &ipr_cmd->ioarcb; @@ -5192,7 +5166,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) default: WARN_ON(1); - return AC_ERR_INVALID; + return -1; } mb(); @@ -6214,7 +6188,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); ipr_cmd->timer.data = (unsigned long) ipr_cmd; - ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); + ipr_cmd->timer.expires = jiffies + (ipr_transop_timeout * HZ); ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; ipr_cmd->done = ipr_reset_ioa_job; add_timer(&ipr_cmd->timer); @@ -6411,7 +6385,6 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START); if (rc != PCIBIOS_SUCCESSFUL) { - pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev); ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); rc = IPR_RC_JOB_CONTINUE; } else { @@ -7144,6 +7117,8 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, ioa_cfg->pdev = pdev; ioa_cfg->log_level = ipr_log_level; ioa_cfg->doorbell = IPR_DOORBELL; + if (!ipr_auto_create) + ioa_cfg->doorbell |= IPR_RUNTIME_RESET; sprintf(ioa_cfg->eye_catcher, IPR_EYECATCHER); sprintf(ioa_cfg->trace_start, IPR_TRACE_START_LABEL); sprintf(ioa_cfg->ipr_free_label, IPR_FREEQ_LABEL); @@ -7258,13 +7233,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, goto out_scsi_host_put; } - if (ipr_transop_timeout) - ioa_cfg->transop_timeout = ipr_transop_timeout; - else if (dev_id->driver_data & IPR_USE_LONG_TRANSOP_TIMEOUT) - ioa_cfg->transop_timeout = IPR_LONG_OPERATIONAL_TIMEOUT; - else - ioa_cfg->transop_timeout = IPR_OPERATIONAL_TIMEOUT; - ipr_regs_pci = pci_resource_start(pdev, 0); rc = pci_request_regions(pdev, IPR_NAME); @@ -7572,45 +7540,29 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571A, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, 0 }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571E, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, 0 }, { } }; MODULE_DEVICE_TABLE(pci, ipr_pci_table); diff --git a/trunk/drivers/scsi/ipr.h b/trunk/drivers/scsi/ipr.h index bc53d7cebe0a..88f285de97bb 100644 --- a/trunk/drivers/scsi/ipr.h +++ b/trunk/drivers/scsi/ipr.h @@ -37,8 +37,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.3.2" -#define IPR_DRIVER_DATE "(March 23, 2007)" +#define IPR_DRIVER_VERSION "2.3.1" +#define IPR_DRIVER_DATE "(January 23, 2007)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -55,7 +55,6 @@ #define IPR_NUM_BASE_CMD_BLKS 100 #define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 -#define PCI_DEVICE_ID_IBM_SCAMP_E 0x034A #define IPR_SUBS_DEV_ID_2780 0x0264 #define IPR_SUBS_DEV_ID_5702 0x0266 @@ -70,12 +69,8 @@ #define IPR_SUBS_DEV_ID_572A 0x02C1 #define IPR_SUBS_DEV_ID_572B 0x02C2 #define IPR_SUBS_DEV_ID_572F 0x02C3 -#define IPR_SUBS_DEV_ID_574D 0x030B -#define IPR_SUBS_DEV_ID_574E 0x030A #define IPR_SUBS_DEV_ID_575B 0x030D #define IPR_SUBS_DEV_ID_575C 0x0338 -#define IPR_SUBS_DEV_ID_575D 0x033E -#define IPR_SUBS_DEV_ID_57B3 0x033A #define IPR_SUBS_DEV_ID_57B7 0x0360 #define IPR_SUBS_DEV_ID_57B8 0x02C2 @@ -109,9 +104,6 @@ #define IPR_IOASC_IOA_WAS_RESET 0x10000001 #define IPR_IOASC_PCI_ACCESS_ERROR 0x10000002 -/* Driver data flags */ -#define IPR_USE_LONG_TRANSOP_TIMEOUT 0x00000001 - #define IPR_DEFAULT_MAX_ERROR_DUMP 984 #define IPR_NUM_LOG_HCAMS 2 #define IPR_NUM_CFG_CHG_HCAMS 2 @@ -187,7 +179,6 @@ #define IPR_SET_SUP_DEVICE_TIMEOUT (2 * 60 * HZ) #define IPR_REQUEST_SENSE_TIMEOUT (10 * HZ) #define IPR_OPERATIONAL_TIMEOUT (5 * 60) -#define IPR_LONG_OPERATIONAL_TIMEOUT (12 * 60) #define IPR_WAIT_FOR_RESET_TIMEOUT (2 * HZ) #define IPR_CHECK_FOR_RESET_TIMEOUT (HZ / 10) #define IPR_WAIT_FOR_BIST_TIMEOUT (2 * HZ) @@ -422,25 +413,9 @@ struct ipr_ioarcb_ata_regs { u8 ctl; }__attribute__ ((packed, aligned(4))); -struct ipr_ioadl_desc { - __be32 flags_and_data_len; -#define IPR_IOADL_FLAGS_MASK 0xff000000 -#define IPR_IOADL_GET_FLAGS(x) (be32_to_cpu(x) & IPR_IOADL_FLAGS_MASK) -#define IPR_IOADL_DATA_LEN_MASK 0x00ffffff -#define IPR_IOADL_GET_DATA_LEN(x) (be32_to_cpu(x) & IPR_IOADL_DATA_LEN_MASK) -#define IPR_IOADL_FLAGS_READ 0x48000000 -#define IPR_IOADL_FLAGS_READ_LAST 0x49000000 -#define IPR_IOADL_FLAGS_WRITE 0x68000000 -#define IPR_IOADL_FLAGS_WRITE_LAST 0x69000000 -#define IPR_IOADL_FLAGS_LAST 0x01000000 - - __be32 address; -}__attribute__((packed, aligned (8))); - struct ipr_ioarcb_add_data { union { struct ipr_ioarcb_ata_regs regs; - struct ipr_ioadl_desc ioadl[5]; __be32 add_cmd_parms[10]; }u; }__attribute__ ((packed, aligned(4))); @@ -472,6 +447,21 @@ struct ipr_ioarcb { struct ipr_ioarcb_add_data add_data; }__attribute__((packed, aligned (4))); +struct ipr_ioadl_desc { + __be32 flags_and_data_len; +#define IPR_IOADL_FLAGS_MASK 0xff000000 +#define IPR_IOADL_GET_FLAGS(x) (be32_to_cpu(x) & IPR_IOADL_FLAGS_MASK) +#define IPR_IOADL_DATA_LEN_MASK 0x00ffffff +#define IPR_IOADL_GET_DATA_LEN(x) (be32_to_cpu(x) & IPR_IOADL_DATA_LEN_MASK) +#define IPR_IOADL_FLAGS_READ 0x48000000 +#define IPR_IOADL_FLAGS_READ_LAST 0x49000000 +#define IPR_IOADL_FLAGS_WRITE 0x68000000 +#define IPR_IOADL_FLAGS_WRITE_LAST 0x69000000 +#define IPR_IOADL_FLAGS_LAST 0x01000000 + + __be32 address; +}__attribute__((packed, aligned (8))); + struct ipr_ioasa_vset { __be32 failing_lba_hi; __be32 failing_lba_lo; @@ -1129,7 +1119,6 @@ struct ipr_ioa_cfg { struct ipr_bus_attributes bus_attr[IPR_MAX_NUM_BUSES]; - unsigned int transop_timeout; const struct ipr_chip_cfg_t *chip_cfg; void __iomem *hdw_dma_regs; /* iomapped PCI memory space */ diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index c9a3abf9e7b6..8f55e1431433 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -527,12 +527,12 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) * than 8K, but there are no targets that currently do this. * For now we fail until we find a vendor that needs it */ - if (ISCSI_DEF_MAX_RECV_SEG_LEN < + if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH < tcp_conn->in.datalen) { printk(KERN_ERR "iscsi_tcp: received buffer of len %u " "but conn buffer is only %u (opcode %0x)\n", tcp_conn->in.datalen, - ISCSI_DEF_MAX_RECV_SEG_LEN, opcode); + DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, opcode); rc = ISCSI_ERR_PROTO; break; } @@ -1762,7 +1762,7 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) * due to strange issues with iser these are not set * in iscsi_conn_setup */ - conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN; + conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL); if (!tcp_conn) @@ -1777,24 +1777,14 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0, CRYPTO_ALG_ASYNC); tcp_conn->tx_hash.flags = 0; - if (IS_ERR(tcp_conn->tx_hash.tfm)) { - printk(KERN_ERR "Could not create connection due to crc32c " - "loading error %ld. Make sure the crc32c module is " - "built as a module or into the kernel\n", - PTR_ERR(tcp_conn->tx_hash.tfm)); + if (IS_ERR(tcp_conn->tx_hash.tfm)) goto free_tcp_conn; - } tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0, CRYPTO_ALG_ASYNC); tcp_conn->rx_hash.flags = 0; - if (IS_ERR(tcp_conn->rx_hash.tfm)) { - printk(KERN_ERR "Could not create connection due to crc32c " - "loading error %ld. Make sure the crc32c module is " - "built as a module or into the kernel\n", - PTR_ERR(tcp_conn->rx_hash.tfm)); + if (IS_ERR(tcp_conn->rx_hash.tfm)) goto free_tx_tfm; - } return cls_conn; @@ -2148,7 +2138,6 @@ static struct scsi_host_template iscsi_sht = { .change_queue_depth = iscsi_change_queue_depth, .can_queue = ISCSI_XMIT_CMDS_MAX - 1, .sg_tablesize = ISCSI_SG_TABLESIZE, - .max_sectors = 0xFFFF, .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_host_reset_handler = iscsi_eh_host_reset, diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 3f5b9b445b29..7c75771c77ff 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -270,14 +269,14 @@ static int iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto out; } - senselen = be16_to_cpu(get_unaligned((__be16 *) data)); + senselen = be16_to_cpu(*(__be16 *)data); if (datalen < senselen) goto invalid_datalen; memcpy(sc->sense_buffer, data + 2, min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); debug_scsi("copied %d bytes of sense\n", - min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); + min(senselen, SCSI_SENSE_BUFFERSIZE)); } if (sc->sc_data_direction == DMA_TO_DEVICE) @@ -578,7 +577,7 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) } EXPORT_SYMBOL_GPL(iscsi_conn_failure); -static int iscsi_xmit_mtask(struct iscsi_conn *conn) +static int iscsi_xmit_imm_task(struct iscsi_conn *conn) { struct iscsi_hdr *hdr = conn->mtask->hdr; int rc, was_logout = 0; @@ -592,9 +591,6 @@ static int iscsi_xmit_mtask(struct iscsi_conn *conn) if (rc) return rc; - /* done with this in-progress mtask */ - conn->mtask = NULL; - if (was_logout) { set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); return -ENODATA; @@ -647,9 +643,11 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) conn->ctask = NULL; } if (conn->mtask) { - rc = iscsi_xmit_mtask(conn); + rc = iscsi_xmit_imm_task(conn); if (rc) goto again; + /* done with this in-progress mtask */ + conn->mtask = NULL; } /* process immediate first */ @@ -660,10 +658,12 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) list_add_tail(&conn->mtask->running, &conn->mgmt_run_list); spin_unlock_bh(&conn->session->lock); - rc = iscsi_xmit_mtask(conn); + rc = iscsi_xmit_imm_task(conn); if (rc) goto again; } + /* done with this mtask */ + conn->mtask = NULL; } /* process command queue */ @@ -701,10 +701,12 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) list_add_tail(&conn->mtask->running, &conn->mgmt_run_list); spin_unlock_bh(&conn->session->lock); - rc = iscsi_xmit_mtask(conn); - if (rc) + rc = tt->xmit_mgmt_task(conn, conn->mtask); + if (rc) goto again; } + /* done with this mtask */ + conn->mtask = NULL; } return -ENODATA; @@ -1521,7 +1523,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) } spin_unlock_bh(&session->lock); - data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL); + data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); if (!data) goto login_mtask_data_alloc_fail; conn->login_mtask->data = conn->data = data; @@ -1595,9 +1597,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) wake_up(&conn->ehwait); } - /* flush queued up work because we free the connection below */ - scsi_flush_work(session->host); - spin_lock_bh(&session->lock); kfree(conn->data); kfree(conn->persistent_address); diff --git a/trunk/drivers/scsi/libsrp.c b/trunk/drivers/scsi/libsrp.c index 5631c199a8eb..6335830df810 100644 --- a/trunk/drivers/scsi/libsrp.c +++ b/trunk/drivers/scsi/libsrp.c @@ -224,7 +224,8 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, struct srp_direct_buf *md = NULL; struct scatterlist dummy, *sg = NULL; dma_addr_t token = 0; - int err = 0; + long err; + unsigned int done = 0; int nmd, nsg = 0, len; if (dma_map || ext_desc) { @@ -256,8 +257,8 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, sg_dma_address(&dummy) = token; err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE, id->table_desc.len); - if (err) { - eprintk("Error copying indirect table %d\n", err); + if (err < 0) { + eprintk("Error copying indirect table %ld\n", err); goto free_mem; } } else { @@ -270,7 +271,6 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, DMA_BIDIRECTIONAL); if (!nsg) { eprintk("fail to map %p %d\n", iue, sc->use_sg); - err = -EIO; goto free_mem; } len = min(sc->request_bufflen, id->len); @@ -286,7 +286,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, if (token && dma_map) dma_free_coherent(iue->target->dev, id->table_desc.len, md, token); - return err; + return done; } static int data_out_desc_size(struct srp_cmd *cmd) @@ -351,7 +351,7 @@ int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, break; default: eprintk("Unknown format %d %x\n", dir, format); - err = -EINVAL; + break; } return err; diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index dcf6106f557a..057fd7e0e379 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -671,7 +671,7 @@ static int lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) { uint8_t lenlo, lenhi; - int Length; + uint32_t Length; int i, j; int finished = 0; int index = 0; diff --git a/trunk/drivers/scsi/osst.c b/trunk/drivers/scsi/osst.c index 08060fb478b6..a967fadb7439 100644 --- a/trunk/drivers/scsi/osst.c +++ b/trunk/drivers/scsi/osst.c @@ -87,7 +87,6 @@ MODULE_AUTHOR("Willem Riede"); MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR); -MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE); module_param(max_dev, int, 0444); MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); diff --git a/trunk/drivers/scsi/pci2000.h b/trunk/drivers/scsi/pci2000.h new file mode 100644 index 000000000000..0ebd8ce9e1de --- /dev/null +++ b/trunk/drivers/scsi/pci2000.h @@ -0,0 +1,197 @@ +/**************************************************************************** + * Perceptive Solutions, Inc. PCI-2000 device driver for Linux. + * + * pci2000.h - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters + * + * Copyright (c) 1997-1999 Perceptive Solutions, Inc. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that redistributions of source + * code retain the above copyright notice and this comment without + * modification. + * + * Technical updates and product information at: + * http://www.psidisk.com + * + * Please send questions, comments, bug reports to: + * tech@psidisk.com Technical Support + * + ****************************************************************************/ +#ifndef _PCI2000_H +#define _PCI2000_H + +#include + +#ifndef PSI_EIDE_SCSIOP +#define PSI_EIDE_SCSIOP 1 + +#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s)) + +/************************************************/ +/* definition of standard data types */ +/************************************************/ +#define CHAR char +#define UCHAR unsigned char +#define SHORT short +#define USHORT unsigned short +#define BOOL long +#define LONG long +#define ULONG unsigned long +#define VOID void + +typedef CHAR *PCHAR; +typedef UCHAR *PUCHAR; +typedef SHORT *PSHORT; +typedef USHORT *PUSHORT; +typedef BOOL *PBOOL; +typedef LONG *PLONG; +typedef ULONG *PULONG; +typedef VOID *PVOID; + + +/************************************************/ +/* Misc. macros */ +/************************************************/ +#define ANY2SCSI(up, p) \ +((UCHAR *)up)[0] = (((ULONG)(p)) >> 8); \ +((UCHAR *)up)[1] = ((ULONG)(p)); + +#define SCSI2LONG(up) \ +( (((long)*(((UCHAR *)up))) << 16) \ ++ (((long)(((UCHAR *)up)[1])) << 8) \ ++ ((long)(((UCHAR *)up)[2])) ) + +#define XANY2SCSI(up, p) \ +((UCHAR *)up)[0] = ((long)(p)) >> 24; \ +((UCHAR *)up)[1] = ((long)(p)) >> 16; \ +((UCHAR *)up)[2] = ((long)(p)) >> 8; \ +((UCHAR *)up)[3] = ((long)(p)); + +#define XSCSI2LONG(up) \ +( (((long)(((UCHAR *)up)[0])) << 24) \ ++ (((long)(((UCHAR *)up)[1])) << 16) \ ++ (((long)(((UCHAR *)up)[2])) << 8) \ ++ ((long)(((UCHAR *)up)[3])) ) + +/************************************************/ +/* SCSI CDB operation codes */ +/************************************************/ +#define SCSIOP_TEST_UNIT_READY 0x00 +#define SCSIOP_REZERO_UNIT 0x01 +#define SCSIOP_REWIND 0x01 +#define SCSIOP_REQUEST_BLOCK_ADDR 0x02 +#define SCSIOP_REQUEST_SENSE 0x03 +#define SCSIOP_FORMAT_UNIT 0x04 +#define SCSIOP_READ_BLOCK_LIMITS 0x05 +#define SCSIOP_REASSIGN_BLOCKS 0x07 +#define SCSIOP_READ6 0x08 +#define SCSIOP_RECEIVE 0x08 +#define SCSIOP_WRITE6 0x0A +#define SCSIOP_PRINT 0x0A +#define SCSIOP_SEND 0x0A +#define SCSIOP_SEEK6 0x0B +#define SCSIOP_TRACK_SELECT 0x0B +#define SCSIOP_SLEW_PRINT 0x0B +#define SCSIOP_SEEK_BLOCK 0x0C +#define SCSIOP_PARTITION 0x0D +#define SCSIOP_READ_REVERSE 0x0F +#define SCSIOP_WRITE_FILEMARKS 0x10 +#define SCSIOP_FLUSH_BUFFER 0x10 +#define SCSIOP_SPACE 0x11 +#define SCSIOP_INQUIRY 0x12 +#define SCSIOP_VERIFY6 0x13 +#define SCSIOP_RECOVER_BUF_DATA 0x14 +#define SCSIOP_MODE_SELECT 0x15 +#define SCSIOP_RESERVE_UNIT 0x16 +#define SCSIOP_RELEASE_UNIT 0x17 +#define SCSIOP_COPY 0x18 +#define SCSIOP_ERASE 0x19 +#define SCSIOP_MODE_SENSE 0x1A +#define SCSIOP_START_STOP_UNIT 0x1B +#define SCSIOP_STOP_PRINT 0x1B +#define SCSIOP_LOAD_UNLOAD 0x1B +#define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C +#define SCSIOP_SEND_DIAGNOSTIC 0x1D +#define SCSIOP_MEDIUM_REMOVAL 0x1E +#define SCSIOP_READ_CAPACITY 0x25 +#define SCSIOP_READ 0x28 +#define SCSIOP_WRITE 0x2A +#define SCSIOP_SEEK 0x2B +#define SCSIOP_LOCATE 0x2B +#define SCSIOP_WRITE_VERIFY 0x2E +#define SCSIOP_VERIFY 0x2F +#define SCSIOP_SEARCH_DATA_HIGH 0x30 +#define SCSIOP_SEARCH_DATA_EQUAL 0x31 +#define SCSIOP_SEARCH_DATA_LOW 0x32 +#define SCSIOP_SET_LIMITS 0x33 +#define SCSIOP_READ_POSITION 0x34 +#define SCSIOP_SYNCHRONIZE_CACHE 0x35 +#define SCSIOP_COMPARE 0x39 +#define SCSIOP_COPY_COMPARE 0x3A +#define SCSIOP_WRITE_DATA_BUFF 0x3B +#define SCSIOP_READ_DATA_BUFF 0x3C +#define SCSIOP_CHANGE_DEFINITION 0x40 +#define SCSIOP_READ_SUB_CHANNEL 0x42 +#define SCSIOP_READ_TOC 0x43 +#define SCSIOP_READ_HEADER 0x44 +#define SCSIOP_PLAY_AUDIO 0x45 +#define SCSIOP_PLAY_AUDIO_MSF 0x47 +#define SCSIOP_PLAY_TRACK_INDEX 0x48 +#define SCSIOP_PLAY_TRACK_RELATIVE 0x49 +#define SCSIOP_PAUSE_RESUME 0x4B +#define SCSIOP_LOG_SELECT 0x4C +#define SCSIOP_LOG_SENSE 0x4D +#define SCSIOP_MODE_SELECT10 0x55 +#define SCSIOP_MODE_SENSE10 0x5A +#define SCSIOP_LOAD_UNLOAD_SLOT 0xA6 +#define SCSIOP_MECHANISM_STATUS 0xBD +#define SCSIOP_READ_CD 0xBE + +// SCSI read capacity structure +typedef struct _READ_CAPACITY_DATA + { + ULONG blks; /* total blocks (converted to little endian) */ + ULONG blksiz; /* size of each (converted to little endian) */ + } READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA; + +// SCSI inquiry data +typedef struct _INQUIRYDATA + { + UCHAR DeviceType :5; + UCHAR DeviceTypeQualifier :3; + UCHAR DeviceTypeModifier :7; + UCHAR RemovableMedia :1; + UCHAR Versions; + UCHAR ResponseDataFormat; + UCHAR AdditionalLength; + UCHAR Reserved[2]; + UCHAR SoftReset :1; + UCHAR CommandQueue :1; + UCHAR Reserved2 :1; + UCHAR LinkedCommands :1; + UCHAR Synchronous :1; + UCHAR Wide16Bit :1; + UCHAR Wide32Bit :1; + UCHAR RelativeAddressing :1; + UCHAR VendorId[8]; + UCHAR ProductId[16]; + UCHAR ProductRevisionLevel[4]; + UCHAR VendorSpecific[20]; + UCHAR Reserved3[40]; + } INQUIRYDATA, *PINQUIRYDATA; + +#endif + +// function prototypes +int Pci2000_Detect (struct scsi_host_template *tpnt); +int Pci2000_Command (Scsi_Cmnd *SCpnt); +int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)); +int Pci2000_Abort (Scsi_Cmnd *SCpnt); +int Pci2000_Reset (Scsi_Cmnd *SCpnt, unsigned int flags); +int Pci2000_Release (struct Scsi_Host *pshost); +int Pci2000_BiosParam (struct scsi_device *sdev, + struct block_device *bdev, + sector_t capacity, int geom[]); + +#endif diff --git a/trunk/drivers/scsi/pcmcia/Kconfig b/trunk/drivers/scsi/pcmcia/Kconfig index 7dd787f6ab27..eac8e179cfff 100644 --- a/trunk/drivers/scsi/pcmcia/Kconfig +++ b/trunk/drivers/scsi/pcmcia/Kconfig @@ -3,11 +3,11 @@ # menu "PCMCIA SCSI adapter support" - depends on SCSI!=n && PCMCIA!=n + depends on SCSI!=n && PCMCIA!=n && MODULES config PCMCIA_AHA152X tristate "Adaptec AHA152X PCMCIA support" - depends on !64BIT + depends on m && !64BIT select SCSI_SPI_ATTRS help Say Y here if you intend to attach this type of PCMCIA SCSI host @@ -18,6 +18,7 @@ config PCMCIA_AHA152X config PCMCIA_FDOMAIN tristate "Future Domain PCMCIA support" + depends on m help Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. @@ -27,7 +28,7 @@ config PCMCIA_FDOMAIN config PCMCIA_NINJA_SCSI tristate "NinjaSCSI-3 / NinjaSCSI-32Bi (16bit) PCMCIA support" - depends on !64BIT + depends on m && !64BIT help If you intend to attach this type of PCMCIA SCSI host adapter to your computer, say Y here and read @@ -61,6 +62,7 @@ config PCMCIA_NINJA_SCSI config PCMCIA_QLOGIC tristate "Qlogic PCMCIA support" + depends on m help Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. @@ -70,6 +72,7 @@ config PCMCIA_QLOGIC config PCMCIA_SYM53C500 tristate "Symbios 53c500 PCMCIA support" + depends on m help Say Y here if you have a New Media Bus Toaster or other PCMCIA SCSI adapter based on the Symbios 53c500 controller. diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index e8948b679f5b..05f4f2a378eb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -1478,17 +1478,14 @@ typedef union { uint32_t b24 : 24; struct { -#ifdef __BIG_ENDIAN - uint8_t domain; - uint8_t area; - uint8_t al_pa; -#elif __LITTLE_ENDIAN + uint8_t d_id[3]; + uint8_t rsvd_1; + } r; + + struct { uint8_t al_pa; uint8_t area; uint8_t domain; -#else -#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!" -#endif uint8_t rsvd_1; } b; } port_id_t; diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 3e296ab845b6..98c01cd5e1a8 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -11,11 +11,6 @@ #include "qla_devtbl.h" -#ifdef CONFIG_SPARC -#include -#include -#endif - /* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */ #ifndef EXT_IS_LUN_BIT_SET #define EXT_IS_LUN_BIT_SET(P,L) \ @@ -93,7 +88,12 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); - ha->isp_ops.nvram_config(ha); + rval = ha->isp_ops.nvram_config(ha); + if (rval) { + DEBUG2(printk("scsi(%ld): Unable to verify NVRAM data.\n", + ha->host_no)); + return rval; + } if (ha->flags.disable_serdes) { /* Mask HBA via NVRAM settings? */ @@ -1393,28 +1393,6 @@ qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *de } } -/* On sparc systems, obtain port and node WWN from firmware - * properties. - */ -static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, nvram_t *nv) -{ -#ifdef CONFIG_SPARC - struct pci_dev *pdev = ha->pdev; - struct pcidev_cookie *pcp = pdev->sysdata; - struct device_node *dp = pcp->prom_node; - u8 *val; - int len; - - val = of_get_property(dp, "port-wwn", &len); - if (val && len >= WWN_SIZE) - memcpy(nv->port_name, val, WWN_SIZE); - - val = of_get_property(dp, "node-wwn", &len); - if (val && len >= WWN_SIZE) - memcpy(nv->node_name, val, WWN_SIZE); -#endif -} - /* * NVRAM configuration for ISP 2xxx * @@ -1431,7 +1409,6 @@ static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, nvram_t *nv) int qla2x00_nvram_config(scsi_qla_host_t *ha) { - int rval; uint8_t chksum = 0; uint16_t cnt; uint8_t *dptr1, *dptr2; @@ -1440,8 +1417,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) uint8_t *ptr = (uint8_t *)ha->request_ring; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; - rval = QLA_SUCCESS; - /* Determine NVRAM starting address. */ ha->nvram_size = sizeof(nvram_t); ha->nvram_base = 0; @@ -1465,57 +1440,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], nv->nvram_version); - qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " - "invalid -- WWPN) defaults.\n"); - - /* - * Set default initialization control block. - */ - memset(nv, 0, ha->nvram_size); - nv->parameter_block_version = ICB_VERSION; - - if (IS_QLA23XX(ha)) { - nv->firmware_options[0] = BIT_2 | BIT_1; - nv->firmware_options[1] = BIT_7 | BIT_5; - nv->add_firmware_options[0] = BIT_5; - nv->add_firmware_options[1] = BIT_5 | BIT_4; - nv->frame_payload_size = __constant_cpu_to_le16(2048); - nv->special_options[1] = BIT_7; - } else if (IS_QLA2200(ha)) { - nv->firmware_options[0] = BIT_2 | BIT_1; - nv->firmware_options[1] = BIT_7 | BIT_5; - nv->add_firmware_options[0] = BIT_5; - nv->add_firmware_options[1] = BIT_5 | BIT_4; - nv->frame_payload_size = __constant_cpu_to_le16(1024); - } else if (IS_QLA2100(ha)) { - nv->firmware_options[0] = BIT_3 | BIT_1; - nv->firmware_options[1] = BIT_5; - nv->frame_payload_size = __constant_cpu_to_le16(1024); - } - - nv->max_iocb_allocation = __constant_cpu_to_le16(256); - nv->execution_throttle = __constant_cpu_to_le16(16); - nv->retry_count = 8; - nv->retry_delay = 1; - - nv->port_name[0] = 33; - nv->port_name[3] = 224; - nv->port_name[4] = 139; - - qla2xxx_nvram_wwn_from_ofw(ha, nv); - - nv->login_timeout = 4; - - /* - * Set default host adapter parameters - */ - nv->host_p[1] = BIT_2; - nv->reset_delay = 5; - nv->port_down_retry_count = 8; - nv->max_luns_per_target = __constant_cpu_to_le16(8); - nv->link_down_timeout = 60; - - rval = 1; + return QLA_FUNCTION_FAILED; } #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) @@ -1728,11 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) } } - if (rval) { - DEBUG2_3(printk(KERN_WARNING - "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); - } - return (rval); + return QLA_SUCCESS; } static void @@ -3150,7 +3071,9 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) ha->isp_ops.get_flash_version(ha, ha->request_ring); - ha->isp_ops.nvram_config(ha); + rval = ha->isp_ops.nvram_config(ha); + if (rval) + goto isp_abort_retry; if (!qla2x00_restart_isp(ha)) { clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); @@ -3180,6 +3103,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) } } } else { /* failed the ISP abort */ +isp_abort_retry: ha->flags.online = 1; if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { if (ha->isp_abort_cnt == 0) { @@ -3366,32 +3290,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha) spin_unlock_irqrestore(&ha->hardware_lock, flags); } -/* On sparc systems, obtain port and node WWN from firmware - * properties. - */ -static void qla24xx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, struct nvram_24xx *nv) -{ -#ifdef CONFIG_SPARC - struct pci_dev *pdev = ha->pdev; - struct pcidev_cookie *pcp = pdev->sysdata; - struct device_node *dp = pcp->prom_node; - u8 *val; - int len; - - val = of_get_property(dp, "port-wwn", &len); - if (val && len >= WWN_SIZE) - memcpy(nv->port_name, val, WWN_SIZE); - - val = of_get_property(dp, "node-wwn", &len); - if (val && len >= WWN_SIZE) - memcpy(nv->node_name, val, WWN_SIZE); -#endif -} - int qla24xx_nvram_config(scsi_qla_host_t *ha) { - int rval; struct init_cb_24xx *icb; struct nvram_24xx *nv; uint32_t *dptr; @@ -3399,7 +3300,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) uint32_t chksum; uint16_t cnt; - rval = QLA_SUCCESS; icb = (struct init_cb_24xx *)ha->init_cb; nv = (struct nvram_24xx *)ha->request_ring; @@ -3432,52 +3332,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], le16_to_cpu(nv->nvram_version)); - qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " - "invalid -- WWPN) defaults.\n"); - - /* - * Set default initialization control block. - */ - memset(nv, 0, ha->nvram_size); - nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION); - nv->version = __constant_cpu_to_le16(ICB_VERSION); - nv->frame_payload_size = __constant_cpu_to_le16(2048); - nv->execution_throttle = __constant_cpu_to_le16(0xFFFF); - nv->exchange_count = __constant_cpu_to_le16(0); - nv->hard_address = __constant_cpu_to_le16(124); - nv->port_name[0] = 0x21; - nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn); - nv->port_name[2] = 0x00; - nv->port_name[3] = 0xe0; - nv->port_name[4] = 0x8b; - nv->port_name[5] = 0x1c; - nv->port_name[6] = 0x55; - nv->port_name[7] = 0x86; - nv->node_name[0] = 0x20; - nv->node_name[1] = 0x00; - nv->node_name[2] = 0x00; - nv->node_name[3] = 0xe0; - nv->node_name[4] = 0x8b; - nv->node_name[5] = 0x1c; - nv->node_name[6] = 0x55; - nv->node_name[7] = 0x86; - qla24xx_nvram_wwn_from_ofw(ha, nv); - nv->login_retry_count = __constant_cpu_to_le16(8); - nv->interrupt_delay_timer = __constant_cpu_to_le16(0); - nv->login_timeout = __constant_cpu_to_le16(0); - nv->firmware_options_1 = - __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1); - nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4); - nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12); - nv->firmware_options_3 = __constant_cpu_to_le32(2 << 13); - nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10); - nv->efi_parameters = __constant_cpu_to_le32(0); - nv->reset_delay = 5; - nv->max_luns_per_target = __constant_cpu_to_le16(128); - nv->port_down_retry_count = __constant_cpu_to_le16(30); - nv->link_down_timeout = __constant_cpu_to_le16(30); - - rval = 1; + return QLA_FUNCTION_FAILED; } /* Reset Initialization control block */ @@ -3624,11 +3479,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) ha->flags.process_response_queue = 1; } - if (rval) { - DEBUG2_3(printk(KERN_WARNING - "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); - } - return (rval); + return QLA_SUCCESS; } static int diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index 71e32a248528..83376f6ac3db 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -1280,14 +1280,14 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, } else { if (name != NULL) { /* This function returns name in big endian. */ - name[0] = MSB(mcp->mb[2]); - name[1] = LSB(mcp->mb[2]); - name[2] = MSB(mcp->mb[3]); - name[3] = LSB(mcp->mb[3]); - name[4] = MSB(mcp->mb[6]); - name[5] = LSB(mcp->mb[6]); - name[6] = MSB(mcp->mb[7]); - name[7] = LSB(mcp->mb[7]); + name[0] = LSB(mcp->mb[2]); + name[1] = MSB(mcp->mb[2]); + name[2] = LSB(mcp->mb[3]); + name[3] = MSB(mcp->mb[3]); + name[4] = LSB(mcp->mb[6]); + name[5] = MSB(mcp->mb[6]); + name[6] = LSB(mcp->mb[7]); + name[7] = MSB(mcp->mb[7]); } DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index b78919a318e2..68f5d24b938b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -62,7 +62,7 @@ MODULE_PARM_DESC(ql2xallocfwdump, "vary by ISP type. Default is 1 - allocate memory."); int ql2xextended_error_logging; -module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR); +module_param(ql2xextended_error_logging, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xextended_error_logging, "Option to enable extended error logging, " "Default is 0 - no logging. 1 - log errors."); @@ -157,8 +157,6 @@ static struct scsi_host_template qla24xx_driver_template = { .slave_alloc = qla2xxx_slave_alloc, .slave_destroy = qla2xxx_slave_destroy, - .scan_finished = qla2xxx_scan_finished, - .scan_start = qla2xxx_scan_start, .change_queue_depth = qla2x00_change_queue_depth, .change_queue_type = qla2x00_change_queue_type, .this_id = -1, @@ -1707,7 +1705,6 @@ qla2x00_remove_one(struct pci_dev *pdev) scsi_host_put(ha->host); - pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } @@ -1750,6 +1747,8 @@ qla2x00_free_device(scsi_qla_host_t *ha) if (ha->iobase) iounmap(ha->iobase); pci_release_regions(ha->pdev); + + pci_disable_device(ha->pdev); } static inline void diff --git a/trunk/drivers/scsi/qla2xxx/qla_sup.c b/trunk/drivers/scsi/qla2xxx/qla_sup.c index 206bda093da2..ff1dd4175a7f 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_sup.c +++ b/trunk/drivers/scsi/qla2xxx/qla_sup.c @@ -466,7 +466,6 @@ qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr) udelay(10); else rval = QLA_FUNCTION_TIMEOUT; - cond_resched(); } /* TODO: What happens if we time out? */ @@ -509,7 +508,6 @@ qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) udelay(10); else rval = QLA_FUNCTION_TIMEOUT; - cond_resched(); } return rval; } @@ -1257,7 +1255,6 @@ qla2x00_poll_flash(scsi_qla_host_t *ha, uint32_t addr, uint8_t poll_data, } udelay(10); barrier(); - cond_resched(); } return status; } @@ -1406,7 +1403,6 @@ qla2x00_read_flash_data(scsi_qla_host_t *ha, uint8_t *tmp_buf, uint32_t saddr, if (saddr % 100) udelay(10); *tmp_buf = data; - cond_resched(); } } @@ -1453,6 +1449,7 @@ uint8_t * qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, uint32_t offset, uint32_t length) { + unsigned long flags; uint32_t addr, midpoint; uint8_t *data; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; @@ -1461,6 +1458,7 @@ qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, qla2x00_suspend_hba(ha); /* Go with read. */ + spin_lock_irqsave(&ha->hardware_lock, flags); midpoint = ha->optrom_size / 2; qla2x00_flash_enable(ha); @@ -1475,6 +1473,7 @@ qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, *data = qla2x00_read_flash_byte(ha, addr); } qla2x00_flash_disable(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Resume HBA. */ qla2x00_resume_hba(ha); @@ -1488,6 +1487,7 @@ qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, { int rval; + unsigned long flags; uint8_t man_id, flash_id, sec_number, data; uint16_t wd; uint32_t addr, liter, sec_mask, rest_addr; @@ -1500,6 +1500,7 @@ qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, sec_number = 0; /* Reset ISP chip. */ + spin_lock_irqsave(&ha->hardware_lock, flags); WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); @@ -1688,10 +1689,10 @@ qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, rval = QLA_FUNCTION_FAILED; break; } - cond_resched(); } } while (0); qla2x00_flash_disable(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Resume HBA. */ qla2x00_resume_hba(ha); diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index dc85495c337f..61347aee55ce 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.07-k6" +#define QLA2XXX_VERSION "8.01.07-k5" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 4c1e31334765..1c89ee3e69ba 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -344,6 +344,7 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost) void scsi_log_send(struct scsi_cmnd *cmd) { unsigned int level; + struct scsi_device *sdev; /* * If ML QUEUE log level is greater than or equal to: @@ -360,17 +361,22 @@ void scsi_log_send(struct scsi_cmnd *cmd) level = SCSI_LOG_LEVEL(SCSI_LOG_MLQUEUE_SHIFT, SCSI_LOG_MLQUEUE_BITS); if (level > 1) { - scmd_printk(KERN_INFO, cmd, "Send: "); + sdev = cmd->device; + sdev_printk(KERN_INFO, sdev, "send "); if (level > 2) printk("0x%p ", cmd); - printk("\n"); + /* + * spaces to match disposition and cmd->result + * output in scsi_log_completion. + */ + printk(" "); scsi_print_command(cmd); if (level > 3) { printk(KERN_INFO "buffer = 0x%p, bufflen = %d," " done = 0x%p, queuecommand 0x%p\n", cmd->request_buffer, cmd->request_bufflen, cmd->done, - cmd->device->host->hostt->queuecommand); + sdev->host->hostt->queuecommand); } } @@ -380,6 +386,7 @@ void scsi_log_send(struct scsi_cmnd *cmd) void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) { unsigned int level; + struct scsi_device *sdev; /* * If ML COMPLETE log level is greater than or equal to: @@ -398,7 +405,8 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) SCSI_LOG_MLCOMPLETE_BITS); if (((level > 0) && (cmd->result || disposition != SUCCESS)) || (level > 1)) { - scmd_printk(KERN_INFO, cmd, "Done: "); + sdev = cmd->device; + sdev_printk(KERN_INFO, sdev, "done "); if (level > 2) printk("0x%p ", cmd); /* @@ -407,35 +415,40 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) */ switch (disposition) { case SUCCESS: - printk("SUCCESS\n"); + printk("SUCCESS"); break; case NEEDS_RETRY: - printk("RETRY\n"); + printk("RETRY "); break; case ADD_TO_MLQUEUE: - printk("MLQUEUE\n"); + printk("MLQUEUE"); break; case FAILED: - printk("FAILED\n"); + printk("FAILED "); break; case TIMEOUT_ERROR: /* * If called via scsi_times_out. */ - printk("TIMEOUT\n"); + printk("TIMEOUT"); break; default: - printk("UNKNOWN\n"); + printk("UNKNOWN"); } - scsi_print_result(cmd); + printk(" %8x ", cmd->result); scsi_print_command(cmd); - if (status_byte(cmd->result) & CHECK_CONDITION) + if (status_byte(cmd->result) & CHECK_CONDITION) { + /* + * XXX The scsi_print_sense formatting/prefix + * doesn't match this function. + */ scsi_print_sense("", cmd); - if (level > 3) - scmd_printk(KERN_INFO, cmd, - "scsi host busy %d failed %d\n", - cmd->device->host->host_busy, - cmd->device->host->host_failed); + } + if (level > 3) { + printk(KERN_INFO "scsi host busy %d failed %d\n", + sdev->host->host_busy, + sdev->host->host_failed); + } } } } diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 3963e7013bd9..918bb6019540 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -184,19 +184,10 @@ int scsi_delete_timer(struct scsi_cmnd *scmd) **/ void scsi_times_out(struct scsi_cmnd *scmd) { - enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *); - scsi_log_completion(scmd, TIMEOUT_ERROR); if (scmd->device->host->transportt->eh_timed_out) - eh_timed_out = scmd->device->host->transportt->eh_timed_out; - else if (scmd->device->host->hostt->eh_timed_out) - eh_timed_out = scmd->device->host->hostt->eh_timed_out; - else - eh_timed_out = NULL; - - if (eh_timed_out) - switch (eh_timed_out(scmd)) { + switch (scmd->device->host->transportt->eh_timed_out(scmd)) { case EH_HANDLED: __scsi_done(scmd); return; @@ -932,12 +923,10 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd) static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0}; if (scmd->device->allow_restart) { - int i, rtn = NEEDS_RETRY; - - for (i = 0; rtn == NEEDS_RETRY && i < 2; i++) - rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, - START_UNIT_TIMEOUT, 0); + int rtn; + rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, + START_UNIT_TIMEOUT, 0); if (rtn == SUCCESS) return 0; } diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 61fbcdcbb009..05d79af5ab90 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -848,8 +848,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) memcpy(req->sense, cmd->sense_buffer, len); req->sense_len = len; } - } - req->data_len = cmd->resid; + } else + req->data_len = cmd->resid; } /* @@ -968,7 +968,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) } if (result) { if (!(req->cmd_flags & REQ_QUIET)) { - scsi_print_result(cmd); + scmd_printk(KERN_INFO, cmd, + "SCSI error: return code = 0x%08x\n", + result); if (driver_byte(result) & DRIVER_SENSE) scsi_print_sense("", cmd); } diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index a67f315244d7..0949145304ea 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -181,8 +181,10 @@ int scsi_complete_async_scans(void) return 0; } +#ifdef MODULE /* Only exported for the benefit of scsi_wait_scan */ EXPORT_SYMBOL_GPL(scsi_complete_async_scans); +#endif /** * scsi_unlock_floptical - unlock device via a special MODE SENSE command diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index 67a38a1409ba..939de0de18bc 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -276,22 +276,8 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; } -static int scsi_bus_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) -{ - struct scsi_device *sdev = to_scsi_device(dev); - int i = 0; - int length = 0; - - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, - "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); - envp[i] = NULL; - return 0; -} - static int scsi_bus_suspend(struct device * dev, pm_message_t state) { - struct device_driver *drv = dev->driver; struct scsi_device *sdev = to_scsi_device(dev); struct scsi_host_template *sht = sdev->host->hostt; int err; @@ -300,51 +286,28 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state) if (err) return err; - /* call HLD suspend first */ - if (drv && drv->suspend) { - err = drv->suspend(dev, state); - if (err) - return err; - } - - /* then, call host suspend */ - if (sht->suspend) { + if (sht->suspend) err = sht->suspend(sdev, state); - if (err) { - if (drv && drv->resume) - drv->resume(dev); - return err; - } - } - return 0; + return err; } static int scsi_bus_resume(struct device * dev) { - struct device_driver *drv = dev->driver; struct scsi_device *sdev = to_scsi_device(dev); struct scsi_host_template *sht = sdev->host->hostt; - int err = 0, err2 = 0; + int err = 0; - /* call host resume first */ if (sht->resume) err = sht->resume(sdev); - /* then, call HLD resume */ - if (drv && drv->resume) - err2 = drv->resume(dev); - scsi_device_resume(sdev); - - /* favor LLD failure */ - return err ? err : err2;; + return err; } struct bus_type scsi_bus_type = { .name = "scsi", .match = scsi_bus_match, - .uevent = scsi_bus_uevent, .suspend = scsi_bus_suspend, .resume = scsi_bus_resume, }; @@ -584,14 +547,6 @@ show_sdev_iostat(iorequest_cnt); show_sdev_iostat(iodone_cnt); show_sdev_iostat(ioerr_cnt); -static ssize_t -sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct scsi_device *sdev; - sdev = to_scsi_device(dev); - return snprintf (buf, 20, SCSI_DEVICE_MODALIAS_FMT "\n", sdev->type); -} -static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL); /* Default template for device attributes. May NOT be modified */ static struct device_attribute *scsi_sysfs_sdev_attrs[] = { @@ -611,7 +566,6 @@ static struct device_attribute *scsi_sysfs_sdev_attrs[] = { &dev_attr_iorequest_cnt, &dev_attr_iodone_cnt, &dev_attr_ioerr_cnt, - &dev_attr_modalias, NULL }; diff --git a/trunk/drivers/scsi/scsi_tgt_if.c b/trunk/drivers/scsi/scsi_tgt_if.c index ca22ddf81746..0e08817fdecf 100644 --- a/trunk/drivers/scsi/scsi_tgt_if.c +++ b/trunk/drivers/scsi/scsi_tgt_if.c @@ -179,12 +179,10 @@ static int event_recv_msg(struct tgt_event *ev) switch (ev->hdr.type) { case TGT_UEVENT_CMD_RSP: err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no, - ev->p.cmd_rsp.result, ev->p.cmd_rsp.tag, - ev->p.cmd_rsp.uaddr, + ev->p.cmd_rsp.result, ev->p.cmd_rsp.len, - ev->p.cmd_rsp.sense_uaddr, - ev->p.cmd_rsp.sense_len, + ev->p.cmd_rsp.uaddr, ev->p.cmd_rsp.rw); break; case TGT_UEVENT_TSK_MGMT_RSP: diff --git a/trunk/drivers/scsi/scsi_tgt_lib.c b/trunk/drivers/scsi/scsi_tgt_lib.c index 2570f48a69c7..d402aff5f314 100644 --- a/trunk/drivers/scsi/scsi_tgt_lib.c +++ b/trunk/drivers/scsi/scsi_tgt_lib.c @@ -28,6 +28,7 @@ #include #include #include +#include <../drivers/md/dm-bio-list.h> #include "scsi_tgt_priv.h" @@ -41,12 +42,16 @@ static struct kmem_cache *scsi_tgt_cmd_cache; struct scsi_tgt_cmd { /* TODO replace work with James b's code */ struct work_struct work; - /* TODO fix limits of some drivers */ - struct bio *bio; + /* TODO replace the lists with a large bio */ + struct bio_list xfer_done_list; + struct bio_list xfer_list; struct list_head hash_list; struct request *rq; u64 tag; + + void *buffer; + unsigned bufflen; }; #define TGT_HASH_ORDER 4 @@ -88,12 +93,7 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, if (!tcmd) goto put_dev; - /* - * The blk helpers are used to the READ/WRITE requests - * transfering data from a initiator point of view. Since - * we are in target mode we want the opposite. - */ - rq = blk_get_request(shost->uspace_req_q, !write, gfp_mask); + rq = blk_get_request(shost->uspace_req_q, write, gfp_mask); if (!rq) goto free_tcmd; @@ -111,6 +111,8 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, rq->cmd_flags |= REQ_TYPE_BLOCK_PC; rq->end_io_data = tcmd; + bio_list_init(&tcmd->xfer_list); + bio_list_init(&tcmd->xfer_done_list); tcmd->rq = rq; return cmd; @@ -155,6 +157,22 @@ void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) } EXPORT_SYMBOL_GPL(scsi_host_put_command); +static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) +{ + struct bio *bio; + + /* must call bio_endio in case bio was bounced */ + while ((bio = bio_list_pop(&tcmd->xfer_done_list))) { + bio_endio(bio, bio->bi_size, 0); + bio_unmap_user(bio); + } + + while ((bio = bio_list_pop(&tcmd->xfer_list))) { + bio_endio(bio, bio->bi_size, 0); + bio_unmap_user(bio); + } +} + static void cmd_hashlist_del(struct scsi_cmnd *cmd) { struct request_queue *q = cmd->request->q; @@ -167,11 +185,6 @@ static void cmd_hashlist_del(struct scsi_cmnd *cmd) spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); } -static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) -{ - blk_rq_unmap_user(tcmd->bio); -} - static void scsi_tgt_cmd_destroy(struct work_struct *work) { struct scsi_tgt_cmd *tcmd = @@ -180,6 +193,16 @@ static void scsi_tgt_cmd_destroy(struct work_struct *work) dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, rq_data_dir(cmd->request)); + /* + * We fix rq->cmd_flags here since when we told bio_map_user + * to write vm for WRITE commands, blk_rq_bio_prep set + * rq_data_dir the flags to READ. + */ + if (cmd->sc_data_direction == DMA_TO_DEVICE) + cmd->request->cmd_flags |= REQ_RW; + else + cmd->request->cmd_flags &= ~REQ_RW; + scsi_unmap_user_pages(tcmd); scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd); } @@ -192,7 +215,6 @@ static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, struct list_head *head; tcmd->tag = tag; - tcmd->bio = NULL; INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); spin_lock_irqsave(&qdata->cmd_hash_lock, flags); head = &qdata->cmd_hash[cmd_hashfn(tag)]; @@ -327,14 +349,10 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); scsi_tgt_uspace_send_status(cmd, tcmd->tag); - - if (cmd->request_buffer) - scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); - queue_work(scsi_tgtd, &tcmd->work); } -static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd) +static int __scsi_tgt_transfer_response(struct scsi_cmnd *cmd) { struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); int err; @@ -347,12 +365,30 @@ static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd) case SCSI_MLQUEUE_DEVICE_BUSY: return -EAGAIN; } + return 0; } +static void scsi_tgt_transfer_response(struct scsi_cmnd *cmd) +{ + struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; + int err; + + err = __scsi_tgt_transfer_response(cmd); + if (!err) + return; + + cmd->result = DID_BUS_BUSY << 16; + err = scsi_tgt_uspace_send_status(cmd, tcmd->tag); + if (err <= 0) + /* the eh will have to pick this up */ + printk(KERN_ERR "Could not send cmd %p status\n", cmd); +} + static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) { struct request *rq = cmd->request; + struct scsi_tgt_cmd *tcmd = rq->end_io_data; int count; cmd->use_sg = rq->nr_phys_segments; @@ -362,54 +398,143 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) cmd->request_bufflen = rq->data_len; - dprintk("cmd %p cnt %d %lu\n", cmd, cmd->use_sg, rq_data_dir(rq)); + dprintk("cmd %p addr %p cnt %d %lu\n", cmd, tcmd->buffer, cmd->use_sg, + rq_data_dir(rq)); count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer); if (likely(count <= cmd->use_sg)) { cmd->use_sg = count; return 0; } - eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg); + eprintk("cmd %p addr %p cnt %d\n", cmd, tcmd->buffer, cmd->use_sg); scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); return -EINVAL; } /* TODO: test this crap and replace bio_map_user with new interface maybe */ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd, - unsigned long uaddr, unsigned int len, int rw) + int rw) { struct request_queue *q = cmd->request->q; struct request *rq = cmd->request; + void *uaddr = tcmd->buffer; + unsigned int len = tcmd->bufflen; + struct bio *bio; int err; - dprintk("%lx %u\n", uaddr, len); - err = blk_rq_map_user(q, rq, (void *)uaddr, len); - if (err) { + while (len > 0) { + dprintk("%lx %u\n", (unsigned long) uaddr, len); + bio = bio_map_user(q, NULL, (unsigned long) uaddr, len, rw); + if (IS_ERR(bio)) { + err = PTR_ERR(bio); + dprintk("fail to map %lx %u %d %x\n", + (unsigned long) uaddr, len, err, cmd->cmnd[0]); + goto unmap_bios; + } + + uaddr += bio->bi_size; + len -= bio->bi_size; + /* - * TODO: need to fixup sg_tablesize, max_segment_size, - * max_sectors, etc for modern HW and software drivers - * where this value is bogus. - * - * TODO2: we can alloc a reserve buffer of max size - * we can handle and do the slow copy path for really large - * IO. + * The first bio is added and merged. We could probably + * try to add others using scsi_merge_bio() but for now + * we keep it simple. The first bio should be pretty large + * (either hitting the 1 MB bio pages limit or a queue limit) + * already but for really large IO we may want to try and + * merge these. */ - eprintk("Could not handle request of size %u.\n", len); - return err; + if (!rq->bio) { + blk_rq_bio_prep(q, rq, bio); + rq->data_len = bio->bi_size; + } else + /* put list of bios to transfer in next go around */ + bio_list_add(&tcmd->xfer_list, bio); } - tcmd->bio = rq->bio; + cmd->offset = 0; err = scsi_tgt_init_cmd(cmd, GFP_KERNEL); if (err) - goto unmap_rq; + goto unmap_bios; return 0; -unmap_rq: - scsi_unmap_user_pages(tcmd); +unmap_bios: + if (rq->bio) { + bio_unmap_user(rq->bio); + while ((bio = bio_list_pop(&tcmd->xfer_list))) + bio_unmap_user(bio); + } + return err; } +static int scsi_tgt_transfer_data(struct scsi_cmnd *); + +static void scsi_tgt_data_transfer_done(struct scsi_cmnd *cmd) +{ + struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; + struct bio *bio; + int err; + + /* should we free resources here on error ? */ + if (cmd->result) { +send_uspace_err: + err = scsi_tgt_uspace_send_status(cmd, tcmd->tag); + if (err <= 0) + /* the tgt uspace eh will have to pick this up */ + printk(KERN_ERR "Could not send cmd %p status\n", cmd); + return; + } + + dprintk("cmd %p request_bufflen %u bufflen %u\n", + cmd, cmd->request_bufflen, tcmd->bufflen); + + scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); + bio_list_add(&tcmd->xfer_done_list, cmd->request->bio); + + tcmd->buffer += cmd->request_bufflen; + cmd->offset += cmd->request_bufflen; + + if (!tcmd->xfer_list.head) { + scsi_tgt_transfer_response(cmd); + return; + } + + dprintk("cmd2 %p request_bufflen %u bufflen %u\n", + cmd, cmd->request_bufflen, tcmd->bufflen); + + bio = bio_list_pop(&tcmd->xfer_list); + BUG_ON(!bio); + + blk_rq_bio_prep(cmd->request->q, cmd->request, bio); + cmd->request->data_len = bio->bi_size; + err = scsi_tgt_init_cmd(cmd, GFP_ATOMIC); + if (err) { + cmd->result = DID_ERROR << 16; + goto send_uspace_err; + } + + if (scsi_tgt_transfer_data(cmd)) { + cmd->result = DID_NO_CONNECT << 16; + goto send_uspace_err; + } +} + +static int scsi_tgt_transfer_data(struct scsi_cmnd *cmd) +{ + int err; + struct Scsi_Host *host = scsi_tgt_cmd_to_host(cmd); + + err = host->hostt->transfer_data(cmd, scsi_tgt_data_transfer_done); + switch (err) { + case SCSI_MLQUEUE_HOST_BUSY: + case SCSI_MLQUEUE_DEVICE_BUSY: + return -EAGAIN; + default: + return 0; + } +} + static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr, unsigned len) { @@ -459,9 +584,8 @@ static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag) return rq; } -int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, - unsigned long uaddr, u32 len, unsigned long sense_uaddr, - u32 sense_len, u8 rw) +int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len, + unsigned long uaddr, u8 rw) { struct Scsi_Host *shost; struct scsi_cmnd *cmd; @@ -493,9 +617,8 @@ int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, } cmd = rq->special; - dprintk("cmd %p scb %x result %d len %d bufflen %u %lu %x\n", - cmd, cmd->cmnd[0], result, len, cmd->request_bufflen, - rq_data_dir(rq), cmd->cmnd[0]); + dprintk("cmd %p result %d len %d bufflen %u %lu %x\n", cmd, + result, len, cmd->request_bufflen, rq_data_dir(rq), cmd->cmnd[0]); if (result == TASK_ABORTED) { scsi_tgt_abort_cmd(shost, cmd); @@ -506,36 +629,36 @@ int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, * in the request_* values */ tcmd = cmd->request->end_io_data; + tcmd->buffer = (void *)uaddr; + tcmd->bufflen = len; cmd->result = result; - if (cmd->result == SAM_STAT_CHECK_CONDITION) - scsi_tgt_copy_sense(cmd, sense_uaddr, sense_len); - - if (len) { - err = scsi_map_user_pages(rq->end_io_data, cmd, uaddr, len, rw); - if (err) { - /* - * user-space daemon bugs or OOM - * TODO: we can do better for OOM. - */ - struct scsi_tgt_queuedata *qdata; - struct list_head *head; - unsigned long flags; - - eprintk("cmd %p ret %d uaddr %lx len %d rw %d\n", - cmd, err, uaddr, len, rw); - - qdata = shost->uspace_req_q->queuedata; - head = &qdata->cmd_hash[cmd_hashfn(tcmd->tag)]; + if (!tcmd->bufflen || cmd->request_buffer) { + err = __scsi_tgt_transfer_response(cmd); + goto done; + } - spin_lock_irqsave(&qdata->cmd_hash_lock, flags); - list_add(&tcmd->hash_list, head); - spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); + /* + * TODO: Do we need to handle case where request does not + * align with LLD. + */ + err = scsi_map_user_pages(rq->end_io_data, cmd, rw); + if (err) { + eprintk("%p %d\n", cmd, err); + err = -EAGAIN; + goto done; + } - goto done; - } + /* userspace failure */ + if (cmd->result) { + if (status_byte(cmd->result) == CHECK_CONDITION) + scsi_tgt_copy_sense(cmd, uaddr, len); + err = __scsi_tgt_transfer_response(cmd); + goto done; } - err = scsi_tgt_transfer_response(cmd); + /* ask the target LLD to transfer the data to the buffer */ + err = scsi_tgt_transfer_data(cmd); + done: scsi_host_put(shost); return err; diff --git a/trunk/drivers/scsi/scsi_tgt_priv.h b/trunk/drivers/scsi/scsi_tgt_priv.h index e9e6db1c417f..84488c51ff62 100644 --- a/trunk/drivers/scsi/scsi_tgt_priv.h +++ b/trunk/drivers/scsi/scsi_tgt_priv.h @@ -18,9 +18,8 @@ extern int scsi_tgt_if_init(void); extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 tag); extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag); -extern int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, - unsigned long uaddr, u32 len, unsigned long sense_uaddr, - u32 sense_len, u8 rw); +extern int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len, + unsigned long uaddr, u8 rw); extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, struct scsi_lun *scsilun, void *data); extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result); diff --git a/trunk/drivers/scsi/scsi_transport_fc.c b/trunk/drivers/scsi/scsi_transport_fc.c index 14c4f065b2b8..58afdb401703 100644 --- a/trunk/drivers/scsi/scsi_transport_fc.c +++ b/trunk/drivers/scsi/scsi_transport_fc.c @@ -200,8 +200,6 @@ static const struct { { FC_PORTSPEED_2GBIT, "2 Gbit" }, { FC_PORTSPEED_4GBIT, "4 Gbit" }, { FC_PORTSPEED_10GBIT, "10 Gbit" }, - { FC_PORTSPEED_8GBIT, "8 Gbit" }, - { FC_PORTSPEED_16GBIT, "16 Gbit" }, { FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" }, }; fc_bitfield_name_search(port_speed, fc_port_speed_names) diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index caf1836bbeca..aabaa0576ab4 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -49,7 +49,7 @@ struct iscsi_internal { struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; }; -static atomic_t iscsi_session_nr; /* sysfs session id for next new session */ +static int iscsi_session_nr; /* sysfs session id for next new session */ /* * list of registered transports and lock that must @@ -300,7 +300,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) int err; ihost = shost->shost_data; - session->sid = atomic_add_return(1, &iscsi_session_nr); + session->sid = iscsi_session_nr++; session->target_id = target_id; snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", @@ -1419,8 +1419,6 @@ static __init int iscsi_transport_init(void) printk(KERN_INFO "Loading iSCSI transport class v%s.\n", ISCSI_TRANSPORT_VERSION); - atomic_set(&iscsi_session_nr, 0); - err = class_register(&iscsi_transport_class); if (err) return err; diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 00e46662296f..5a8f55fea5ff 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -58,10 +58,16 @@ #include #include #include -#include #include "scsi_logging.h" +/* + * More than enough for everybody ;) The huge number of majors + * is a leftover from 16bit dev_t days, we don't really need that + * much numberspace. + */ +#define SD_MAJORS 16 + MODULE_AUTHOR("Eric Youngdale"); MODULE_DESCRIPTION("SCSI disk (sd) driver"); MODULE_LICENSE("GPL"); @@ -82,9 +88,45 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK12_MAJOR); MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR); MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR); MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR); -MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); -MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); -MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); + +/* + * This is limited by the naming scheme enforced in sd_probe, + * add another character to it if you really need more disks. + */ +#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26) + +/* + * Time out in seconds for disks and Magneto-opticals (which are slower). + */ +#define SD_TIMEOUT (30 * HZ) +#define SD_MOD_TIMEOUT (75 * HZ) + +/* + * Number of allowed retries + */ +#define SD_MAX_RETRIES 5 +#define SD_PASSTHROUGH_RETRIES 1 + +/* + * Size of the initial data buffer for mode and read capacity data + */ +#define SD_BUF_SIZE 512 + +struct scsi_disk { + struct scsi_driver *driver; /* always &sd_template */ + struct scsi_device *device; + struct class_device cdev; + struct gendisk *disk; + unsigned int openers; /* protected by BKL for now, yuck */ + sector_t capacity; /* size in 512-byte sectors */ + u32 index; + u8 media_present; + u8 write_prot; + unsigned WCE : 1; /* state of disk WCE bit */ + unsigned RCD : 1; /* state of disk RCD bit, unused */ + unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ +}; +#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) static DEFINE_IDR(sd_index_idr); static DEFINE_SPINLOCK(sd_index_lock); @@ -94,6 +136,20 @@ static DEFINE_SPINLOCK(sd_index_lock); * object after last put) */ static DEFINE_MUTEX(sd_ref_mutex); +static int sd_revalidate_disk(struct gendisk *disk); +static void sd_rw_intr(struct scsi_cmnd * SCpnt); + +static int sd_probe(struct device *); +static int sd_remove(struct device *); +static void sd_shutdown(struct device *dev); +static void sd_rescan(struct device *); +static int sd_init_command(struct scsi_cmnd *); +static int sd_issue_flush(struct device *, sector_t *); +static void sd_prepare_flush(request_queue_t *, struct request *); +static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname, + unsigned char *buffer); +static void scsi_disk_release(struct class_device *cdev); + static const char *sd_cache_types[] = { "write through", "none", "write back", "write back, no read (daft)" @@ -143,27 +199,13 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT, SD_MAX_RETRIES, &data, &sshdr)) { if (scsi_sense_valid(&sshdr)) - sd_print_sense_hdr(sdkp, &sshdr); + scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr); return -EINVAL; } sd_revalidate_disk(sdkp->disk); return count; } -static ssize_t sd_store_manage_start_stop(struct class_device *cdev, - const char *buf, size_t count) -{ - struct scsi_disk *sdkp = to_scsi_disk(cdev); - struct scsi_device *sdp = sdkp->device; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - sdp->manage_start_stop = simple_strtoul(buf, NULL, 10); - - return count; -} - static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf, size_t count) { @@ -196,14 +238,6 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf) return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); } -static ssize_t sd_show_manage_start_stop(struct class_device *cdev, char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(cdev); - struct scsi_device *sdp = sdkp->device; - - return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); -} - static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(cdev); @@ -217,8 +251,6 @@ static struct class_device_attribute sd_disk_attrs[] = { __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, sd_store_allow_restart), - __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, - sd_store_manage_start_stop), __ATTR_NULL, }; @@ -235,8 +267,6 @@ static struct scsi_driver sd_template = { .name = "sd", .probe = sd_probe, .remove = sd_remove, - .suspend = sd_suspend, - .resume = sd_resume, .shutdown = sd_shutdown, }, .rescan = sd_rescan, @@ -341,19 +371,15 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) unsigned int this_count = SCpnt->request_bufflen >> 9; unsigned int timeout = sdp->timeout; - SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, - "sd_init_command: block=%llu, " - "count=%d\n", - (unsigned long long)block, - this_count)); + SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, " + "count=%d\n", disk->disk_name, + (unsigned long long)block, this_count)); if (!sdp || !scsi_device_online(sdp) || block + rq->nr_sectors > get_capacity(disk)) { - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "Finishing %ld sectors\n", - rq->nr_sectors)); - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "Retry with 0x%p\n", SCpnt)); + SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", + rq->nr_sectors)); + SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); return 0; } @@ -365,8 +391,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ return 0; } - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", - (unsigned long long)block)); + SCSI_LOG_HLQUEUE(2, printk("%s : block=%llu\n", + disk->disk_name, (unsigned long long)block)); /* * If we have a 1K hardware sectorsize, prevent access to single @@ -381,8 +407,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) */ if (sdp->sector_size == 1024) { if ((block & 1) || (rq->nr_sectors & 1)) { - scmd_printk(KERN_ERR, SCpnt, - "Bad block number requested\n"); + printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 1; @@ -391,8 +416,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) } if (sdp->sector_size == 2048) { if ((block & 3) || (rq->nr_sectors & 3)) { - scmd_printk(KERN_ERR, SCpnt, - "Bad block number requested\n"); + printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 2; @@ -401,8 +425,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) } if (sdp->sector_size == 4096) { if ((block & 7) || (rq->nr_sectors & 7)) { - scmd_printk(KERN_ERR, SCpnt, - "Bad block number requested\n"); + printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 3; @@ -419,15 +442,13 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) SCpnt->cmnd[0] = READ_6; SCpnt->sc_data_direction = DMA_FROM_DEVICE; } else { - scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); + printk(KERN_ERR "sd: Unknown command %x\n", rq->cmd_flags); return 0; } - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "%s %d/%ld 512 byte blocks.\n", - (rq_data_dir(rq) == WRITE) ? - "writing" : "reading", this_count, - rq->nr_sectors)); + SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", + disk->disk_name, (rq_data_dir(rq) == WRITE) ? + "writing" : "reading", this_count, rq->nr_sectors)); SCpnt->cmnd[1] = 0; @@ -469,8 +490,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) * during operation and thus turned off * use_10_for_rw. */ - scmd_printk(KERN_ERR, SCpnt, - "FUA write on READ/WRITE(6) drive\n"); + printk(KERN_ERR "sd: FUA write on READ/WRITE(6) drive\n"); return 0; } @@ -529,7 +549,7 @@ static int sd_open(struct inode *inode, struct file *filp) return -ENXIO; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n")); + SCSI_LOG_HLQUEUE(3, printk("sd_open: disk=%s\n", disk->disk_name)); sdev = sdkp->device; @@ -599,7 +619,7 @@ static int sd_release(struct inode *inode, struct file *filp) struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_device *sdev = sdkp->device; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n")); + SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name)); if (!--sdkp->openers && sdev->removable) { if (scsi_block_when_processing_errors(sdev)) @@ -712,7 +732,8 @@ static int sd_media_changed(struct gendisk *disk) struct scsi_device *sdp = sdkp->device; int retval; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); + SCSI_LOG_HLQUEUE(3, printk("sd_media_changed: disk=%s\n", + disk->disk_name)); if (!sdp->removable) return 0; @@ -765,10 +786,9 @@ static int sd_media_changed(struct gendisk *disk) return 1; } -static int sd_sync_cache(struct scsi_disk *sdkp) +static int sd_sync_cache(struct scsi_device *sdp) { int retries, res; - struct scsi_device *sdp = sdkp->device; struct scsi_sense_hdr sshdr; if (!scsi_device_online(sdp)) @@ -789,27 +809,28 @@ static int sd_sync_cache(struct scsi_disk *sdkp) break; } - if (res) { - sd_print_result(sdkp, res); - if (driver_byte(res) & DRIVER_SENSE) - sd_print_sense_hdr(sdkp, &sshdr); + if (res) { printk(KERN_WARNING "FAILED\n status = %x, message = %02x, " + "host = %d, driver = %02x\n ", + status_byte(res), msg_byte(res), + host_byte(res), driver_byte(res)); + if (driver_byte(res) & DRIVER_SENSE) + scsi_print_sense_hdr("sd", &sshdr); } - if (res) - return -EIO; - return 0; + return res; } static int sd_issue_flush(struct device *dev, sector_t *error_sector) { int ret = 0; + struct scsi_device *sdp = to_scsi_device(dev); struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); if (!sdkp) return -ENODEV; if (sdkp->WCE) - ret = sd_sync_cache(sdkp); + ret = sd_sync_cache(sdp); scsi_disk_put(sdkp); return ret; } @@ -907,14 +928,12 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) sense_deferred = scsi_sense_is_deferred(&sshdr); } #ifdef CONFIG_SCSI_LOGGING - SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); + SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", + SCpnt->request->rq_disk->disk_name, result)); if (sense_valid) { - SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, - "sd_rw_intr: sb[respc,sk,asc," - "ascq]=%x,%x,%x,%x\n", - sshdr.response_code, - sshdr.sense_key, sshdr.asc, - sshdr.ascq)); + SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: sb[respc,sk,asc," + "ascq]=%x,%x,%x,%x\n", sshdr.response_code, + sshdr.sense_key, sshdr.asc, sshdr.ascq)); } #endif if (driver_byte(result) != DRIVER_SENSE && @@ -1006,7 +1025,7 @@ static int media_not_present(struct scsi_disk *sdkp, * spinup disk - called only in sd_revalidate_disk() */ static void -sd_spinup_disk(struct scsi_disk *sdkp) +sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) { unsigned char cmd[10]; unsigned long spintime_expire = 0; @@ -1050,10 +1069,9 @@ sd_spinup_disk(struct scsi_disk *sdkp) if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { /* no sense, TUR either succeeded or failed * with a status error */ - if(!spintime && !scsi_status_is_good(the_result)) { - sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n"); - sd_print_result(sdkp, the_result); - } + if(!spintime && !scsi_status_is_good(the_result)) + printk(KERN_NOTICE "%s: Unit Not Ready, " + "error = 0x%x\n", diskname, the_result); break; } @@ -1078,7 +1096,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) */ } else if (sense_valid && sshdr.sense_key == NOT_READY) { if (!spintime) { - sd_printk(KERN_NOTICE, sdkp, "Spinning up disk..."); + printk(KERN_NOTICE "%s: Spinning up disk...", + diskname); cmd[0] = START_STOP; cmd[1] = 1; /* Return immediately */ memset((void *) &cmd[2], 0, 8); @@ -1111,8 +1130,9 @@ sd_spinup_disk(struct scsi_disk *sdkp) /* we don't understand the sense code, so it's * probably pointless to loop */ if(!spintime) { - sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n"); - sd_print_sense_hdr(sdkp, &sshdr); + printk(KERN_NOTICE "%s: Unit Not Ready, " + "sense:\n", diskname); + scsi_print_sense_hdr("", &sshdr); } break; } @@ -1131,7 +1151,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) * read disk capacity */ static void -sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) +sd_read_capacity(struct scsi_disk *sdkp, char *diskname, + unsigned char *buffer) { unsigned char cmd[16]; int the_result, retries; @@ -1170,12 +1191,18 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) } while (the_result && retries); if (the_result && !longrc) { - sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY failed\n"); - sd_print_result(sdkp, the_result); + printk(KERN_NOTICE "%s : READ CAPACITY failed.\n" + "%s : status=%x, message=%02x, host=%d, driver=%02x \n", + diskname, diskname, + status_byte(the_result), + msg_byte(the_result), + host_byte(the_result), + driver_byte(the_result)); + if (driver_byte(the_result) & DRIVER_SENSE) - sd_print_sense_hdr(sdkp, &sshdr); + scsi_print_sense_hdr("sd", &sshdr); else - sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n"); + printk("%s : sense not available. \n", diskname); /* Set dirty bit for removable devices if not ready - * sometimes drives will not report this properly. */ @@ -1191,10 +1218,16 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) return; } else if (the_result && longrc) { /* READ CAPACITY(16) has been failed */ - sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY(16) failed\n"); - sd_print_result(sdkp, the_result); - sd_printk(KERN_NOTICE, sdkp, "Use 0xffffffff as device size\n"); - + printk(KERN_NOTICE "%s : READ CAPACITY(16) failed.\n" + "%s : status=%x, message=%02x, host=%d, driver=%02x \n", + diskname, diskname, + status_byte(the_result), + msg_byte(the_result), + host_byte(the_result), + driver_byte(the_result)); + printk(KERN_NOTICE "%s : use 0xffffffff as device size\n", + diskname); + sdkp->capacity = 1 + (sector_t) 0xffffffff; goto got_data; } @@ -1205,14 +1238,14 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) if (buffer[0] == 0xff && buffer[1] == 0xff && buffer[2] == 0xff && buffer[3] == 0xff) { if(sizeof(sdkp->capacity) > 4) { - sd_printk(KERN_NOTICE, sdkp, "Very big device. " - "Trying to use READ CAPACITY(16).\n"); + printk(KERN_NOTICE "%s : very big device. try to use" + " READ CAPACITY(16).\n", diskname); longrc = 1; goto repeat; } - sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use " - "a kernel compiled with support for large " - "block devices.\n"); + printk(KERN_ERR "%s: too big for this kernel. Use a " + "kernel compiled with support for large block " + "devices.\n", diskname); sdkp->capacity = 0; goto got_data; } @@ -1251,8 +1284,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) got_data: if (sector_size == 0) { sector_size = 512; - sd_printk(KERN_NOTICE, sdkp, "Sector size 0 reported, " - "assuming 512.\n"); + printk(KERN_NOTICE "%s : sector size 0 reported, " + "assuming 512.\n", diskname); } if (sector_size != 512 && @@ -1260,8 +1293,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) sector_size != 2048 && sector_size != 4096 && sector_size != 256) { - sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n", - sector_size); + printk(KERN_NOTICE "%s : unsupported sector size " + "%d.\n", diskname, sector_size); /* * The user might want to re-format the drive with * a supported sectorsize. Once this happens, it @@ -1294,10 +1327,10 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) mb -= sz - 974; sector_div(mb, 1950); - sd_printk(KERN_NOTICE, sdkp, - "%llu %d-byte hardware sectors (%llu MB)\n", - (unsigned long long)sdkp->capacity, - hard_sector, (unsigned long long)mb); + printk(KERN_NOTICE "SCSI device %s: " + "%llu %d-byte hdwr sectors (%llu MB)\n", + diskname, (unsigned long long)sdkp->capacity, + hard_sector, (unsigned long long)mb); } /* Rescale capacity to 512-byte units */ @@ -1329,7 +1362,8 @@ sd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage, * called with buffer of length SD_BUF_SIZE */ static void -sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) +sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, + unsigned char *buffer) { int res; struct scsi_device *sdp = sdkp->device; @@ -1337,7 +1371,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) set_disk_ro(sdkp->disk, 0); if (sdp->skip_ms_page_3f) { - sd_printk(KERN_NOTICE, sdkp, "Assuming Write Enabled\n"); + printk(KERN_NOTICE "%s: assuming Write Enabled\n", diskname); return; } @@ -1369,16 +1403,15 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) } if (!scsi_status_is_good(res)) { - sd_printk(KERN_WARNING, sdkp, - "Test WP failed, assume Write Enabled\n"); + printk(KERN_WARNING + "%s: test WP failed, assume Write Enabled\n", diskname); } else { sdkp->write_prot = ((data.device_specific & 0x80) != 0); set_disk_ro(sdkp->disk, sdkp->write_prot); - sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", - sdkp->write_prot ? "on" : "off"); - sd_printk(KERN_DEBUG, sdkp, - "Mode Sense: %02x %02x %02x %02x\n", - buffer[0], buffer[1], buffer[2], buffer[3]); + printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname, + sdkp->write_prot ? "on" : "off"); + printk(KERN_DEBUG "%s: Mode Sense: %02x %02x %02x %02x\n", + diskname, buffer[0], buffer[1], buffer[2], buffer[3]); } } @@ -1387,7 +1420,8 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) * called with buffer of length SD_BUF_SIZE */ static void -sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) +sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, + unsigned char *buffer) { int len = 0, res; struct scsi_device *sdp = sdkp->device; @@ -1416,7 +1450,8 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) if (!data.header_length) { modepage = 6; - sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response\n"); + printk(KERN_ERR "%s: missing header in MODE_SENSE response\n", + diskname); } /* that went OK, now ask for the proper length */ @@ -1443,12 +1478,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) int offset = data.header_length + data.block_descriptor_length; if (offset >= SD_BUF_SIZE - 2) { - sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n"); + printk(KERN_ERR "%s: malformed MODE SENSE response", + diskname); goto defaults; } if ((buffer[offset] & 0x3f) != modepage) { - sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); + printk(KERN_ERR "%s: got wrong page\n", diskname); goto defaults; } @@ -1462,13 +1498,14 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) sdkp->DPOFUA = (data.device_specific & 0x10) != 0; if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) { - sd_printk(KERN_NOTICE, sdkp, - "Uses READ/WRITE(6), disabling FUA\n"); + printk(KERN_NOTICE "SCSI device %s: uses " + "READ/WRITE(6), disabling FUA\n", diskname); sdkp->DPOFUA = 0; } - sd_printk(KERN_NOTICE, sdkp, - "Write cache: %s, read cache: %s, %s\n", + printk(KERN_NOTICE "SCSI device %s: " + "write cache: %s, read cache: %s, %s\n", + diskname, sdkp->WCE ? "enabled" : "disabled", sdkp->RCD ? "disabled" : "enabled", sdkp->DPOFUA ? "supports DPO and FUA" @@ -1481,13 +1518,15 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) if (scsi_sense_valid(&sshdr) && sshdr.sense_key == ILLEGAL_REQUEST && sshdr.asc == 0x24 && sshdr.ascq == 0x0) - /* Invalid field in CDB */ - sd_printk(KERN_NOTICE, sdkp, "Cache data unavailable\n"); + printk(KERN_NOTICE "%s: cache data unavailable\n", + diskname); /* Invalid field in CDB */ else - sd_printk(KERN_ERR, sdkp, "Asking for cache data failed\n"); + printk(KERN_ERR "%s: asking for cache data failed\n", + diskname); defaults: - sd_printk(KERN_ERR, sdkp, "Assuming drive cache: write through\n"); + printk(KERN_ERR "%s: assuming drive cache: write through\n", + diskname); sdkp->WCE = 0; sdkp->RCD = 0; sdkp->DPOFUA = 0; @@ -1505,8 +1544,7 @@ static int sd_revalidate_disk(struct gendisk *disk) unsigned char *buffer; unsigned ordered; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, - "sd_revalidate_disk\n")); + SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name)); /* * If the device is offline, don't try and read capacity or any @@ -1517,8 +1555,8 @@ static int sd_revalidate_disk(struct gendisk *disk) buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL | __GFP_DMA); if (!buffer) { - sd_printk(KERN_WARNING, sdkp, "sd_revalidate_disk: Memory " - "allocation failure.\n"); + printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation " + "failure.\n"); goto out; } @@ -1530,16 +1568,16 @@ static int sd_revalidate_disk(struct gendisk *disk) sdkp->WCE = 0; sdkp->RCD = 0; - sd_spinup_disk(sdkp); + sd_spinup_disk(sdkp, disk->disk_name); /* * Without media there is no reason to ask; moreover, some devices * react badly if we do. */ if (sdkp->media_present) { - sd_read_capacity(sdkp, buffer); - sd_read_write_protect_flag(sdkp, buffer); - sd_read_cache_type(sdkp, buffer); + sd_read_capacity(sdkp, disk->disk_name, buffer); + sd_read_write_protect_flag(sdkp, disk->disk_name, buffer); + sd_read_cache_type(sdkp, disk->disk_name, buffer); } /* @@ -1671,8 +1709,8 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); add_disk(gd); - sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", - sdp->removable ? "removable " : ""); + sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n", + sdp->removable ? "removable " : "", gd->disk_name); return 0; @@ -1736,31 +1774,6 @@ static void scsi_disk_release(struct class_device *cdev) kfree(sdkp); } -static int sd_start_stop_device(struct scsi_disk *sdkp, int start) -{ - unsigned char cmd[6] = { START_STOP }; /* START_VALID */ - struct scsi_sense_hdr sshdr; - struct scsi_device *sdp = sdkp->device; - int res; - - if (start) - cmd[4] |= 1; /* START */ - - if (!scsi_device_online(sdp)) - return -ENODEV; - - res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, - SD_TIMEOUT, SD_MAX_RETRIES); - if (res) { - sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n"); - sd_print_result(sdkp, res); - if (driver_byte(res) & DRIVER_SENSE) - sd_print_sense_hdr(sdkp, &sshdr); - } - - return res; -} - /* * Send a SYNCHRONIZE CACHE instruction down to the device through * the normal SCSI command structure. Wait for the command to @@ -1768,62 +1781,20 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) */ static void sd_shutdown(struct device *dev) { + struct scsi_device *sdp = to_scsi_device(dev); struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); if (!sdkp) return; /* this can happen */ if (sdkp->WCE) { - sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); - sd_sync_cache(sdkp); - } - - if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - sd_start_stop_device(sdkp, 0); + printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n", + sdkp->disk->disk_name); + sd_sync_cache(sdp); } - scsi_disk_put(sdkp); } -static int sd_suspend(struct device *dev, pm_message_t mesg) -{ - struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); - int ret; - - if (!sdkp) - return 0; /* this can happen */ - - if (sdkp->WCE) { - sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); - ret = sd_sync_cache(sdkp); - if (ret) - return ret; - } - - if (mesg.event == PM_EVENT_SUSPEND && - sdkp->device->manage_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - ret = sd_start_stop_device(sdkp, 0); - if (ret) - return ret; - } - - return 0; -} - -static int sd_resume(struct device *dev) -{ - struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); - - if (!sdkp->device->manage_start_stop) - return 0; - - sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); - - return sd_start_stop_device(sdkp, 1); -} - /** * init_sd - entry point for this driver (both when built in or when * a module). @@ -1881,19 +1852,3 @@ static void __exit exit_sd(void) module_init(init_sd); module_exit(exit_sd); - -static void sd_print_sense_hdr(struct scsi_disk *sdkp, - struct scsi_sense_hdr *sshdr) -{ - sd_printk(KERN_INFO, sdkp, ""); - scsi_show_sense_hdr(sshdr); - sd_printk(KERN_INFO, sdkp, ""); - scsi_show_extd_sense(sshdr->asc, sshdr->ascq); -} - -static void sd_print_result(struct scsi_disk *sdkp, int result) -{ - sd_printk(KERN_INFO, sdkp, ""); - scsi_show_result(result); -} - diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 570977cf9efb..81e3bc7b02a1 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -917,8 +917,6 @@ sg_ioctl(struct inode *inode, struct file *filp, return result; if (val < 0) return -EINVAL; - val = min_t(int, val, - sdp->device->request_queue->max_sectors * 512); if (val != sfp->reserve.bufflen) { if (sg_res_in_use(sfp) || sfp->mmap_called) return -EBUSY; @@ -927,8 +925,7 @@ sg_ioctl(struct inode *inode, struct file *filp, } return 0; case SG_GET_RESERVED_SIZE: - val = min_t(int, sfp->reserve.bufflen, - sdp->device->request_queue->max_sectors * 512); + val = (int) sfp->reserve.bufflen; return put_user(val, ip); case SG_SET_COMMAND_Q: result = get_user(val, ip); @@ -1064,9 +1061,6 @@ sg_ioctl(struct inode *inode, struct file *filp, if (sdp->detached) return -ENODEV; return scsi_ioctl(sdp->device, cmd_in, p); - case BLKSECTGET: - return put_user(sdp->device->request_queue->max_sectors * 512, - ip); default: if (read_only) return -EPERM; /* don't know so take safe approach */ @@ -2345,7 +2339,6 @@ sg_add_sfp(Sg_device * sdp, int dev) { Sg_fd *sfp; unsigned long iflags; - int bufflen; sfp = kzalloc(sizeof(*sfp), GFP_ATOMIC | __GFP_NOWARN); if (!sfp) @@ -2376,9 +2369,7 @@ sg_add_sfp(Sg_device * sdp, int dev) if (unlikely(sg_big_buff != def_reserved_size)) sg_big_buff = def_reserved_size; - bufflen = min_t(int, sg_big_buff, - sdp->device->request_queue->max_sectors * 512); - sg_build_reserve(sfp, bufflen); + sg_build_reserve(sfp, sg_big_buff); SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n", sfp->reserve.bufflen, sfp->reserve.k_use_sg)); return sfp; diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c index f9a52af7f5b4..1857d68e7195 100644 --- a/trunk/drivers/scsi/sr.c +++ b/trunk/drivers/scsi/sr.c @@ -62,8 +62,6 @@ MODULE_DESCRIPTION("SCSI cdrom (sr) driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR); -MODULE_ALIAS_SCSI_DEVICE(TYPE_ROM); -MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); #define SR_DISKS 256 diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index 55bfeccf68a2..98d8411bbccc 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -89,7 +89,6 @@ MODULE_AUTHOR("Kai Makisara"); MODULE_DESCRIPTION("SCSI tape (st) driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR); -MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE); /* Set 'perm' (4th argument) to 0 to disable module_param's definition * of sysfs parameters (which module_param doesn't yet support). diff --git a/trunk/include/asm-i386/voyager.h b/trunk/include/asm-i386/voyager.h index 91a9932937ab..5b27838905b2 100644 --- a/trunk/include/asm-i386/voyager.h +++ b/trunk/include/asm-i386/voyager.h @@ -487,11 +487,15 @@ extern struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS]; extern struct voyager_SUS *voyager_SUS; /* variables exported always */ -extern struct task_struct *voyager_thread; extern int voyager_level; +extern int kvoyagerd_running; +extern struct semaphore kvoyagerd_sem; extern struct voyager_status voyager_status; + + /* functions exported by the voyager and voyager_smp modules */ + extern int voyager_cat_readb(__u8 module, __u8 asic, int reg); extern void voyager_cat_init(void); extern void voyager_detect(struct voyager_bios_info *); diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index 418dfb5adadd..d3bbc7188b6a 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -613,6 +613,7 @@ typedef struct ide_drive_s { u8 quirk_list; /* considered quirky, set for a specific host */ u8 init_speed; /* transfer rate set at boot */ + u8 pio_speed; /* unused by core, used by some drivers for fallback from DMA */ u8 current_speed; /* current transfer rate set */ u8 desired_speed; /* desired transfer rate set */ u8 dn; /* now wide spread use */ diff --git a/trunk/include/scsi/iscsi_proto.h b/trunk/include/scsi/iscsi_proto.h index 8d1e4e8026fe..4a44278ed768 100644 --- a/trunk/include/scsi/iscsi_proto.h +++ b/trunk/include/scsi/iscsi_proto.h @@ -588,17 +588,7 @@ struct iscsi_reject { #define VALUE_MAXLEN 255 #define TARGET_NAME_MAXLEN VALUE_MAXLEN -#define ISCSI_DEF_MAX_RECV_SEG_LEN 8192 -#define ISCSI_MIN_MAX_RECV_SEG_LEN 512 -#define ISCSI_MAX_MAX_RECV_SEG_LEN 16777215 - -#define ISCSI_DEF_FIRST_BURST_LEN 65536 -#define ISCSI_MIN_FIRST_BURST_LEN 512 -#define ISCSI_MAX_FIRST_BURST_LEN 16777215 - -#define ISCSI_DEF_MAX_BURST_LEN 262144 -#define ISCSI_MIN_MAX_BURST_LEN 512 -#define ISCSI_MAX_MAX_BURST_LEN 16777215 +#define DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH 8192 /************************* RFC 3720 End *****************************/ diff --git a/trunk/include/scsi/scsi.h b/trunk/include/scsi/scsi.h index 9f8f80ab0c8b..5c0e9791441c 100644 --- a/trunk/include/scsi/scsi.h +++ b/trunk/include/scsi/scsi.h @@ -203,7 +203,6 @@ static inline int scsi_status_is_good(int status) /* * DEVICE TYPES - * Please keep them in 0x%02x format for $MODALIAS to work */ #define TYPE_DISK 0x00 diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h index a2e0c1032491..d6948d0e8cdb 100644 --- a/trunk/include/scsi/scsi_cmnd.h +++ b/trunk/include/scsi/scsi_cmnd.h @@ -73,6 +73,9 @@ struct scsi_cmnd { unsigned short use_sg; /* Number of pieces of scatter-gather */ unsigned short sglist_len; /* size of malloc'd scatter-gather list */ + /* offset in cmd we are at (for multi-transfer tgt cmds) */ + unsigned offset; + unsigned underflow; /* Return error if less than this amount is transferred */ diff --git a/trunk/include/scsi/scsi_dbg.h b/trunk/include/scsi/scsi_dbg.h index 5a43a4cd96c6..3bbbfbe8cbfc 100644 --- a/trunk/include/scsi/scsi_dbg.h +++ b/trunk/include/scsi/scsi_dbg.h @@ -5,16 +5,14 @@ struct scsi_cmnd; struct scsi_sense_hdr; extern void scsi_print_command(struct scsi_cmnd *); -extern void __scsi_print_command(unsigned char *); -extern void scsi_show_extd_sense(unsigned char, unsigned char); -extern void scsi_show_sense_hdr(struct scsi_sense_hdr *); extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *); -extern void scsi_print_sense(char *, struct scsi_cmnd *); +extern void __scsi_print_command(unsigned char *); +extern void scsi_print_sense(const char *, struct scsi_cmnd *); extern void __scsi_print_sense(const char *name, const unsigned char *sense_buffer, int sense_len); -extern void scsi_show_result(int); -extern void scsi_print_result(struct scsi_cmnd *); +extern void scsi_print_driverbyte(int); +extern void scsi_print_hostbyte(int); extern void scsi_print_status(unsigned char); extern const char *scsi_sense_key_string(unsigned char); extern const char *scsi_extd_sense_format(unsigned char, unsigned char); diff --git a/trunk/include/scsi/scsi_device.h b/trunk/include/scsi/scsi_device.h index 2f3c5b8b1d6a..9dd37e2f5a84 100644 --- a/trunk/include/scsi/scsi_device.h +++ b/trunk/include/scsi/scsi_device.h @@ -5,7 +5,6 @@ #include #include #include -#include #include struct request_queue; @@ -120,7 +119,6 @@ struct scsi_device { unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ unsigned no_start_on_add:1; /* do not issue start on add */ unsigned allow_restart:1; /* issue START_UNIT in error handler */ - unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ unsigned select_no_atn:1; unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ @@ -156,11 +154,8 @@ struct scsi_device { #define sdev_printk(prefix, sdev, fmt, a...) \ dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a) -#define scmd_printk(prefix, scmd, fmt, a...) \ - (scmd)->request->rq_disk ? \ - sdev_printk(prefix, (scmd)->device, "[%s] " fmt, \ - (scmd)->request->rq_disk->disk_name, ##a) : \ - sdev_printk(prefix, (scmd)->device, fmt, ##a) +#define scmd_printk(prefix, scmd, fmt, a...) \ + dev_printk(prefix, &(scmd)->device->sdev_gendev, fmt, ##a) enum scsi_target_state { STARGET_RUNNING = 1, @@ -358,9 +353,4 @@ static inline int scsi_device_qas(struct scsi_device *sdev) return 0; return sdev->inquiry[56] & 0x02; } - -#define MODULE_ALIAS_SCSI_DEVICE(type) \ - MODULE_ALIAS("scsi:t-" __stringify(type) "*") -#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" - #endif /* _SCSI_SCSI_DEVICE_H */ diff --git a/trunk/include/scsi/scsi_host.h b/trunk/include/scsi/scsi_host.h index 68f461b7a835..7f1f411d07af 100644 --- a/trunk/include/scsi/scsi_host.h +++ b/trunk/include/scsi/scsi_host.h @@ -129,11 +129,6 @@ struct scsi_host_template { * the LLD. When the driver is finished processing the command * the done callback is invoked. * - * This is called to inform the LLD to transfer - * cmd->request_bufflen bytes. The cmd->use_sg speciefies the - * number of scatterlist entried in the command and - * cmd->request_buffer contains the scatterlist. - * * return values: see queuecommand * * If the LLD accepts the cmd, it should set the result to an @@ -144,6 +139,20 @@ struct scsi_host_template { /* TODO: rename */ int (* transfer_response)(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); + /* + * This is called to inform the LLD to transfer cmd->request_bufflen + * bytes of the cmd at cmd->offset in the cmd. The cmd->use_sg + * speciefies the number of scatterlist entried in the command + * and cmd->request_buffer contains the scatterlist. + * + * If the command cannot be processed in one transfer_data call + * becuase a scatterlist within the LLD's limits cannot be + * created then transfer_data will be called multiple times. + * It is initially called from process context, and later + * calls are from the interrup context. + */ + int (* transfer_data)(struct scsi_cmnd *, + void (*done)(struct scsi_cmnd *)); /* Used as callback for the completion of task management request. */ int (* tsk_mgmt_response)(u64 mid, int result); @@ -325,19 +334,6 @@ struct scsi_host_template { */ int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int); - /* - * This is an optional routine that allows the transport to become - * involved when a scsi io timer fires. The return value tells the - * timer routine how to finish the io timeout handling: - * EH_HANDLED: I fixed the error, please complete the command - * EH_RESET_TIMER: I need more time, reset the timer and - * begin counting again - * EH_NOT_HANDLED Begin normal error recovery - * - * Status: OPTIONAL - */ - enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *); - /* * suspend support */ diff --git a/trunk/include/scsi/scsi_tgt_if.h b/trunk/include/scsi/scsi_tgt_if.h index 4cf9dff29a2f..07d6e77ae895 100644 --- a/trunk/include/scsi/scsi_tgt_if.h +++ b/trunk/include/scsi/scsi_tgt_if.h @@ -45,13 +45,11 @@ struct tgt_event { /* user-> kernel */ struct { int host_no; + uint32_t len; int result; - aligned_u64 tag; aligned_u64 uaddr; - aligned_u64 sense_uaddr; - uint32_t len; - uint32_t sense_len; uint8_t rw; + aligned_u64 tag; } cmd_rsp; struct { int host_no; diff --git a/trunk/include/scsi/scsi_transport_fc.h b/trunk/include/scsi/scsi_transport_fc.h index 1e797308640a..798f7c7ee426 100644 --- a/trunk/include/scsi/scsi_transport_fc.h +++ b/trunk/include/scsi/scsi_transport_fc.h @@ -108,8 +108,6 @@ enum fc_port_state { #define FC_PORTSPEED_2GBIT 2 #define FC_PORTSPEED_4GBIT 4 #define FC_PORTSPEED_10GBIT 8 -#define FC_PORTSPEED_8GBIT 0x10 -#define FC_PORTSPEED_16GBIT 0x20 #define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */ /* diff --git a/trunk/include/scsi/sd.h b/trunk/include/scsi/sd.h deleted file mode 100644 index 5261488e1108..000000000000 --- a/trunk/include/scsi/sd.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _SCSI_DISK_H -#define _SCSI_DISK_H - -/* - * More than enough for everybody ;) The huge number of majors - * is a leftover from 16bit dev_t days, we don't really need that - * much numberspace. - */ -#define SD_MAJORS 16 - -/* - * This is limited by the naming scheme enforced in sd_probe, - * add another character to it if you really need more disks. - */ -#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26) - -/* - * Time out in seconds for disks and Magneto-opticals (which are slower). - */ -#define SD_TIMEOUT (30 * HZ) -#define SD_MOD_TIMEOUT (75 * HZ) - -/* - * Number of allowed retries - */ -#define SD_MAX_RETRIES 5 -#define SD_PASSTHROUGH_RETRIES 1 - -/* - * Size of the initial data buffer for mode and read capacity data - */ -#define SD_BUF_SIZE 512 - -struct scsi_disk { - struct scsi_driver *driver; /* always &sd_template */ - struct scsi_device *device; - struct class_device cdev; - struct gendisk *disk; - unsigned int openers; /* protected by BKL for now, yuck */ - sector_t capacity; /* size in 512-byte sectors */ - u32 index; - u8 media_present; - u8 write_prot; - unsigned WCE : 1; /* state of disk WCE bit */ - unsigned RCD : 1; /* state of disk RCD bit, unused */ - unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ -}; -#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) - -static int sd_revalidate_disk(struct gendisk *disk); -static void sd_rw_intr(struct scsi_cmnd * SCpnt); -static int sd_probe(struct device *); -static int sd_remove(struct device *); -static void sd_shutdown(struct device *dev); -static int sd_suspend(struct device *dev, pm_message_t state); -static int sd_resume(struct device *dev); -static void sd_rescan(struct device *); -static int sd_init_command(struct scsi_cmnd *); -static int sd_issue_flush(struct device *, sector_t *); -static void sd_prepare_flush(request_queue_t *, struct request *); -static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); -static void scsi_disk_release(struct class_device *cdev); -static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); -static void sd_print_result(struct scsi_disk *, int); - -#define sd_printk(prefix, sdsk, fmt, a...) \ - (sdsk)->disk ? \ - sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ - (sdsk)->disk->disk_name, ##a) : \ - sdev_printk(prefix, (sdsk)->device, fmt, ##a) - -#endif /* _SCSI_DISK_H */ diff --git a/trunk/net/iucv/af_iucv.c b/trunk/net/iucv/af_iucv.c index 2f1373855a8b..d9e9ddb8eac5 100644 --- a/trunk/net/iucv/af_iucv.c +++ b/trunk/net/iucv/af_iucv.c @@ -961,7 +961,7 @@ static void iucv_callback_connack(struct iucv_path *path, u8 ipuser[16]) } static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len, - struct sk_buff_head fragmented_skb_q) + struct sk_buff_head *fragmented_skb_q) { int dataleft, size, copied = 0; struct sk_buff *nskb; @@ -981,8 +981,8 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len, copied += size; dataleft -= size; - nskb->h.raw = nskb->data; - nskb->nh.raw = nskb->data; + skb_reset_transport_header(nskb); + skb_reset_network_header(nskb); nskb->len = size; skb_queue_tail(fragmented_skb_q, nskb);