summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-11-19 16:51:10 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2002-11-19 16:51:10 -0800
commitde5bd36f7695fae088f899f81e2be84eb3e62314 (patch)
tree79765017970f13af092c1a3dc32eceb8ddf5d611
parent0d0b710572e61bd3756856f7c760dea89913f1ac (diff)
parent9f311f51f4c01f8fba4faa315ddd5e8dc54671d8 (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.c23
-rw-r--r--drivers/pci/Makefile4
-rw-r--r--drivers/pci/compat.c37
-rw-r--r--drivers/pcmcia/cistpl.c5
-rw-r--r--drivers/usb/core/config.c23
-rw-r--r--drivers/usb/media/vicam.c234
-rw-r--r--drivers/usb/net/pegasus.c303
-rw-r--r--drivers/usb/net/pegasus.h15
-rw-r--r--drivers/usb/serial/usb-serial.c81
-rw-r--r--drivers/usb/storage/freecom.c56
-rw-r--r--drivers/usb/storage/isd200.c4
-rw-r--r--drivers/usb/storage/transport.c178
-rw-r--r--drivers/usb/storage/transport.h14
-rw-r--r--include/linux/pci.h17
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(&ethcmd, 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) \