From: Linus Torvalds Date: Fri, 23 Nov 2007 20:26:06 +0000 (-0500) Subject: Import 2.3.10 X-Git-Tag: 2.3.10 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=96278de684c1958c63a241a0d30d07c154a6ed41;p=history.git Import 2.3.10 --- diff --git a/drivers/misc/parport_ieee1284.c b/drivers/misc/parport_ieee1284.c index 6cac030a195b..dd33021c3645 100644 --- a/drivers/misc/parport_ieee1284.c +++ b/drivers/misc/parport_ieee1284.c @@ -17,7 +17,7 @@ #include #include -#define DEBUG /* undef me for production */ +#undef DEBUG /* undef me for production */ #ifdef CONFIG_LP_CONSOLE #undef DEBUG /* Don't want a garbled console */ diff --git a/drivers/misc/parport_pc.c b/drivers/misc/parport_pc.c index f9db1830eaf2..6023b44009b2 100644 --- a/drivers/misc/parport_pc.c +++ b/drivers/misc/parport_pc.c @@ -1275,9 +1275,7 @@ static int __init parport_ECPPS2_supported(struct parport *pb) static int __init parport_EPP_supported(struct parport *pb) { - /* If EPP timeout bit clear then EPP available */ - if (!clear_epp_timeout(pb)) - return 0; /* No way to clear timeout */ + const struct parport_pc_private *priv = pb->private_data; /* * Theory: @@ -1292,50 +1290,21 @@ static int __init parport_EPP_supported(struct parport *pb) * This bit is always high in non EPP modes. */ - parport_pc_data_reverse (pb); - parport_pc_enable_irq (pb); - clear_epp_timeout(pb); - - inb (EPPDATA (pb)); - udelay(30); /* Wait for possible EPP timeout */ - - if (parport_pc_read_status(pb) & 0x01) - goto supported; - - /* - * Theory: - * Write two values to the EPP address register and - * read them back. When the transfer times out, the state of - * the EPP register is undefined in some cases (EPP 1.9?) but - * in others (EPP 1.7, ECPEPP?) it is possible to read back - * its value. - */ - clear_epp_timeout(pb); - udelay(30); /* Wait for possible EPP timeout */ - - /* We must enable the outputs to be able to read the address - register. */ - - parport_pc_data_forward (pb); - - outb (0x55, EPPADDR (pb)); - - clear_epp_timeout(pb); - udelay(30); /* Wait for possible EPP timeout */ - - if (inb (EPPADDR (pb)) == 0x55) { - clear_epp_timeout(pb); - udelay(30); /* Wait for possible EPP timeout */ - outb (0xaa, EPPADDR (pb)); + /* If EPP timeout bit clear then EPP available */ + if (!clear_epp_timeout(pb)) + return 0; /* No way to clear timeout */ - if (inb (EPPADDR (pb)) == 0xaa) - goto supported; + /* Check for Intel bug. */ + if (priv->ecr) { + unsigned char i; + for (i = 0x00; i < 0x80; i += 0x20) { + outb (i, ECONTROL (pb)); + if (clear_epp_timeout (pb)) + /* Phony EPP in ECP. */ + return 0; + } } - return 0; - - supported: - clear_epp_timeout(pb); pb->modes |= PARPORT_MODE_EPP; /* Set up access functions to use EPP hardware. */ @@ -1581,8 +1550,9 @@ static int __init probe_one_port(unsigned long int base, } if (base != 0x3bc) { if (!check_region(base+0x3, 5)) { - parport_ECPEPP_supported(p); parport_EPP_supported(p); + if (!(p->modes & PARPORT_MODE_EPP)) + parport_ECPEPP_supported(p); } } if (!parport_SPP_supported (p)) { @@ -1708,6 +1678,7 @@ static int __init probe_one_port(unsigned long int base, outb (0x24, ECONTROL (p)); parport_pc_write_data(p, 0); + parport_pc_data_forward (p); parport_pc_write_control(p, PARPORT_CONTROL_SELECT); udelay (50); parport_pc_write_control(p, diff --git a/drivers/net/Config.in b/drivers/net/Config.in index af78dbe00a30..79a89cb4b086 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -281,6 +281,9 @@ if [ "$CONFIG_WAN_ROUTER" != "n" ]; then fi fi fi + +endmenu + # # X.25 network drivers # diff --git a/drivers/pci/oldproc.c b/drivers/pci/oldproc.c index 95afed2fb4bb..6ff8a9d44d4a 100644 --- a/drivers/pci/oldproc.c +++ b/drivers/pci/oldproc.c @@ -263,6 +263,7 @@ struct pci_dev_info dev_info[] = { DEVICE( BROOKTREE, BROOKTREE_878, "Bt878"), DEVICE( BROOKTREE, BROOKTREE_8474, "Bt8474"), DEVICE( SIERRA, SIERRA_STB, "STB Horizon 64"), + DEVICE( SGI, SGI_IOC3, "IOC3"), DEVICE( ACC, ACC_2056, "2056"), DEVICE( WINBOND, WINBOND_83769, "W83769F"), DEVICE( WINBOND, WINBOND_82C105, "SL82C105"), diff --git a/drivers/usb/hub.h b/drivers/usb/hub.h index d015c5a33063..5c7b0c31f9d2 100644 --- a/drivers/usb/hub.h +++ b/drivers/usb/hub.h @@ -12,6 +12,7 @@ /* * Port feature numbers */ +#define USB_PORT_FEAT_CONNECTION 0 #define USB_PORT_FEAT_ENABLE 1 #define USB_PORT_FEAT_SUSPEND 2 #define USB_PORT_FEAT_OVER_CURRENT 3 @@ -40,7 +41,7 @@ #define USB_PORT_STAT_C_OVERCURRENT 0x0008 #define USB_PORT_STAT_C_RESET 0x0010 -/* Characteristics */ +/* wHubCharacteristics (masks) */ #define HUB_CHAR_LPSM 0x0003 #define HUB_CHAR_COMPOUND 0x0004 #define HUB_CHAR_OCPM 0x0018 diff --git a/drivers/usb/printer.c b/drivers/usb/printer.c index a5864498cc97..4e5f0914dc1b 100644 --- a/drivers/usb/printer.c +++ b/drivers/usb/printer.c @@ -124,6 +124,7 @@ static int open_printer(struct inode * inode, struct file * file) return -EBUSY; } if (!(p->obuf = (char *)__get_free_page(GFP_KERNEL))) { + p->isopen = 0; return -ENOMEM; } diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c index 1aa1a0eea6cc..58867fb58640 100644 --- a/drivers/usb/uhci.c +++ b/drivers/usb/uhci.c @@ -1437,10 +1437,12 @@ static struct uhci *alloc_uhci(unsigned int io_addr) /* We need exactly one page (per UHCI specs), how convenient */ uhci->fl = (void *)__get_free_page(GFP_KERNEL); + if (!uhci->fl) + goto au_free_uhci; bus = kmalloc(sizeof(*bus), GFP_KERNEL); if (!bus) - return NULL; + goto au_free_fl; memset(bus, 0, sizeof(*bus)); @@ -1460,7 +1462,7 @@ static struct uhci *alloc_uhci(unsigned int io_addr) */ usb = uhci_usb_allocate(NULL); if (!usb) - return NULL; + goto au_free_bus; usb->bus = bus; dev = usb_to_uhci(usb); @@ -1531,6 +1533,18 @@ static struct uhci *alloc_uhci(unsigned int io_addr) } return uhci; + +/* + * error exits: + */ + +au_free_bus: + kfree (bus); +au_free_fl: + free_page ((unsigned long)uhci->fl); +au_free_uhci: + kfree (uhci); + return NULL; } diff --git a/drivers/usb/uhci.h b/drivers/usb/uhci.h index d450218ecf38..5fa7a7feb041 100644 --- a/drivers/usb/uhci.h +++ b/drivers/usb/uhci.h @@ -167,12 +167,12 @@ struct uhci_device { * Linus: * * generic-iso-QH -> dev1-iso-QH -> generic-irq-QH -> dev1-irq-QH -> ... - * | | | | - * End dev1-iso-TD1 End dev1-irq-TD1 - * | - * dev1-iso-TD2 - * | - * .... + * | | | | + * End dev1-iso-TD1 End dev1-irq-TD1 + * | + * dev1-iso-TD2 + * | + * .... * * This may vary a bit (the UHCI docs don't explicitly say you can put iso * transfers in QH's and all of their pictures don't have that either) but diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index bbce88b64c9b..b73c34eca69e 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -260,7 +260,7 @@ static int usb_check_descriptor(unsigned char *ptr, int len, unsigned char desct static int usb_parse_endpoint(struct usb_device *dev, struct usb_endpoint_descriptor *endpoint, unsigned char *ptr, int len) { - int parsed = usb_expect_descriptor(ptr, len, USB_DT_ENDPOINT, 7); + int parsed = usb_expect_descriptor(ptr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE); int i; if (parsed < 0) @@ -284,7 +284,7 @@ static int usb_parse_endpoint(struct usb_device *dev, struct usb_endpoint_descri static int usb_parse_interface(struct usb_device *dev, struct usb_interface_descriptor *interface, unsigned char *ptr, int len) { int i; - int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, 9); + int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE); int retval; if (parsed < 0) @@ -848,29 +848,40 @@ int usb_get_report(struct usb_device *dev) int usb_get_configuration(struct usb_device *dev) { unsigned int cfgno; - unsigned char buffer[400]; unsigned char * bufptr; - + unsigned char * buffer; + int parse; + + buffer = (unsigned char *) __get_free_page (GFP_KERNEL); + if (!buffer) + return -1; + bufptr = buffer; for (cfgno = 0 ; cfgno < dev->descriptor.bNumConfigurations ; cfgno++) { unsigned int size; /* Get the first 8 bytes - guaranteed */ - if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, 8)) + if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, 8)) { + __free_page ((struct page *) buffer); return -1; + } /* Get the full buffer */ size = le16_to_cpup((unsigned short *)(bufptr+2)); - if (bufptr+size > buffer+sizeof(buffer)) { + if (bufptr+size > buffer+PAGE_SIZE) { printk(KERN_INFO "usb: truncated DT_CONFIG (want %d).\n", size); - size = buffer+sizeof(buffer)-bufptr; + size = buffer+PAGE_SIZE-bufptr; } - if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, size)) + if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, size)) { + __free_page ((struct page *) buffer); return -1; + } /* Prepare for next configuration */ bufptr += size; } - return usb_parse_configuration(dev, buffer, bufptr - buffer); + parse = usb_parse_configuration(dev, buffer, bufptr - buffer); + __free_page ((struct page *) buffer); + return parse; } int usb_get_stringtable(struct usb_device *dev) diff --git a/drivers/usb/usb.h b/drivers/usb/usb.h index f0ebc9a2683d..6bbd5a879bff 100644 --- a/drivers/usb/usb.h +++ b/drivers/usb/usb.h @@ -31,9 +31,16 @@ typedef struct { } devrequest; /* - * Class codes + * Device and/or Interface Class codes */ +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 #define USB_CLASS_HUB 9 +#define USB_CLASS_VENDOR_SPEC 0xff /* * Descriptor types @@ -47,6 +54,28 @@ typedef struct { #define USB_DT_HUB 0x29 #define USB_DT_HID 0x21 +/* + * Descriptor sizes per descriptor type + */ +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIG_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_HUB_NONVAR_SIZE 7 + +/* + * USB Request Type and Endpoint Directions + */ +#define USB_DIR_OUT 0 +#define USB_DIR_IN 0x80 + +/* + * USB Packet IDs (PIDs) + */ +#define USB_PID_OUT 0xe1 +#define USB_PID_IN 0x69 +#define USB_PID_SETUP 0x2d + /* * Standard requests */ @@ -276,7 +305,7 @@ struct usb_bus { struct usb_device { int devnum; /* Device number on USB bus */ int slow; /* Slow device? */ - int maxpacketsize; /* Maximum packet size */ + int maxpacketsize; /* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */ int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */ int halted; /* endpoint halts */ struct usb_config_descriptor *actconfig;/* the active configuration */ @@ -343,16 +372,16 @@ extern void usb_destroy_configuration(struct usb_device *dev); * Let's not fall in that trap. We'll just encode it as a simple * unsigned int. The encoding is: * + * - max size: bits 0-1 (00 = 8, 01 = 16, 10 = 32, 11 = 64) + * - direction: bit 7 (0 = Host-to-Device, 1 = Device-to-Host) * - device: bits 8-14 * - endpoint: bits 15-18 * - Data0/1: bit 19 - * - direction: bit 7 (0 = Host-to-Device, 1 = Device-to-Host) - * - speed: bit 26 (0 = High, 1 = Low Speed) - * - max size: bits 0-1 (00 = 8, 01 = 16, 10 = 32, 11 = 64) + * - speed: bit 26 (00 = Full, 01 = Low Speed) * - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk) * * Why? Because it's arbitrary, and whatever encoding we select is really - * up to us. This one happens to share a lot of bit positions with the UCHI + * up to us. This one happens to share a lot of bit positions with the UHCI * specification, so that much of the uhci driver can just mask the bits * appropriately. */ @@ -373,6 +402,7 @@ extern void usb_destroy_configuration(struct usb_device *dev); #define usb_pipebulk(pipe) (usb_pipetype((pipe)) == 3) #define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff) +#define PIPE_DEVEP_MASK 0x0007ff00 /* The D0/D1 toggle bits */ #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1) @@ -394,7 +424,7 @@ static inline unsigned int __default_pipe(struct usb_device *dev) return (dev->slow << 26); } -/* Create control pipes.. */ +/* Create various pipes... */ #define usb_sndctrlpipe(dev,endpoint) ((2 << 30) | __create_pipe(dev,endpoint)) #define usb_rcvctrlpipe(dev,endpoint) ((2 << 30) | __create_pipe(dev,endpoint) | 0x80) #define usb_sndisocpipe(dev,endpoint) ((0 << 30) | __create_pipe(dev,endpoint)) diff --git a/include/linux/pci.h b/include/linux/pci.h index 25700218c267..d3ff7e104722 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -622,6 +622,9 @@ #define PCI_VENDOR_ID_SIERRA 0x10a8 #define PCI_DEVICE_ID_SIERRA_STB 0x0000 +#define PCI_VENDOR_ID_SGI 0x10a9 +#define PCI_DEVICE_ID_SGI_IOC3 0x0003 + #define PCI_VENDOR_ID_ACC 0x10aa #define PCI_DEVICE_ID_ACC_2056 0x0000 diff --git a/mm/memory.c b/mm/memory.c index b65da93acb47..a31e862b2d62 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -344,12 +344,10 @@ static inline int zap_pte_range(struct mm_struct *mm, pmd_t * pmd, unsigned long pte_t page; if (!size) break; - spin_lock(&mm->page_table_lock); page = *pte; pte++; size--; pte_clear(pte-1); - spin_unlock(&mm->page_table_lock); if (pte_none(page)) continue; freed += free_pte(page); @@ -394,11 +392,21 @@ void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long s int freed = 0; dir = pgd_offset(mm, address); + + /* + * This is a long-lived spinlock. That's fine. + * There's no contention, because the page table + * lock only protects against kswapd anyway, and + * even if kswapd happened to be looking at this + * process we _want_ it to get stuck. + */ + spin_lock(&mm->page_table_lock); while (address < end) { freed += zap_pmd_range(mm, dir, address, end - address); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } + spin_unlock(&mm->page_table_lock); /* * Update rss for the mm_struct (not necessarily current->mm) */