diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-11-19 16:51:10 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-11-19 16:51:10 -0800 |
| commit | de5bd36f7695fae088f899f81e2be84eb3e62314 (patch) | |
| tree | 79765017970f13af092c1a3dc32eceb8ddf5d611 | |
| parent | 0d0b710572e61bd3756856f7c760dea89913f1ac (diff) | |
| parent | 9f311f51f4c01f8fba4faa315ddd5e8dc54671d8 (diff) | |
Merge master.kernel.org:/home/acme/BK/includes-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
| -rw-r--r-- | drivers/isdn/hisax/bkm_a8.c | 23 | ||||
| -rw-r--r-- | drivers/pci/Makefile | 4 | ||||
| -rw-r--r-- | drivers/pci/compat.c | 37 | ||||
| -rw-r--r-- | drivers/pcmcia/cistpl.c | 5 | ||||
| -rw-r--r-- | drivers/usb/core/config.c | 23 | ||||
| -rw-r--r-- | drivers/usb/media/vicam.c | 234 | ||||
| -rw-r--r-- | drivers/usb/net/pegasus.c | 303 | ||||
| -rw-r--r-- | drivers/usb/net/pegasus.h | 15 | ||||
| -rw-r--r-- | drivers/usb/serial/usb-serial.c | 81 | ||||
| -rw-r--r-- | drivers/usb/storage/freecom.c | 56 | ||||
| -rw-r--r-- | drivers/usb/storage/isd200.c | 4 | ||||
| -rw-r--r-- | drivers/usb/storage/transport.c | 178 | ||||
| -rw-r--r-- | drivers/usb/storage/transport.h | 14 | ||||
| -rw-r--r-- | include/linux/pci.h | 17 |
14 files changed, 518 insertions, 476 deletions
diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c index a0b4282dae01..6954b99388bb 100644 --- a/drivers/isdn/hisax/bkm_a8.c +++ b/drivers/isdn/hisax/bkm_a8.c @@ -278,8 +278,6 @@ sct_alloc_io(u_int adr, u_int len) static struct pci_dev *dev_a8 __initdata = NULL; static u16 sub_vendor_id __initdata = 0; static u16 sub_sys_id __initdata = 0; -static u_char pci_bus __initdata = 0; -static u_char pci_device_fn __initdata = 0; static u_char pci_irq __initdata = 0; #endif /* CONFIG_PCI */ @@ -328,8 +326,6 @@ setup_sct_quadro(struct IsdnCard *card) return(0); pci_ioaddr1 = pci_resource_start(dev_a8, 1); pci_irq = dev_a8->irq; - pci_bus = dev_a8->bus->number; - pci_device_fn = dev_a8->devfn; found = 1; break; } @@ -342,20 +338,17 @@ setup_sct_quadro(struct IsdnCard *card) } #ifdef ATTEMPT_PCI_REMAPPING /* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */ - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_REVISION_ID, &pci_rev_id); + pci_read_config_byte(dev_a8, PCI_REVISION_ID, &pci_rev_id); if ((pci_ioaddr1 & 0x80) && (pci_rev_id == 1)) { printk(KERN_WARNING "HiSax: %s (%s): PLX rev 1, remapping required!\n", CardType[card->typ], sct_quadro_subtypes[cs->subtyp]); /* Restart PCI negotiation */ - pcibios_write_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, (u_int) - 1); + pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, (u_int) - 1); /* Move up by 0x80 byte */ pci_ioaddr1 += 0x80; pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK; - pcibios_write_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, pci_ioaddr1); + pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, pci_ioaddr1); dev_a8->resource[ 1].start = pci_ioaddr1; } #endif /* End HACK */ @@ -366,11 +359,11 @@ setup_sct_quadro(struct IsdnCard *card) sct_quadro_subtypes[cs->subtyp]); return (0); } - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &pci_ioaddr1); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &pci_ioaddr2); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_3, &pci_ioaddr3); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_4, &pci_ioaddr4); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_5, &pci_ioaddr5); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_1, &pci_ioaddr1); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_2, &pci_ioaddr2); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_3, &pci_ioaddr3); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_4, &pci_ioaddr4); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_5, &pci_ioaddr5); if (!pci_ioaddr1 || !pci_ioaddr2 || !pci_ioaddr3 || !pci_ioaddr4 || !pci_ioaddr5) { printk(KERN_WARNING "HiSax: %s (%s): No IO base address(es)\n", CardType[card->typ], diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 39322fec9a8f..2749c3ccd859 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,10 +3,10 @@ # export-objs := access.o hotplug.o pci-driver.o pci.o pool.o \ - probe.o proc.o search.o compat.o setup-bus.o + probe.o proc.o search.o setup-bus.o obj-y += access.o probe.o pci.o pool.o quirks.o \ - compat.o names.o pci-driver.o search.o hotplug.o + names.o pci-driver.o search.o hotplug.o obj-$(CONFIG_PM) += power.o obj-$(CONFIG_PROC_FS) += proc.o diff --git a/drivers/pci/compat.c b/drivers/pci/compat.c deleted file mode 100644 index 048c610a9e62..000000000000 --- a/drivers/pci/compat.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * $Id: compat.c,v 1.1 1998/02/16 10:35:50 mj Exp $ - * - * PCI Bus Services -- Function For Backward Compatibility - * - * Copyright 1998--2000 Martin Mares <mj@ucw.cz> - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pci.h> - -/* Obsolete functions, these will be going away... */ - -#define PCI_OP(rw,size,type) \ -int pcibios_##rw##_config_##size (unsigned char bus, unsigned char dev_fn, \ - unsigned char where, unsigned type val) \ -{ \ - struct pci_dev *dev = pci_find_slot(bus, dev_fn); \ - if (!dev) return PCIBIOS_DEVICE_NOT_FOUND; \ - return pci_##rw##_config_##size(dev, where, val); \ -} - -PCI_OP(read, byte, char *) -PCI_OP(read, word, short *) -PCI_OP(read, dword, int *) -PCI_OP(write, byte, char) -PCI_OP(write, word, short) -PCI_OP(write, dword, int) - -EXPORT_SYMBOL(pcibios_read_config_byte); -EXPORT_SYMBOL(pcibios_read_config_word); -EXPORT_SYMBOL(pcibios_read_config_dword); -EXPORT_SYMBOL(pcibios_write_config_byte); -EXPORT_SYMBOL(pcibios_write_config_word); -EXPORT_SYMBOL(pcibios_write_config_dword); diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index d8ab8d3aa1e7..cc4d817c6dee 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -430,7 +430,10 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple) #ifdef CONFIG_CARDBUS if (s->state & SOCKET_CARDBUS) { u_int ptr; - pcibios_read_config_dword(s->cap.cb_dev->subordinate->number, 0, 0x28, &ptr); + struct pci_dev *dev = pci_find_slot (s->cap.cb_dev->subordinate->number, 0); + if (!dev) + return CS_BAD_HANDLE; + pci_read_config_dword(dev, 0x28, &ptr); tuple->CISOffset = ptr & ~7; SPACE(tuple->Flags) = (ptr & 7); } else diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index cdc0c665c63a..3a3dfdc54e97 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -109,7 +109,8 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b interface->num_altsetting = 0; interface->max_altsetting = USB_ALTSETTINGALLOC; - interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL); + interface->altsetting = kmalloc(sizeof(*interface->altsetting) * interface->max_altsetting, + GFP_KERNEL); if (!interface->altsetting) { err("couldn't kmalloc interface->altsetting"); @@ -118,29 +119,27 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b while (size > 0) { struct usb_interface_descriptor *d; - + if (interface->num_altsetting >= interface->max_altsetting) { - void *ptr; + struct usb_host_interface *ptr; int oldmas; oldmas = interface->max_altsetting; interface->max_altsetting += USB_ALTSETTINGALLOC; if (interface->max_altsetting > USB_MAXALTSETTING) { - warn("too many alternate settings (max %d)", - USB_MAXALTSETTING); + warn("too many alternate settings (incr %d max %d)\n", + USB_ALTSETTINGALLOC, USB_MAXALTSETTING); return -1; } - ptr = interface->altsetting; - interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL); - if (!interface->altsetting) { + ptr = kmalloc(sizeof(*ptr) * interface->max_altsetting, GFP_KERNEL); + if (ptr == NULL) { err("couldn't kmalloc interface->altsetting"); - interface->altsetting = ptr; return -1; } - memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas); - - kfree(ptr); + memcpy(ptr, interface->altsetting, sizeof(*interface->altsetting) * oldmas); + kfree(interface->altsetting); + interface->altsetting = ptr; } ifp = interface->altsetting + interface->num_altsetting; diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 4b41945f2b6c..1f7138f93133 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c @@ -1,6 +1,7 @@ /* * USB ViCam WebCam driver - * Copyright (c) 2002 Joe Burks (jburks@wavicle.org) + * Copyright (c) 2002 Joe Burks (jburks@wavicle.org), + * John Tyner (fill in email address) * * Supports 3COM HomeConnect PC Digital WebCam * @@ -43,14 +44,6 @@ // #define VICAM_DEBUG -#ifndef MODULE_LICENSE -#define MODULE_LICENSE(a) -#endif - -#ifndef bool -#define bool int -#endif - #ifdef VICAM_DEBUG #define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __FUNCTION__, lineno, ##args) #define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args) @@ -403,26 +396,27 @@ static void rvfree(void *mem, unsigned long size) } vfree(mem); } - + struct vicam_camera { u16 shutter_speed; // capture shutter speed u16 gain; // capture gain u8 *raw_image; // raw data captured from the camera u8 *framebuf; // processed data in RGB24 format + u8 *cntrlbuf; // area used to send control msgs struct video_device vdev; // v4l video device struct usb_device *udev; // usb device struct semaphore busy_lock; // guard against SMP multithreading - bool is_initialized; + int is_initialized; u8 open_count; u8 bulkEndpoint; - bool needsDummyRead; + int needsDummyRead; -#ifdef CONFIG_PROC_FS - struct proc_dir_entry *proc_entry; +#if defined(CONFIG_VIDEO_PROC_FS) + struct proc_dir_entry *proc_dir; #endif }; @@ -437,22 +431,16 @@ send_control_msg(struct usb_device *udev, u8 request, u16 value, u16 index, { int status; - // for reasons not yet known to me, you can't send USB control messages - // with data in the module (if you are compiled as a module). Whatever - // the reason, copying it to memory allocated as kernel memory then - // doing the usb control message fixes the problem. - - unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL); - memcpy(transfer_buffer, cp, size); + /* cp must be memory that has been allocated by kmalloc */ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, - transfer_buffer, size, HZ); + cp, size, HZ); - kfree(transfer_buffer); + status = min(status, 0); if (status < 0) { printk(KERN_INFO "Failed sending control message, error %d.\n", @@ -465,29 +453,30 @@ send_control_msg(struct usb_device *udev, u8 request, u16 value, u16 index, static int initialize_camera(struct vicam_camera *cam) { + const struct { + u8 *data; + u32 size; + } firmware[] = { + { .data = setup1, .size = sizeof(setup1) }, + { .data = setup2, .size = sizeof(setup2) }, + { .data = setup3, .size = sizeof(setup3) }, + { .data = setup4, .size = sizeof(setup4) }, + { .data = setup5, .size = sizeof(setup5) }, + { .data = setup3, .size = sizeof(setup3) }, + { .data = NULL, .size = 0 } + }; + struct usb_device *udev = cam->udev; - int status; + int err, i; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup1, sizeof (setup1))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup2, sizeof (setup2))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup3, sizeof (setup3))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup4, sizeof (setup4))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup5, sizeof (setup5))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup3, sizeof (setup3))) < 0) - return status; + for (i = 0, err = 0; firmware[i].data && !err; i++) { + memcpy(cam->cntrlbuf, firmware[i].data, firmware[i].size); - return 0; + err = send_control_msg(udev, 0xff, 0, 0, + cam->cntrlbuf, firmware[i].size); + } + + return err; } static int @@ -752,7 +741,8 @@ vicam_open(struct inode *inode, struct file *file) "vicam video_device improperly initialized"); } - down_interruptible(&cam->busy_lock); + if ( down_interruptible(&cam->busy_lock) ) + return -EINTR; if (cam->open_count > 0) { printk(KERN_INFO @@ -774,6 +764,14 @@ vicam_open(struct inode *inode, struct file *file) return -ENOMEM; } + cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!cam->cntrlbuf) { + kfree(cam->raw_image); + rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); + up(&cam->busy_lock); + return -ENOMEM; + } + // First upload firmware, then turn the camera on if (!cam->is_initialized) { @@ -803,6 +801,7 @@ vicam_close(struct inode *inode, struct file *file) kfree(cam->raw_image); rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); + kfree(cam->cntrlbuf); cam->open_count--; @@ -831,7 +830,7 @@ inline void writepixel(char *rgb, int Y, int Cr, int Cb) // Copyright (C) 2002 Monroe Williams (monroe@pobox.com) // -------------------------------------------------------------------------------- -void vicam_decode_color( char *data, char *rgb) +static void vicam_decode_color( char *data, char *rgb) { int x,y; int Cr, Cb; @@ -915,7 +914,7 @@ void vicam_decode_color( char *data, char *rgb) static void read_frame(struct vicam_camera *cam, int framenum) { - unsigned char request[16]; + unsigned char *request = cam->cntrlbuf; int realShutter; int n; int actual_length; @@ -984,7 +983,8 @@ vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos ) DBG("read %d bytes.\n", (int) count); - down_interruptible(&cam->busy_lock); + if ( down_interruptible(&cam->busy_lock) ) + return -EINTR; if (*ppos >= VICAM_MAX_FRAME_SIZE) { *ppos = 0; @@ -1057,24 +1057,17 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -#ifdef CONFIG_PROC_FS +#if defined(CONFIG_VIDEO_PROC_FS) static struct proc_dir_entry *vicam_proc_root = NULL; -static int -vicam_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int vicam_read_helper(char *page, char **start, off_t off, + int count, int *eof, int value) { char *out = page; int len; - struct vicam_camera *cam = (struct vicam_camera *) data; - out += - sprintf(out, "Vicam-based WebCam Linux Driver.\n"); - out += sprintf(out, "(c) 2002 Joe Burks (jburks@wavicle.org)\n"); - out += sprintf(out, "vicam stats:\n"); - out += sprintf(out, " Shutter Speed: 1/%d\n", cam->shutter_speed); - out += sprintf(out, " Gain: %d\n", cam->gain); + out += sprintf(out, "%d",value); len = out - page; len -= off; @@ -1089,38 +1082,43 @@ vicam_read_proc(char *page, char **start, off_t off, return len; } -static int -vicam_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) +static int vicam_read_proc_shutter(char *page, char **start, off_t off, + int count, int *eof, void *data) { - char *in; - char *start; - struct vicam_camera *cam = (struct vicam_camera *) data; - - in = kmalloc(count + 1, GFP_KERNEL); - if (!in) - return -ENOMEM; + return vicam_read_helper(page,start,off,count,eof, + ((struct vicam_camera *)data)->shutter_speed); +} - in[count] = 0; // I'm not sure buffer is gauranteed to be null terminated - // so I do this to make sure I have a null in there. +static int vicam_read_proc_gain(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + return vicam_read_helper(page,start,off,count,eof, + ((struct vicam_camera *)data)->gain); +} - strncpy(in, buffer, count); +static int vicam_write_proc_shutter(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct vicam_camera *cam = (struct vicam_camera *)data; + + cam->shutter_speed = simple_strtoul(buffer, NULL, 10); - start = strstr(in, "gain="); - if (start - && (start == in || *(start - 1) == ' ' || *(start - 1) == ',')) - cam->gain = simple_strtoul(start + 5, NULL, 10); + return count; +} - start = strstr(in, "shutter="); - if (start - && (start == in || *(start - 1) == ' ' || *(start - 1) == ',')) - cam->shutter_speed = simple_strtoul(start + 8, NULL, 10); +static int vicam_write_proc_gain(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct vicam_camera *cam = (struct vicam_camera *)data; + + cam->gain = simple_strtoul(buffer, NULL, 10); - kfree(in); return count; } -void + + +static void vicam_create_proc_root(void) { vicam_proc_root = create_proc_entry("video/vicam", S_IFDIR, 0); @@ -1132,19 +1130,17 @@ vicam_create_proc_root(void) "could not create /proc entry for vicam!"); } -void +static void vicam_destroy_proc_root(void) { if (vicam_proc_root) remove_proc_entry("video/vicam", 0); } -void -vicam_create_proc_entry(void *ptr) +static void +vicam_create_proc_entry(struct vicam_camera *cam) { - struct vicam_camera *cam = (struct vicam_camera *) ptr; - - char name[7]; + char name[64]; struct proc_dir_entry *ent; DBG(KERN_INFO "vicam: creating proc entry\n"); @@ -1158,46 +1154,54 @@ vicam_create_proc_entry(void *ptr) sprintf(name, "video%d", cam->vdev.minor); + cam->proc_dir = create_proc_entry(name, S_IFDIR, vicam_proc_root); + + if ( !cam->proc_dir ) return; // We should probably return an error here + ent = - create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, - vicam_proc_root); - if (!ent) - return; + create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR, + cam->proc_dir); + if (ent) { + ent->data = cam; + ent->read_proc = vicam_read_proc_shutter; + ent->write_proc = vicam_write_proc_shutter; + ent->size = 64; + } - ent->data = cam; - ent->read_proc = vicam_read_proc; - ent->write_proc = vicam_write_proc; - ent->size = 512; - cam->proc_entry = ent; + ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR, + cam->proc_dir); + if ( ent ) { + ent->data = cam; + ent->read_proc = vicam_read_proc_gain; + ent->write_proc = vicam_write_proc_gain; + ent->size = 64; + } } -void +static void vicam_destroy_proc_entry(void *ptr) { struct vicam_camera *cam = (struct vicam_camera *) ptr; - char name[7]; + char name[16]; - if (!cam || !cam->proc_entry) + if ( !cam->proc_dir ) return; sprintf(name, "video%d", cam->vdev.minor); - remove_proc_entry(name, vicam_proc_root); - cam->proc_entry = NULL; + remove_proc_entry("shutter", cam->proc_dir); + remove_proc_entry("gain", cam->proc_dir); + remove_proc_entry(name,vicam_proc_root); + cam->proc_dir = NULL; } +#else +static inline void vicam_create_proc_root(void) { } +static inline void vicam_destroy_proc_root(void) { } +static inline void vicam_create_proc_entry(struct vicam_camera *cam) { } +static inline void vicam_destroy_proc_entry(void *ptr) { } #endif -int -vicam_video_init(struct video_device *vdev) -{ - // This would normally create the proc entry for this camera -#ifdef CONFIG_PROC_FS - vicam_create_proc_entry(vdev->priv); -#endif - return 0; -} - static struct file_operations vicam_fops = { .owner = THIS_MODULE, .open = vicam_open, @@ -1296,6 +1300,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) return -EIO; } + vicam_create_proc_entry(cam); + printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor); dev_set_drvdata(&intf->dev, cam); @@ -1314,9 +1320,7 @@ vicam_disconnect(struct usb_interface *intf) video_unregister_device(&cam->vdev); -#ifdef CONFIG_PROC_FS vicam_destroy_proc_entry(cam); -#endif kfree(cam); @@ -1329,9 +1333,7 @@ static int __init usb_vicam_init(void) { DBG(KERN_INFO "ViCam-based WebCam driver startup\n"); -#ifdef CONFIG_PROC_FS vicam_create_proc_root(); -#endif if (usb_register(&vicam_driver) != 0) printk(KERN_WARNING "usb_register failed!\n"); return 0; @@ -1344,9 +1346,7 @@ usb_vicam_exit(void) "ViCam-based WebCam driver shutdown\n"); usb_deregister(&vicam_driver); -#ifdef CONFIG_PROC_FS vicam_destroy_proc_root(); -#endif } module_init(usb_vicam_init); diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 34ed89241550..94ec69af89f1 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -28,7 +28,6 @@ * is out of the interrupt routine. */ - #include <linux/sched.h> #include <linux/slab.h> #include <linux/init.h> @@ -46,7 +45,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.5.6 (2002/06/23)" +#define DRIVER_VERSION "v0.5.7 (2002/11/18)" #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" @@ -119,16 +118,9 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, void *data) { int ret; - unsigned char *buffer; + unsigned char buffer[256]; DECLARE_WAITQUEUE(wait, current); - buffer = kmalloc(size, GFP_KERNEL); - if (!buffer) { - err("unable to allocate memory for configuration descriptors"); - return 0; - } - memcpy(buffer, data, size); - add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); while (pegasus->flags & ETH_REGS_CHANGED) @@ -144,9 +136,9 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, pegasus->ctrl_urb->transfer_buffer_length = size; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, - usb_rcvctrlpipe(pegasus->usb, 0), - (char *) &pegasus->dr, - buffer, size, ctrl_callback, pegasus); + usb_rcvctrlpipe(pegasus->usb, 0), + (char *) &pegasus->dr, + buffer, size, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -161,7 +153,6 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, out: remove_wait_queue(&pegasus->ctrl_wait, &wait); memcpy(data, buffer, size); - kfree(buffer); return ret; } @@ -170,14 +161,9 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, void *data) { int ret; - unsigned char *buffer; + unsigned char buffer[256]; DECLARE_WAITQUEUE(wait, current); - buffer = kmalloc(size, GFP_KERNEL); - if (!buffer) { - err("unable to allocate memory for configuration descriptors"); - return 0; - } memcpy(buffer, data, size); add_wait_queue(&pegasus->ctrl_wait, &wait); @@ -195,9 +181,9 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, pegasus->ctrl_urb->transfer_buffer_length = size; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, - usb_sndctrlpipe(pegasus->usb, 0), - (char *) &pegasus->dr, - buffer, size, ctrl_callback, pegasus); + usb_sndctrlpipe(pegasus->usb, 0), + (char *) &pegasus->dr, + buffer, size, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -210,7 +196,6 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, schedule(); out: remove_wait_queue(&pegasus->ctrl_wait, &wait); - kfree(buffer); return ret; } @@ -218,17 +203,9 @@ out: static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) { int ret; - unsigned char *buffer; - __u16 dat = data; + __u16 tmp = data; DECLARE_WAITQUEUE(wait, current); - buffer = kmalloc(1, GFP_KERNEL); - if (!buffer) { - err("unable to allocate memory for configuration descriptors"); - return 0; - } - memcpy(buffer, &data, 1); - add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); while (pegasus->flags & ETH_REGS_CHANGED) @@ -238,15 +215,15 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) pegasus->dr.bRequestType = PEGASUS_REQT_WRITE; pegasus->dr.bRequest = PEGASUS_REQ_SET_REG; - pegasus->dr.wValue = cpu_to_le16p(&dat); + pegasus->dr.wValue = cpu_to_le16p(&tmp); pegasus->dr.wIndex = cpu_to_le16p(&indx); pegasus->dr.wLength = cpu_to_le16(1); pegasus->ctrl_urb->transfer_buffer_length = 1; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, - usb_sndctrlpipe(pegasus->usb, 0), - (char *) &pegasus->dr, - buffer, 1, ctrl_callback, pegasus); + usb_sndctrlpipe(pegasus->usb, 0), + (char *) &pegasus->dr, + &data, 1, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -259,7 +236,6 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) schedule(); out: remove_wait_queue(&pegasus->ctrl_wait, &wait); - kfree(buffer); return ret; } @@ -276,9 +252,9 @@ static int update_eth_regs_async(pegasus_t * pegasus) pegasus->ctrl_urb->transfer_buffer_length = 3; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, - usb_sndctrlpipe(pegasus->usb, 0), - (char *) &pegasus->dr, - pegasus->eth_regs, 3, ctrl_callback, pegasus); + usb_sndctrlpipe(pegasus->usb, 0), + (char *) &pegasus->dr, + pegasus->eth_regs, 3, ctrl_callback, pegasus); if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) err("%s: BAD CTRL %d, flgs %x", __FUNCTION__, ret, @@ -294,7 +270,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) __u16 regdi; set_register(pegasus, PhyCtrl, 0); - set_registers(pegasus, PhyAddr, sizeof(data), data); + set_registers(pegasus, PhyAddr, sizeof (data), data); set_register(pegasus, PhyCtrl, (indx | PHY_READ)); for (i = 0; i < REG_TIMEOUT; i++) { get_registers(pegasus, PhyCtrl, 1, data); @@ -311,6 +287,15 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) return 1; } +static int mdio_read(struct net_device *dev, int phy_id, int loc) +{ + pegasus_t *pegasus = (pegasus_t *) dev->priv; + int res; + + read_mii_word(pegasus, phy_id, loc, (u16 *) & res); + return res & 0xffff; +} + static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) { int i; @@ -332,6 +317,13 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) return 1; } +static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) +{ + pegasus_t *pegasus = (pegasus_t *) dev->priv; + + write_mii_word(pegasus, phy_id, loc, val); +} + static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) { int i; @@ -415,8 +407,8 @@ static void set_ethernet_addr(pegasus_t * pegasus) __u8 node_id[6]; get_node_id(pegasus, node_id); - set_registers(pegasus, EthID, sizeof(node_id), node_id); - memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id)); + set_registers(pegasus, EthID, sizeof (node_id), node_id); + memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); } static inline int reset_mac(pegasus_t * pegasus) @@ -473,7 +465,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) data[1] = 0; data[2] = (loopback & 1) ? 0x09 : 0x01; - memcpy(pegasus->eth_regs, data, sizeof(data)); + memcpy(pegasus->eth_regs, data, sizeof (data)); set_registers(pegasus, EthCtrl0, 3, data); if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || @@ -486,18 +478,18 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) return 0; } -static void fill_skb_pool(pegasus_t *pegasus) +static void fill_skb_pool(pegasus_t * pegasus) { int i; - for (i=0; i < RX_SKBS; i++) { + for (i = 0; i < RX_SKBS; i++) { if (pegasus->rx_pool[i]) continue; pegasus->rx_pool[i] = dev_alloc_skb(PEGASUS_MTU + 2); /* - ** we give up if the allocation fail. the tasklet will be - ** rescheduled again anyway... - */ + ** we give up if the allocation fail. the tasklet will be + ** rescheduled again anyway... + */ if (pegasus->rx_pool[i] == NULL) return; pegasus->rx_pool[i]->dev = pegasus->net; @@ -505,11 +497,11 @@ static void fill_skb_pool(pegasus_t *pegasus) } } -static void free_skb_pool(pegasus_t *pegasus) +static void free_skb_pool(pegasus_t * pegasus) { int i; - for (i=0; i < RX_SKBS; i++) { + for (i = 0; i < RX_SKBS; i++) { if (pegasus->rx_pool[i]) { dev_kfree_skb(pegasus->rx_pool[i]); pegasus->rx_pool[i] = NULL; @@ -517,12 +509,12 @@ static void free_skb_pool(pegasus_t *pegasus) } } -static inline struct sk_buff *pull_skb(pegasus_t *pegasus) +static inline struct sk_buff *pull_skb(pegasus_t * pegasus) { int i; struct sk_buff *skb; - for (i=0; i < RX_SKBS; i++) { + for (i = 0; i < RX_SKBS; i++) { if (likely(pegasus->rx_pool[i] != NULL)) { skb = pegasus->rx_pool[i]; pegasus->rx_pool[i] = NULL; @@ -563,7 +555,7 @@ static void read_bulk_callback(struct urb *urb) if (!count) goto goon; - rx_status = le32_to_cpu(*(int *)(urb->transfer_buffer + count - 4)); + rx_status = le32_to_cpu(*(int *) (urb->transfer_buffer + count - 4)); if (rx_status & 0x000e0000) { dbg("%s: RX packet error %x", net->name, rx_status & 0xe0000); pegasus->stats.rx_errors++; @@ -575,20 +567,24 @@ static void read_bulk_callback(struct urb *urb) pegasus->stats.rx_frame_errors++; goto goon; } - pkt_len = (rx_status & 0xfff) - 8; + if (pegasus->chip == 0x8513) { + pkt_len = le32_to_cpu(*(int *)urb->transfer_buffer); + pkt_len &= 0x0fff; + pegasus->rx_skb->data += 2; + } else { + pkt_len = (rx_status & 0xfff) - 8; + } - if (pegasus->rx_skb == NULL) - printk("%s: rx_skb == NULL\n", __FUNCTION__); /* - ** we are sure at this point pegasus->rx_skb != NULL - ** so we go ahead and pass up the packet. - */ + * at this point we are sure pegasus->rx_skb != NULL + * so we go ahead and pass up the packet. + */ skb_put(pegasus->rx_skb, pkt_len); pegasus->rx_skb->protocol = eth_type_trans(pegasus->rx_skb, net); netif_rx(pegasus->rx_skb); pegasus->stats.rx_packets++; pegasus->stats.rx_bytes += pkt_len; - + spin_lock(&pegasus->rx_pool_lock); pegasus->rx_skb = pull_skb(pegasus); spin_unlock(&pegasus->rx_pool_lock); @@ -597,19 +593,19 @@ static void read_bulk_callback(struct urb *urb) goto tl_sched; goon: usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, - read_bulk_callback, pegasus); + usb_rcvbulkpipe(pegasus->usb, 1), + pegasus->rx_skb->data, PEGASUS_MTU + 8, + read_bulk_callback, pegasus); if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { pegasus->flags |= PEGASUS_RX_URB_FAIL; goto tl_sched; } else { pegasus->flags &= ~PEGASUS_RX_URB_FAIL; } - + return; - -tl_sched: + + tl_sched: tasklet_schedule(&pegasus->rx_tl); } @@ -617,7 +613,7 @@ static void rx_fixup(unsigned long data) { pegasus_t *pegasus; - pegasus = (pegasus_t *)data; + pegasus = (pegasus_t *) data; spin_lock_irq(&pegasus->rx_pool_lock); fill_skb_pool(pegasus); @@ -636,9 +632,9 @@ static void rx_fixup(unsigned long data) return; } usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, - read_bulk_callback, pegasus); + usb_rcvbulkpipe(pegasus->usb, 1), + pegasus->rx_skb->data, PEGASUS_MTU + 8, + read_bulk_callback, pegasus); try_again: if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { pegasus->flags |= PEGASUS_RX_URB_FAIL; @@ -704,10 +700,9 @@ static void intr_callback(struct urb *urb) } } - status = usb_submit_urb (urb, SLAB_ATOMIC); + status = usb_submit_urb(urb, SLAB_ATOMIC); if (status) - err ("%s: can't resubmit interrupt urb, %d", - net->name, status); + err("%s: can't resubmit interrupt urb, %d", net->name, status); } static void pegasus_tx_timeout(struct net_device *net) @@ -735,9 +730,9 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net) ((__u16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16); memcpy(pegasus->tx_buff + 2, skb->data, skb->len); usb_fill_bulk_urb(pegasus->tx_urb, pegasus->usb, - usb_sndbulkpipe(pegasus->usb, 2), - pegasus->tx_buff, count, - write_bulk_callback, pegasus); + usb_sndbulkpipe(pegasus->usb, 2), + pegasus->tx_buff, count, + write_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) { warn("failed tx_urb %d", res); pegasus->stats.tx_errors++; @@ -794,7 +789,7 @@ static void set_carrier(struct net_device *net) } -static void free_all_urbs(pegasus_t *pegasus) +static void free_all_urbs(pegasus_t * pegasus) { usb_free_urb(pegasus->intr_urb); usb_free_urb(pegasus->tx_urb); @@ -802,7 +797,7 @@ static void free_all_urbs(pegasus_t *pegasus) usb_free_urb(pegasus->ctrl_urb); } -static void unlink_all_urbs(pegasus_t *pegasus) +static void unlink_all_urbs(pegasus_t * pegasus) { usb_unlink_urb(pegasus->intr_urb); usb_unlink_urb(pegasus->tx_urb); @@ -810,7 +805,7 @@ static void unlink_all_urbs(pegasus_t *pegasus) usb_unlink_urb(pegasus->ctrl_urb); } -static int alloc_urbs(pegasus_t *pegasus) +static int alloc_urbs(pegasus_t * pegasus) { pegasus->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); if (!pegasus->ctrl_urb) { @@ -846,22 +841,22 @@ static int pegasus_open(struct net_device *net) if (pegasus->rx_skb == NULL) pegasus->rx_skb = pull_skb(pegasus); /* - ** Note: no point to free the pool. it is empty :-) - */ + ** Note: no point to free the pool. it is empty :-) + */ if (!pegasus->rx_skb) return -ENOMEM; down(&pegasus->sem); usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, - read_bulk_callback, pegasus); + usb_rcvbulkpipe(pegasus->usb, 1), + pegasus->rx_skb->data, PEGASUS_MTU + 8, + read_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) warn("%s: failed rx_urb %d", __FUNCTION__, res); usb_fill_int_urb(pegasus->intr_urb, pegasus->usb, - usb_rcvintpipe(pegasus->usb, 3), - pegasus->intr_buff, sizeof(pegasus->intr_buff), - intr_callback, pegasus, pegasus->intr_interval); + usb_rcvintpipe(pegasus->usb, 3), + pegasus->intr_buff, sizeof (pegasus->intr_buff), + intr_callback, pegasus, pegasus->intr_interval); if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) warn("%s: failed intr_urb %d", __FUNCTION__, res); netif_start_queue(net); @@ -896,7 +891,82 @@ static int pegasus_close(struct net_device *net) return 0; } +#ifdef CONFIG_MII +static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + pegasus_t *pegasus = dev->priv; + + if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) + return -EFAULT; + + switch (ethcmd) { + /* get driver-specific version/etc. info */ + case ETHTOOL_GDRVINFO:{ + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strncpy(info.driver, driver_name, + sizeof (info.driver) - 1); + strncpy(info.version, DRIVER_VERSION, + sizeof (info.version) - 1); + if (copy_to_user(useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get settings */ + case ETHTOOL_GSET:{ + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + mii_ethtool_gset(&pegasus->mii, &ecmd); + if (copy_to_user(useraddr, &ecmd, sizeof (ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET:{ + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof (ecmd))) + return -EFAULT; + r = mii_ethtool_sset(&pegasus->mii, &ecmd); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST:{ + return mii_nway_restart(&pegasus->mii); + } + + /* get link status */ + case ETHTOOL_GLINK:{ + struct ethtool_value edata = { ETHTOOL_GLINK }; + edata.data = mii_link_ok(&pegasus->mii); + if (copy_to_user(useraddr, &edata, sizeof (edata))) + return -EFAULT; + return 0; + } + /* get message-level */ + case ETHTOOL_GMSGLVL:{ + struct ethtool_value edata = { ETHTOOL_GMSGLVL }; + /* edata.data = pegasus->msg_enable; FIXME */ + if (copy_to_user(useraddr, &edata, sizeof (edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL:{ + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof (edata))) + return -EFAULT; + /* sp->msg_enable = edata.data; FIXME */ + return 0; + } + + } + + return -EOPNOTSUPP; + +} +#else static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) { pegasus_t *pegasus; @@ -912,8 +982,8 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN); usb_make_path(pegasus->usb, info.bus_info, - sizeof info.bus_info); - if (copy_to_user(uaddr, &info, sizeof(info))) + sizeof info.bus_info); + if (copy_to_user(uaddr, &info, sizeof (info))) return -EFAULT; return 0; } @@ -950,7 +1020,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) ecmd.duplex = bmcr & BMCR_FULLDPLX ? DUPLEX_FULL : DUPLEX_HALF; } - if (copy_to_user(uaddr, &ecmd, sizeof(ecmd))) + if (copy_to_user(uaddr, &ecmd, sizeof (ecmd))) return -EFAULT; return 0; @@ -961,7 +1031,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) case ETHTOOL_GLINK:{ struct ethtool_value edata = { ETHTOOL_GLINK }; edata.data = netif_carrier_ok(net); - if (copy_to_user(uaddr, &edata, sizeof(edata))) + if (copy_to_user(uaddr, &edata, sizeof (edata))) return -EFAULT; return 0; } @@ -969,7 +1039,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) return -EOPNOTSUPP; } } - +#endif static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd) { __u16 *data = (__u16 *) & rq->ifr_data; @@ -1045,8 +1115,26 @@ static __u8 mii_phy_probe(pegasus_t * pegasus) static inline void setup_pegasus_II(pegasus_t * pegasus) { + u16 data = 0xa5; + set_register(pegasus, Reg1d, 0); + set_register(pegasus, Reg7b, 1); + mdelay(100); set_register(pegasus, Reg7b, 2); + + set_register(pegasus, 0x83, data); + get_registers(pegasus, 0x83, 1, &data); + + if (data == 0xa5) { + pegasus->chip = 0x8513; + } else { + pegasus->chip = 0; + } + + set_register(pegasus, 0x80, 0xc0); + set_register(pegasus, 0x83, 0xff); + set_register(pegasus, 0x84, 0x01); + if (pegasus->features & HAS_HOME_PNA && mii_mode) set_register(pegasus, Reg81, 6); else @@ -1065,13 +1153,13 @@ static int pegasus_probe(struct usb_interface *intf, err("usb_set_configuration() failed"); return -ENODEV; } - if (!(pegasus = kmalloc(sizeof(struct pegasus), GFP_KERNEL))) { + if (!(pegasus = kmalloc(sizeof (struct pegasus), GFP_KERNEL))) { err("out of memory allocating device structure"); return -ENOMEM; } usb_get_dev(dev); - memset(pegasus, 0, sizeof(struct pegasus)); + memset(pegasus, 0, sizeof (struct pegasus)); pegasus->dev_index = dev_index; init_waitqueue_head(&pegasus->ctrl_wait); @@ -1088,8 +1176,8 @@ static int pegasus_probe(struct usb_interface *intf, } init_MUTEX(&pegasus->sem); - tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long)pegasus); - + tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); + down(&pegasus->sem); pegasus->usb = dev; pegasus->net = net; @@ -1104,6 +1192,11 @@ static int pegasus_probe(struct usb_interface *intf, net->set_multicast_list = pegasus_set_multicast; net->get_stats = pegasus_netdev_stats; net->mtu = PEGASUS_MTU; + pegasus->mii.dev = net; + pegasus->mii.mdio_read = mdio_read; + pegasus->mii.mdio_write = mdio_write; + pegasus->mii.phy_id_mask = 0x1f; + pegasus->mii.reg_num_mask = 0x1f; spin_lock_init(&pegasus->rx_pool_lock); pegasus->features = usb_dev_id[dev_index].private; @@ -1132,7 +1225,7 @@ static int pegasus_probe(struct usb_interface *intf, exit: up(&pegasus->sem); if (pegasus) { - dev_set_drvdata (&intf->dev, pegasus); + dev_set_drvdata(&intf->dev, pegasus); return 0; } return -EIO; @@ -1140,9 +1233,9 @@ exit: static void pegasus_disconnect(struct usb_interface *intf) { - struct pegasus *pegasus = dev_get_drvdata (&intf->dev); + struct pegasus *pegasus = dev_get_drvdata(&intf->dev); - dev_set_drvdata (&intf->dev, NULL); + dev_set_drvdata(&intf->dev, NULL); if (!pegasus) { warn("unregistering non-existant device"); return; @@ -1162,10 +1255,10 @@ static void pegasus_disconnect(struct usb_interface *intf) } static struct usb_driver pegasus_driver = { - .name = driver_name, - .probe = pegasus_probe, - .disconnect = pegasus_disconnect, - .id_table = pegasus_ids, + .name = driver_name, + .probe = pegasus_probe, + .disconnect = pegasus_disconnect, + .id_table = pegasus_ids, }; int __init pegasus_init(void) diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h index d7ec89f5d610..476cbeb92b97 100644 --- a/drivers/usb/net/pegasus.h +++ b/drivers/usb/net/pegasus.h @@ -85,6 +85,7 @@ typedef struct pegasus { struct usb_device *usb; struct net_device *net; struct net_device_stats stats; + struct mii_if_info mii; unsigned flags; unsigned features; int dev_index; @@ -97,6 +98,7 @@ typedef struct pegasus { wait_queue_head_t ctrl_wait; struct semaphore sem; spinlock_t rx_pool_lock; + int chip; unsigned char intr_buff[8]; __u8 tx_buff[PEGASUS_MTU]; __u8 eth_regs[4]; @@ -131,11 +133,11 @@ struct usb_eth_dev { #define VENDOR_LANEED 0x056e #define VENDOR_LINKSYS 0x066b #define VENDOR_MELCO 0x0411 +#define VENDOR_NETGEAR 0x0846 #define VENDOR_SMARTBRIDGES 0x08d1 #define VENDOR_SMC 0x0707 #define VENDOR_SOHOWARE 0x15e8 #define VENDOR_SIEMENS 0x067c -#define VENDOR_JTEC 0x11ad #else /* PEGASUS_DEV */ @@ -169,7 +171,10 @@ PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", VENDOR_ADMTEK, 0x8511, DEFAULT_GPIO_RESET | PEGASUS_II ) -PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)", +PEGASUS_DEV( "ADMtek ADM8513 \"Pegasus II\" USB Ethernet", + VENDOR_ADMTEK, 0x8513, + DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)", VENDOR_ADMTEK, 0x0986, DEFAULT_GPIO_RESET | HAS_HOME_PNA ) PEGASUS_DEV( "AN986A USB MAC", VENDOR_ADMTEK, 1986, @@ -192,7 +197,7 @@ PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004, DEFAULT_GPIO_RESET ) -PEGASUS_DEV( "Corega FEter", VENDOR_COREGA, 0x000d, +PEGASUS_DEV( "Corega FEter USB-TXS", VENDOR_COREGA, 0x000d, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001, LINKSYS_GPIO_RESET ) @@ -246,6 +251,8 @@ PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009, DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "NETGEAR FA101", VENDOR_NETGEAR, 0x1020, + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200, @@ -258,8 +265,6 @@ PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001, DEFAULT_GPIO_RESET | PEGASUS_II ) -PEGASUS_DEV( "FA8101 USB To ETHERNET", VENDOR_JTEC, 0x8101, - DEFAULT_GPIO_RESET | PEGASUS_II ) #endif /* PEGASUS_DEV */ diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 75510b41e8ab..1ee4eace260b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -14,6 +14,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (11/19/2002) gkh + * removed a few #ifdefs for the generic code and cleaned up the failure + * logic in initialization. + * * (10/02/2002) gkh * moved the console code to console.c and out of this file. * @@ -341,7 +345,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.6" +#define DRIVER_VERSION "v1.7" #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" #define DRIVER_DESC "USB Serial Driver core" @@ -382,7 +386,29 @@ static struct usb_device_id generic_serial_ids[] = { {.driver_info = 42}, {} }; -#endif + +static int generic_register (void) +{ + generic_device_ids[0].idVendor = vendor; + generic_device_ids[0].idProduct = product; + generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; + + /* register our generic driver with ourselves */ + return usb_serial_register (&generic_device); +} + +static void generic_deregister (void) +{ + /* remove our generic driver */ + usb_serial_deregister (&generic_device); +} + +#else + +static inline int generic_register (void) { return 0; } +static inline void generic_deregister (void) { } + +#endif /* CONFIG_USB_SERIAL_GENERIC */ /* Driver structure we register with the USB core */ static struct usb_driver usb_serial_driver = { @@ -409,7 +435,6 @@ static struct termios * serial_termios_locked[SERIAL_TTY_MINORS]; static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ static LIST_HEAD(usb_serial_driver_list); - struct usb_serial *usb_serial_get_by_minor (unsigned int minor) { return serial_table[minor]; @@ -839,7 +864,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int length += sprintf (page+length, "%d:", i); if (serial->type->owner) - length += sprintf (page+length, " module:%s", serial->type->owner->name); + length += sprintf (page+length, " module:%s", module_name(serial->type->owner)); length += sprintf (page+length, " name:\"%s\"", serial->type->name); length += sprintf (page+length, " vendor:%04x product:%04x", serial->vendor, serial->product); length += sprintf (page+length, " num_ports:%d", serial->num_ports); @@ -1574,40 +1599,49 @@ static struct tty_driver serial_tty_driver = { static int __init usb_serial_init(void) { int i; - int result; + int result = 0; /* Initalize our global data */ for (i = 0; i < SERIAL_TTY_MINORS; ++i) { serial_table[i] = NULL; } + /* register the generic driver, if we should */ + result = generic_register(); + if (result < 0) { + err("%s - registering generic driver failed", __FUNCTION__); + goto exit; + } + /* register the tty driver */ serial_tty_driver.init_termios = tty_std_termios; serial_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - if (tty_register_driver (&serial_tty_driver)) { - err("%s - failed to register tty driver", __FUNCTION__); - return -1; + result = tty_register_driver (&serial_tty_driver); + if (result) { + err("%s - tty_register_driver failed", __FUNCTION__); + goto exit_generic; } /* register the USB driver */ result = usb_register(&usb_serial_driver); if (result < 0) { - tty_unregister_driver(&serial_tty_driver); - err("usb_register failed for the usb-serial driver. Error number %d", result); - return -1; + err("%s - usb_register failed", __FUNCTION__); + goto exit_tty; } -#ifdef CONFIG_USB_SERIAL_GENERIC - generic_device_ids[0].idVendor = vendor; - generic_device_ids[0].idProduct = product; - generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; - /* register our generic driver with ourselves */ - usb_serial_register (&generic_device); -#endif - info(DRIVER_DESC " " DRIVER_VERSION); - return 0; + return result; + +exit_tty: + tty_unregister_driver(&serial_tty_driver); + +exit_generic: + generic_deregister(); + +exit: + err ("%s - returning with error %d", __FUNCTION__, result); + return result; } @@ -1615,11 +1649,8 @@ static void __exit usb_serial_exit(void) { usb_serial_console_exit(); -#ifdef CONFIG_USB_SERIAL_GENERIC - /* remove our generic driver */ - usb_serial_deregister (&generic_device); -#endif - + generic_deregister(); + usb_deregister(&usb_serial_driver); tty_unregister_driver(&serial_tty_driver); } diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 32e9b512adc1..c58935a2e6b0 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -115,7 +115,7 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, freecom_udata_t extra = (freecom_udata_t) us->extra; struct freecom_xfer_wrap *fxfr = (struct freecom_xfer_wrap *) extra->buffer; - int result, partial; + int result; fxfr->Type = FCM_PACKET_INPUT | 0x00; fxfr->Timeout = 0; /* Short timeout for debugging. */ @@ -125,14 +125,12 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, US_DEBUGP("Read data Freecom! (c=%d)\n", count); /* Issue the transfer command. */ - result = usb_stor_bulk_msg (us, fxfr, opipe, - FCM_PACKET_LENGTH, &partial); + result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, + FCM_PACKET_LENGTH, NULL); if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("Freecom readdata xport failure: r=%d, p=%d\n", - result, partial); + US_DEBUGP ("Freecom readdata transport error\n"); return USB_STOR_TRANSPORT_ERROR; } - US_DEBUGP("Done issuing read request: %d %d\n", result, partial); /* Now transfer all of our blocks. */ US_DEBUGP("Start of read\n"); @@ -151,7 +149,7 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, freecom_udata_t extra = (freecom_udata_t) us->extra; struct freecom_xfer_wrap *fxfr = (struct freecom_xfer_wrap *) extra->buffer; - int result, partial; + int result; fxfr->Type = FCM_PACKET_OUTPUT | 0x00; fxfr->Timeout = 0; /* Short timeout for debugging. */ @@ -161,15 +159,12 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, US_DEBUGP("Write data Freecom! (c=%d)\n", count); /* Issue the transfer command. */ - result = usb_stor_bulk_msg (us, fxfr, opipe, - FCM_PACKET_LENGTH, &partial); + result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, + FCM_PACKET_LENGTH, NULL); if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("Freecom writedata xport failure: r=%d, p=%d\n", - result, partial); + US_DEBUGP ("Freecom writedata transport error\n"); return USB_STOR_TRANSPORT_ERROR; } - US_DEBUGP("Done issuing write request: %d %d\n", - result, partial); /* Now transfer all of our blocks. */ US_DEBUGP("Start of write\n"); @@ -191,7 +186,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) struct freecom_status *fst; unsigned int ipipe, opipe; /* We need both pipes. */ int result; - int partial; + unsigned int partial; int length; freecom_udata_t extra; @@ -215,23 +210,22 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) US_DEBUG(pdump (srb->cmnd, 12)); /* Send it out. */ - result = usb_stor_bulk_msg (us, fcb, opipe, - FCM_PACKET_LENGTH, &partial); + result = usb_stor_bulk_transfer_buf (us, opipe, fcb, + FCM_PACKET_LENGTH, NULL); /* The Freecom device will only fail if there is something wrong in * USB land. It returns the status in its own registers, which * come back in the bulk pipe. */ if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("freecom xport failure: r=%d, p=%d\n", - result, partial); + US_DEBUGP ("freecom transport error\n"); return USB_STOR_TRANSPORT_ERROR; } /* There are times we can optimize out this status read, but it * doesn't hurt us to always do it now. */ - result = usb_stor_bulk_msg (us, fst, ipipe, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); - US_DEBUGP("foo Status result %d %d\n", result, partial); + US_DEBUGP("foo Status result %d %u\n", result, partial); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -256,24 +250,23 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) memset (fcb->Filler, 0, sizeof (fcb->Filler)); /* Send it out. */ - result = usb_stor_bulk_msg (us, fcb, opipe, - FCM_PACKET_LENGTH, &partial); + result = usb_stor_bulk_transfer_buf (us, opipe, fcb, + FCM_PACKET_LENGTH, NULL); /* The Freecom device will only fail if there is something * wrong in USB land. It returns the status in its own * registers, which come back in the bulk pipe. */ if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("freecom xport failure: r=%d, p=%d\n", - result, partial); + US_DEBUGP ("freecom transport error\n"); return USB_STOR_TRANSPORT_ERROR; } /* get the data */ - result = usb_stor_bulk_msg (us, fst, ipipe, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); - US_DEBUGP("bar Status result %d %d\n", result, partial); + US_DEBUGP("bar Status result %d %u\n", result, partial); if (result > USB_STOR_XFER_SHORT) return USB_STOR_TRANSPORT_ERROR; @@ -328,7 +321,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) return result; US_DEBUGP("FCM: Waiting for status\n"); - result = usb_stor_bulk_msg (us, fst, ipipe, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); US_DEBUG(pdump ((void *) fst, partial)); @@ -354,7 +347,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) return result; US_DEBUGP("FCM: Waiting for status\n"); - result = usb_stor_bulk_msg (us, fst, ipipe, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); if (partial != 4 || result > USB_STOR_XFER_SHORT) @@ -385,13 +378,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) } return USB_STOR_TRANSPORT_GOOD; - - US_DEBUGP("Freecom: transfer_length = %d\n", - usb_stor_transfer_length (srb)); - - US_DEBUGP("Freecom: direction = %d\n", srb->sc_data_direction); - - return USB_STOR_TRANSPORT_ERROR; } int diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 32c5474b6585..a2ea1d931558 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -668,7 +668,7 @@ int isd200_write_config( struct us_data *us ) #endif /* let's send the command via the control pipe */ - result = usb_stor_control_msg( + result = usb_stor_ctrl_transfer( us, us->send_ctrl_pipe, 0x01, @@ -709,7 +709,7 @@ int isd200_read_config( struct us_data *us ) /* read the configuration information from ISD200. Use this to */ /* determine what the special ATA CDB bytes are. */ - result = usb_stor_control_msg( + result = usb_stor_ctrl_transfer( us, us->recv_ctrl_pipe, 0x02, diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index aefbefa07085..378cf03db154 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -479,7 +479,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, usb_stor_blocking_completion, NULL); status = usb_stor_msg_common(us); - /* return the actual length of the data transferred if no error*/ + /* return the actual length of the data transferred if no error */ if (status >= 0) status = us->current_urb->actual_length; return status; @@ -543,48 +543,92 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) return 0; } + /* - * Transfer one control message + * Interpret the results of a URB transfer * - * This function does basically the same thing as usb_stor_control_msg() - * above, except that return codes are USB_STOR_XFER_xxx rather than the - * urb status or transfer length. + * This function prints appropriate debugging messages, clears halts on + * bulk endpoints, and translates the status to the corresponding + * USB_STOR_XFER_xxx return code. */ -int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, - u8 request, u8 requesttype, u16 value, u16 index, - void *data, u16 size) { - int result; +static int interpret_urb_result(struct us_data *us, unsigned int pipe, + unsigned int length, int result, unsigned int partial) { - US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x " - "value=%04x index=%02x len=%d\n", - request, requesttype, value, index, size); - result = usb_stor_control_msg(us, pipe, request, requesttype, - value, index, data, size); - US_DEBUGP("usb_stor_control_msg returned %d\n", result); + US_DEBUGP("Status code %d; transferred %u/%u\n", + result, partial, length); - /* a stall indicates a protocol error */ + /* stalled */ if (result == -EPIPE) { - US_DEBUGP("-- stall on control pipe\n"); + + /* for non-bulk (i.e., control) endpoints, a stall indicates + * a protocol error */ + if (!usb_pipebulk(pipe)) { + US_DEBUGP("-- stall on control pipe\n"); + return USB_STOR_XFER_ERROR; + } + + /* for a bulk endpoint, clear the stall */ + US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); + if (usb_stor_clear_halt(us, pipe) < 0) + return USB_STOR_XFER_ERROR; + return USB_STOR_XFER_STALLED; + } + + /* NAK - that means we've retried this a few times already */ + if (result == -ETIMEDOUT) { + US_DEBUGP("-- device NAKed\n"); + return USB_STOR_XFER_ERROR; + } + + /* the transfer was cancelled, presumably by an abort */ + if (result == -ENODEV) { + US_DEBUGP("-- transfer cancelled\n"); return USB_STOR_XFER_ERROR; } - /* some other serious problem here */ + /* the catch-all error case */ if (result < 0) { US_DEBUGP("-- unknown error\n"); return USB_STOR_XFER_ERROR; } - /* was the entire command transferred? */ - if (result < size) { - US_DEBUGP("-- transferred only %d bytes\n", result); + /* no error code; did we send all the data? */ + if (partial != length) { + US_DEBUGP("-- transferred only %u bytes\n", partial); return USB_STOR_XFER_SHORT; } - US_DEBUGP("-- transfer completed successfully\n"); + US_DEBUGP("-- transfer complete\n"); return USB_STOR_XFER_GOOD; } /* + * Transfer one control message + * + * This function does basically the same thing as usb_stor_control_msg() + * above, except that return codes are USB_STOR_XFER_xxx rather than the + * urb status or transfer length. + */ +int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, + u8 request, u8 requesttype, u16 value, u16 index, + void *data, u16 size) { + int result; + unsigned int partial = 0; + + US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x " + "value=%04x index=%02x len=%u\n", + request, requesttype, value, index, size); + result = usb_stor_control_msg(us, pipe, request, requesttype, + value, index, data, size); + + if (result > 0) { /* Separate out the amount transferred */ + partial = result; + result = 0; + } + return interpret_urb_result(us, pipe, size, result, partial); +} + +/* * Transfer one buffer via bulk transfer * * This function does basically the same thing as usb_stor_bulk_msg() @@ -596,50 +640,17 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, * urb status or transfer length. */ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, - char *buf, unsigned int length, unsigned int *act_len) + void *buf, unsigned int length, unsigned int *act_len) { int result; - int partial; + unsigned int partial; /* transfer the data */ - US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %d bytes\n", length); + US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %u bytes\n", length); result = usb_stor_bulk_msg(us, buf, pipe, length, &partial); - US_DEBUGP("usb_stor_bulk_msg() returned %d xferred %d/%d\n", - result, partial, length); if (act_len) *act_len = partial; - - /* if we stall, we need to clear it before we go on */ - if (result == -EPIPE) { - US_DEBUGP("clearing endpoint halt for pipe 0x%x," - " stalled at %d bytes\n", pipe, partial); - if (usb_stor_clear_halt(us, pipe) < 0) - return USB_STOR_XFER_ERROR; - return USB_STOR_XFER_STALLED; - } - - /* NAK - that means we've retried a few times already */ - if (result == -ETIMEDOUT) { - US_DEBUGP("-- device NAKed\n"); - return USB_STOR_XFER_ERROR; - } - - /* the catch-all error case */ - if (result) { - US_DEBUGP("-- unknown error\n"); - return USB_STOR_XFER_ERROR; - } - - /* did we send all the data? */ - if (partial == length) { - US_DEBUGP("-- transfer complete\n"); - return USB_STOR_XFER_GOOD; - } - - /* no error code, so we must have transferred some data, - * just not all of it */ - US_DEBUGP("-- transferred only %d bytes\n", partial); - return USB_STOR_XFER_SHORT; + return interpret_urb_result(us, pipe, length, result, partial); } /* @@ -653,10 +664,10 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, unsigned int *act_len) { int result; - int partial; + unsigned int partial; /* initialize the scatter-gather request block */ - US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %d bytes, " + US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %u bytes, " "%d entries\n", length, num_sg); result = usb_sg_init(us->current_sg, us->pusb_dev, pipe, 0, sg, num_sg, length, SLAB_NOIO); @@ -685,55 +696,22 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, result = us->current_sg->status; partial = us->current_sg->bytes; - US_DEBUGP("usb_sg_wait() returned %d xferred %d/%d\n", - result, partial, length); if (act_len) *act_len = partial; - - /* if we stall, we need to clear it before we go on */ - if (result == -EPIPE) { - US_DEBUGP("clearing endpoint halt for pipe 0x%x, " - "stalled at %d bytes\n", pipe, partial); - if (usb_stor_clear_halt(us, pipe) < 0) - return USB_STOR_XFER_ERROR; - return USB_STOR_XFER_STALLED; - } - - /* NAK - that means we've retried this a few times already */ - if (result == -ETIMEDOUT) { - US_DEBUGP("-- device NAKed\n"); - return USB_STOR_XFER_ERROR; - } - - /* the catch-all error case */ - if (result) { - US_DEBUGP("-- unknown error\n"); - return USB_STOR_XFER_ERROR; - } - - /* did we send all the data? */ - if (partial == length) { - US_DEBUGP("-- transfer complete\n"); - return USB_STOR_XFER_GOOD; - } - - /* no error code, so we must have transferred some data, - * just not all of it */ - US_DEBUGP("-- transferred only %d bytes\n", partial); - return USB_STOR_XFER_SHORT; + return interpret_urb_result(us, pipe, length, result, partial); } /* * Transfer an entire SCSI command's worth of data payload over the bulk * pipe. * - * Nore that this uses usb_stor_bulk_transfer_buf() and + * Note that this uses usb_stor_bulk_transfer_buf() and * usb_stor_bulk_transfer_sglist() to achieve its goals -- * this function simply determines whether we're going to use * scatter-gather or not, and acts appropriately. */ int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe, - char *buf, unsigned int length_left, int use_sg, int *residual) + void *buf, unsigned int length_left, int use_sg, int *residual) { int result; unsigned int partial; @@ -1278,7 +1256,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) (bcb.Lun >> 4), (bcb.Lun & 0x0F), le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length); result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, - (char *) &bcb, US_BULK_CB_WRAP_LEN, NULL); + &bcb, US_BULK_CB_WRAP_LEN, NULL); US_DEBUGP("Bulk command transfer result=%d\n", result); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -1302,7 +1280,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) /* get CSW for device status */ US_DEBUGP("Attempting to get CSW...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, - (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL); + &bcs, US_BULK_CS_WRAP_LEN, NULL); /* did the attempt to read the CSW fail? */ if (result == USB_STOR_XFER_STALLED) { @@ -1310,7 +1288,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) /* get the status again */ US_DEBUGP("Attempting to get CSW (2nd try)...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, - (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL); + &bcs, US_BULK_CS_WRAP_LEN, NULL); } /* if we still have a failure at this point, we're in trouble */ diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index df787201daa2..a8ac7f3fbf8f 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -117,6 +117,7 @@ struct bulk_cs_wrap { /* * usb_stor_bulk_transfer_xxx() return codes, in order of severity */ + #define USB_STOR_XFER_GOOD 0 /* good transfer */ #define USB_STOR_XFER_SHORT 1 /* transfered less than expected */ #define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ @@ -129,7 +130,14 @@ struct bulk_cs_wrap { #define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */ #define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */ #define USB_STOR_TRANSPORT_ERROR 2 /* Transport bad (i.e. device dead) */ -#define USB_STOR_TRANSPORT_ABORTED 3 /* Transport aborted */ + +/* + * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED + * return codes. But now the transport and low-level transfer routines + * treat an abort as just another error (-ENOENT for a cancelled URB). + * It is up to the invoke_transport() function to test for aborts and + * distinguish them from genuine communication errors. + */ /* * CBI accept device specific command @@ -162,12 +170,12 @@ extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size); extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, - char *buf, unsigned int length, unsigned int *act_len); + void *buf, unsigned int length, unsigned int *act_len); extern int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, struct scatterlist *sg, int num_sg, unsigned int length, unsigned int *act_len); extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe, - char *buf, unsigned int length, int use_sg, int *residual); + void *buf, unsigned int length, int use_sg, int *residual); static __inline__ int usb_stor_bulk_transfer_srb(struct us_data *us, unsigned int pipe, Scsi_Cmnd *srb, unsigned int length) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 7206acd7870b..3fa04d5f93f8 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -517,21 +517,6 @@ void pcibios_update_resource(struct pci_dev *, struct resource *, void pcibios_update_irq(struct pci_dev *, int irq); void pcibios_fixup_pbus_ranges(struct pci_bus *, struct pbus_set_ranges_data *); -/* Backward compatibility, don't use in new code! */ - -int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char *val); -int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short *val); -int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int *val); -int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char val); -int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short val); -int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int val); - /* Generic PCI functions used internally */ int pci_bus_exists(const struct list_head *list, int nr); @@ -668,8 +653,6 @@ extern struct pci_dev *isa_bridge; static inline int pci_present(void) { return 0; } #define _PCI_NOP(o,s,t) \ - static inline int pcibios_##o##_config_##s (u8 bus, u8 dfn, u8 where, t val) \ - { return PCIBIOS_FUNC_NOT_SUPPORTED; } \ static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \ { return PCIBIOS_FUNC_NOT_SUPPORTED; } #define _PCI_NOP_ALL(o,x) _PCI_NOP(o,byte,u8 x) \ |
