diff options
author | Len Brown <len.brown@intel.com> | 2004-08-02 06:08:40 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2004-08-02 06:08:40 -0400 |
commit | ec3b036720858caae7951be6d5dfa70e3071eb8b (patch) | |
tree | f5516210ff25363865d804c3eaf478085e0f9922 /drivers | |
parent | 023a2af5c04653827d36d4c9892e029cd83914cf (diff) | |
parent | 81fd00e2e58911325c794b6f98d683ecb7db2b04 (diff) | |
download | history-ec3b036720858caae7951be6d5dfa70e3071eb8b.tar.gz |
Merge intel.com:/home/lenb/bk/linux-2.6.8
into intel.com:/home/lenb/src/linux-acpi-test-2.6.8
Diffstat (limited to 'drivers')
55 files changed, 828 insertions, 538 deletions
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index e33b5357ec5ecc..b2f13752cb5189 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -110,8 +110,8 @@ #endif -extern const struct atmdev_ops fore200e_ops; -extern const struct fore200e_bus fore200e_bus[]; +static const struct atmdev_ops fore200e_ops; +static const struct fore200e_bus fore200e_bus[]; static struct fore200e* fore200e_boards = NULL; diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h index 92e514c79c4845..9da028683bb8a6 100644 --- a/drivers/atm/iphase.h +++ b/drivers/atm/iphase.h @@ -68,8 +68,6 @@ #define IF_IADBG_SUNI_STAT 0x02000000 // suni statistics #define IF_IADBG_RESET 0x04000000 -extern unsigned int IADebugFlag; - #define IF_IADBG(f) if (IADebugFlag & (f)) #ifdef CONFIG_ATM_IA_DEBUG /* Debug build */ diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index afb9d4391a7a6e..c44f27f24847b7 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -33,6 +33,13 @@ config BLK_DEV_SWIM_IOP Say Y here to support the SWIM (Super Woz Integrated Machine) IOP floppy controller on the Macintosh IIfx and Quadra 900/950. +config MAC_FLOPPY + tristate "Support for PowerMac floppy" + depends on PPC_PMAC && !PPC_PMAC64 + help + If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple) + floppy controller, say Y here. Most commonly found in PowerMacs. + config BLK_DEV_PS2 tristate "PS/2 ESDI hard disk support" depends on MCA && MCA_LEGACY diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 7e37bdb44d0a23..5bf390d1b5ff88 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4190,7 +4190,7 @@ static int __init floppy_setup(char *str) printk("\n"); } else DPRINT("botched floppy option\n"); - DPRINT("Read linux/Documentation/floppy.txt\n"); + DPRINT("Read Documentation/floppy.txt\n"); return 0; } diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index e12d4c85eae440..9babb21df10c0c 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -65,7 +65,7 @@ #define URB_ZERO_PACKET 0 #endif -#define VERSION "2.6" +#define VERSION "2.7" static struct usb_driver hci_usb_driver; @@ -98,6 +98,9 @@ static struct usb_device_id blacklist_ids[] = { /* Broadcom BCM2035 */ { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET }, + /* ISSC Bluetooth Adapter v3.1 */ + { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, + /* Digianswer device */ { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c index 97ab1b33fb650c..b6a14c80e23791 100644 --- a/drivers/cdrom/aztcd.c +++ b/drivers/cdrom/aztcd.c @@ -129,7 +129,7 @@ Werner Zimmermann, August 8, 1995 V1.70 Multisession support now is completed, but there is still not enough testing done. If you can test it, please contact me. For - details please read /usr/src/linux/Documentation/cdrom/aztcd + details please read Documentation/cdrom/aztcd Werner Zimmermann, August 19, 1995 V1.80 Modification to suit the new kernel boot procedure introduced with kernel 1.3.33. Will definitely not work with older kernels. diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 5a08b536444c7d..4c271524ea6480 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1921,6 +1921,8 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, struct packet_command cgc; int nr, ret; + cdi->last_sense = 0; + memset(&cgc, 0, sizeof(cgc)); /* @@ -1972,6 +1974,8 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, if (!q) return -ENXIO; + cdi->last_sense = 0; + while (nframes) { nr = nframes; if (cdi->cdda_method == CDDA_BPC_SINGLE) @@ -2019,6 +2023,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, nframes -= nr; lba += nr; + ubuf += len; } return ret; diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c index 62e2d11b382963..caaeb724a3424f 100644 --- a/drivers/cdrom/optcd.c +++ b/drivers/cdrom/optcd.c @@ -964,7 +964,7 @@ static int update_toc(void) #endif /* MULTISESSION */ if (disk_info.multi) printk(KERN_WARNING "optcd: Multisession support experimental, " - "see linux/Documentation/cdrom/optcd\n"); + "see Documentation/cdrom/optcd\n"); DEBUG((DEBUG_TOC, "exiting update_toc")); diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c index cd33f63b97cd0d..a2475c6bb183e3 100644 --- a/drivers/cdrom/sbpcd.c +++ b/drivers/cdrom/sbpcd.c @@ -5715,7 +5715,7 @@ int __init sbpcd_init(void) if (port_index>0) { - msg(DBG_INF, "You should read linux/Documentation/cdrom/sbpcd\n"); + msg(DBG_INF, "You should read Documentation/cdrom/sbpcd\n"); msg(DBG_INF, "and then configure sbpcd.h for your hardware.\n"); } check_datarate(); diff --git a/drivers/cdrom/sbpcd.h b/drivers/cdrom/sbpcd.h index 16a0208a259874..2f2225f13c6f04 100644 --- a/drivers/cdrom/sbpcd.h +++ b/drivers/cdrom/sbpcd.h @@ -5,7 +5,7 @@ /* * Attention! This file contains user-serviceable parts! * I recommend to make use of it... - * If you feel helpless, look into linux/Documentation/cdrom/sbpcd + * If you feel helpless, look into Documentation/cdrom/sbpcd * (good idea anyway, at least before mailing me). * * The definitions for the first controller can get overridden by diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 60c50c2eb1af16..37e06735107522 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -976,14 +976,18 @@ config HPET_RTC_IRQ is assumed the platform called hpet_alloc with the RTC IRQ values for the HPET timers. -config HPET_NOMMAP - bool "HPET - Control mmap capability." - default n +config HPET_MMAP + bool "Allow mmap of HPET" + default y depends on HPET help - If you say Y here, then the mmap interface for the HPET driver returns ENOSYS. - Some hardware implementations might not want all the memory in the page the - HPET control registers reside to be exposed. + If you say Y here, user applications will be able to mmap + the HPET registers. + + In some hardware implementations, the page containing HPET + registers may also contain other things that shouldn't be + exposed to the user. If this applies to your hardware, + say N here. config MAX_RAW_DEVS int "Maximum number of RAW devices to support (1-8192)" diff --git a/drivers/char/README.scc b/drivers/char/README.scc index 8837d8a5dd08e7..90fa4b8aed10a3 100644 --- a/drivers/char/README.scc +++ b/drivers/char/README.scc @@ -2,4 +2,4 @@ The z8530drv is now a network device driver, you can find it in ../net/scc.c A subset of the documentation is in - ../../Documentation/networking/z8530drv.txt + Documentation/networking/z8530drv.txt diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 36d9d2876b1606..5e8c472446ef08 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -1,8 +1,14 @@ /* * Intel & MS High Precision Event Timer Implementation. - * Contributors: + * + * Copyright (C) 2003 Intel Corporation * Venki Pallipadi - * Bob Picco + * (c) Copyright 2004 Hewlett-Packard Development Company, L.P. + * Bob Picco <robert.picco@hp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> @@ -250,9 +256,7 @@ static unsigned int hpet_poll(struct file *file, poll_table * wait) static int hpet_mmap(struct file *file, struct vm_area_struct *vma) { -#ifdef CONFIG_HPET_NOMMAP - return -ENOSYS; -#else +#ifdef CONFIG_HPET_MMAP struct hpet_dev *devp; unsigned long addr; @@ -276,6 +280,8 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) } return 0; +#else + return -ENOSYS; #endif } @@ -901,14 +907,10 @@ static acpi_status __init hpet_resources(struct acpi_resource *res, void *data) hdp->hd_nirqs = irqp->number_of_interrupts; for (i = 0; i < hdp->hd_nirqs; i++) -#ifdef CONFIG_IA64 hdp->hd_irq[i] = acpi_register_gsi(irqp->interrupts[i], irqp->edge_level, irqp->active_high_low); -#else - hdp->hd_irq[i] = irqp->interrupts[i]; -#endif } } diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index de456d01ccea2f..0d3763dc6a50b8 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -72,7 +72,7 @@ /* * There is a bunch of documentation about the card, jumpers, config * settings, restrictions, cables, device names and numbers in - * ../../Documentation/specialix.txt + * Documentation/specialix.txt */ #include <linux/config.h> diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 6c25d34b89390b..5f5bc3b6e8bc59 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1,8 +1,9 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 0.34 Sept 17, 2002 + * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 * * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. + * Portions Copyright (C) 2003 Red Hat Inc * * Thanks to HighPoint Technologies for their assistance, and hardware. * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his @@ -39,6 +40,13 @@ * Reset the hpt366 on error, reset on dma * Fix disabling Fast Interrupt hpt366. * Mike Waychison <crlf@sun.com> + * + * Added support for 372N clocking and clock switching. The 372N needs + * different clocks on read/write. This requires overloading rw_disk and + * other deeply crazy things. Thanks to <http://www.hoerstreich.de> for + * keeping me sane. + * Alan Cox <alan@redhat.com> + * */ @@ -168,6 +176,9 @@ static u32 hpt_revision (struct pci_dev *dev) class_rev &= 0xff; switch(dev->device) { + /* Remap new 372N onto 372 */ + case PCI_DEVICE_ID_TTI_HPT372N: + class_rev = PCI_DEVICE_ID_TTI_HPT372; break; case PCI_DEVICE_ID_TTI_HPT374: class_rev = PCI_DEVICE_ID_TTI_HPT374; break; case PCI_DEVICE_ID_TTI_HPT371: @@ -217,6 +228,11 @@ static u8 hpt3xx_ratemask (ide_drive_t *drive) return mode; } +/* + * Note for the future; the SATA hpt37x we must set + * either PIO or UDMA modes 0,4,5 + */ + static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed) { struct pci_dev *dev = HWIF(drive)->pci_dev; @@ -672,6 +688,69 @@ static int hpt374_ide_dma_end (ide_drive_t *drive) return __ide_dma_end(drive); } +/** + * hpt372n_set_clock - perform clock switching dance + * @drive: Drive to switch + * @mode: Switching mode (0x21 for write, 0x23 otherwise) + * + * Switch the DPLL clock on the HPT372N devices. This is a + * right mess. + */ + +static void hpt372n_set_clock(ide_drive_t *drive, int mode) +{ + ide_hwif_t *hwif = HWIF(drive); + + /* FIXME: should we check for DMA active and BUG() */ + /* Tristate the bus */ + outb(0x80, hwif->dma_base+0x73); + outb(0x80, hwif->dma_base+0x77); + + /* Switch clock and reset channels */ + outb(mode, hwif->dma_base+0x7B); + outb(0xC0, hwif->dma_base+0x79); + + /* Reset state machines */ + outb(0x37, hwif->dma_base+0x70); + outb(0x37, hwif->dma_base+0x74); + + /* Complete reset */ + outb(0x00, hwif->dma_base+0x79); + + /* Reconnect channels to bus */ + outb(0x00, hwif->dma_base+0x73); + outb(0x00, hwif->dma_base+0x77); +} + +/** + * hpt372n_rw_disk - wrapper for I/O + * @drive: drive for command + * @rq: block request structure + * @block: block number + * + * This is called when a disk I/O is issued to the 372N instead + * of the default functionality. We need it because of the clock + * switching + * + */ + +static ide_startstop_t hpt372n_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block) +{ + int wantclock; + + if(rq_data_dir(rq) == READ) + wantclock = 0x21; + else + wantclock = 0x23; + + if(HWIF(drive)->config_data != wantclock) + { + hpt372n_set_clock(drive, wantclock); + HWIF(drive)->config_data = wantclock; + } + return __ide_do_rw_disk(drive, rq, block); +} + /* * Since SUN Cobalt is attempting to do this operation, I should disclose * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date @@ -793,13 +872,23 @@ static int __devinit init_hpt37x(struct pci_dev *dev) u16 freq; u32 pll; u8 reg5bh; - -#if 1 u8 reg5ah = 0; + unsigned long dmabase = pci_resource_start(dev, 4); + u8 did, rid; + int is_372n = 0; + pci_read_config_byte(dev, 0x5a, ®5ah); /* interrupt force enable */ pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10)); -#endif + + if(dmabase) + { + did = inb(dmabase + 0x22); + rid = inb(dmabase + 0x28); + + if((did == 4 && rid == 6) || (did == 5 && rid > 1)) + is_372n = 1; + } /* * default to pci clock. make sure MA15/16 are set to output @@ -810,47 +899,86 @@ static int __devinit init_hpt37x(struct pci_dev *dev) /* * set up the PLL. we need to adjust it so that it's stable. * freq = Tpll * 192 / Tpci + * + * Todo. For non x86 should probably check the dword is + * set to 0xABCDExxx indicating the BIOS saved f_CNT */ pci_read_config_word(dev, 0x78, &freq); freq &= 0x1FF; - if (freq < 0xa0) { - pll = F_LOW_PCI_33; - if (hpt_minimum_revision(dev,8)) - pci_set_drvdata(dev, (void *) thirty_three_base_hpt374); - else if (hpt_minimum_revision(dev,5)) - pci_set_drvdata(dev, (void *) thirty_three_base_hpt372); - else if (hpt_minimum_revision(dev,4)) - pci_set_drvdata(dev, (void *) thirty_three_base_hpt370a); + + /* + * The 372N uses different PCI clock information and has + * some other complications + * On PCI33 timing we must clock switch + * On PCI66 timing we must NOT use the PCI clock + * + * Currently we always set up the PLL for the 372N + */ + + pci_set_drvdata(dev, NULL); + + if(is_372n) + { + printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n"); + if(freq < 0x55) + pll = F_LOW_PCI_33; + else if(freq < 0x70) + pll = F_LOW_PCI_40; + else if(freq < 0x7F) + pll = F_LOW_PCI_50; else - pci_set_drvdata(dev, (void *) thirty_three_base_hpt370); - printk("HPT37X: using 33MHz PCI clock\n"); - } else if (freq < 0xb0) { - pll = F_LOW_PCI_40; - } else if (freq < 0xc8) { - pll = F_LOW_PCI_50; - if (hpt_minimum_revision(dev,8)) - pci_set_drvdata(dev, NULL); - else if (hpt_minimum_revision(dev,5)) - pci_set_drvdata(dev, (void *) fifty_base_hpt372); - else if (hpt_minimum_revision(dev,4)) - pci_set_drvdata(dev, (void *) fifty_base_hpt370a); + pll = F_LOW_PCI_66; + + printk(KERN_INFO "FREQ: %d PLL: %d\n", freq, pll); + + /* We always use the pll not the PCI clock on 372N */ + } + else + { + if(freq < 0x9C) + pll = F_LOW_PCI_33; + else if(freq < 0xb0) + pll = F_LOW_PCI_40; + else if(freq <0xc8) + pll = F_LOW_PCI_50; else - pci_set_drvdata(dev, (void *) fifty_base_hpt370a); - printk("HPT37X: using 50MHz PCI clock\n"); - } else { - pll = F_LOW_PCI_66; - if (hpt_minimum_revision(dev,8)) - { - printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n"); - pci_set_drvdata(dev, NULL); + pll = F_LOW_PCI_66; + + if (pll == F_LOW_PCI_33) { + if (hpt_minimum_revision(dev,8)) + pci_set_drvdata(dev, (void *) thirty_three_base_hpt374); + else if (hpt_minimum_revision(dev,5)) + pci_set_drvdata(dev, (void *) thirty_three_base_hpt372); + else if (hpt_minimum_revision(dev,4)) + pci_set_drvdata(dev, (void *) thirty_three_base_hpt370a); + else + pci_set_drvdata(dev, (void *) thirty_three_base_hpt370); + printk("HPT37X: using 33MHz PCI clock\n"); + } else if (pll == F_LOW_PCI_40) { + /* Unsupported */ + } else if (pll == F_LOW_PCI_50) { + if (hpt_minimum_revision(dev,8)) + pci_set_drvdata(dev, NULL); + else if (hpt_minimum_revision(dev,5)) + pci_set_drvdata(dev, (void *) fifty_base_hpt372); + else if (hpt_minimum_revision(dev,4)) + pci_set_drvdata(dev, (void *) fifty_base_hpt370a); + else + pci_set_drvdata(dev, (void *) fifty_base_hpt370a); + printk("HPT37X: using 50MHz PCI clock\n"); + } else { + if (hpt_minimum_revision(dev,8)) + { + printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n"); + } + else if (hpt_minimum_revision(dev,5)) + pci_set_drvdata(dev, (void *) sixty_six_base_hpt372); + else if (hpt_minimum_revision(dev,4)) + pci_set_drvdata(dev, (void *) sixty_six_base_hpt370a); + else + pci_set_drvdata(dev, (void *) sixty_six_base_hpt370); + printk("HPT37X: using 66MHz PCI clock\n"); } - else if (hpt_minimum_revision(dev,5)) - pci_set_drvdata(dev, (void *) sixty_six_base_hpt372); - else if (hpt_minimum_revision(dev,4)) - pci_set_drvdata(dev, (void *) sixty_six_base_hpt370a); - else - pci_set_drvdata(dev, (void *) sixty_six_base_hpt370); - printk("HPT37X: using 66MHz PCI clock\n"); } /* @@ -863,6 +991,11 @@ static int __devinit init_hpt37x(struct pci_dev *dev) if (pci_get_drvdata(dev)) goto init_hpt37X_done; + if (hpt_minimum_revision(dev,8)) + { + printk(KERN_ERR "HPT374: Only 33MHz PCI timings are supported.\n"); + return -EOPNOTSUPP; + } /* * adjust PLL based upon PCI clock, enable it, and wait for * stabilization. @@ -1000,12 +1133,27 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; u8 ata66 = 0, regmask = (hwif->channel) ? 0x01 : 0x02; - + u8 did, rid; + unsigned long dmabase = hwif->dma_base; + int is_372n = 0; + + if(dmabase) + { + did = inb(dmabase + 0x22); + rid = inb(dmabase + 0x28); + + if((did == 4 && rid == 6) || (did == 5 && rid > 1)) + is_372n = 1; + } + hwif->tuneproc = &hpt3xx_tune_drive; hwif->speedproc = &hpt3xx_tune_chipset; hwif->quirkproc = &hpt3xx_quirkproc; hwif->intrproc = &hpt3xx_intrproc; hwif->maskproc = &hpt3xx_maskproc; + + if(is_372n) + hwif->rw_disk = &hpt372n_rw_disk; /* * The HPT37x uses the CBLID pins as outputs for MA15/MA16 @@ -1179,7 +1327,8 @@ static void __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d u8 pin1 = 0, pin2 = 0; unsigned int class_rev; char *chipset_names[] = {"HPT366", "HPT366", "HPT368", - "HPT370", "HPT370A", "HPT372"}; + "HPT370", "HPT370A", "HPT372", + "HPT372N" }; if (PCI_FUNC(dev->devfn) & 1) return; @@ -1187,9 +1336,14 @@ static void __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; - strcpy(d->name, chipset_names[class_rev]); + if(dev->device == PCI_DEVICE_ID_TTI_HPT372N) + class_rev = 6; + + if(class_rev <= 6) + d->name = chipset_names[class_rev]; switch(class_rev) { + case 6: case 5: case 4: case 3: ide_setup_pci_device(dev, d); @@ -1243,6 +1397,7 @@ static struct pci_device_id hpt366_pci_tbl[] = { { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, + { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, { 0, }, }; MODULE_DEVICE_TABLE(pci, hpt366_pci_tbl); diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 0282df04047061..ecf6830b3b51e3 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -1322,7 +1322,7 @@ static unsigned int dv1394_poll(struct file *file, struct poll_table_struct *wai static int dv1394_fasync(int fd, struct file *file, int on) { /* I just copied this code verbatim from Alan Cox's mouse driver example - (linux/Documentation/DocBook/) */ + (Documentation/DocBook/) */ struct video_card *video = file_to_video_card(file); diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h index c38f8718d8c51b..31299feb766088 100644 --- a/drivers/isdn/hardware/eicon/platform.h +++ b/drivers/isdn/hardware/eicon/platform.h @@ -1,4 +1,4 @@ -/* $Id: platform.h,v 1.37 2004/03/20 17:44:29 armin Exp $ +/* $Id: platform.h,v 1.37.4.1 2004/07/28 14:47:21 armin Exp $ * * platform.h * @@ -214,10 +214,7 @@ void diva_os_free_message_buffer(diva_os_message_buffer_s *dmb); */ static __inline__ void diva_os_sleep(dword mSec) { - unsigned long timeout = HZ * mSec / 1000 + 1; - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(timeout); + msleep(mSec); } static __inline__ void diva_os_wait(dword mSec) { diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 6b2623af12393e..04065ab2610f9f 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c @@ -7,7 +7,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * based on the teles driver from Jan den Ouden * diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index b920679e8eb277..26bb71d96b38a2 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -8,7 +8,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * based on the teles driver from Jan den Ouden * diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 843ed75f82c2ea..2b54e7d6fb98cc 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -9,7 +9,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * Thanks to Eicon Technology for documents and information * diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index 8b6da9ea4cb4ac..b336781296a5ce 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -9,7 +9,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * Thanks to Elsa GmbH for documents and information * diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index c058ccbc51f17f..20042fda89a5fc 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -11,7 +11,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * */ diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c index 270df3bd551b24..20b9499529528c 100644 --- a/drivers/isdn/hisax/isac.c +++ b/drivers/isdn/hisax/isac.c @@ -9,7 +9,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * */ diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c index 35536661b027d6..4d08d27f14995b 100644 --- a/drivers/isdn/hisax/isdnl1.c +++ b/drivers/isdn/hisax/isdnl1.c @@ -10,7 +10,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index da87f1ee623821..d311b5fbf89501 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c @@ -8,7 +8,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c index 5145948dc4a6d6..f571b5d18e91f4 100644 --- a/drivers/isdn/hisax/isdnl3.c +++ b/drivers/isdn/hisax/isdnl3.c @@ -8,7 +8,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c index 23547749478e7c..d6c1c8f8329d86 100644 --- a/drivers/isdn/hisax/l3_1tr6.c +++ b/drivers/isdn/hisax/l3_1tr6.c @@ -9,7 +9,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * */ diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c index 092634c03a1467..ec92308c1efc75 100644 --- a/drivers/isdn/hisax/l3dss1.c +++ b/drivers/isdn/hisax/l3dss1.c @@ -12,7 +12,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c index 6056ac1d767326..082726db39855c 100644 --- a/drivers/isdn/hisax/tei.c +++ b/drivers/isdn/hisax/tei.c @@ -8,7 +8,7 @@ * of the GNU General Public License, incorporated herein by reference. * * For changes and modifications please read - * ../../../Documentation/isdn/HiSax.cert + * Documentation/isdn/HiSax.cert * * Thanks to Jan den Ouden * Fritz Elfert diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c index ee2071b061cd1f..da1d2fb9fc8dd5 100644 --- a/drivers/isdn/i4l/isdn_x25iface.c +++ b/drivers/isdn/i4l/isdn_x25iface.c @@ -8,7 +8,7 @@ * stuff needed to support the Linux X.25 PLP code on top of devices that * can provide a lab_b service using the concap_proto mechanism. * This module supports a network interface wich provides lapb_sematics - * -- as defined in ../../Documentation/networking/x25-iface.txt -- to + * -- as defined in Documentation/networking/x25-iface.txt -- to * the upper layer and assumes that the lower layer provides a reliable * data link service by means of the concap_device_ops callbacks. * @@ -270,7 +270,7 @@ int isdn_x25iface_disconn_ind(struct concap_proto *cprot) } /* process a frame handed over to us from linux network layer. First byte - semantics as defined in ../../Documentation/networking/x25-iface.txt + semantics as defined in Documentation/networking/x25-iface.txt */ int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb) { diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 80b5a8200c726d..f87ed85539d5f1 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -118,13 +118,6 @@ config PMAC_BACKLIGHT events; also, the PowerBook button device will be enabled so you can change the screen brightness. -config MAC_FLOPPY - bool "Support for PowerMac floppy" - depends on PPC_PMAC && !PPC_PMAC64 - help - If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple) - floppy controller, say Y here. Most commonly found in PowerMacs. - config MAC_SERIAL tristate "Support for PowerMac serial ports (OBSOLETE DRIVER)" depends on PPC_PMAC && BROKEN @@ -191,7 +184,7 @@ config THERM_PM72 G5 machines. config ANSLCD - bool "Support for ANS LCD display" + tristate "Support for ANS LCD display" depends on ADB_CUDA && PPC_PMAC endmenu diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c index c4b82b5a88dc56..0e130f598a7909 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c @@ -136,7 +136,7 @@ const char anslcd_logo[] = "********************" /* Line #1 */ "* Welcome to *" /* Line #2 */ "********************"; /* Line #4 */ -int __init +static int __init anslcd_init(void) { int a; @@ -173,5 +173,12 @@ anslcd_init(void) return 0; } -__initcall(anslcd_init); +static void __exit +anslcd_exit(void) +{ + misc_deregister(&anslcd_dev); + iounmap(anslcd_ptr); +} +module_init(anslcd_init); +module_exit(anslcd_exit); diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 67af530004aac7..aa0719775e477f 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -435,6 +435,7 @@ int __pmac check_media_bay(struct device_node *which_bay, int what) #endif /* CONFIG_BLK_DEV_IDE */ return -ENODEV; } +EXPORT_SYMBOL(check_media_bay); int __pmac check_media_bay_by_base(unsigned long base, int what) { diff --git a/drivers/media/dvb/frontends/alps_tdlb7.c b/drivers/media/dvb/frontends/alps_tdlb7.c index 64d95f2f88c95b..cf165f2d576704 100644 --- a/drivers/media/dvb/frontends/alps_tdlb7.c +++ b/drivers/media/dvb/frontends/alps_tdlb7.c @@ -28,8 +28,6 @@ */ - -#define __KERNEL_SYSCALLS__ #include <linux/module.h> #include <linux/init.h> #include <linux/vmalloc.h> @@ -151,13 +149,13 @@ static int sp8870_read_firmware_file (const char *fn, char **fp) loff_t filesize; char *dp; - fd = open(fn, 0, 0); + fd = sys_open(fn, 0, 0); if (fd == -1) { printk("%s: unable to open '%s'.\n", __FUNCTION__, fn); return -EIO; } - filesize = lseek(fd, 0L, 2); + filesize = sys_lseek(fd, 0L, 2); if (filesize <= 0 || filesize < SP8870_FIRMWARE_OFFSET + SP8870_FIRMWARE_SIZE) { printk("%s: firmware filesize to small '%s'\n", __FUNCTION__, fn); sys_close(fd); @@ -171,8 +169,8 @@ static int sp8870_read_firmware_file (const char *fn, char **fp) return -EIO; } - lseek(fd, SP8870_FIRMWARE_OFFSET, 0); - if (read(fd, dp, SP8870_FIRMWARE_SIZE) != SP8870_FIRMWARE_SIZE) { + sys_lseek(fd, SP8870_FIRMWARE_OFFSET, 0); + if (sys_read(fd, dp, SP8870_FIRMWARE_SIZE) != SP8870_FIRMWARE_SIZE) { printk("%s: failed to read '%s'.\n",__FUNCTION__, fn); vfree(dp); sys_close(fd); diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index 3b3a73bb00d737..53ebf4a69b07e2 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c @@ -12,7 +12,6 @@ next 0x4000 loaded. This may change in future versions. */ -#define __KERNEL_SYSCALLS__ #include <linux/kernel.h> #include <linux/vmalloc.h> #include <linux/module.h> @@ -211,13 +210,13 @@ int sp887x_initial_setup (struct dvb_frontend *fe) // Load the firmware set_fs(get_ds()); - fd = open(sp887x_firmware, 0, 0); + fd = sys_open(sp887x_firmware, 0, 0); if (fd < 0) { printk(KERN_WARNING "%s: Unable to open firmware %s\n", __FUNCTION__, sp887x_firmware); return -EIO; } - filesize = lseek(fd, 0L, 2); + filesize = sys_lseek(fd, 0L, 2); if (filesize <= 0) { printk(KERN_WARNING "%s: Firmware %s is empty\n", __FUNCTION__, sp887x_firmware); @@ -239,8 +238,8 @@ int sp887x_initial_setup (struct dvb_frontend *fe) // read it! // read the first 16384 bytes from the file // ignore the first 10 bytes - lseek(fd, 10, 0); - if (read(fd, firmware, fw_size) != fw_size) { + sys_lseek(fd, 10, 0); + if (sys_read(fd, firmware, fw_size) != fw_size) { printk(KERN_WARNING "%s: Failed to read firmware\n", __FUNCTION__); vfree(firmware); sys_close(fd); diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 76a6027dbdb61a..28dc299a8cd5ad 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -32,7 +32,6 @@ */ -#define __KERNEL_SYSCALLS__ #include <linux/kernel.h> #include <linux/vmalloc.h> #include <linux/module.h> @@ -40,7 +39,6 @@ #include <linux/string.h> #include <linux/slab.h> #include <linux/fs.h> -#include <linux/unistd.h> #include <linux/fcntl.h> #include <linux/errno.h> #include <linux/syscalls.h> @@ -399,13 +397,13 @@ static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda // Load the firmware set_fs(get_ds()); - fd = open(tda1004x_firmware, 0, 0); + fd = sys_open(tda1004x_firmware, 0, 0); if (fd < 0) { printk("%s: Unable to open firmware %s\n", __FUNCTION__, tda1004x_firmware); return -EIO; } - filesize = lseek(fd, 0L, 2); + filesize = sys_lseek(fd, 0L, 2); if (filesize <= 0) { printk("%s: Firmware %s is empty\n", __FUNCTION__, tda1004x_firmware); @@ -436,8 +434,8 @@ static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda } // read it! - lseek(fd, fw_offset, 0); - if (read(fd, firmware, fw_size) != fw_size) { + sys_lseek(fd, fw_offset, 0); + if (sys_read(fd, firmware, fw_size) != fw_size) { printk("%s: Failed to read firmware\n", __FUNCTION__); vfree(firmware); sys_close(fd); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6e57c143423081..6917b665b65a48 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4214,13 +4214,6 @@ out: return 0; } -#ifdef CONFIG_NET_FASTROUTE -static int bond_accept_fastpath(struct net_device *bond_dev, struct dst_entry *dst) -{ - return -1; -} -#endif - /*------------------------- Device initialization ---------------------------*/ /* @@ -4294,9 +4287,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par bond_set_mode_ops(bond_dev, bond->params.mode); bond_dev->destructor = free_netdev; -#ifdef CONFIG_NET_FASTROUTE - bond_dev->accept_fastpath = bond_accept_fastpath; -#endif /* Initialize the device options */ bond_dev->tx_queue_len = 0; diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index fc0a851a93f977..7e15c51afd435d 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -57,13 +57,6 @@ static void set_multicast_list(struct net_device *dev) { } -#ifdef CONFIG_NET_FASTROUTE -static int dummy_accept_fastpath(struct net_device *dev, struct dst_entry *dst) -{ - return -1; -} -#endif - static void __init dummy_setup(struct net_device *dev) { /* Initialize the device structure. */ @@ -71,9 +64,6 @@ static void __init dummy_setup(struct net_device *dev) dev->hard_start_xmit = dummy_xmit; dev->set_multicast_list = set_multicast_list; dev->set_mac_address = dummy_set_address; -#ifdef CONFIG_NET_FASTROUTE - dev->accept_fastpath = dummy_accept_fastpath; -#endif /* Fill in device structure with ethernet-generic values. */ ether_setup(dev); diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index f7fc3b9c0a5ce3..2049556d1764f4 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -7,7 +7,7 @@ * ------------------ * * You can find a subset of the documentation in - * linux/Documentation/networking/z8530drv.txt. + * Documentation/networking/z8530drv.txt. */ /* diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index f79e9ab1c5325d..64b35cc250c982 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -79,6 +79,8 @@ #define PPPOE_HASH_BITS 4 #define PPPOE_HASH_SIZE (1<<PPPOE_HASH_BITS) +static struct ppp_channel_ops pppoe_chan_ops; + static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb); static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e5b49ebf6a3e03..0e46154729d4b2 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3635,9 +3635,25 @@ static int tg3_chip_reset(struct tg3 *tp) /* restore 5701 hardware bug workaround flag */ tp->tg3_flags = flags_save; + /* Unfortunately, we have to delay before the PCI read back. + * Some 575X chips even will not respond to a PCI cfg access + * when the reset command is given to the chip. + * + * How do these hardware designers expect things to work + * properly if the PCI write is posted for a long period + * of time? It is always necessary to have some method by + * which a register read back can occur to push the write + * out which does the reset. + * + * For most tg3 variants the trick below was working. + * Ho hum... + */ + udelay(120); + /* Flush PCI posted writes. The normal MMIO registers * are inaccessible at this time so this is the only - * way to make this reliably. I tried to use indirect + * way to make this reliably (actually, this is no longer + * the case, see above). I tried to use indirect * register read/write but this upset some 5701 variants. */ pci_read_config_dword(tp->pdev, PCI_COMMAND, &val); diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 44d21edef3c489..6454331093e67b 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -212,7 +212,7 @@ MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)"); /* Define this to enable Link beat monitoring */ #undef MONITOR -/* Turn on debugging. See linux/Documentation/networking/tlan.txt for details */ +/* Turn on debugging. See Documentation/networking/tlan.txt for details */ static int debug; static int bbuf; diff --git a/drivers/net/wireless/arlan.h b/drivers/net/wireless/arlan.h index eacf37fdd26b3f..a48af699c9c563 100644 --- a/drivers/net/wireless/arlan.h +++ b/drivers/net/wireless/arlan.h @@ -52,7 +52,6 @@ extern int arlan_debug; extern int arlan_entry_debug; extern int arlan_exit_debug; extern int testMemory; -extern const char* arlan_version; extern int arlan_command(struct net_device * dev, int command); #define SIDUNKNOWN -1 diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c index dd50660379043a..3ee31021f1b054 100644 --- a/drivers/net/wireless/prism54/isl_38xx.c +++ b/drivers/net/wireless/prism54/isl_38xx.c @@ -18,8 +18,6 @@ * */ -#define __KERNEL_SYSCALLS__ - #include <linux/version.h> #include <linux/module.h> #include <linux/types.h> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 03681b915a5653..929012e60815a5 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -1,22 +1,15 @@ # # PCI configuration # -config PCI_USE_VECTOR - bool "Vector-based interrupt indexing (MSI)" +config PCI_MSI + bool "Message Signaled Interrupts (MSI and MSI-X)" depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 default n help - This replaces the current existing IRQ-based index interrupt scheme - with the vector-base index scheme. The advantages of vector base - over IRQ base are listed below: - 1) Support MSI implementation. - 2) Support future IOxAPIC hotplug - - Note that this allows the device drivers to enable MSI, Message - Signaled Interrupt, on all MSI capable device functions detected. - Message Signal Interrupt enables an MSI-capable hardware device to - send an inbound Memory Write on its PCI bus instead of asserting - IRQ signal on device IRQ pin. + This allows device drivers to enable MSI (Message Signaled + Interrupts). Message Signaled Interrupts enable a device to + generate an interrupt using an inbound Memory Write on its + PCI bus instead of asserting a device IRQ pin. If you don't know what to do here, say N. diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 260b12b34779ee..377c7238c4cc30 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -26,7 +26,7 @@ obj-$(CONFIG_PPC32) += setup-irq.o obj-$(CONFIG_PPC64) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o obj-$(CONFIG_X86_VISWS) += setup-irq.o -obj-$(CONFIG_PCI_USE_VECTOR) += msi.o +obj-$(CONFIG_PCI_MSI) += msi.o # Cardbus & CompactPCI use setup-bus obj-$(CONFIG_HOTPLUG) += setup-bus.o diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 35c73b9769e07f..d4c89d73e16dda 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -64,15 +64,13 @@ static void msi_set_mask_bit(unsigned int vector, int flag) case PCI_CAP_ID_MSI: { int pos; - unsigned int mask_bits; + u32 mask_bits; pos = entry->mask_base; - entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn, - pos, 4, &mask_bits); + pci_read_config_dword(entry->dev, pos, &mask_bits); mask_bits &= ~(1); mask_bits |= flag; - entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn, - pos, 4, mask_bits); + pci_write_config_dword(entry->dev, pos, mask_bits); break; } case PCI_CAP_ID_MSIX: @@ -105,15 +103,13 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) if (!(pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI))) return; - entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn, - msi_lower_address_reg(pos), 4, + pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), &address.lo_address.value); address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT); entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); - entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn, - msi_lower_address_reg(pos), 4, + pci_write_config_dword(entry->dev, msi_lower_address_reg(pos), address.lo_address.value); break; } @@ -158,13 +154,25 @@ static void unmask_MSI_irq(unsigned int vector) static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector) { + struct msi_desc *entry; + unsigned long flags; + + spin_lock_irqsave(&msi_lock, flags); + entry = msi_desc[vector]; + if (!entry || !entry->dev) { + spin_unlock_irqrestore(&msi_lock, flags); + return 0; + } + entry->msi_attrib.state = 1; /* Mark it active */ + spin_unlock_irqrestore(&msi_lock, flags); + return 0; /* never anything pending */ } -static void pci_disable_msi(unsigned int vector); +static void release_msi(unsigned int vector); static void shutdown_msi_irq(unsigned int vector) { - pci_disable_msi(vector); + release_msi(vector); } #define shutdown_msi_irq_wo_maskbit shutdown_msi_irq @@ -179,6 +187,18 @@ static void end_msi_irq_wo_maskbit(unsigned int vector) static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) { + struct msi_desc *entry; + unsigned long flags; + + spin_lock_irqsave(&msi_lock, flags); + entry = msi_desc[vector]; + if (!entry || !entry->dev) { + spin_unlock_irqrestore(&msi_lock, flags); + return 0; + } + entry->msi_attrib.state = 1; /* Mark it active */ + spin_unlock_irqrestore(&msi_lock, flags); + unmask_MSI_irq(vector); return 0; /* never anything pending */ } @@ -200,7 +220,7 @@ static void end_msi_irq_w_maskbit(unsigned int vector) * which implement the MSI-X Capability Structure. */ static struct hw_interrupt_type msix_irq_type = { - .typename = "PCI MSI-X", + .typename = "PCI-MSI-X", .startup = startup_msi_irq_w_maskbit, .shutdown = shutdown_msi_irq_w_maskbit, .enable = enable_msi_irq_w_maskbit, @@ -216,7 +236,7 @@ static struct hw_interrupt_type msix_irq_type = { * Mask-and-Pending Bits. */ static struct hw_interrupt_type msi_irq_w_maskbit_type = { - .typename = "PCI MSI", + .typename = "PCI-MSI", .startup = startup_msi_irq_w_maskbit, .shutdown = shutdown_msi_irq_w_maskbit, .enable = enable_msi_irq_w_maskbit, @@ -232,7 +252,7 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = { * Mask-and-Pending Bits. */ static struct hw_interrupt_type msi_irq_wo_maskbit_type = { - .typename = "PCI MSI", + .typename = "PCI-MSI", .startup = startup_msi_irq_wo_maskbit, .shutdown = shutdown_msi_irq_wo_maskbit, .enable = enable_msi_irq_wo_maskbit, @@ -265,6 +285,7 @@ static void msi_address_init(struct msg_address *msi_address) msi_address->lo_address.value |= (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT); } +static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); static int assign_msi_vector(void) { static int new_vector_avail = 1; @@ -278,6 +299,8 @@ static int assign_msi_vector(void) spin_lock_irqsave(&msi_lock, flags); if (!new_vector_avail) { + int free_vector = 0; + /* * vector_irq[] = -1 indicates that this specific vector is: * - assigned for MSI (since MSI have no associated IRQ) or @@ -294,13 +317,34 @@ static int assign_msi_vector(void) for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) { if (vector_irq[vector] != 0) continue; - vector_irq[vector] = -1; - nr_released_vectors--; + free_vector = vector; + if (!msi_desc[vector]) + break; + else + continue; + } + if (!free_vector) { spin_unlock_irqrestore(&msi_lock, flags); - return vector; + return -EBUSY; } + vector_irq[free_vector] = -1; + nr_released_vectors--; spin_unlock_irqrestore(&msi_lock, flags); - return -EBUSY; + if (msi_desc[free_vector] != NULL) { + struct pci_dev *dev; + int tail; + + /* free all linked vectors before re-assign */ + do { + spin_lock_irqsave(&msi_lock, flags); + dev = msi_desc[free_vector]->dev; + tail = msi_desc[free_vector]->link.tail; + spin_unlock_irqrestore(&msi_lock, flags); + msi_free_vector(dev, tail, 1); + } while (free_vector != tail); + } + + return free_vector; } vector = assign_irq_vector(AUTO_ASSIGN); last_alloc_vector = vector; @@ -333,6 +377,15 @@ static int msi_init(void) printk(KERN_INFO "WARNING: MSI INIT FAILURE\n"); return status; } + last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); + if (last_alloc_vector < 0) { + pci_msi_enable = 0; + printk(KERN_INFO "WARNING: ALL VECTORS ARE BUSY\n"); + status = -EBUSY; + return status; + } + vector_irq[last_alloc_vector] = 0; + nr_released_vectors++; printk(KERN_INFO "MSI INIT SUCCESS\n"); return status; @@ -383,55 +436,49 @@ static void irq_handler_init(int cap_id, int pos, int mask) static void enable_msi_mode(struct pci_dev *dev, int pos, int type) { - u32 control; + u16 control; - dev->bus->ops->read(dev->bus, dev->devfn, - msi_control_reg(pos), 2, &control); + pci_read_config_word(dev, msi_control_reg(pos), &control); if (type == PCI_CAP_ID_MSI) { /* Set enabled bits to single MSI & enable MSI_enable bit */ msi_enable(control, 1); - dev->bus->ops->write(dev->bus, dev->devfn, - msi_control_reg(pos), 2, control); + pci_write_config_word(dev, msi_control_reg(pos), control); } else { msix_enable(control); - dev->bus->ops->write(dev->bus, dev->devfn, - msi_control_reg(pos), 2, control); + pci_write_config_word(dev, msi_control_reg(pos), control); } if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { /* PCI Express Endpoint device detected */ - u32 cmd; - dev->bus->ops->read(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd); + u16 cmd; + pci_read_config_word(dev, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_INTX_DISABLE; - dev->bus->ops->write(dev->bus, dev->devfn, PCI_COMMAND, 2, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); } } static void disable_msi_mode(struct pci_dev *dev, int pos, int type) { - u32 control; + u16 control; - dev->bus->ops->read(dev->bus, dev->devfn, - msi_control_reg(pos), 2, &control); + pci_read_config_word(dev, msi_control_reg(pos), &control); if (type == PCI_CAP_ID_MSI) { /* Set enabled bits to single MSI & enable MSI_enable bit */ msi_disable(control); - dev->bus->ops->write(dev->bus, dev->devfn, - msi_control_reg(pos), 2, control); + pci_write_config_word(dev, msi_control_reg(pos), control); } else { msix_disable(control); - dev->bus->ops->write(dev->bus, dev->devfn, - msi_control_reg(pos), 2, control); + pci_write_config_word(dev, msi_control_reg(pos), control); } if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { /* PCI Express Endpoint device detected */ - u32 cmd; - dev->bus->ops->read(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd); + u16 cmd; + pci_read_config_word(dev, PCI_COMMAND, &cmd); cmd &= ~PCI_COMMAND_INTX_DISABLE; - dev->bus->ops->write(dev->bus, dev->devfn, PCI_COMMAND, 2, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); } } -static int msi_lookup_vector(struct pci_dev *dev) +static int msi_lookup_vector(struct pci_dev *dev, int type) { int vector; unsigned long flags; @@ -439,11 +486,11 @@ static int msi_lookup_vector(struct pci_dev *dev) spin_lock_irqsave(&msi_lock, flags); for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) { if (!msi_desc[vector] || msi_desc[vector]->dev != dev || - msi_desc[vector]->msi_attrib.entry_nr || + msi_desc[vector]->msi_attrib.type != type || msi_desc[vector]->msi_attrib.default_vector != dev->irq) - continue; /* not entry 0, skip */ + continue; spin_unlock_irqrestore(&msi_lock, flags); - /* This pre-assigned entry-0 MSI vector for this device + /* This pre-assigned MSI vector for this device already exits. Override dev->irq with this vector */ dev->irq = vector; return 0; @@ -458,10 +505,9 @@ void pci_scan_msi_device(struct pci_dev *dev) if (!dev) return; - if (pci_find_capability(dev, PCI_CAP_ID_MSIX) > 0) { - nr_reserved_vectors++; + if (pci_find_capability(dev, PCI_CAP_ID_MSIX) > 0) nr_msix_devices++; - } else if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0) + else if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0) nr_reserved_vectors++; } @@ -480,22 +526,10 @@ static int msi_capability_init(struct pci_dev *dev) struct msg_address address; struct msg_data data; int pos, vector; - u32 control; + u16 control; pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (!pos) - return -EINVAL; - - dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), - 2, &control); - if (control & PCI_MSI_FLAGS_ENABLE) - return 0; - - if (!msi_lookup_vector(dev)) { - /* Lookup Sucess */ - enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); - return 0; - } + pci_read_config_word(dev, msi_control_reg(pos), &control); /* MSI Entry Initialization */ if (!(entry = alloc_msi_entry())) return -ENOMEM; @@ -504,11 +538,14 @@ static int msi_capability_init(struct pci_dev *dev) kmem_cache_free(msi_cachep, entry); return -EBUSY; } + entry->link.head = vector; + entry->link.tail = vector; entry->msi_attrib.type = PCI_CAP_ID_MSI; + entry->msi_attrib.state = 0; /* Mark it not active */ entry->msi_attrib.entry_nr = 0; entry->msi_attrib.maskbit = is_mask_bit_support(control); - entry->msi_attrib.default_vector = dev->irq; - dev->irq = vector; /* save default pre-assigned ioapic vector */ + entry->msi_attrib.default_vector = dev->irq; /* Save IOAPIC IRQ */ + dev->irq = vector; entry->dev = dev; if (is_mask_bit_support(control)) { entry->mask_base = msi_mask_bits_reg(pos, @@ -521,27 +558,27 @@ static int msi_capability_init(struct pci_dev *dev) msi_data_init(&data, vector); entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); - dev->bus->ops->write(dev->bus, dev->devfn, msi_lower_address_reg(pos), - 4, address.lo_address.value); + pci_write_config_dword(dev, msi_lower_address_reg(pos), + address.lo_address.value); if (is_64bit_address(control)) { - dev->bus->ops->write(dev->bus, dev->devfn, - msi_upper_address_reg(pos), 4, address.hi_address); - dev->bus->ops->write(dev->bus, dev->devfn, - msi_data_reg(pos, 1), 2, *((u32*)&data)); + pci_write_config_dword(dev, + msi_upper_address_reg(pos), address.hi_address); + pci_write_config_word(dev, + msi_data_reg(pos, 1), *((u32*)&data)); } else - dev->bus->ops->write(dev->bus, dev->devfn, - msi_data_reg(pos, 0), 2, *((u32*)&data)); + pci_write_config_word(dev, + msi_data_reg(pos, 0), *((u32*)&data)); if (entry->msi_attrib.maskbit) { unsigned int maskbits, temp; /* All MSIs are unmasked by default, Mask them all */ - dev->bus->ops->read(dev->bus, dev->devfn, - msi_mask_bits_reg(pos, is_64bit_address(control)), 4, + pci_read_config_dword(dev, + msi_mask_bits_reg(pos, is_64bit_address(control)), &maskbits); temp = (1 << multi_msi_capable(control)); temp = ((temp - 1) & ~temp); maskbits |= temp; - dev->bus->ops->write(dev->bus, dev->devfn, - msi_mask_bits_reg(pos, is_64bit_address(control)), 4, + pci_write_config_dword(dev, + msi_mask_bits_reg(pos, is_64bit_address(control)), maskbits); } attach_msi_entry(entry, vector); @@ -556,238 +593,219 @@ static int msi_capability_init(struct pci_dev *dev) * @dev: pointer to the pci_dev data structure of MSI-X device function * * Setup the MSI-X capability structure of device funtion with a - * single MSI-X vector. A return of zero indicates the successful setup - * of an entry zero with the new MSI-X vector or non-zero for otherwise. - * To request for additional MSI-X vectors, the device drivers are - * required to utilize the following supported APIs: - * 1) msi_alloc_vectors(...) for requesting one or more MSI-X vectors - * 2) msi_free_vectors(...) for releasing one or more MSI-X vectors - * back to PCI subsystem before calling free_irq(...) + * single MSI-X vector. A return of zero indicates the successful setup of + * requested MSI-X entries with allocated vectors or non-zero for otherwise. **/ -static int msix_capability_init(struct pci_dev *dev) +static int msix_capability_init(struct pci_dev *dev, + struct msix_entry *entries, int nvec) { - struct msi_desc *entry; + struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; struct msg_address address; struct msg_data data; - int vector = 0, pos, dev_msi_cap, i; + int vector, pos, i, j, nr_entries, temp = 0; u32 phys_addr, table_offset; - u32 control; + u16 control; u8 bir; void *base; pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (!pos) - return -EINVAL; - /* Request & Map MSI-X table region */ - dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), 2, - &control); - if (control & PCI_MSIX_FLAGS_ENABLE) - return 0; - - if (!msi_lookup_vector(dev)) { - /* Lookup Sucess */ - enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); - return 0; - } - - dev_msi_cap = multi_msix_capable(control); - dev->bus->ops->read(dev->bus, dev->devfn, - msix_table_offset_reg(pos), 4, &table_offset); + pci_read_config_word(dev, msi_control_reg(pos), &control); + nr_entries = multi_msix_capable(control); + pci_read_config_dword(dev, msix_table_offset_reg(pos), + &table_offset); bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); phys_addr = pci_resource_start (dev, bir); phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK); if (!request_mem_region(phys_addr, - dev_msi_cap * PCI_MSIX_ENTRY_SIZE, - "MSI-X iomap Failure")) + nr_entries * PCI_MSIX_ENTRY_SIZE, + "MSI-X vector table")) return -ENOMEM; - base = ioremap_nocache(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE); - if (base == NULL) - goto free_region; - /* MSI Entry Initialization */ - entry = alloc_msi_entry(); - if (!entry) - goto free_iomap; - if ((vector = get_msi_vector(dev)) < 0) - goto free_entry; + base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); + if (base == NULL) { + release_mem_region(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); + return -ENOMEM; + } + /* MSI-X Table Initialization */ + for (i = 0; i < nvec; i++) { + entry = alloc_msi_entry(); + if (!entry) + break; + if ((vector = get_msi_vector(dev)) < 0) + break; - entry->msi_attrib.type = PCI_CAP_ID_MSIX; - entry->msi_attrib.entry_nr = 0; - entry->msi_attrib.maskbit = 1; - entry->msi_attrib.default_vector = dev->irq; - dev->irq = vector; /* save default pre-assigned ioapic vector */ - entry->dev = dev; - entry->mask_base = (unsigned long)base; - /* Replace with MSI handler */ - irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); - /* Configure MSI-X capability structure */ - msi_address_init(&address); - msi_data_init(&data, vector); - entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> - MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); - writel(address.lo_address.value, base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(address.hi_address, base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(*(u32*)&data, base + PCI_MSIX_ENTRY_DATA_OFFSET); - /* Initialize all entries from 1 up to 0 */ - for (i = 1; i < dev_msi_cap; i++) { - writel(0, base + i * PCI_MSIX_ENTRY_SIZE + + j = entries[i].entry; + entries[i].vector = vector; + entry->msi_attrib.type = PCI_CAP_ID_MSIX; + entry->msi_attrib.state = 0; /* Mark it not active */ + entry->msi_attrib.entry_nr = j; + entry->msi_attrib.maskbit = 1; + entry->msi_attrib.default_vector = dev->irq; + entry->dev = dev; + entry->mask_base = (unsigned long)base; + if (!head) { + entry->link.head = vector; + entry->link.tail = vector; + head = entry; + } else { + entry->link.head = temp; + entry->link.tail = tail->link.tail; + tail->link.tail = vector; + head->link.head = vector; + } + temp = vector; + tail = entry; + /* Replace with MSI-X handler */ + irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); + /* Configure MSI-X capability structure */ + msi_address_init(&address); + msi_data_init(&data, vector); + entry->msi_attrib.current_cpu = + ((address.lo_address.u.dest_id >> + MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); + writel(address.lo_address.value, + base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(0, base + i * PCI_MSIX_ENTRY_SIZE + + writel(address.hi_address, + base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(0, base + i * PCI_MSIX_ENTRY_SIZE + + writel(*(u32*)&data, + base + j * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_DATA_OFFSET); + attach_msi_entry(entry, vector); } - attach_msi_entry(entry, vector); - /* Set MSI enabled bits */ + if (i != nvec) { + i--; + for (; i >= 0; i--) { + vector = (entries + i)->vector; + msi_free_vector(dev, vector, 0); + (entries + i)->vector = 0; + } + return -EBUSY; + } + /* Set MSI-X enabled bits */ enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); return 0; - -free_entry: - kmem_cache_free(msi_cachep, entry); -free_iomap: - iounmap(base); -free_region: - release_mem_region(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE); - - return ((vector < 0) ? -EBUSY : -ENOMEM); } /** - * pci_enable_msi - configure device's MSI(X) capability structure - * @dev: pointer to the pci_dev data structure of MSI(X) device function + * pci_enable_msi - configure device's MSI capability structure + * @dev: pointer to the pci_dev data structure of MSI device function * - * Setup the MSI/MSI-X capability structure of device function with - * a single MSI(X) vector upon its software driver call to request for - * MSI(X) mode enabled on its hardware device function. A return of zero - * indicates the successful setup of an entry zero with the new MSI(X) + * Setup the MSI capability structure of device function with + * a single MSI vector upon its software driver call to request for + * MSI mode enabled on its hardware device function. A return of zero + * indicates the successful setup of an entry zero with the new MSI * vector or non-zero for otherwise. **/ int pci_enable_msi(struct pci_dev* dev) { - int status = -EINVAL; + int pos, temp = dev->irq, status = -EINVAL; + u16 control; if (!pci_msi_enable || !dev) return status; - if (msi_init() < 0) - return -ENOMEM; + if ((status = msi_init()) < 0) + return status; - if ((status = msix_capability_init(dev)) == -EINVAL) - status = msi_capability_init(dev); - if (!status) - nr_reserved_vectors--; + if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSI))) + return -EINVAL; + + pci_read_config_word(dev, msi_control_reg(pos), &control); + if (control & PCI_MSI_FLAGS_ENABLE) + return 0; /* Already in MSI mode */ + + if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { + /* Lookup Sucess */ + unsigned long flags; + + spin_lock_irqsave(&msi_lock, flags); + if (!vector_irq[dev->irq]) { + msi_desc[dev->irq]->msi_attrib.state = 0; + vector_irq[dev->irq] = -1; + nr_released_vectors--; + spin_unlock_irqrestore(&msi_lock, flags); + enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); + return 0; + } + spin_unlock_irqrestore(&msi_lock, flags); + dev->irq = temp; + } + /* Check whether driver already requested for MSI-X vectors */ + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 && + !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { + printk(KERN_INFO "Can't enable MSI. Device already had MSI-X vectors assigned\n"); + dev->irq = temp; + return -EINVAL; + } + status = msi_capability_init(dev); + if (!status) { + if (!pos) + nr_reserved_vectors--; /* Only MSI capable */ + else if (nr_msix_devices > 0) + nr_msix_devices--; /* Both MSI and MSI-X capable, + but choose enabling MSI */ + } return status; } -static int msi_free_vector(struct pci_dev* dev, int vector); -static void pci_disable_msi(unsigned int vector) +void pci_disable_msi(struct pci_dev* dev) { - int head, tail, type, default_vector; struct msi_desc *entry; - struct pci_dev *dev; + int pos, default_vector; + u16 control; unsigned long flags; + if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSI))) + return; + + pci_read_config_word(dev, msi_control_reg(pos), &control); + if (!(control & PCI_MSI_FLAGS_ENABLE)) + return; + spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[vector]; - if (!entry || !entry->dev) { + entry = msi_desc[dev->irq]; + if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { spin_unlock_irqrestore(&msi_lock, flags); return; } - dev = entry->dev; - type = entry->msi_attrib.type; - head = entry->link.head; - tail = entry->link.tail; - default_vector = entry->msi_attrib.default_vector; - spin_unlock_irqrestore(&msi_lock, flags); - - disable_msi_mode(dev, pci_find_capability(dev, type), type); - /* Restore dev->irq to its default pin-assertion vector */ - dev->irq = default_vector; - if (type == PCI_CAP_ID_MSIX && head != tail) { - /* Bad driver, which do not call msi_free_vectors before exit. - We must do a cleanup here */ - while (1) { - spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[vector]; - head = entry->link.head; - tail = entry->link.tail; - spin_unlock_irqrestore(&msi_lock, flags); - if (tail == head) - break; - if (msi_free_vector(dev, entry->link.tail)) - break; - } + if (entry->msi_attrib.state) { + spin_unlock_irqrestore(&msi_lock, flags); + printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n", + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + dev->irq); + BUG_ON(entry->msi_attrib.state > 0); + } else { + vector_irq[dev->irq] = 0; /* free it */ + nr_released_vectors++; + default_vector = entry->msi_attrib.default_vector; + spin_unlock_irqrestore(&msi_lock, flags); + /* Restore dev->irq to its default pin-assertion vector */ + dev->irq = default_vector; + disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), + PCI_CAP_ID_MSI); } } -static int msi_alloc_vector(struct pci_dev* dev, int head) +static void release_msi(unsigned int vector) { struct msi_desc *entry; - struct msg_address address; - struct msg_data data; - int i, offset, pos, dev_msi_cap, vector; - u32 low_address, control; - unsigned long base = 0L; unsigned long flags; spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[dev->irq]; - if (!entry) { - spin_unlock_irqrestore(&msi_lock, flags); - return -EINVAL; - } - base = entry->mask_base; + entry = msi_desc[vector]; + if (entry && entry->dev) + entry->msi_attrib.state = 0; /* Mark it not active */ spin_unlock_irqrestore(&msi_lock, flags); - - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), - 2, &control); - dev_msi_cap = multi_msix_capable(control); - for (i = 1; i < dev_msi_cap; i++) { - if (!(low_address = readl(base + i * PCI_MSIX_ENTRY_SIZE))) - break; - } - if (i >= dev_msi_cap) - return -EINVAL; - - /* MSI Entry Initialization */ - if (!(entry = alloc_msi_entry())) - return -ENOMEM; - - if ((vector = get_new_vector()) < 0) { - kmem_cache_free(msi_cachep, entry); - return vector; - } - entry->msi_attrib.type = PCI_CAP_ID_MSIX; - entry->msi_attrib.entry_nr = i; - entry->msi_attrib.maskbit = 1; - entry->dev = dev; - entry->link.head = head; - entry->mask_base = base; - irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); - /* Configure MSI-X capability structure */ - msi_address_init(&address); - msi_data_init(&data, vector); - entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> - MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); - offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; - writel(address.lo_address.value, base + offset + - PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); - writel(address.hi_address, base + offset + - PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); - writel(*(u32*)&data, base + offset + PCI_MSIX_ENTRY_DATA_OFFSET); - writel(1, base + offset + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); - attach_msi_entry(entry, vector); - - return vector; } -static int msi_free_vector(struct pci_dev* dev, int vector) +static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) { struct msi_desc *entry; - int entry_nr, type; + int head, entry_nr, type; unsigned long base = 0L; unsigned long flags; @@ -799,66 +817,177 @@ static int msi_free_vector(struct pci_dev* dev, int vector) } type = entry->msi_attrib.type; entry_nr = entry->msi_attrib.entry_nr; + head = entry->link.head; base = entry->mask_base; - if (entry->link.tail != entry->link.head) { - msi_desc[entry->link.head]->link.tail = entry->link.tail; - if (entry->link.tail) - msi_desc[entry->link.tail]->link.head = entry->link.head; - } + msi_desc[entry->link.head]->link.tail = entry->link.tail; + msi_desc[entry->link.tail]->link.head = entry->link.head; entry->dev = NULL; - vector_irq[vector] = 0; - nr_released_vectors++; + if (!reassign) { + vector_irq[vector] = 0; + nr_released_vectors++; + } msi_desc[vector] = NULL; spin_unlock_irqrestore(&msi_lock, flags); kmem_cache_free(msi_cachep, entry); + if (type == PCI_CAP_ID_MSIX) { - int offset; + if (!reassign) + writel(1, base + + entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); + + if (head == vector) { + /* + * Detect last MSI-X vector to be released. + * Release the MSI-X memory-mapped table. + */ + int pos, nr_entries; + u32 phys_addr, table_offset; + u16 control; + u8 bir; + + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + pci_read_config_word(dev, msi_control_reg(pos), + &control); + nr_entries = multi_msix_capable(control); + pci_read_config_dword(dev, msix_table_offset_reg(pos), + &table_offset); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); + phys_addr = pci_resource_start (dev, bir); + phys_addr += (u32)(table_offset & + ~PCI_MSIX_FLAGS_BIRMASK); + iounmap((void*)base); + release_mem_region(phys_addr, + nr_entries * PCI_MSIX_ENTRY_SIZE); + } + } - offset = entry_nr * PCI_MSIX_ENTRY_SIZE; - writel(1, base + offset + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); - writel(0, base + offset + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); + return 0; +} + +static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec) +{ + int vector = head, tail = 0; + int i = 0, j = 0, nr_entries = 0; + unsigned long base = 0L; + unsigned long flags; + + spin_lock_irqsave(&msi_lock, flags); + while (head != tail) { + nr_entries++; + tail = msi_desc[vector]->link.tail; + if (entries[0].entry == msi_desc[vector]->msi_attrib.entry_nr) + j = vector; + vector = tail; } + if (*nvec > nr_entries) { + spin_unlock_irqrestore(&msi_lock, flags); + *nvec = nr_entries; + return -EINVAL; + } + vector = ((j > 0) ? j : head); + for (i = 0; i < *nvec; i++) { + j = msi_desc[vector]->msi_attrib.entry_nr; + msi_desc[vector]->msi_attrib.state = 0; /* Mark it not active */ + vector_irq[vector] = -1; /* Mark it busy */ + nr_released_vectors--; + entries[i].vector = vector; + if (j != (entries + i)->entry) { + base = msi_desc[vector]->mask_base; + msi_desc[vector]->msi_attrib.entry_nr = + (entries + i)->entry; + writel( readl(base + j * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET), base + + (entries + i)->entry * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); + writel( readl(base + j * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET), base + + (entries + i)->entry * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); + writel( (readl(base + j * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_DATA_OFFSET) & 0xff00) | vector, + base + (entries+i)->entry*PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_DATA_OFFSET); + } + vector = msi_desc[vector]->link.tail; + } + spin_unlock_irqrestore(&msi_lock, flags); return 0; } /** - * msi_alloc_vectors - allocate additional MSI-X vectors + * pci_enable_msix - configure device's MSI-X capability structure * @dev: pointer to the pci_dev data structure of MSI-X device function - * @vector: pointer to an array of new allocated MSI-X vectors + * @data: pointer to an array of MSI-X entries * @nvec: number of MSI-X vectors requested for allocation by device driver * - * Allocate additional MSI-X vectors requested by device driver. A - * return of zero indicates the successful setup of MSI-X capability - * structure with new allocated MSI-X vectors or non-zero for otherwise. + * Setup the MSI-X capability structure of device function with the number + * of requested vectors upon its software driver call to request for + * MSI-X mode enabled on its hardware device function. A return of zero + * indicates the successful configuration of MSI-X capability structure + * with new allocated MSI-X vectors. A return of < 0 indicates a failure. + * Or a return of > 0 indicates that driver request is exceeding the number + * of vectors available. Driver should use the returned value to re-send + * its request. **/ -int msi_alloc_vectors(struct pci_dev* dev, int *vector, int nvec) +int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) { - struct msi_desc *entry; - int i, head, pos, vec, free_vectors, alloc_vectors; - int *vectors = (int *)vector; - u32 control; + int status, pos, nr_entries, free_vectors; + int i, j, temp; + u16 control; unsigned long flags; - if (!pci_msi_enable || !dev) + if (!pci_msi_enable || !dev || !entries) return -EINVAL; + if ((status = msi_init()) < 0) + return status; + if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX))) return -EINVAL; - dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), 2, &control); - if (nvec > multi_msix_capable(control)) + pci_read_config_word(dev, msi_control_reg(pos), &control); + if (control & PCI_MSIX_FLAGS_ENABLE) + return -EINVAL; /* Already in MSI-X mode */ + + nr_entries = multi_msix_capable(control); + if (nvec > nr_entries) return -EINVAL; - spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[dev->irq]; - if (!entry || entry->dev != dev || /* legal call */ - entry->msi_attrib.type != PCI_CAP_ID_MSIX || /* must be MSI-X */ - entry->link.head != entry->link.tail) { /* already multi */ - spin_unlock_irqrestore(&msi_lock, flags); + /* Check for any invalid entries */ + for (i = 0; i < nvec; i++) { + if (entries[i].entry >= nr_entries) + return -EINVAL; /* invalid entry */ + for (j = i + 1; j < nvec; j++) { + if (entries[i].entry == entries[j].entry) + return -EINVAL; /* duplicate entry */ + } + } + temp = dev->irq; + if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { + /* Lookup Sucess */ + nr_entries = nvec; + /* Reroute MSI-X table */ + if (reroute_msix_table(dev->irq, entries, &nr_entries)) { + /* #requested > #previous-assigned */ + dev->irq = temp; + return nr_entries; + } + dev->irq = temp; + enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); + return 0; + } + /* Check whether driver already requested for MSI vector */ + if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 && + !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { + printk(KERN_INFO "Can't enable MSI-X. Device already had MSI vector assigned\n"); + dev->irq = temp; return -EINVAL; } + + spin_lock_irqsave(&msi_lock, flags); /* * msi_lock is provided to ensure that enough vectors resources are * available before granting. @@ -874,71 +1003,65 @@ int msi_alloc_vectors(struct pci_dev* dev, int *vector, int nvec) free_vectors /= nr_msix_devices; spin_unlock_irqrestore(&msi_lock, flags); - if (nvec > free_vectors) - return -EBUSY; - - alloc_vectors = 0; - head = dev->irq; - for (i = 0; i < nvec; i++) { - if ((vec = msi_alloc_vector(dev, head)) < 0) - break; - *(vectors + i) = vec; - head = vec; - alloc_vectors++; - } - if (alloc_vectors != nvec) { - for (i = 0; i < alloc_vectors; i++) { - vec = *(vectors + i); - msi_free_vector(dev, vec); - } - spin_lock_irqsave(&msi_lock, flags); - msi_desc[dev->irq]->link.tail = msi_desc[dev->irq]->link.head; - spin_unlock_irqrestore(&msi_lock, flags); - return -EBUSY; + if (nvec > free_vectors) { + if (free_vectors > 0) + return free_vectors; + else + return -EBUSY; } - if (nr_msix_devices > 0) + + status = msix_capability_init(dev, entries, nvec); + if (!status && nr_msix_devices > 0) nr_msix_devices--; - return 0; + return status; } -/** - * msi_free_vectors - reclaim MSI-X vectors to unused state - * @dev: pointer to the pci_dev data structure of MSI-X device function - * @vector: pointer to an array of released MSI-X vectors - * @nvec: number of MSI-X vectors requested for release by device driver - * - * Reclaim MSI-X vectors released by device driver to unused state, - * which may be used later on. A return of zero indicates the - * success or non-zero for otherwise. Device driver should call this - * before calling function free_irq. - **/ -int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec) +void pci_disable_msix(struct pci_dev* dev) { - struct msi_desc *entry; - int i; - unsigned long flags; + int pos, temp; + u16 control; - if (!pci_msi_enable) - return -EINVAL; + if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX))) + return; - spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[dev->irq]; - if (!entry || entry->dev != dev || - entry->msi_attrib.type != PCI_CAP_ID_MSIX || - entry->link.head == entry->link.tail) { /* Nothing to free */ + pci_read_config_word(dev, msi_control_reg(pos), &control); + if (!(control & PCI_MSIX_FLAGS_ENABLE)) + return; + + temp = dev->irq; + if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { + int state, vector, head, tail = 0, warning = 0; + unsigned long flags; + + vector = head = dev->irq; + spin_lock_irqsave(&msi_lock, flags); + while (head != tail) { + state = msi_desc[vector]->msi_attrib.state; + if (state) + warning = 1; + else { + vector_irq[vector] = 0; /* free it */ + nr_released_vectors++; + } + tail = msi_desc[vector]->link.tail; + vector = tail; + } spin_unlock_irqrestore(&msi_lock, flags); - return -EINVAL; - } - spin_unlock_irqrestore(&msi_lock, flags); + if (warning) { + dev->irq = temp; + printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n", + dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + BUG_ON(warning > 0); + } else { + dev->irq = temp; + disable_msi_mode(dev, + pci_find_capability(dev, PCI_CAP_ID_MSIX), + PCI_CAP_ID_MSIX); - for (i = 0; i < nvec; i++) { - if (*(vector + i) == dev->irq) - continue;/* Don't free entry 0 if mistaken by driver */ - msi_free_vector(dev, *(vector + i)); + } } - - return 0; } /** @@ -952,62 +1075,73 @@ int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec) **/ void msi_remove_pci_irq_vectors(struct pci_dev* dev) { - struct msi_desc *entry; - int type, temp; + int state, pos, temp; unsigned long flags; if (!pci_msi_enable || !dev) return; - if (!pci_find_capability(dev, PCI_CAP_ID_MSI)) { - if (!pci_find_capability(dev, PCI_CAP_ID_MSIX)) - return; - } - temp = dev->irq; - if (msi_lookup_vector(dev)) - return; - - spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[dev->irq]; - if (!entry || entry->dev != dev) { + temp = dev->irq; /* Save IOAPIC IRQ */ + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) > 0 && + !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { + spin_lock_irqsave(&msi_lock, flags); + state = msi_desc[dev->irq]->msi_attrib.state; spin_unlock_irqrestore(&msi_lock, flags); - return; + if (state) { + printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n", + dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), dev->irq); + BUG_ON(state > 0); + } else /* Release MSI vector assigned to this device */ + msi_free_vector(dev, dev->irq, 0); + dev->irq = temp; /* Restore IOAPIC IRQ */ } - type = entry->msi_attrib.type; - spin_unlock_irqrestore(&msi_lock, flags); + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 && + !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) { + int vector, head, tail = 0, warning = 0; + unsigned long base = 0L; - msi_free_vector(dev, dev->irq); - if (type == PCI_CAP_ID_MSIX) { - int i, pos, dev_msi_cap; - u32 phys_addr, table_offset; - u32 control; - u8 bir; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), 2, &control); - dev_msi_cap = multi_msix_capable(control); - dev->bus->ops->read(dev->bus, dev->devfn, - msix_table_offset_reg(pos), 4, &table_offset); - bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); - phys_addr = pci_resource_start (dev, bir); - phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK); - for (i = FIRST_DEVICE_VECTOR; i < NR_IRQS; i++) { + vector = head = dev->irq; + while (head != tail) { spin_lock_irqsave(&msi_lock, flags); - if (!msi_desc[i] || msi_desc[i]->dev != dev) { - spin_unlock_irqrestore(&msi_lock, flags); - continue; - } + state = msi_desc[vector]->msi_attrib.state; + tail = msi_desc[vector]->link.tail; + base = msi_desc[vector]->mask_base; spin_unlock_irqrestore(&msi_lock, flags); - msi_free_vector(dev, i); + if (state) + warning = 1; + else if (vector != head) /* Release MSI-X vector */ + msi_free_vector(dev, vector, 0); + vector = tail; + } + msi_free_vector(dev, vector, 0); + if (warning) { + /* Force to release the MSI-X memory-mapped table */ + u32 phys_addr, table_offset; + u16 control; + u8 bir; + + pci_read_config_word(dev, msi_control_reg(pos), + &control); + pci_read_config_dword(dev, msix_table_offset_reg(pos), + &table_offset); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); + phys_addr = pci_resource_start (dev, bir); + phys_addr += (u32)(table_offset & + ~PCI_MSIX_FLAGS_BIRMASK); + iounmap((void*)base); + release_mem_region(phys_addr, PCI_MSIX_ENTRY_SIZE * + multi_msix_capable(control)); + printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n", + dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + BUG_ON(warning > 0); } - writel(1, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); - iounmap((void*)entry->mask_base); - release_mem_region(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE); + dev->irq = temp; /* Restore IOAPIC IRQ */ } - dev->irq = temp; - nr_reserved_vectors++; } EXPORT_SYMBOL(pci_enable_msi); -EXPORT_SYMBOL(msi_alloc_vectors); -EXPORT_SYMBOL(msi_free_vectors); +EXPORT_SYMBOL(pci_disable_msi); +EXPORT_SYMBOL(pci_enable_msix); +EXPORT_SYMBOL(pci_disable_msix); diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index 524504fdd4f015..3a7a5285439306 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h @@ -140,7 +140,8 @@ struct msi_desc { struct { __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ __u8 maskbit : 1; /* mask-pending bit supported ? */ - __u8 reserved: 2; /* reserved */ + __u8 state : 1; /* {0: free, 1: busy} */ + __u8 reserved: 1; /* reserved */ __u8 entry_nr; /* specific enabled entry */ __u8 default_vector; /* default pre-assigned vector */ __u8 current_cpu; /* current destination cpu */ diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index ceeed4fb4f1126..0efa9c6e730adc 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -29,10 +29,6 @@ file under either the MPL or the GPL. ======================================================================*/ -/* - * Please see linux/Documentation/arm/SA1100/PCMCIA for more information - * on the low-level kernel interface. - */ #include <linux/module.h> #include <linux/init.h> diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index d9d363a9e2e17d..d11f86948afe2f 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -1386,7 +1386,7 @@ static int aha152x_biosparam(struct scsi_device *sdev, struct block_device *bdev "aha152x: unable to verify geometry for disk with >1GB.\n" " Using default translation. Please verify yourself.\n" " Perhaps you need to enable extended translation in the driver.\n" - " See /usr/src/linux/Documentation/scsi/aha152x.txt for details.\n"); + " See Documentation/scsi/aha152x.txt for details.\n"); } } else { info_array[0] = info[0]; diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 3b749ddd0c0949..6529f0c557724e 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -681,6 +681,7 @@ static int fdomain_get_irq( int base ) static int fdomain_isa_detect( int *irq, int *iobase ) { +#ifndef PCMCIA int i, j; int base = 0xdeadbeef; int flag = 0; @@ -786,6 +787,9 @@ static int fdomain_isa_detect( int *irq, int *iobase ) *iobase = base; return 1; /* success */ +#else + return 0; +#endif } /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int* diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig index b7d208e60886eb..df52190f4d94e0 100644 --- a/drivers/scsi/pcmcia/Kconfig +++ b/drivers/scsi/pcmcia/Kconfig @@ -17,7 +17,7 @@ config PCMCIA_AHA152X config PCMCIA_FDOMAIN tristate "Future Domain PCMCIA support" - depends on m && ISA + depends on m help Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 239d5c0e580f71..1b324b8002e941 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -1215,7 +1215,7 @@ static void dc390_dumpinfo (struct dc390_acb* pACB, struct dc390_dcb* pDCB, stru pdev = pACB->pdev; pci_read_config_word(pdev, PCI_STATUS, &pstat); printk ("DC390: Register dump: PCI Status: %04x\n", pstat); - printk ("DC390: In case of driver trouble read linux/Documentation/scsi/tmscsim.txt\n"); + printk ("DC390: In case of driver trouble read Documentation/scsi/tmscsim.txt\n"); } diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index 51a39a31417af8..529a2de54fec22 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c @@ -16,7 +16,7 @@ * Based on the Linux CPiA driver written by Peter Pregler, * Scott J. Bertin and Johannes Erdfelt. * - * Please see the file: linux/Documentation/usb/ov511.txt + * Please see the file: Documentation/usb/ov511.txt * and the website at: http://alpha.dyndns.org/ov511 * for more info. * diff --git a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c index 471873b0c1e324..51717375a8c0db 100644 --- a/drivers/usb/misc/tiglusb.c +++ b/drivers/usb/misc/tiglusb.c @@ -10,7 +10,7 @@ * * Based on dabusb.c, printer.c & scanner.c * - * Please see the file: linux/Documentation/usb/SilverLink.txt + * Please see the file: Documentation/usb/silverlink.txt * and the website at: http://lpg.ticalc.org/prj_usb/ * for more info. * |