diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-07-18 21:21:28 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-07-18 21:21:28 -0700 |
| commit | 047cef3222151cd62f2134597b73a59621acbdaf (patch) | |
| tree | 40d5bb994afd49c3a67c849a29181509284888a1 | |
| parent | b6938a7bd23a74cfa7a81c0765ec255ea1c7e12e (diff) | |
| parent | 23c7f059db5b57c37ad070a1863ee69e5796daec (diff) | |
Merge http://linuxusb.bkbits.net/linus-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
80 files changed, 1422 insertions, 5289 deletions
diff --git a/Documentation/usb/ov511.txt b/Documentation/usb/ov511.txt index f7a2108e7530..4c33f949dfb0 100644 --- a/Documentation/usb/ov511.txt +++ b/Documentation/usb/ov511.txt @@ -128,16 +128,6 @@ MODULE PARAMETERS: programs that expect RGB data (e.g. gqcam) to work with this driver. If your colors look VERY wrong, you may want to change this. - NAME: buf_timeout (Temporarily disabled. Memory is deallocated immediately) - TYPE: integer - DEFAULT: 5 (seconds) - DESC: Number of seconds before unused frame buffers are deallocated. - Previously, memory was allocated upon open() and deallocated upon - close(). Deallocation now occurs only if the driver is closed and this - timeout is reached. If you are capturing frames less frequently than - the default timeout, increase this. This will not make any difference - with programs that capture multiple frames during an open/close cycle. - NAME: cams TYPE: integer (1-4 for OV511, 1-31 for OV511+) DEFAULT: 1 @@ -161,13 +151,6 @@ MODULE PARAMETERS: DESC: This configures the camera's sensor to transmit a colored test-pattern instead of an image. This does not work correctly yet. - NAME: sensor_gbr (*** TEMPORARILY DISABLED ***) - TYPE: integer (Boolean) - DEFAULT: 0 - DESC: This makes the sensor output GBR422 instead of YUV420. This saves the - driver the trouble of converting YUV to RGB, but it currently does not - work very well (the colors are not quite right) - NAME: dumppix TYPE: integer (0-2) DEFAULT: 0 @@ -259,14 +242,6 @@ MODULE PARAMETERS: 13 VIDEO_PALETTE_YUV422P (YUV 4:2:2 Planar) 15 VIDEO_PALETTE_YUV420P (YUV 4:2:0 Planar, same as 10) - NAME: tuner - TYPE: integer - DEFAULT: -1 (autodetect) - DESC: This sets the exact type of the tuner module in a device. This is set - automatically based on the custom ID of the OV511 device. In cases - where this fails, you can override this auto-detection. Please see - linux/drivers/media/video/tuner.h for a complete list. - NAME: backlight TYPE: integer (Boolean) DEFAULT: 0 (off) diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 65e4999ba5bf..07c5ea5b7e81 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c @@ -2091,11 +2091,11 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign } static /*const*/ struct file_operations usb_mixer_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - ioctl: usb_audio_ioctl_mixdev, - open: usb_audio_open_mixdev, - release: usb_audio_release_mixdev, + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = usb_audio_ioctl_mixdev, + .open = usb_audio_open_mixdev, + .release = usb_audio_release_mixdev, }; /* --------------------------------------------------------------------- */ @@ -2727,15 +2727,15 @@ static int usb_audio_release(struct inode *inode, struct file *file) } static /*const*/ struct file_operations usb_audio_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - read: usb_audio_read, - write: usb_audio_write, - poll: usb_audio_poll, - ioctl: usb_audio_ioctl, - mmap: usb_audio_mmap, - open: usb_audio_open, - release: usb_audio_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = usb_audio_read, + .write = usb_audio_write, + .poll = usb_audio_poll, + .ioctl = usb_audio_ioctl, + .mmap = usb_audio_mmap, + .open = usb_audio_open, + .release = usb_audio_release, }; /* --------------------------------------------------------------------- */ @@ -2753,11 +2753,11 @@ static struct usb_device_id usb_audio_ids [] = { MODULE_DEVICE_TABLE (usb, usb_audio_ids); static struct usb_driver usb_audio_driver = { - name: "audio", - probe: usb_audio_probe, - disconnect: usb_audio_disconnect, - driver_list: LIST_HEAD_INIT(usb_audio_driver.driver_list), - id_table: usb_audio_ids, + .name = "audio", + .probe = usb_audio_probe, + .disconnect = usb_audio_disconnect, + .driver_list = LIST_HEAD_INIT(usb_audio_driver.driver_list), + .id_table = usb_audio_ids, }; static void *find_descriptor(void *descstart, unsigned int desclen, void *after, diff --git a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c index a2ad9ef139c7..8fae68841bbf 100644 --- a/drivers/usb/class/bluetty.c +++ b/drivers/usb/class/bluetty.c @@ -234,10 +234,10 @@ static struct usb_device_id usb_bluetooth_ids [] = { MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids); static struct usb_driver usb_bluetooth_driver = { - name: "bluetty", - probe: usb_bluetooth_probe, - disconnect: usb_bluetooth_disconnect, - id_table: usb_bluetooth_ids, + .name = "bluetty", + .probe = usb_bluetooth_probe, + .disconnect = usb_bluetooth_disconnect, + .id_table = usb_bluetooth_ids, }; static int bluetooth_refcount; @@ -1284,30 +1284,30 @@ static void usb_bluetooth_disconnect(struct usb_device *dev, void *ptr) static struct tty_driver bluetooth_tty_driver = { - magic: TTY_DRIVER_MAGIC, - driver_name: "usb-bluetooth", - name: "usb/ttub/%d", - major: BLUETOOTH_TTY_MAJOR, - minor_start: 0, - num: BLUETOOTH_TTY_MINORS, - type: TTY_DRIVER_TYPE_SERIAL, - subtype: SERIAL_TYPE_NORMAL, - flags: TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, - - refcount: &bluetooth_refcount, - table: bluetooth_tty, - termios: bluetooth_termios, - termios_locked: bluetooth_termios_locked, - - open: bluetooth_open, - close: bluetooth_close, - write: bluetooth_write, - write_room: bluetooth_write_room, - ioctl: bluetooth_ioctl, - set_termios: bluetooth_set_termios, - throttle: bluetooth_throttle, - unthrottle: bluetooth_unthrottle, - chars_in_buffer: bluetooth_chars_in_buffer, + .magic = TTY_DRIVER_MAGIC, + .driver_name = "usb-bluetooth", + .name = "usb/ttub/%d", + .major = BLUETOOTH_TTY_MAJOR, + .minor_start = 0, + .num = BLUETOOTH_TTY_MINORS, + .type = TTY_DRIVER_TYPE_SERIAL, + .subtype = SERIAL_TYPE_NORMAL, + .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, + + .refcount = &bluetooth_refcount, + .table = bluetooth_tty, + .termios = bluetooth_termios, + .termios_locked = bluetooth_termios_locked, + + .open = bluetooth_open, + .close = bluetooth_close, + .write = bluetooth_write, + .write_room = bluetooth_write_room, + .ioctl = bluetooth_ioctl, + .set_termios = bluetooth_set_termios, + .throttle = bluetooth_throttle, + .unthrottle = bluetooth_unthrottle, + .chars_in_buffer = bluetooth_chars_in_buffer, }; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 0e1d275b53b1..8fc07f6fb5d7 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -683,10 +683,10 @@ static struct usb_device_id acm_ids[] = { MODULE_DEVICE_TABLE (usb, acm_ids); static struct usb_driver acm_driver = { - name: "acm", - probe: acm_probe, - disconnect: acm_disconnect, - id_table: acm_ids, + .name = "acm", + .probe = acm_probe, + .disconnect = acm_disconnect, + .id_table = acm_ids, }; /* @@ -700,32 +700,32 @@ static struct termios *acm_tty_termios[ACM_TTY_MINORS]; static struct termios *acm_tty_termios_locked[ACM_TTY_MINORS]; static struct tty_driver acm_tty_driver = { - magic: TTY_DRIVER_MAGIC, - driver_name: "acm", - name: "usb/acm/%d", - major: ACM_TTY_MAJOR, - minor_start: 0, - num: ACM_TTY_MINORS, - type: TTY_DRIVER_TYPE_SERIAL, - subtype: SERIAL_TYPE_NORMAL, - flags: TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, - - refcount: &acm_tty_refcount, - - table: acm_tty_table, - termios: acm_tty_termios, - termios_locked: acm_tty_termios_locked, - - open: acm_tty_open, - close: acm_tty_close, - write: acm_tty_write, - write_room: acm_tty_write_room, - ioctl: acm_tty_ioctl, - throttle: acm_tty_throttle, - unthrottle: acm_tty_unthrottle, - chars_in_buffer: acm_tty_chars_in_buffer, - break_ctl: acm_tty_break_ctl, - set_termios: acm_tty_set_termios + .magic = TTY_DRIVER_MAGIC, + .driver_name = "acm", + .name = "usb/acm/%d", + .major = ACM_TTY_MAJOR, + .minor_start = 0, + .num = ACM_TTY_MINORS, + .type = TTY_DRIVER_TYPE_SERIAL, + .subtype = SERIAL_TYPE_NORMAL, + .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, + + .refcount = &acm_tty_refcount, + + .table = acm_tty_table, + .termios = acm_tty_termios, + .termios_locked = acm_tty_termios_locked, + + .open = acm_tty_open, + .close = acm_tty_close, + .write = acm_tty_write, + .write_room = acm_tty_write_room, + .ioctl = acm_tty_ioctl, + .throttle = acm_tty_throttle, + .unthrottle = acm_tty_unthrottle, + .chars_in_buffer = acm_tty_chars_in_buffer, + .break_ctl = acm_tty_break_ctl, + .set_termios = acm_tty_set_termios }; /* diff --git a/drivers/usb/class/printer.c b/drivers/usb/class/printer.c index cd9b52896fa5..b08c164dfd75 100644 --- a/drivers/usb/class/printer.c +++ b/drivers/usb/class/printer.c @@ -655,7 +655,10 @@ static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, (count - writecount) : USBLP_BUF_SIZE; if (copy_from_user(usblp->writeurb->transfer_buffer, buffer + writecount, - usblp->writeurb->transfer_buffer_length)) return -EFAULT; + usblp->writeurb->transfer_buffer_length)) { + up(&usblp->sem); + return writecount ? writecount : -EFAULT; + } usblp->writeurb->dev = usblp->dev; usblp->wcomplete = 0; @@ -783,13 +786,13 @@ static unsigned int usblp_quirks (__u16 vendor, __u16 product) } static struct file_operations usblp_fops = { - owner: THIS_MODULE, - read: usblp_read, - write: usblp_write, - poll: usblp_poll, - ioctl: usblp_ioctl, - open: usblp_open, - release: usblp_release, + .owner = THIS_MODULE, + .read = usblp_read, + .write = usblp_write, + .poll = usblp_poll, + .ioctl = usblp_ioctl, + .open = usblp_open, + .release = usblp_release, }; static void *usblp_probe(struct usb_device *dev, unsigned int ifnum, @@ -1097,11 +1100,11 @@ static struct usb_device_id usblp_ids [] = { MODULE_DEVICE_TABLE (usb, usblp_ids); static struct usb_driver usblp_driver = { - owner: THIS_MODULE, - name: "usblp", - probe: usblp_probe, - disconnect: usblp_disconnect, - id_table: usblp_ids, + .owner = THIS_MODULE, + .name = "usblp", + .probe = usblp_probe, + .disconnect = usblp_disconnect, + .id_table = usblp_ids, }; static int __init usblp_init(void) diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c index 8aae77591839..cd35694b7d35 100644 --- a/drivers/usb/class/usb-midi.c +++ b/drivers/usb/class/usb-midi.c @@ -988,12 +988,12 @@ static int usb_midi_release(struct inode *inode, struct file *file) } static struct file_operations usb_midi_fops = { - llseek: usb_midi_llseek, - read: usb_midi_read, - write: usb_midi_write, - poll: usb_midi_poll, - open: usb_midi_open, - release: usb_midi_release, + .llseek = usb_midi_llseek, + .read = usb_midi_read, + .write = usb_midi_write, + .poll = usb_midi_poll, + .open = usb_midi_open, + .release = usb_midi_release, }; /* ------------------------------------------------------------------------- */ @@ -2095,11 +2095,11 @@ static void usb_midi_disconnect(struct usb_device *dev, void *ptr) static struct usb_driver usb_midi_driver = { - name: "midi", - probe: usb_midi_probe, - disconnect: usb_midi_disconnect, - id_table: NULL, /* check all devices */ - driver_list: LIST_HEAD_INIT(usb_midi_driver.driver_list) + .name = "midi", + .probe = usb_midi_probe, + .disconnect = usb_midi_disconnect, + .id_table = NULL, /* check all devices */ + .driver_list = LIST_HEAD_INIT(usb_midi_driver.driver_list) }; /* ------------------------------------------------------------------------- */ @@ -2168,15 +2168,15 @@ static void snd_usb_midi_output_trigger(snd_rawmidi_substream_t * substream, static snd_rawmidi_ops_t snd_usbmidi_output = { - open: snd_usbmidi_output_open, - close: snd_usbmidi_output_close, - trigger: snd_usbmidi_output_trigger, + .open = snd_usbmidi_output_open, + .close = snd_usbmidi_output_close, + .trigger = snd_usbmidi_output_trigger, }; static snd_rawmidi_ops_t snd_usbmidi_input = { - open: snd_usbmidi_input_open, - close: snd_usbmidi_input_close, - trigger: snd_usbmidi_input_trigger, + .open = snd_usbmidi_input_open, + .close = snd_usbmidi_input_close, + .trigger = snd_usbmidi_input_trigger, }; int snd_usbmidi_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rrawmidi) @@ -2211,7 +2211,7 @@ int snd_usbmidi_create( snd_card_t * card, int err, idx; snd_region_t *region; static snd_device_opt_t ops = { - dev_free: snd_usbmidi_dev_free, + .dev_free = snd_usbmidi_dev_free, }; *rchip = NULL; diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index c15f5f4e60b2..e701a4975071 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -152,8 +152,8 @@ static const struct class_info clas_info[] = void usbdevfs_conn_disc_event(void) { - wake_up(&deviceconndiscwq); conndiscevcnt++; + wake_up(&deviceconndiscwq); } static const char *class_decode(const int class) @@ -239,6 +239,7 @@ static char *usb_dump_interface_descriptor(char *start, char *end, const struct if (start > end) return start; + lock_kernel(); /* driver might be unloaded */ start += sprintf(start, format_iface, desc->bInterfaceNumber, desc->bAlternateSetting, @@ -248,6 +249,7 @@ static char *usb_dump_interface_descriptor(char *start, char *end, const struct desc->bInterfaceSubClass, desc->bInterfaceProtocol, iface->driver ? iface->driver->name : "(none)"); + unlock_kernel(); return start; } @@ -597,6 +599,13 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct unlock_kernel(); return POLLIN; } + + /* we may have dropped BKL - need to check for having lost the race */ + if (file->private_data) { + kfree(st); + goto lost_race; + } + /* * need to prevent the module from being unloaded, since * proc_unregister does not call the release method and @@ -606,6 +615,7 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct file->private_data = st; mask = POLLIN; } +lost_race: if (file->f_mode & FMODE_READ) poll_wait(file, &deviceconndiscwq, wait); if (st->lastev != conndiscevcnt) @@ -656,9 +666,9 @@ static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig) } struct file_operations usbdevfs_devices_fops = { - llseek: usb_device_lseek, - read: usb_device_read, - poll: usb_device_poll, - open: usb_device_open, - release: usb_device_release, + .llseek = usb_device_lseek, + .read = usb_device_read, + .poll = usb_device_poll, + .open = usb_device_open, + .release = usb_device_release, }; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index b7c95b292a48..e80a3ed170f8 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -324,9 +324,9 @@ static void driver_disconnect(struct usb_device *dev, void *context) } struct usb_driver usbdevfs_driver = { - name: "usbfs", - probe: driver_probe, - disconnect: driver_disconnect, + .name = "usbfs", + .probe = driver_probe, + .disconnect = driver_disconnect, }; static int claimintf(struct dev_state *ps, unsigned int intf) @@ -361,14 +361,14 @@ static int releaseintf(struct dev_state *ps, unsigned int intf) if (intf >= 8*sizeof(ps->ifclaimed)) return -EINVAL; err = -EINVAL; - lock_kernel(); dev = ps->dev; + down(&dev->serialize); if (dev && test_and_clear_bit(intf, &ps->ifclaimed)) { iface = &dev->actconfig->interface[intf]; usb_driver_release_interface(&usbdevfs_driver, iface); err = 0; } - unlock_kernel(); + up(&dev->serialize); return err; } @@ -722,14 +722,11 @@ static int proc_resetdevice(struct dev_state *ps) if (test_bit(i, &ps->ifclaimed)) continue; - if (intf->driver) { - const struct usb_device_id *id; - down(&intf->driver->serialize); - intf->driver->disconnect(ps->dev, intf->private_data); - id = usb_match_id(ps->dev,intf,intf->driver->id_table); - intf->driver->probe(ps->dev, i, id); - up(&intf->driver->serialize); + lock_kernel(); + if (intf->driver && ps->dev) { + usb_bind_driver(intf->driver,ps->dev, i); } + unlock_kernel(); } return 0; @@ -1092,16 +1089,17 @@ static int proc_ioctl (struct dev_state *ps, void *arg) /* disconnect kernel driver from interface, leaving it unbound. */ case USBDEVFS_DISCONNECT: + /* this function is voodoo. without locking it is a maybe thing */ + lock_kernel(); driver = ifp->driver; if (driver) { - down (&driver->serialize); dbg ("disconnect '%s' from dev %d interface %d", driver->name, ps->dev->devnum, ctrl.ifno); - driver->disconnect (ps->dev, ifp->private_data); + usb_unbind_driver(ps->dev, ifp); usb_driver_release_interface (driver, ifp); - up (&driver->serialize); } else retval = -EINVAL; + unlock_kernel(); break; /* let kernel drivers try to (re)bind to the interface */ @@ -1111,18 +1109,28 @@ static int proc_ioctl (struct dev_state *ps, void *arg) /* talk directly to the interface's driver */ default: + lock_kernel(); /* against module unload */ driver = ifp->driver; - if (driver == 0 || driver->ioctl == 0) - retval = -ENOSYS; - else { - if (ifp->driver->owner) + if (driver == 0 || driver->ioctl == 0) { + unlock_kernel(); + retval = -ENOSYS; + } else { + if (ifp->driver->owner) { __MOD_INC_USE_COUNT(ifp->driver->owner); + unlock_kernel(); + } /* ifno might usefully be passed ... */ retval = driver->ioctl (ps->dev, ctrl.ioctl_code, buf); /* size = min_t(int, size, retval)? */ - if (ifp->driver->owner) + if (ifp->driver->owner) { __MOD_DEC_USE_COUNT(ifp->driver->owner); + } else { + unlock_kernel(); + } } + + if (retval == -ENOIOCTLCMD) + retval = -ENOTTY; } /* cleanup and return */ @@ -1139,7 +1147,7 @@ static int proc_ioctl (struct dev_state *ps, void *arg) static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct dev_state *ps = (struct dev_state *)file->private_data; - int ret = -ENOIOCTLCMD; + int ret = -ENOTTY; if (!(file->f_mode & FMODE_WRITE)) return -EPERM; @@ -1248,10 +1256,10 @@ static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wai } struct file_operations usbdevfs_device_file_operations = { - llseek: usbdev_lseek, - read: usbdev_read, - poll: usbdev_poll, - ioctl: usbdev_ioctl, - open: usbdev_open, - release: usbdev_release, + .llseek = usbdev_lseek, + .read = usbdev_read, + .poll = usbdev_poll, + .ioctl = usbdev_ioctl, + .open = usbdev_open, + .release = usbdev_release, }; diff --git a/drivers/usb/core/drivers.c b/drivers/usb/core/drivers.c index 3419792c7fb6..22dc21354868 100644 --- a/drivers/usb/core/drivers.c +++ b/drivers/usb/core/drivers.c @@ -66,6 +66,7 @@ static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff start = page; end = page + (PAGE_SIZE - 100); pos = *ppos; + lock_kernel(); /* else drivers might be unloaded */ for (; tmp != &usb_driver_list; tmp = tmp->next) { struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list); int minor = driver->fops ? driver->minor : -1; @@ -80,6 +81,7 @@ static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff break; } } + unlock_kernel(); if (start == page) start += sprintf(start, "(none)\n"); len = start - page; @@ -120,6 +122,6 @@ static loff_t usb_driver_lseek(struct file * file, loff_t offset, int orig) } struct file_operations usbdevfs_drivers_fops = { - llseek: usb_driver_lseek, - read: usb_driver_read, + .llseek = usb_driver_lseek, + .read = usb_driver_read, }; diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index eba43f1d84e5..803fb19e5ad2 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -44,10 +44,13 @@ static int usb_open(struct inode * inode, struct file * file) spin_lock (&minor_lock); c = usb_minors[minor]; - spin_unlock (&minor_lock); - if (!c || !(new_fops = fops_get(c))) + if (!c || !(new_fops = fops_get(c))) { + spin_unlock(&minor_lock); return err; + } + spin_unlock(&minor_lock); + old_fops = file->f_op; file->f_op = new_fops; /* Curiouser and curiouser... NULL ->open() as "no device" ? */ @@ -62,8 +65,8 @@ static int usb_open(struct inode * inode, struct file * file) } static struct file_operations usb_fops = { - owner: THIS_MODULE, - open: usb_open, + .owner = THIS_MODULE, + .open = usb_open, }; int usb_major_init(void) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 15a2c346b4af..05bb930ea5fd 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1240,11 +1240,11 @@ static int hcd_free_dev (struct usb_device *udev) * bus glue for non-PCI system busses will need to use this. */ struct usb_operations usb_hcd_operations = { - allocate: hcd_alloc_dev, - get_frame_number: hcd_get_frame_number, - submit_urb: hcd_submit_urb, - unlink_urb: hcd_unlink_urb, - deallocate: hcd_free_dev, + .allocate = hcd_alloc_dev, + .get_frame_number = hcd_get_frame_number, + .submit_urb = hcd_submit_urb, + .unlink_urb = hcd_unlink_urb, + .deallocate = hcd_free_dev, }; EXPORT_SYMBOL (usb_hcd_operations); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index ad1422fabdfa..f80a98621d26 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1046,8 +1046,6 @@ static void usb_hub_events(void) static int usb_hub_thread(void *__hub) { - lock_kernel(); - /* * This thread doesn't need any user-level access, * so get rid of all our resources @@ -1067,8 +1065,6 @@ static int usb_hub_thread(void *__hub) } while (!signal_pending(current)); dbg("usb_hub_thread exiting"); - - unlock_kernel(); complete_and_exit(&khubd_exited, 0); } @@ -1083,11 +1079,11 @@ static struct usb_device_id hub_id_table [] = { MODULE_DEVICE_TABLE (usb, hub_id_table); static struct usb_driver hub_driver = { - name: "hub", - probe: hub_probe, - ioctl: hub_ioctl, - disconnect: hub_disconnect, - id_table: hub_id_table, + .name = "hub", + .probe = hub_probe, + .ioctl = hub_ioctl, + .disconnect = hub_disconnect, + .id_table = hub_id_table, }; /* diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 08d08e3516e8..ffb7e6e13284 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -284,23 +284,23 @@ static int default_open (struct inode *inode, struct file *filp) } static struct file_operations default_file_operations = { - read: default_read_file, - write: default_write_file, - open: default_open, - llseek: default_file_lseek, + .read = default_read_file, + .write = default_write_file, + .open = default_open, + .llseek = default_file_lseek, }; static struct inode_operations usbfs_dir_inode_operations = { - create: usbfs_create, - lookup: simple_lookup, - unlink: usbfs_unlink, - mkdir: usbfs_mkdir, - rmdir: usbfs_rmdir, + .create = usbfs_create, + .lookup = simple_lookup, + .unlink = usbfs_unlink, + .mkdir = usbfs_mkdir, + .rmdir = usbfs_rmdir, }; static struct super_operations usbfs_ops = { - statfs: simple_statfs, - drop_inode: generic_delete_inode, + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, }; static int usbfs_fill_super(struct super_block *sb, void *data, int silent) @@ -468,17 +468,17 @@ static struct super_block *usb_get_sb(struct file_system_type *fs_type, } static struct file_system_type usbdevice_fs_type = { - owner: THIS_MODULE, - name: "usbdevfs", - get_sb: usb_get_sb, - kill_sb: kill_anon_super, + .owner = THIS_MODULE, + .name = "usbdevfs", + .get_sb = usb_get_sb, + .kill_sb = kill_anon_super, }; static struct file_system_type usb_fs_type = { - owner: THIS_MODULE, - name: "usbfs", - get_sb: usb_get_sb, - kill_sb: kill_anon_super, + .owner = THIS_MODULE, + .name = "usbfs", + .get_sb = usb_get_sb, + .kill_sb = kill_anon_super, }; /* --------------------------------------------------------------------- */ diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 55c9e8955d24..ed2e03089e57 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -32,6 +32,7 @@ #include <linux/init.h> #include <linux/spinlock.h> #include <linux/errno.h> +#include <linux/smp_lock.h> #ifdef CONFIG_USB_DEBUG #define DEBUG @@ -117,6 +118,108 @@ void usb_scan_devices(void) up (&usb_bus_list_lock); } +/** + * usb_unbind_driver - disconnects a driver from a device + * @device: usb device to be disconnected + * @intf: interface of the device to be disconnected + * Context: BKL held + * + * Handles module usage count correctly + */ + +void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf) +{ + struct usb_driver *driver; + void *priv; + int m; + + + driver = intf->driver; + priv = intf->private_data; + + if (!driver) + return; + + /* as soon as we increase the module use count we drop the BKL + before that we must not sleep */ + if (driver->owner) { + m = try_inc_mod_count(driver->owner); + if (m == 0) { + err("Dieing driver still bound to device.\n"); + return; + } + unlock_kernel(); + } + down(&driver->serialize); /* if we sleep here on an umanaged driver + the holder of the lock guards against + module unload */ + + driver->disconnect(device, priv); + + up(&driver->serialize); + if (driver->owner) { + lock_kernel(); + __MOD_DEC_USE_COUNT(driver->owner); + } +} + +/** + * usb_bind_driver - connect a driver to a device's interface + * @driver: device driver to be bound to a devices interface + * @dev: device to be bound + * @ifnum: index number of the interface to be used + * + * Does a save binding of a driver to a device's interface + * Returns a pointer to the drivers private description of the binding + */ + +void *usb_bind_driver(struct usb_driver *driver, struct usb_device *dev, unsigned int ifnum) +{ + int i,m; + void *private = NULL; + const struct usb_device_id *id; + struct usb_interface *interface; + + if (driver->owner) { + m = try_inc_mod_count(driver->owner); + if (m == 0) + return NULL; /* this horse is dead - don't ride*/ + unlock_kernel(); + } + + interface = &dev->actconfig->interface[ifnum]; + + id = driver->id_table; + /* new style driver? */ + if (id) { + for (i = 0; i < interface->num_altsetting; i++) { + interface->act_altsetting = i; + id = usb_match_id(dev, interface, id); + if (id) { + down(&driver->serialize); + private = driver->probe(dev,ifnum,id); + up(&driver->serialize); + if (private != NULL) + break; + } + } + + /* if driver not bound, leave defaults unchanged */ + if (private == NULL) + interface->act_altsetting = 0; + } else { /* "old style" driver */ + down(&driver->serialize); + private = driver->probe(dev, ifnum, NULL); + up(&driver->serialize); + } + if (driver->owner) { + lock_kernel(); + __MOD_DEC_USE_COUNT(driver->owner); + } + + return private; +} + /* * This function is part of a depth-first search down the device tree, * removing any instances of a device driver. @@ -136,18 +239,12 @@ static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev) if (!dev->actconfig) return; - + for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { struct usb_interface *interface = &dev->actconfig->interface[i]; - + if (interface->driver == driver) { - if (driver->owner) - __MOD_INC_USE_COUNT(driver->owner); - down(&driver->serialize); - driver->disconnect(dev, interface->private_data); - up(&driver->serialize); - if (driver->owner) - __MOD_DEC_USE_COUNT(driver->owner); + usb_unbind_driver(dev, interface); /* if driver->disconnect didn't release the interface */ if (interface->driver) usb_driver_release_interface(driver, interface); @@ -163,7 +260,7 @@ static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev) /** * usb_deregister - unregister a USB driver * @driver: USB operations of the driver to unregister - * Context: !in_interrupt () + * Context: !in_interrupt (), must be called with BKL held * * Unlinks the specified driver from the internal USB driver list. * @@ -528,9 +625,7 @@ static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) struct list_head *tmp; struct usb_interface *interface; void *private; - const struct usb_device_id *id; struct usb_driver *driver; - int i; if ((!dev) || (ifnum >= dev->actconfig->bNumInterfaces)) { err("bad find_interface_driver params"); @@ -545,37 +640,12 @@ static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) goto out_err; private = NULL; + lock_kernel(); for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) { driver = list_entry(tmp, struct usb_driver, driver_list); tmp = tmp->next; - if (driver->owner) - __MOD_INC_USE_COUNT(driver->owner); - id = driver->id_table; - /* new style driver? */ - if (id) { - for (i = 0; i < interface->num_altsetting; i++) { - interface->act_altsetting = i; - id = usb_match_id(dev, interface, id); - if (id) { - down(&driver->serialize); - private = driver->probe(dev,ifnum,id); - up(&driver->serialize); - if (private != NULL) - break; - } - } - - /* if driver not bound, leave defaults unchanged */ - if (private == NULL) - interface->act_altsetting = 0; - } else { /* "old style" driver */ - down(&driver->serialize); - private = driver->probe(dev, ifnum, NULL); - up(&driver->serialize); - } - if (driver->owner) - __MOD_DEC_USE_COUNT(driver->owner); + private = usb_bind_driver(driver, dev, ifnum); /* probe() may have changed the config on us */ interface = dev->actconfig->interface + ifnum; @@ -583,9 +653,11 @@ static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) if (private) { usb_driver_claim_interface(driver, interface, private); up(&dev->serialize); + unlock_kernel(); return 0; } } + unlock_kernel(); out_err: up(&dev->serialize); @@ -764,9 +836,9 @@ show_config (struct device *dev, char *buf, size_t count, loff_t off) return sprintf (buf, "%u\n", udev->actconfig->bConfigurationValue); } static struct driver_file_entry usb_config_entry = { - name: "configuration", - mode: S_IRUGO, - show: show_config, + .name = "configuration", + .mode = S_IRUGO, + .show = show_config, }; /* interfaces have one current setting; alternates @@ -783,9 +855,9 @@ show_altsetting (struct device *dev, char *buf, size_t count, loff_t off) return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting); } static struct driver_file_entry usb_altsetting_entry = { - name: "altsetting", - mode: S_IRUGO, - show: show_altsetting, + .name = "altsetting", + .mode = S_IRUGO, + .show = show_altsetting, }; /* product driverfs file */ @@ -804,9 +876,9 @@ static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t return len+1; } static struct driver_file_entry usb_product_entry = { - name: "product", - mode: S_IRUGO, - show: show_product, + .name = "product", + .mode = S_IRUGO, + .show = show_product, }; /* manufacturer driverfs file */ @@ -826,9 +898,9 @@ show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off) return len+1; } static struct driver_file_entry usb_manufacturer_entry = { - name: "manufacturer", - mode: S_IRUGO, - show: show_manufacturer, + .name = "manufacturer", + .mode = S_IRUGO, + .show = show_manufacturer, }; /* serial number driverfs file */ @@ -848,9 +920,9 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off) return len+1; } static struct driver_file_entry usb_serial_entry = { - name: "serial", - mode: S_IRUGO, - show: show_serial, + .name = "serial", + .mode = S_IRUGO, + .show = show_serial, }; /* @@ -1121,27 +1193,22 @@ void usb_disconnect(struct usb_device **pdev) info("USB disconnect on device %d", dev->devnum); + lock_kernel(); if (dev->actconfig) { for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { struct usb_interface *interface = &dev->actconfig->interface[i]; struct usb_driver *driver = interface->driver; if (driver) { - if (driver->owner) - __MOD_INC_USE_COUNT(driver->owner); - down(&driver->serialize); - driver->disconnect(dev, interface->private_data); - up(&driver->serialize); + usb_unbind_driver(dev, interface); /* if driver->disconnect didn't release the interface */ if (interface->driver) usb_driver_release_interface(driver, interface); - /* we don't need the driver any longer */ - if (driver->owner) - __MOD_DEC_USE_COUNT(driver->owner); } /* remove our device node for this interface */ put_device(&interface->dev); } } + unlock_kernel(); /* Free up all the children.. */ for (i = 0; i < USB_MAXCHILDREN; i++) { @@ -1416,7 +1483,7 @@ struct list_head *usb_bus_get_list(void) #endif struct bus_type usb_bus_type = { - name: "usb", + .name = "usb", }; /* @@ -1475,6 +1542,8 @@ EXPORT_SYMBOL(usb_new_device); EXPORT_SYMBOL(usb_reset_device); EXPORT_SYMBOL(usb_connect); EXPORT_SYMBOL(usb_disconnect); +EXPORT_SYMBOL(usb_bind_driver); +EXPORT_SYMBOL(usb_unbind_driver); EXPORT_SYMBOL(__usb_get_extra_descriptor); diff --git a/drivers/usb/host/Config.in b/drivers/usb/host/Config.in index dbfb819f8d33..0a6f97342a77 100644 --- a/drivers/usb/host/Config.in +++ b/drivers/usb/host/Config.in @@ -6,6 +6,5 @@ dep_tristate ' EHCI HCD (USB 2.0) support' CONFIG_USB_EHCI_HCD $CONFIG_USB dep_tristate ' OHCI HCD support' CONFIG_USB_OHCI_HCD $CONFIG_USB dep_tristate ' UHCI HCD (most Intel and VIA) support' CONFIG_USB_UHCI_HCD_ALT $CONFIG_USB if [ "$CONFIG_ARM" = "y" ]; then - dep_tristate ' SA1111 OHCI-compatible host interface support' CONFIG_USB_OHCI_SA1111 $CONFIG_USB dep_tristate ' SL811HS support' CONFIG_USB_SL811HS $CONFIG_USB fi diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 85b355751fa2..32d1f6086dc1 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -9,8 +9,6 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_UHCI_HCD_ALT) += uhci-hcd.o -obj-$(CONFIG_USB_OHCI) += usb-ohci.o usb-ohci-pci.o -obj-$(CONFIG_USB_OHCI_SA1111) += usb-ohci.o usb-ohci-sa1111.o obj-$(CONFIG_USB_SL811HS) += hc_sl811.o include $(TOPDIR)/Rules.make diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index fd9bbb044010..74496b06a130 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -702,47 +702,47 @@ static void ehci_free_config (struct usb_hcd *hcd, struct usb_device *udev) static const char hcd_name [] = "ehci-hcd"; static const struct hc_driver ehci_driver = { - description: hcd_name, + .description = hcd_name, /* * generic hardware linkage */ - irq: ehci_irq, - flags: HCD_MEMORY | HCD_USB2, + .irq = ehci_irq, + .flags = HCD_MEMORY | HCD_USB2, /* * basic lifecycle operations */ - start: ehci_start, + .start = ehci_start, #ifdef CONFIG_PM - suspend: ehci_suspend, - resume: ehci_resume, + .suspend = ehci_suspend, + .resume = ehci_resume, #endif - stop: ehci_stop, + .stop = ehci_stop, /* * memory lifecycle (except per-request) */ - hcd_alloc: ehci_hcd_alloc, - hcd_free: ehci_hcd_free, + .hcd_alloc = ehci_hcd_alloc, + .hcd_free = ehci_hcd_free, /* * managing i/o requests and associated device resources */ - urb_enqueue: ehci_urb_enqueue, - urb_dequeue: ehci_urb_dequeue, - free_config: ehci_free_config, + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .free_config = ehci_free_config, /* * scheduling support */ - get_frame_number: ehci_get_frame, + .get_frame_number = ehci_get_frame, /* * root hub support */ - hub_status_data: ehci_hub_status_data, - hub_control: ehci_hub_control, + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, }; /*-------------------------------------------------------------------------*/ @@ -754,15 +754,15 @@ static const struct pci_device_id __devinitdata pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ - class: ((PCI_CLASS_SERIAL_USB << 8) | 0x20), - class_mask: ~0, - driver_data: (unsigned long) &ehci_driver, + .class = ((PCI_CLASS_SERIAL_USB << 8) | 0x20), + .class_mask = ~0, + .driver_data = (unsigned long) &ehci_driver, /* no matter who makes it */ - vendor: PCI_ANY_ID, - device: PCI_ANY_ID, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { /* end: all zeroes */ } }; @@ -770,15 +770,15 @@ MODULE_DEVICE_TABLE (pci, pci_ids); /* pci driver glue; this is a "new style" PCI driver module */ static struct pci_driver ehci_pci_driver = { - name: (char *) hcd_name, - id_table: pci_ids, + .name = (char *) hcd_name, + .id_table = pci_ids, - probe: usb_hcd_pci_probe, - remove: usb_hcd_pci_remove, + .probe = usb_hcd_pci_probe, + .remove = usb_hcd_pci_remove, #ifdef CONFIG_PM - suspend: usb_hcd_pci_suspend, - resume: usb_hcd_pci_resume, + .suspend = usb_hcd_pci_suspend, + .resume = usb_hcd_pci_resume, #endif }; diff --git a/drivers/usb/host/hc_simple.c b/drivers/usb/host/hc_simple.c index 3a7218442adb..570267835101 100644 --- a/drivers/usb/host/hc_simple.c +++ b/drivers/usb/host/hc_simple.c @@ -343,11 +343,11 @@ static int hci_get_current_frame_number (struct usb_device *usb_dev) **************************************************************************/ static struct usb_operations hci_device_operations = { - allocate: hci_alloc_dev, - deallocate: hci_free_dev, - get_frame_number: hci_get_current_frame_number, - submit_urb: hci_submit_urb, - unlink_urb: hci_unlink_urb, + .allocate = hci_alloc_dev, + .deallocate = hci_free_dev, + .get_frame_number = hci_get_current_frame_number, + .submit_urb = hci_submit_urb, + .unlink_urb = hci_unlink_urb, }; /*************************************************************************** diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index a56ae64e60cc..2ee09b0a3bcd 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -167,7 +167,7 @@ static int ohci_urb_enqueue ( else if ((urb->transfer_flags & USB_ZERO_PACKET) != 0 && (urb->transfer_buffer_length % usb_maxpacket (urb->dev, pipe, - usb_pipeout (pipe))) != 0) + usb_pipeout (pipe))) == 0) size++; break; case PIPE_ISOCHRONOUS: /* number of packets from URB */ diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 347dc5d34b0c..a1979e532787 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -284,47 +284,47 @@ dbg ("sleeping = %d, disabled = %d", ohci->sleeping, ohci->disabled); /*-------------------------------------------------------------------------*/ static const struct hc_driver ohci_pci_hc_driver = { - description: hcd_name, + .description = hcd_name, /* * generic hardware linkage */ - irq: ohci_irq, - flags: HCD_MEMORY | HCD_USB11, + .irq = ohci_irq, + .flags = HCD_MEMORY | HCD_USB11, /* * basic lifecycle operations */ - start: ohci_pci_start, + .start = ohci_pci_start, #ifdef CONFIG_PM - suspend: ohci_pci_suspend, - resume: ohci_pci_resume, + .suspend = ohci_pci_suspend, + .resume = ohci_pci_resume, #endif - stop: ohci_stop, + .stop = ohci_stop, /* * memory lifecycle (except per-request) */ - hcd_alloc: ohci_hcd_alloc, - hcd_free: ohci_hcd_free, + .hcd_alloc = ohci_hcd_alloc, + .hcd_free = ohci_hcd_free, /* * managing i/o requests and associated device resources */ - urb_enqueue: ohci_urb_enqueue, - urb_dequeue: ohci_urb_dequeue, - free_config: ohci_free_config, + .urb_enqueue = ohci_urb_enqueue, + .urb_dequeue = ohci_urb_dequeue, + .free_config = ohci_free_config, /* * scheduling support */ - get_frame_number: ohci_get_frame, + .get_frame_number = ohci_get_frame, /* * root hub support */ - hub_status_data: ohci_hub_status_data, - hub_control: ohci_hub_control, + .hub_status_data = ohci_hub_status_data, + .hub_control = ohci_hub_control, }; /*-------------------------------------------------------------------------*/ @@ -333,15 +333,15 @@ static const struct hc_driver ohci_pci_hc_driver = { static const struct pci_device_id __devinitdata pci_ids [] = { { /* handle any USB OHCI controller */ - class: (PCI_CLASS_SERIAL_USB << 8) | 0x10, - class_mask: ~0, - driver_data: (unsigned long) &ohci_pci_hc_driver, + .class = (PCI_CLASS_SERIAL_USB << 8) | 0x10, + .class_mask = ~0, + .driver_data = (unsigned long) &ohci_pci_hc_driver, /* no matter who makes it */ - vendor: PCI_ANY_ID, - device: PCI_ANY_ID, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { /* end: all zeroes */ } }; @@ -349,15 +349,15 @@ MODULE_DEVICE_TABLE (pci, pci_ids); /* pci driver glue; this is a "new style" PCI driver module */ static struct pci_driver ohci_pci_driver = { - name: (char *) hcd_name, - id_table: pci_ids, + .name = (char *) hcd_name, + .id_table = pci_ids, - probe: usb_hcd_pci_probe, - remove: usb_hcd_pci_remove, + .probe = usb_hcd_pci_probe, + .remove = usb_hcd_pci_remove, #ifdef CONFIG_PM - suspend: usb_hcd_pci_suspend, - resume: usb_hcd_pci_resume, + .suspend = usb_hcd_pci_suspend, + .resume = usb_hcd_pci_resume, #endif }; diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 95fc8b82af57..05c2127aa57f 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -288,47 +288,47 @@ ohci_sa1111_start (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ static const struct hc_driver ohci_sa1111_hc_driver = { - description: hcd_name, + .description = hcd_name, /* * generic hardware linkage */ - irq: ohci_irq, - flags: HCD_USB11, + .irq = ohci_irq, + .flags = HCD_USB11, /* * basic lifecycle operations */ - start: ohci_sa1111_start, + .start = ohci_sa1111_start, #ifdef CONFIG_PM /* suspend: ohci_sa1111_suspend, -- tbd */ /* resume: ohci_sa1111_resume, -- tbd */ #endif - stop: ohci_stop, + .stop = ohci_stop, /* * memory lifecycle (except per-request) */ - hcd_alloc: ohci_hcd_alloc, - hcd_free: ohci_hcd_free, + .hcd_alloc = ohci_hcd_alloc, + .hcd_free = ohci_hcd_free, /* * managing i/o requests and associated device resources */ - urb_enqueue: ohci_urb_enqueue, - urb_dequeue: ohci_urb_dequeue, - free_config: ohci_free_config, + .urb_enqueue = ohci_urb_enqueue, + .urb_dequeue = ohci_urb_dequeue, + .free_config = ohci_free_config, /* * scheduling support */ - get_frame_number: ohci_get_frame, + .get_frame_number = ohci_get_frame, /* * root hub support */ - hub_status_data: ohci_hub_status_data, - hub_control: ohci_hub_control, + .hub_status_data = ohci_hub_status_data, + .hub_control = ohci_hub_control, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 2c27eae0687b..b7817920c542 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -571,11 +571,11 @@ static int uhci_proc_release(struct inode *inode, struct file *file) } static struct file_operations uhci_proc_operations = { - open: uhci_proc_open, - llseek: uhci_proc_lseek, - read: uhci_proc_read, + .open = uhci_proc_open, + .llseek = uhci_proc_lseek, + .read = uhci_proc_read, // write: uhci_proc_write, - release: uhci_proc_release, + .release = uhci_proc_release, }; #endif diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index b077975c6e22..69cf61862f85 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -2476,45 +2476,45 @@ static int uhci_hcd_get_frame_number(struct usb_hcd *hcd) static const char hcd_name[] = "uhci-hcd"; static const struct hc_driver uhci_driver = { - description: hcd_name, + .description = hcd_name, /* Generic hardware linkage */ - irq: uhci_irq, - flags: HCD_USB11, + .irq = uhci_irq, + .flags = HCD_USB11, /* Basic lifecycle operations */ - start: uhci_start, + .start = uhci_start, #ifdef CONFIG_PM - suspend: uhci_suspend, - resume: uhci_resume, + .suspend = uhci_suspend, + .resume = uhci_resume, #endif - stop: uhci_stop, + .stop = uhci_stop, - hcd_alloc: uhci_hcd_alloc, - hcd_free: uhci_hcd_free, + .hcd_alloc = uhci_hcd_alloc, + .hcd_free = uhci_hcd_free, - urb_enqueue: uhci_urb_enqueue, - urb_dequeue: uhci_urb_dequeue, - free_config: NULL, + .urb_enqueue = uhci_urb_enqueue, + .urb_dequeue = uhci_urb_dequeue, + .free_config = NULL, - get_frame_number: uhci_hcd_get_frame_number, + .get_frame_number = uhci_hcd_get_frame_number, - hub_status_data: uhci_hub_status_data, - hub_control: uhci_hub_control, + .hub_status_data = uhci_hub_status_data, + .hub_control = uhci_hub_control, }; static const struct pci_device_id __devinitdata uhci_pci_ids[] = { { /* handle any USB UHCI controller */ - class: ((PCI_CLASS_SERIAL_USB << 8) | 0x00), - class_mask: ~0, - driver_data: (unsigned long) &uhci_driver, + .class = ((PCI_CLASS_SERIAL_USB << 8) | 0x00), + .class_mask = ~0, + .driver_data = (unsigned long) &uhci_driver, /* no matter who makes it */ - vendor: PCI_ANY_ID, - device: PCI_ANY_ID, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { /* end: all zeroes */ } }; @@ -2522,15 +2522,15 @@ static const struct pci_device_id __devinitdata uhci_pci_ids[] = { { MODULE_DEVICE_TABLE(pci, uhci_pci_ids); static struct pci_driver uhci_pci_driver = { - name: (char *)hcd_name, - id_table: uhci_pci_ids, + .name = (char *)hcd_name, + .id_table = uhci_pci_ids, - probe: usb_hcd_pci_probe, - remove: usb_hcd_pci_remove, + .probe = usb_hcd_pci_probe, + .remove = usb_hcd_pci_remove, #ifdef CONFIG_PM - suspend: usb_hcd_pci_suspend, - resume: usb_hcd_pci_resume, + .suspend = usb_hcd_pci_suspend, + .resume = usb_hcd_pci_resume, #endif /* PM */ }; diff --git a/drivers/usb/host/usb-ohci-pci.c b/drivers/usb/host/usb-ohci-pci.c deleted file mode 100644 index ad3958c025d9..000000000000 --- a/drivers/usb/host/usb-ohci-pci.c +++ /dev/null @@ -1,456 +0,0 @@ -#include <linux/config.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/interrupt.h> /* for in_interrupt() */ -#undef DEBUG -#include <linux/usb.h> - -#include "../core/hcd.h" -#include "usb-ohci.h" - -#ifdef CONFIG_PMAC_PBOOK -#include <asm/machdep.h> -#include <asm/pmac_feature.h> -#include <asm/pci-bridge.h> -#ifndef CONFIG_PM -#define CONFIG_PM -#endif -#endif - -int __devinit -hc_add_ohci(struct pci_dev *dev, int irq, void *membase, unsigned long flags, - ohci_t **ohci, const char *name, const char *slot_name); -extern void hc_remove_ohci(ohci_t *ohci); -extern int hc_start (ohci_t * ohci, struct device *parent_dev); -extern int hc_reset (ohci_t * ohci); - -/*-------------------------------------------------------------------------*/ - -/* Increment the module usage count, start the control thread and - * return success. */ - -static struct pci_driver ohci_pci_driver; - -static int __devinit -hc_found_ohci (struct pci_dev *dev, int irq, - void *mem_base, const struct pci_device_id *id) -{ - u8 latency, limit; - ohci_t * ohci; - int ret; - - printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name); - - /* bad pci latencies can contribute to overruns */ - pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); - if (latency) { - pci_read_config_byte (dev, PCI_MAX_LAT, &limit); - if (limit && limit < latency) { - dbg ("PCI latency reduced to max %d", limit); - pci_write_config_byte (dev, PCI_LATENCY_TIMER, limit); - latency = limit; - } - } - - ret = hc_add_ohci(dev, irq, mem_base, id->driver_data, - &ohci, ohci_pci_driver.name, dev->slot_name); - - if (ret == 0) { - ohci->pci_latency = latency; - - if (hc_start (ohci, &ohci->ohci_dev->dev) < 0) { - err ("can't start usb-%s", ohci->slot_name); - hc_remove_ohci(ohci); - return -EBUSY; - } - -#ifdef DEBUG - ohci_dump (ohci, 1); -#endif - } - - return ret; -} - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_PM - -/* controller died; cleanup debris, then restart */ -/* must not be called from interrupt context */ - -static void hc_restart (ohci_t *ohci) -{ - int temp; - int i; - - if (ohci->pci_latency) - pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency); - - ohci->disabled = 1; - ohci->sleeping = 0; - if (ohci->bus->root_hub) - usb_disconnect (&ohci->bus->root_hub); - - /* empty the interrupt branches */ - for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0; - for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0; - - /* no EDs to remove */ - ohci->ed_rm_list [0] = NULL; - ohci->ed_rm_list [1] = NULL; - - /* empty control and bulk lists */ - ohci->ed_isotail = NULL; - ohci->ed_controltail = NULL; - ohci->ed_bulktail = NULL; - - if ((temp = hc_reset (ohci)) < 0 || - (temp = hc_start (ohci, &ohci->ohci_dev->dev)) < 0) { - err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp); - } else - dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name); -} - -#endif /* CONFIG_PM */ - -/*-------------------------------------------------------------------------*/ - -/* configured so that an OHCI device is always provided */ -/* always called with process context; sleeping is OK */ - -static int __devinit -ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) -{ - unsigned long mem_resource, mem_len; - void *mem_base; - int status; - - if (pci_enable_device(dev) < 0) - return -ENODEV; - - if (!dev->irq) { - err("found OHCI device with no IRQ assigned. check BIOS settings!"); - pci_disable_device (dev); - return -ENODEV; - } - - /* we read its hardware registers as memory */ - mem_resource = pci_resource_start(dev, 0); - mem_len = pci_resource_len(dev, 0); - if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) { - dbg ("controller already in use"); - pci_disable_device (dev); - return -EBUSY; - } - - mem_base = ioremap_nocache (mem_resource, mem_len); - if (!mem_base) { - err("Error mapping OHCI memory"); - release_mem_region(mem_resource, mem_len); - pci_disable_device (dev); - return -EFAULT; - } - - /* controller writes into our memory */ - pci_set_master (dev); - - status = hc_found_ohci (dev, dev->irq, mem_base, id); - if (status < 0) { - iounmap (mem_base); - release_mem_region(mem_resource, mem_len); - pci_disable_device (dev); - } - return status; -} - -/*-------------------------------------------------------------------------*/ - -/* may be called from interrupt context [interface spec] */ -/* may be called without controller present */ -/* may be called with controller, bus, and devices active */ - -static void __devexit -ohci_pci_remove (struct pci_dev *dev) -{ - ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev); - void *membase = ohci->regs; - - dbg ("remove %s controller usb-%s%s%s", - hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), - dev->slot_name, - ohci->disabled ? " (disabled)" : "", - in_interrupt () ? " in interrupt" : "" - ); - - hc_remove_ohci(ohci); - - /* unmap the IO address space */ - iounmap (membase); - - release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0)); -} - - -#ifdef CONFIG_PM - -/*-------------------------------------------------------------------------*/ - -static int -ohci_pci_suspend (struct pci_dev *dev, u32 state) -{ - ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev); - unsigned long flags; - u16 cmd; - - if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) { - dbg ("can't suspend usb-%s (state is %s)", dev->slot_name, - hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS)); - return -EIO; - } - - /* act as if usb suspend can always be used */ - info ("USB suspend: usb-%s", dev->slot_name); - ohci->sleeping = 1; - - /* First stop processing */ - spin_lock_irqsave (&usb_ed_lock, flags); - ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE); - writel (ohci->hc_control, &ohci->regs->control); - writel (OHCI_INTR_SF, &ohci->regs->intrstatus); - (void) readl (&ohci->regs->intrstatus); - spin_unlock_irqrestore (&usb_ed_lock, flags); - - /* Wait a frame or two */ - mdelay(1); - if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF) - mdelay (1); - -#ifdef CONFIG_PMAC_PBOOK - if (_machine == _MACH_Pmac) - disable_irq (ohci->irq); - /* else, 2.4 assumes shared irqs -- don't disable */ -#endif - /* Enable remote wakeup */ - writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, &ohci->regs->intrenable); - - /* Suspend chip and let things settle down a bit */ - ohci->hc_control = OHCI_USB_SUSPEND; - writel (ohci->hc_control, &ohci->regs->control); - (void) readl (&ohci->regs->control); - mdelay (500); /* No schedule here ! */ - switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) { - case OHCI_USB_RESET: - dbg("Bus in reset phase ???"); - break; - case OHCI_USB_RESUME: - dbg("Bus in resume phase ???"); - break; - case OHCI_USB_OPER: - dbg("Bus in operational phase ???"); - break; - case OHCI_USB_SUSPEND: - dbg("Bus suspended"); - break; - } - /* In some rare situations, Apple's OHCI have happily trashed - * memory during sleep. We disable it's bus master bit during - * suspend - */ - pci_read_config_word (dev, PCI_COMMAND, &cmd); - cmd &= ~PCI_COMMAND_MASTER; - pci_write_config_word (dev, PCI_COMMAND, cmd); -#ifdef CONFIG_PMAC_PBOOK - { - struct device_node *of_node; - - /* Disable USB PAD & cell clock */ - of_node = pci_device_to_OF_node (ohci->ohci_dev); - if (of_node && _machine == _MACH_Pmac) - pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); - } -#endif - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int -ohci_pci_resume (struct pci_dev *dev) -{ - ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev); - int temp; - unsigned long flags; - - /* guard against multiple resumes */ - atomic_inc (&ohci->resume_count); - if (atomic_read (&ohci->resume_count) != 1) { - err ("concurrent PCI resumes for usb-%s", dev->slot_name); - atomic_dec (&ohci->resume_count); - return 0; - } - -#ifdef CONFIG_PMAC_PBOOK - { - struct device_node *of_node; - - /* Re-enable USB PAD & cell clock */ - of_node = pci_device_to_OF_node (ohci->ohci_dev); - if (of_node && _machine == _MACH_Pmac) - pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1); - } -#endif - - /* did we suspend, or were we powered off? */ - ohci->hc_control = readl (&ohci->regs->control); - temp = ohci->hc_control & OHCI_CTRL_HCFS; - -#ifdef DEBUG - /* the registers may look crazy here */ - ohci_dump_status (ohci); -#endif - - /* Re-enable bus mastering */ - pci_set_master(ohci->ohci_dev); - - switch (temp) { - - case OHCI_USB_RESET: // lost power - info ("USB restart: usb-%s", dev->slot_name); - hc_restart (ohci); - break; - - case OHCI_USB_SUSPEND: // host wakeup - case OHCI_USB_RESUME: // remote wakeup - info ("USB continue: usb-%s from %s wakeup", dev->slot_name, - (temp == OHCI_USB_SUSPEND) - ? "host" : "remote"); - ohci->hc_control = OHCI_USB_RESUME; - writel (ohci->hc_control, &ohci->regs->control); - (void) readl (&ohci->regs->control); - mdelay (20); /* no schedule here ! */ - /* Some controllers (lucent) need a longer delay here */ - mdelay (15); - temp = readl (&ohci->regs->control); - temp = ohci->hc_control & OHCI_CTRL_HCFS; - if (temp != OHCI_USB_RESUME) { - err ("controller usb-%s won't resume", dev->slot_name); - ohci->disabled = 1; - return -EIO; - } - - /* Some chips likes being resumed first */ - writel (OHCI_USB_OPER, &ohci->regs->control); - (void) readl (&ohci->regs->control); - mdelay (3); - - /* Then re-enable operations */ - spin_lock_irqsave (&usb_ed_lock, flags); - ohci->disabled = 0; - ohci->sleeping = 0; - ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; - if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) { - if (ohci->ed_controltail) - ohci->hc_control |= OHCI_CTRL_CLE; - if (ohci->ed_bulktail) - ohci->hc_control |= OHCI_CTRL_BLE; - } - writel (ohci->hc_control, &ohci->regs->control); - writel (OHCI_INTR_SF, &ohci->regs->intrstatus); - writel (OHCI_INTR_SF, &ohci->regs->intrenable); - /* Check for a pending done list */ - writel (OHCI_INTR_WDH, &ohci->regs->intrdisable); - (void) readl (&ohci->regs->intrdisable); - spin_unlock_irqrestore (&usb_ed_lock, flags); -#ifdef CONFIG_PMAC_PBOOK - if (_machine == _MACH_Pmac) - enable_irq (ohci->irq); -#endif - if (ohci->hcca->done_head) - dl_done_list (ohci, dl_reverse_done_list (ohci)); - writel (OHCI_INTR_WDH, &ohci->regs->intrenable); - writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ - writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ - break; - - default: - warn ("odd PCI resume for usb-%s", dev->slot_name); - } - - /* controller is operational, extra resumes are harmless */ - atomic_dec (&ohci->resume_count); - - return 0; -} - -#endif /* CONFIG_PM */ - - -/*-------------------------------------------------------------------------*/ - -static const struct pci_device_id __devinitdata ohci_pci_ids [] = { { - - /* - * AMD-756 [Viper] USB has a serious erratum when used with - * lowspeed devices like mice. - */ - vendor: 0x1022, - device: 0x740c, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - - driver_data: OHCI_QUIRK_AMD756, - -} , { - - /* handle any USB OHCI controller */ - class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10), - class_mask: ~0, - - /* no matter who makes it */ - vendor: PCI_ANY_ID, - device: PCI_ANY_ID, - subvendor: PCI_ANY_ID, - subdevice: PCI_ANY_ID, - - }, { /* end: all zeroes */ } -}; - -MODULE_DEVICE_TABLE (pci, ohci_pci_ids); - -static struct pci_driver ohci_pci_driver = { - name: "usb-ohci", - id_table: &ohci_pci_ids [0], - - probe: ohci_pci_probe, - remove: __devexit_p(ohci_pci_remove), - -#ifdef CONFIG_PM - suspend: ohci_pci_suspend, - resume: ohci_pci_resume, -#endif /* PM */ -}; - - -/*-------------------------------------------------------------------------*/ - -static int __init ohci_hcd_init (void) -{ - return pci_module_init (&ohci_pci_driver); -} - -/*-------------------------------------------------------------------------*/ - -static void __exit ohci_hcd_cleanup (void) -{ - pci_unregister_driver (&ohci_pci_driver); -} - -module_init (ohci_hcd_init); -module_exit (ohci_hcd_cleanup); - -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/host/usb-ohci-sa1111.c b/drivers/usb/host/usb-ohci-sa1111.c deleted file mode 100644 index c6bbd515bc91..000000000000 --- a/drivers/usb/host/usb-ohci-sa1111.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * linux/drivers/usb/usb-ohci-sa1111.c - * - * The outline of this code was taken from Brad Parkers <brad@heeltoe.com> - * original OHCI driver modifications, and reworked into a cleaner form - * by Russell King <rmk@arm.linux.org.uk>. - */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/ioport.h> -#include <linux/interrupt.h> -#include <linux/slab.h> -#include <linux/usb.h> -#include <linux/pci.h> -#include <linux/errno.h> - -#include <asm/hardware.h> -#include <asm/irq.h> -#include <asm/io.h> -#include <asm/arch/assabet.h> -#include <asm/arch/badge4.h> -#include <asm/hardware/sa1111.h> - -#include "usb-ohci.h" - -int __devinit -hc_add_ohci(struct pci_dev *dev, int irq, void *membase, unsigned long flags, - ohci_t **ohci, const char *name, const char *slot_name); -extern void hc_remove_ohci(ohci_t *ohci); -extern int hc_start (ohci_t * ohci, struct device *parent_dev); -extern int hc_reset (ohci_t * ohci); - - -static ohci_t *sa1111_ohci; - -static void __init sa1111_ohci_configure(void) -{ - unsigned int usb_rst = 0; - - printk(KERN_DEBUG __FILE__ - ": starting SA-1111 OHCI USB Controller\n"); - -#ifdef CONFIG_SA1100_BADGE4 - if (machine_is_badge4()) - /* power the bus */ - badge4_set_5V(BADGE4_5V_USB, 1); -#endif - - if (machine_is_xp860() || - machine_has_neponset() || - machine_is_pfs168() || - machine_is_badge4()) - usb_rst = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW; - - /* - * Configure the power sense and control lines. Place the USB - * host controller in reset. - */ - USB_RESET = usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET; - - /* - * Now, carefully enable the USB clock, and take - * the USB host controller out of reset. - */ - SKPCR |= SKPCR_UCLKEN; - udelay(11); - USB_RESET = usb_rst; -} - -static void __exit sa1111_ohci_unconfigure(void) -{ - printk(KERN_DEBUG __FILE__ - ": stopping SA-1111 OHCI USB Controller\n"); - - /* - * Put the USB host controller into reset. - */ - USB_RESET |= USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET; - - /* - * Stop the USB clock. - */ - SKPCR &= ~SKPCR_UCLKEN; - -#ifdef CONFIG_SA1100_BADGE4 - if (machine_is_badge4()) - badge4_set_5V(BADGE4_5V_USB, 0); -#endif -} - - -static int __init sa1111_ohci_init(void) -{ - int ret; - - if (!sa1111) - return -ENODEV; - - /* - * Request memory resources. - */ - if (!request_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT, "usb-ohci")) - return -EBUSY; - - sa1111_ohci_configure(); - - /* - * Initialise the generic OHCI driver. - */ - sa1111_ohci = 0; - ret = hc_add_ohci(SA1111_FAKE_PCIDEV, NIRQHCIM, - (void *)&USB_OHCI_OP_BASE, 0, &sa1111_ohci, - "usb-ohci", "sa1111"); - - if (ret || !sa1111_ohci) { - sa1111_ohci = 0; - sa1111_ohci_unconfigure(); - release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT); - return -EBUSY; - } - - if (hc_start (sa1111_ohci, &sa1111->dev) < 0) { - err ("can't start usb-%s", sa1111_ohci->slot_name); - hc_remove_ohci (sa1111_ohci); - sa1111_ohci = 0; - sa1111_ohci_unconfigure(); - release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT); - return -EBUSY; - } - - return 0; -} - -static void __exit sa1111_ohci_exit(void) -{ - printk(KERN_DEBUG __FUNCTION__ ": cleaning up\n"); - - if (sa1111_ohci) { - hc_remove_ohci(sa1111_ohci); - sa1111_ohci = 0; - } - - sa1111_ohci_unconfigure(); - release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT); - - printk(KERN_DEBUG __FUNCTION__ ": exiting\n"); -} - -module_init(sa1111_ohci_init); -module_exit(sa1111_ohci_exit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/host/usb-ohci.c b/drivers/usb/host/usb-ohci.c deleted file mode 100644 index cf64e80bf4a6..000000000000 --- a/drivers/usb/host/usb-ohci.c +++ /dev/null @@ -1,2537 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> - * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> - * - * [ Initialisation is based on Linus' ] - * [ uhci code and gregs ohci fragments ] - * [ (C) Copyright 1999 Linus Torvalds ] - * [ (C) Copyright 1999 Gregory P. Smith] - * - * - * History: - * - * 2002/03/08 interrupt unlink fix (Matt Hughes), better cleanup on - * load failure (Matthew Frederickson) - * 2002/01/20 async unlink fixes: return -EINPROGRESS (per spec) and - * make interrupt unlink-in-completion work (db) - * - * 2001/09/19 USB_ZERO_PACKET support (Jean Tourrilhes) - * 2001/07/17 power management and pmac cleanup (Benjamin Herrenschmidt) - * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam); - pci_map_single (db) - * 2001/03/21 td and dev/ed allocation uses new pci_pool API (db) - * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam) - * - * 2000/09/26 fixed races in removing the private portion of the urb - * 2000/09/07 disable bulk and control lists when unlinking the last - * endpoint descriptor in order to avoid unrecoverable errors on - * the Lucent chips. (rwc@sgi) - * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some - * urb unlink probs, indentation fixes - * 2000/08/11 various oops fixes mostly affecting iso and cleanup from - * device unplugs. - * 2000/06/28 use PCI hotplug framework, for better power management - * and for Cardbus support (David Brownell) - * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling - * when the controller loses power; handle UE; cleanup; ... - * - * v5.2 1999/12/07 URB 3rd preview, - * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi) - * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume - * i386: HUB, Keyboard, Mouse, Printer - * - * v4.3 1999/10/27 multiple HCs, bulk_request - * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes - * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl. - * v4.0 1999/08/18 - * v3.0 1999/06/25 - * v2.1 1999/05/09 code clean up - * v2.0 1999/05/04 - * v1.0 1999/04/27 initial release - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/timer.h> -#include <linux/list.h> -#include <linux/interrupt.h> /* for in_interrupt() */ - -#ifdef CONFIG_USB_DEBUG -# define DEBUG -#else -# undef DEBUG -#endif -#include <linux/usb.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> - -#define OHCI_USE_NPS // force NoPowerSwitching mode -// #define OHCI_VERBOSE_DEBUG /* not always helpful */ - -#include "../core/hcd.h" -#include "usb-ohci.h" - - -/* - * Version Information - */ -#define DRIVER_VERSION "v5.3" -#define DRIVER_AUTHOR "Roman Weissgaerber <weissg@vienna.at>, David Brownell" -#define DRIVER_DESC "USB OHCI Host Controller Driver" - -#define OHCI_UNLINK_TIMEOUT (HZ / 10) - -static LIST_HEAD (ohci_hcd_list); -spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED; - - -/*-------------------------------------------------------------------------*/ - -/* AMD-756 (D2 rev) reports corrupt register contents in some cases. - * The erratum (#4) description is incorrect. AMD's workaround waits - * till some bits (mostly reserved) are clear; ok for all revs. - */ -#define read_roothub(hc, register, mask) ({ \ - u32 temp = readl (&hc->regs->roothub.register); \ - if (hc->flags & OHCI_QUIRK_AMD756) \ - while (temp & mask) \ - temp = readl (&hc->regs->roothub.register); \ - temp; }) - -static u32 roothub_a (struct ohci *hc) - { return read_roothub (hc, a, 0xfc0fe000); } -static inline u32 roothub_b (struct ohci *hc) - { return readl (&hc->regs->roothub.b); } -static inline u32 roothub_status (struct ohci *hc) - { return readl (&hc->regs->roothub.status); } -static u32 roothub_portstatus (struct ohci *hc, int i) - { return read_roothub (hc, portstatus [i], 0xffe0fce0); } - - -/*-------------------------------------------------------------------------* - * URB support functions - *-------------------------------------------------------------------------*/ - -/* free HCD-private data associated with this URB */ - -static void urb_free_priv (struct ohci *hc, urb_priv_t * urb_priv) -{ - int i; - int last = urb_priv->length - 1; - int len; - int dir; - struct td *td; - - if (last >= 0) { - - /* ISOC, BULK, INTR data buffer starts at td 0 - * CTRL setup starts at td 0 */ - td = urb_priv->td [0]; - - len = td->urb->transfer_buffer_length, - dir = usb_pipeout (td->urb->pipe) - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE; - - /* unmap CTRL URB setup */ - if (usb_pipecontrol (td->urb->pipe)) { - pci_unmap_single (hc->ohci_dev, - td->data_dma, 8, PCI_DMA_TODEVICE); - - /* CTRL data buffer starts at td 1 if len > 0 */ - if (len && last > 0) - td = urb_priv->td [1]; - } - - /* unmap data buffer */ - if (len && td->data_dma) - pci_unmap_single (hc->ohci_dev, td->data_dma, len, dir); - - for (i = 0; i <= last; i++) { - td = urb_priv->td [i]; - if (td) - td_free (hc, td); - } - } - - kfree (urb_priv); -} - -static void urb_rm_priv_locked (struct urb * urb) -{ - urb_priv_t * urb_priv = urb->hcpriv; - - if (urb_priv) { - urb->hcpriv = NULL; - -#ifdef DO_TIMEOUTS - if (urb->timeout) { - list_del (&urb->urb_list); - urb->timeout -= jiffies; - } -#endif - - /* Release int/iso bandwidth */ - if (urb->bandwidth) { - switch (usb_pipetype(urb->pipe)) { - case PIPE_INTERRUPT: - usb_release_bandwidth (urb->dev, urb, 0); - break; - case PIPE_ISOCHRONOUS: - usb_release_bandwidth (urb->dev, urb, 1); - break; - default: - break; - } - } - - urb_free_priv ((struct ohci *)urb->dev->bus->hcpriv, urb_priv); - usb_put_dev (urb->dev); - urb->dev = NULL; - usb_put_urb (urb); - } -} - -static void urb_rm_priv (struct urb * urb) -{ - unsigned long flags; - - spin_lock_irqsave (&usb_ed_lock, flags); - urb_rm_priv_locked (urb); - spin_unlock_irqrestore (&usb_ed_lock, flags); -} - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -static int sohci_get_current_frame_number (struct usb_device * dev); - -/* debug| print the main components of an URB - * small: 0) header + data packets 1) just header */ - -static void urb_print (struct urb * urb, char * str, int small) -{ - unsigned int pipe= urb->pipe; - - if (!urb->dev || !urb->dev->bus) { - dbg("%s URB: no dev", str); - return; - } - -#ifndef OHCI_VERBOSE_DEBUG - if (urb->status != 0) -#endif - dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)", - str, - sohci_get_current_frame_number (urb->dev), - usb_pipedevice (pipe), - usb_pipeendpoint (pipe), - usb_pipeout (pipe)? 'O': 'I', - usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): - (usb_pipecontrol (pipe)? "CTRL": "BULK"), - urb->transfer_flags, - urb->actual_length, - urb->transfer_buffer_length, - urb->status, urb->status); -#ifdef OHCI_VERBOSE_DEBUG - if (!small) { - int i, len; - - if (usb_pipecontrol (pipe)) { - printk (KERN_DEBUG __FILE__ ": cmd(8):"); - for (i = 0; i < 8 ; i++) - printk (" %02x", ((__u8 *) urb->setup_packet) [i]); - printk ("\n"); - } - if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { - printk (KERN_DEBUG __FILE__ ": data(%d/%d):", - urb->actual_length, - urb->transfer_buffer_length); - len = usb_pipeout (pipe)? - urb->transfer_buffer_length: urb->actual_length; - for (i = 0; i < 16 && i < len; i++) - printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); - printk ("%s stat:%d\n", i < len? "...": "", urb->status); - } - } -#endif -} - -/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ -void ep_print_int_eds (ohci_t * ohci, char * str) { - int i, j; - __u32 * ed_p; - for (i= 0; i < 32; i++) { - j = 5; - ed_p = &(ohci->hcca->int_table [i]); - if (*ed_p == 0) - continue; - printk (KERN_DEBUG __FILE__ ": %s branch int %2d(%2x):", str, i, i); - while (*ed_p != 0 && j--) { - ed_t *ed = dma_to_ed (ohci, le32_to_cpup(ed_p)); - printk (" ed: %4x;", ed->hwINFO); - ed_p = &ed->hwNextED; - } - printk ("\n"); - } -} - - -static void ohci_dump_intr_mask (char *label, __u32 mask) -{ - dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", - label, - mask, - (mask & OHCI_INTR_MIE) ? " MIE" : "", - (mask & OHCI_INTR_OC) ? " OC" : "", - (mask & OHCI_INTR_RHSC) ? " RHSC" : "", - (mask & OHCI_INTR_FNO) ? " FNO" : "", - (mask & OHCI_INTR_UE) ? " UE" : "", - (mask & OHCI_INTR_RD) ? " RD" : "", - (mask & OHCI_INTR_SF) ? " SF" : "", - (mask & OHCI_INTR_WDH) ? " WDH" : "", - (mask & OHCI_INTR_SO) ? " SO" : "" - ); -} - -static void maybe_print_eds (char *label, __u32 value) -{ - if (value) - dbg ("%s %08x", label, value); -} - -static char *hcfs2string (int state) -{ - switch (state) { - case OHCI_USB_RESET: return "reset"; - case OHCI_USB_RESUME: return "resume"; - case OHCI_USB_OPER: return "operational"; - case OHCI_USB_SUSPEND: return "suspend"; - } - return "?"; -} - -// dump control and status registers -static void ohci_dump_status (ohci_t *controller) -{ - struct ohci_regs *regs = controller->regs; - __u32 temp; - - temp = readl (®s->revision) & 0xff; - if (temp != 0x10) - dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); - - temp = readl (®s->control); - dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, - (temp & OHCI_CTRL_RWE) ? " RWE" : "", - (temp & OHCI_CTRL_RWC) ? " RWC" : "", - (temp & OHCI_CTRL_IR) ? " IR" : "", - hcfs2string (temp & OHCI_CTRL_HCFS), - (temp & OHCI_CTRL_BLE) ? " BLE" : "", - (temp & OHCI_CTRL_CLE) ? " CLE" : "", - (temp & OHCI_CTRL_IE) ? " IE" : "", - (temp & OHCI_CTRL_PLE) ? " PLE" : "", - temp & OHCI_CTRL_CBSR - ); - - temp = readl (®s->cmdstatus); - dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, - (temp & OHCI_SOC) >> 16, - (temp & OHCI_OCR) ? " OCR" : "", - (temp & OHCI_BLF) ? " BLF" : "", - (temp & OHCI_CLF) ? " CLF" : "", - (temp & OHCI_HCR) ? " HCR" : "" - ); - - ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); - ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); - // intrdisable always same as intrenable - // ohci_dump_intr_mask ("intrdisable", readl (®s->intrdisable)); - - maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); - - maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); - maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); - - maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); - maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); - - maybe_print_eds ("donehead", readl (®s->donehead)); -} - -static void ohci_dump_roothub (ohci_t *controller, int verbose) -{ - __u32 temp, ndp, i; - - temp = roothub_a (controller); - ndp = (temp & RH_A_NDP); - - if (verbose) { - dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, - ((temp & RH_A_POTPGT) >> 24) & 0xff, - (temp & RH_A_NOCP) ? " NOCP" : "", - (temp & RH_A_OCPM) ? " OCPM" : "", - (temp & RH_A_DT) ? " DT" : "", - (temp & RH_A_NPS) ? " NPS" : "", - (temp & RH_A_PSM) ? " PSM" : "", - ndp - ); - temp = roothub_b (controller); - dbg ("roothub.b: %08x PPCM=%04x DR=%04x", - temp, - (temp & RH_B_PPCM) >> 16, - (temp & RH_B_DR) - ); - temp = roothub_status (controller); - dbg ("roothub.status: %08x%s%s%s%s%s%s", - temp, - (temp & RH_HS_CRWE) ? " CRWE" : "", - (temp & RH_HS_OCIC) ? " OCIC" : "", - (temp & RH_HS_LPSC) ? " LPSC" : "", - (temp & RH_HS_DRWE) ? " DRWE" : "", - (temp & RH_HS_OCI) ? " OCI" : "", - (temp & RH_HS_LPS) ? " LPS" : "" - ); - } - - for (i = 0; i < ndp; i++) { - temp = roothub_portstatus (controller, i); - dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", - i, - temp, - (temp & RH_PS_PRSC) ? " PRSC" : "", - (temp & RH_PS_OCIC) ? " OCIC" : "", - (temp & RH_PS_PSSC) ? " PSSC" : "", - (temp & RH_PS_PESC) ? " PESC" : "", - (temp & RH_PS_CSC) ? " CSC" : "", - - (temp & RH_PS_LSDA) ? " LSDA" : "", - (temp & RH_PS_PPS) ? " PPS" : "", - (temp & RH_PS_PRS) ? " PRS" : "", - (temp & RH_PS_POCI) ? " POCI" : "", - (temp & RH_PS_PSS) ? " PSS" : "", - - (temp & RH_PS_PES) ? " PES" : "", - (temp & RH_PS_CCS) ? " CCS" : "" - ); - } -} - -static void ohci_dump (ohci_t *controller, int verbose) -{ - dbg ("OHCI controller usb-%s state", controller->slot_name); - - // dumps some of the state we know about - ohci_dump_status (controller); - if (verbose) - ep_print_int_eds (controller, "hcca"); - dbg ("hcca frame #%04x", controller->hcca->frame_no); - ohci_dump_roothub (controller, 1); -} - - -#endif - -/*-------------------------------------------------------------------------* - * Interface functions (URB) - *-------------------------------------------------------------------------*/ - -/* return a request to the completion handler */ - -static int sohci_return_urb (struct ohci *hc, struct urb * urb) -{ - urb_priv_t * urb_priv = urb->hcpriv; - struct urb * urbt = NULL; - unsigned long flags; - int i; - - if (!urb_priv) - return -1; /* urb already unlinked */ - - /* just to be sure */ - if (!urb->complete) { - urb_rm_priv (urb); - return -1; - } - -#ifdef DEBUG - urb_print (urb, "RET", usb_pipeout (urb->pipe)); -#endif - - switch (usb_pipetype (urb->pipe)) { - case PIPE_INTERRUPT: - pci_unmap_single (hc->ohci_dev, - urb_priv->td [0]->data_dma, - urb->transfer_buffer_length, - usb_pipeout (urb->pipe) - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); - urb->complete (urb); - - /* implicitly requeued */ - urb->actual_length = 0; - urb->status = -EINPROGRESS; - td_submit_urb (urb); - break; - - case PIPE_ISOCHRONOUS: - // for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next); - if (urbt) { /* send the reply and requeue URB */ - pci_unmap_single (hc->ohci_dev, - urb_priv->td [0]->data_dma, - urb->transfer_buffer_length, - usb_pipeout (urb->pipe) - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); - urb->complete (urb); - spin_lock_irqsave (&usb_ed_lock, flags); - urb->actual_length = 0; - urb->status = -EINPROGRESS; - urb->start_frame = urb_priv->ed->last_iso + 1; - if (urb_priv->state != URB_DEL) { - for (i = 0; i < urb->number_of_packets; i++) { - urb->iso_frame_desc[i].actual_length = 0; - urb->iso_frame_desc[i].status = -EXDEV; - } - td_submit_urb (urb); - } - spin_unlock_irqrestore (&usb_ed_lock, flags); - - } else { /* unlink URB, call complete */ - urb_rm_priv (urb); - urb->complete (urb); - } - break; - - case PIPE_BULK: - case PIPE_CONTROL: /* unlink URB, call complete */ - urb_rm_priv (urb); - urb->complete (urb); - break; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* get a transfer request */ - -static int sohci_submit_urb (struct urb * urb, int mem_flags) -{ - ohci_t * ohci; - ed_t * ed; - urb_priv_t * urb_priv; - unsigned int pipe = urb->pipe; - int maxps = usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe)); - int i, size = 0; - unsigned long flags; - int bustime = 0; - - if (!urb->dev || !urb->dev->bus) - return -ENODEV; - - if (urb->hcpriv) /* urb already in use */ - return -EINVAL; - -// if(usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe))) -// return -EPIPE; - - /* increment the reference count of the urb, as we now also control it */ - urb = usb_get_urb (urb); - - usb_get_dev (urb->dev); - ohci = (ohci_t *) urb->dev->bus->hcpriv; - -#ifdef DEBUG - urb_print (urb, "SUB", usb_pipein (pipe)); -#endif - - /* handle a request to the virtual root hub */ - if (usb_pipedevice (pipe) == ohci->rh.devnum) - return rh_submit_urb (urb); - - /* when controller's hung, permit only roothub cleanup attempts - * such as powering down ports */ - if (ohci->disabled) { - usb_put_dev (urb->dev); - usb_put_urb (urb); - return -ESHUTDOWN; - } - - /* every endpoint has a ed, locate and fill it */ - if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) { - usb_put_dev (urb->dev); - usb_put_urb (urb); - return -ENOMEM; - } - - /* for the private part of the URB we need the number of TDs (size) */ - switch (usb_pipetype (pipe)) { - case PIPE_BULK: /* one TD for every 4096 Byte */ - size = (urb->transfer_buffer_length - 1) / 4096 + 1; - - /* If the transfer size is multiple of the pipe mtu, - * we may need an extra TD to create a empty frame - * Jean II */ - if ((urb->transfer_flags & USB_ZERO_PACKET) && - usb_pipeout (pipe) && - (urb->transfer_buffer_length != 0) && - ((urb->transfer_buffer_length % maxps) == 0)) - size++; - break; - case PIPE_ISOCHRONOUS: /* number of packets from URB */ - size = urb->number_of_packets; - if (size <= 0) { - usb_put_dev (urb->dev); - usb_put_urb (urb); - return -EINVAL; - } - for (i = 0; i < urb->number_of_packets; i++) { - urb->iso_frame_desc[i].actual_length = 0; - urb->iso_frame_desc[i].status = -EXDEV; - } - break; - case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ - size = (urb->transfer_buffer_length == 0)? 2: - (urb->transfer_buffer_length - 1) / 4096 + 3; - break; - case PIPE_INTERRUPT: /* one TD */ - size = 1; - break; - } - - /* allocate the private part of the URB */ - urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), mem_flags); - if (!urb_priv) { - usb_put_dev (urb->dev); - usb_put_urb (urb); - return -ENOMEM; - } - memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *)); - - /* fill the private part of the URB */ - urb_priv->length = size; - urb_priv->ed = ed; - - /* allocate the TDs (updating hash chains) */ - spin_lock_irqsave (&usb_ed_lock, flags); - for (i = 0; i < size; i++) { - urb_priv->td[i] = td_alloc (ohci, SLAB_ATOMIC); - if (!urb_priv->td[i]) { - urb_priv->length = i; - urb_free_priv (ohci, urb_priv); - spin_unlock_irqrestore (&usb_ed_lock, flags); - usb_put_dev (urb->dev); - usb_put_urb (urb); - return -ENOMEM; - } - } - - if (ed->state == ED_NEW || (ed->state & ED_DEL)) { - urb_free_priv (ohci, urb_priv); - spin_unlock_irqrestore (&usb_ed_lock, flags); - usb_put_dev (urb->dev); - usb_put_urb (urb); - return -EINVAL; - } - - /* allocate and claim bandwidth if needed; ISO - * needs start frame index if it was't provided. - */ - switch (usb_pipetype (pipe)) { - case PIPE_ISOCHRONOUS: - if (urb->transfer_flags & USB_ISO_ASAP) { - urb->start_frame = ((ed->state == ED_OPER) - ? (ed->last_iso + 1) - : (le16_to_cpu (ohci->hcca->frame_no) + 10)) & 0xffff; - } - /* FALLTHROUGH */ - case PIPE_INTERRUPT: - if (urb->bandwidth == 0) { - bustime = usb_check_bandwidth (urb->dev, urb); - } - if (bustime < 0) { - urb_free_priv (ohci, urb_priv); - spin_unlock_irqrestore (&usb_ed_lock, flags); - usb_put_dev (urb->dev); - usb_put_urb (urb); - return bustime; - } - usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe)); -#ifdef DO_TIMEOUTS - urb->timeout = 0; -#endif - } - - urb->actual_length = 0; - urb->hcpriv = urb_priv; - urb->status = -EINPROGRESS; - - /* link the ed into a chain if is not already */ - if (ed->state != ED_OPER) - ep_link (ohci, ed); - - /* fill the TDs and link it to the ed */ - td_submit_urb (urb); - -#ifdef DO_TIMEOUTS - /* maybe add to ordered list of timeouts */ - if (urb->timeout) { - struct list_head *entry; - - // FIXME: usb-uhci uses relative timeouts (like this), - // while uhci uses absolute ones (probably better). - // Pick one solution and change the affected drivers. - urb->timeout += jiffies; - - list_for_each (entry, &ohci->timeout_list) { - struct urb *next_urb; - - next_urb = list_entry (entry, struct urb, urb_list); - if (time_after_eq (urb->timeout, next_urb->timeout)) - break; - } - list_add (&urb->urb_list, entry); - - /* drive timeouts by SF (messy, but works) */ - writel (OHCI_INTR_SF, &ohci->regs->intrenable); - } -#endif - - spin_unlock_irqrestore (&usb_ed_lock, flags); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* deactivate all TDs and remove the private part of the URB */ -/* interrupt callers must use async unlink mode */ - -static int sohci_unlink_urb (struct urb * urb) -{ - unsigned long flags; - ohci_t * ohci; - - if (!urb) /* just to be sure */ - return -EINVAL; - - if (!urb->dev || !urb->dev->bus) - return -ENODEV; - - ohci = (ohci_t *) urb->dev->bus->hcpriv; - -#ifdef DEBUG - urb_print (urb, "UNLINK", 1); -#endif - - /* handle a request to the virtual root hub */ - if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) - return rh_unlink_urb (urb); - - if (urb->hcpriv && (urb->status == -EINPROGRESS)) { - if (!ohci->disabled) { - urb_priv_t * urb_priv; - - /* interrupt code may not sleep; it must use - * async status return to unlink pending urbs. - */ - if (!(urb->transfer_flags & USB_ASYNC_UNLINK) - && in_interrupt ()) { - err ("bug in call from %p; use async!", - __builtin_return_address(0)); - return -EWOULDBLOCK; - } - - /* flag the urb and its TDs for deletion in some - * upcoming SF interrupt delete list processing - */ - spin_lock_irqsave (&usb_ed_lock, flags); - urb_priv = urb->hcpriv; - - if (!urb_priv || (urb_priv->state == URB_DEL)) { - spin_unlock_irqrestore (&usb_ed_lock, flags); - return 0; - } - - urb_priv->state = URB_DEL; - ep_rm_ed (urb->dev, urb_priv->ed); - urb_priv->ed->state |= ED_URB_DEL; - - if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) { - DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); - DECLARE_WAITQUEUE (wait, current); - int timeout = OHCI_UNLINK_TIMEOUT; - - add_wait_queue (&unlink_wakeup, &wait); - urb_priv->wait = &unlink_wakeup; - spin_unlock_irqrestore (&usb_ed_lock, flags); - - /* wait until all TDs are deleted */ - set_current_state(TASK_UNINTERRUPTIBLE); - while (timeout && (urb->status == -EINPROGRESS)) - timeout = schedule_timeout (timeout); - set_current_state(TASK_RUNNING); - remove_wait_queue (&unlink_wakeup, &wait); - if (urb->status == -EINPROGRESS) { - err ("unlink URB timeout"); - return -ETIMEDOUT; - } - } else { - /* usb_put_dev done in dl_del_list() */ - urb->status = -EINPROGRESS; - spin_unlock_irqrestore (&usb_ed_lock, flags); - return -EINPROGRESS; - } - } else { - urb_rm_priv (urb); - if (urb->transfer_flags & USB_ASYNC_UNLINK) { - urb->status = -ECONNRESET; - if (urb->complete) - urb->complete (urb); - } else - urb->status = -ENOENT; - } - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* allocate private data space for a usb device */ - -static int sohci_alloc_dev (struct usb_device *usb_dev) -{ - struct ohci_device * dev; - - dev = dev_alloc ((struct ohci *) usb_dev->bus->hcpriv, ALLOC_FLAGS); - if (!dev) - return -ENOMEM; - - usb_dev->hcpriv = dev; - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* may be called from interrupt context */ -/* frees private data space of usb device */ - -static int sohci_free_dev (struct usb_device * usb_dev) -{ - unsigned long flags; - int i, cnt = 0; - ed_t * ed; - struct ohci_device * dev = usb_to_ohci (usb_dev); - ohci_t * ohci = usb_dev->bus->hcpriv; - - if (!dev) - return 0; - - if (usb_dev->devnum >= 0) { - - /* driver disconnects should have unlinked all urbs - * (freeing all the TDs, unlinking EDs) but we need - * to defend against bugs that prevent that. - */ - spin_lock_irqsave (&usb_ed_lock, flags); - for(i = 0; i < NUM_EDS; i++) { - ed = &(dev->ed[i]); - if (ed->state != ED_NEW) { - if (ed->state == ED_OPER) { - /* driver on that interface didn't unlink an urb */ - dbg ("driver usb-%s dev %d ed 0x%x unfreed URB", - ohci->slot_name, usb_dev->devnum, i); - ep_unlink (ohci, ed); - } - ep_rm_ed (usb_dev, ed); - ed->state = ED_DEL; - cnt++; - } - } - spin_unlock_irqrestore (&usb_ed_lock, flags); - - /* if the controller is running, tds for those unlinked - * urbs get freed by dl_del_list at the next SF interrupt - */ - if (cnt > 0) { - - if (ohci->disabled) { - /* FIXME: Something like this should kick in, - * though it's currently an exotic case ... - * the controller won't ever be touching - * these lists again!! - dl_del_list (ohci, - le16_to_cpu (ohci->hcca->frame_no) & 1); - */ - warn ("TD leak, %d", cnt); - - } else if (!in_interrupt ()) { - DECLARE_WAIT_QUEUE_HEAD (freedev_wakeup); - DECLARE_WAITQUEUE (wait, current); - int timeout = OHCI_UNLINK_TIMEOUT; - - /* SF interrupt handler calls dl_del_list */ - add_wait_queue (&freedev_wakeup, &wait); - dev->wait = &freedev_wakeup; - set_current_state(TASK_UNINTERRUPTIBLE); - while (timeout && dev->ed_cnt) - timeout = schedule_timeout (timeout); - set_current_state(TASK_RUNNING); - remove_wait_queue (&freedev_wakeup, &wait); - if (dev->ed_cnt) { - err ("free device %d timeout", usb_dev->devnum); - return -ETIMEDOUT; - } - } else { - /* likely some interface's driver has a refcount bug */ - err ("bus %s devnum %d deletion in interrupt", - ohci->slot_name, usb_dev->devnum); - BUG (); - } - } - } - - /* free device, and associated EDs */ - dev_free (ohci, dev); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* tell us the current USB frame number */ - -static int sohci_get_current_frame_number (struct usb_device *usb_dev) -{ - ohci_t * ohci = usb_dev->bus->hcpriv; - - return le16_to_cpu (ohci->hcca->frame_no); -} - -/*-------------------------------------------------------------------------*/ - -struct usb_operations sohci_device_operations = { - allocate: sohci_alloc_dev, - deallocate: sohci_free_dev, - get_frame_number: sohci_get_current_frame_number, - submit_urb: sohci_submit_urb, - unlink_urb: sohci_unlink_urb, -}; - -/*-------------------------------------------------------------------------* - * ED handling functions - *-------------------------------------------------------------------------*/ - -/* search for the right branch to insert an interrupt ed into the int tree - * do some load ballancing; - * returns the branch and - * sets the interval to interval = 2^integer (ld (interval)) */ - -static int ep_int_ballance (ohci_t * ohci, int interval, int load) -{ - int i, branch = 0; - - /* search for the least loaded interrupt endpoint branch of all 32 branches */ - for (i = 0; i < 32; i++) - if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i]) branch = i; - - branch = branch % interval; - for (i = branch; i < 32; i += interval) ohci->ohci_int_load [i] += load; - - return branch; -} - -/*-------------------------------------------------------------------------*/ - -/* 2^int( ld (inter)) */ - -static int ep_2_n_interval (int inter) -{ - int i; - for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++); - return 1 << i; -} - -/*-------------------------------------------------------------------------*/ - -/* the int tree is a binary tree - * in order to process it sequentially the indexes of the branches have to be mapped - * the mapping reverses the bits of a word of num_bits length */ - -static int ep_rev (int num_bits, int word) -{ - int i, wout = 0; - - for (i = 0; i < num_bits; i++) wout |= (((word >> i) & 1) << (num_bits - i - 1)); - return wout; -} - -/*-------------------------------------------------------------------------*/ - -/* link an ed into one of the HC chains */ - -static int ep_link (ohci_t * ohci, ed_t * edi) -{ - int int_branch; - int i; - int inter; - int interval; - int load; - __u32 * ed_p; - volatile ed_t * ed = edi; - - ed->state = ED_OPER; - - switch (ed->type) { - case PIPE_CONTROL: - ed->hwNextED = 0; - if (ohci->ed_controltail == NULL) { - writel (ed->dma, &ohci->regs->ed_controlhead); - } else { - ohci->ed_controltail->hwNextED = cpu_to_le32 (ed->dma); - } - ed->ed_prev = ohci->ed_controltail; - if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && - !ohci->ed_rm_list[1] && !ohci->sleeping) { - ohci->hc_control |= OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); - } - ohci->ed_controltail = edi; - break; - - case PIPE_BULK: - ed->hwNextED = 0; - if (ohci->ed_bulktail == NULL) { - writel (ed->dma, &ohci->regs->ed_bulkhead); - } else { - ohci->ed_bulktail->hwNextED = cpu_to_le32 (ed->dma); - } - ed->ed_prev = ohci->ed_bulktail; - if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && - !ohci->ed_rm_list[1] && !ohci->sleeping) { - ohci->hc_control |= OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); - } - ohci->ed_bulktail = edi; - break; - - case PIPE_INTERRUPT: - load = ed->int_load; - interval = ep_2_n_interval (ed->int_period); - ed->int_interval = interval; - int_branch = ep_int_ballance (ohci, interval, load); - ed->int_branch = int_branch; - - for (i = 0; i < ep_rev (6, interval); i += inter) { - inter = 1; - for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]); - (*ed_p != 0) && ((dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval >= interval); - ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED)) - inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval); - ed->hwNextED = *ed_p; - *ed_p = cpu_to_le32 (ed->dma); - } -#ifdef DEBUG - ep_print_int_eds (ohci, "LINK_INT"); -#endif - break; - - case PIPE_ISOCHRONOUS: - ed->hwNextED = 0; - ed->int_interval = 1; - if (ohci->ed_isotail != NULL) { - ohci->ed_isotail->hwNextED = cpu_to_le32 (ed->dma); - ed->ed_prev = ohci->ed_isotail; - } else { - for ( i = 0; i < 32; i += inter) { - inter = 1; - for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i)]); - *ed_p != 0; - ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED)) - inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval); - *ed_p = cpu_to_le32 (ed->dma); - } - ed->ed_prev = NULL; - } - ohci->ed_isotail = edi; -#ifdef DEBUG - ep_print_int_eds (ohci, "LINK_ISO"); -#endif - break; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* scan the periodic table to find and unlink this ED */ -static void periodic_unlink ( - struct ohci *ohci, - struct ed *ed, - unsigned index, - unsigned period -) { - for (; index < NUM_INTS; index += period) { - __u32 *ed_p = &ohci->hcca->int_table [index]; - - /* ED might have been unlinked through another path */ - while (*ed_p != 0) { - if ((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) { - *ed_p = ed->hwNextED; - break; - } - ed_p = & ((dma_to_ed (ohci, - le32_to_cpup (ed_p)))->hwNextED); - } - } -} - -/* unlink an ed from one of the HC chains. - * just the link to the ed is unlinked. - * the link from the ed still points to another operational ed or 0 - * so the HC can eventually finish the processing of the unlinked ed */ - -static int ep_unlink (ohci_t * ohci, ed_t * ed) -{ - int i; - - ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP); - - switch (ed->type) { - case PIPE_CONTROL: - if (ed->ed_prev == NULL) { - if (!ed->hwNextED) { - ohci->hc_control &= ~OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); - } - writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_controlhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_controltail == ed) { - ohci->ed_controltail = ed->ed_prev; - } else { - (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; - } - break; - - case PIPE_BULK: - if (ed->ed_prev == NULL) { - if (!ed->hwNextED) { - ohci->hc_control &= ~OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); - } - writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_bulkhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_bulktail == ed) { - ohci->ed_bulktail = ed->ed_prev; - } else { - (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; - } - break; - - case PIPE_INTERRUPT: - periodic_unlink (ohci, ed, 0, 1); - for (i = ed->int_branch; i < 32; i += ed->int_interval) - ohci->ohci_int_load[i] -= ed->int_load; -#ifdef DEBUG - ep_print_int_eds (ohci, "UNLINK_INT"); -#endif - break; - - case PIPE_ISOCHRONOUS: - if (ohci->ed_isotail == ed) - ohci->ed_isotail = ed->ed_prev; - if (ed->hwNextED != 0) - (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED))) - ->ed_prev = ed->ed_prev; - - if (ed->ed_prev != NULL) - ed->ed_prev->hwNextED = ed->hwNextED; - else - periodic_unlink (ohci, ed, 0, 1); -#ifdef DEBUG - ep_print_int_eds (ohci, "UNLINK_ISO"); -#endif - break; - } - ed->state = ED_UNLINK; - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, - * but the USB stack is a little bit stateless so we do it at every transaction - * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK - * in all other cases the state is left unchanged - * the ed info fields are setted anyway even though most of them should not change */ - -static ed_t * ep_add_ed ( - struct usb_device * usb_dev, - unsigned int pipe, - int interval, - int load, - int mem_flags -) -{ - ohci_t * ohci = usb_dev->bus->hcpriv; - td_t * td; - ed_t * ed_ret; - volatile ed_t * ed; - unsigned long flags; - - - spin_lock_irqsave (&usb_ed_lock, flags); - - ed = ed_ret = &(usb_to_ohci (usb_dev)->ed[(usb_pipeendpoint (pipe) << 1) | - (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]); - - if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { - /* pending delete request */ - spin_unlock_irqrestore (&usb_ed_lock, flags); - return NULL; - } - - if (ed->state == ED_NEW) { - ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ - /* dummy td; end of td list for ed */ - td = td_alloc (ohci, SLAB_ATOMIC); - /* hash the ed for later reverse mapping */ - if (!td || !hash_add_ed (ohci, (ed_t *)ed)) { - /* out of memory */ - if (td) - td_free(ohci, td); - spin_unlock_irqrestore (&usb_ed_lock, flags); - return NULL; - } - ed->hwTailP = cpu_to_le32 (td->td_dma); - ed->hwHeadP = ed->hwTailP; - ed->state = ED_UNLINK; - ed->type = usb_pipetype (pipe); - usb_to_ohci (usb_dev)->ed_cnt++; - } - - ohci->dev[usb_pipedevice (pipe)] = usb_dev; - - ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe) - | usb_pipeendpoint (pipe) << 7 - | (usb_pipeisoc (pipe)? 0x8000: 0) - | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) - | (usb_dev->speed == USB_SPEED_LOW) << 13 - | usb_maxpacket (usb_dev, pipe, usb_pipeout (pipe)) << 16); - - if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) { - ed->int_period = interval; - ed->int_load = load; - } - - spin_unlock_irqrestore (&usb_ed_lock, flags); - return ed_ret; -} - -/*-------------------------------------------------------------------------*/ - -/* request the removal of an endpoint - * put the ep on the rm_list and request a stop of the bulk or ctrl list - * real removal is done at the next start frame (SF) hardware interrupt */ - -static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed) -{ - unsigned int frame; - ohci_t * ohci = usb_dev->bus->hcpriv; - - if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) - return; - - ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP); - - if (!ohci->disabled) { - switch (ed->type) { - case PIPE_CONTROL: /* stop control list */ - ohci->hc_control &= ~OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); - break; - case PIPE_BULK: /* stop bulk list */ - ohci->hc_control &= ~OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); - break; - } - } - - frame = le16_to_cpu (ohci->hcca->frame_no) & 0x1; - ed->ed_rm_list = ohci->ed_rm_list[frame]; - ohci->ed_rm_list[frame] = ed; - - if (!ohci->disabled && !ohci->sleeping) { - /* enable SOF interrupt */ - writel (OHCI_INTR_SF, &ohci->regs->intrstatus); - writel (OHCI_INTR_SF, &ohci->regs->intrenable); - } -} - -/*-------------------------------------------------------------------------* - * TD handling functions - *-------------------------------------------------------------------------*/ - -/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ - -static void -td_fill (ohci_t * ohci, unsigned int info, - dma_addr_t data, int len, - struct urb * urb, int index) -{ - volatile td_t * td, * td_pt; - urb_priv_t * urb_priv = urb->hcpriv; - - if (index >= urb_priv->length) { - err("internal OHCI error: TD index > length"); - return; - } - - /* use this td as the next dummy */ - td_pt = urb_priv->td [index]; - td_pt->hwNextTD = 0; - - /* fill the old dummy TD */ - td = urb_priv->td [index] = dma_to_td (ohci, - le32_to_cpup (&urb_priv->ed->hwTailP) & ~0xf); - - td->ed = urb_priv->ed; - td->next_dl_td = NULL; - td->index = index; - td->urb = urb; - td->data_dma = data; - if (!len) - data = 0; - - td->hwINFO = cpu_to_le32 (info); - if ((td->ed->type) == PIPE_ISOCHRONOUS) { - td->hwCBP = cpu_to_le32 (data & 0xFFFFF000); - td->ed->last_iso = info & 0xffff; - } else { - td->hwCBP = cpu_to_le32 (data); - } - if (data) - td->hwBE = cpu_to_le32 (data + len - 1); - else - td->hwBE = 0; - td->hwNextTD = cpu_to_le32 (td_pt->td_dma); - td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000); - - /* append to queue */ - td->ed->hwTailP = td->hwNextTD; -} - -/*-------------------------------------------------------------------------*/ - -/* prepare all TDs of a transfer */ - -static void td_submit_urb (struct urb * urb) -{ - urb_priv_t * urb_priv = urb->hcpriv; - ohci_t * ohci = (ohci_t *) urb->dev->bus->hcpriv; - dma_addr_t data; - int data_len = urb->transfer_buffer_length; - int maxps = usb_maxpacket (urb->dev, urb->pipe, usb_pipeout (urb->pipe)); - int cnt = 0; - __u32 info = 0; - unsigned int toggle = 0; - - /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ - if(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe))) { - toggle = TD_T_TOGGLE; - } else { - toggle = TD_T_DATA0; - usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 1); - } - - urb_priv->td_cnt = 0; - - if (data_len) { - data = pci_map_single (ohci->ohci_dev, - urb->transfer_buffer, data_len, - usb_pipeout (urb->pipe) - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE - ); - } else - data = 0; - - switch (usb_pipetype (urb->pipe)) { - case PIPE_BULK: - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; - while(data_len > 4096) { - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, urb, cnt); - data += 4096; data_len -= 4096; cnt++; - } - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, urb, cnt); - cnt++; - - /* If the transfer size is multiple of the pipe mtu, - * we may need an extra TD to create a empty frame - * Note : another way to check this condition is - * to test if(urb_priv->length > cnt) - Jean II */ - if ((urb->transfer_flags & USB_ZERO_PACKET) && - usb_pipeout (urb->pipe) && - (urb->transfer_buffer_length != 0) && - ((urb->transfer_buffer_length % maxps) == 0)) { - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), 0, 0, urb, cnt); - cnt++; - } - - if (!ohci->sleeping) - writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ - break; - - case PIPE_INTERRUPT: - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_OUT | toggle: TD_CC | TD_R | TD_DP_IN | toggle; - td_fill (ohci, info, data, data_len, urb, cnt++); - break; - - case PIPE_CONTROL: - info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (ohci, info, - pci_map_single (ohci->ohci_dev, - urb->setup_packet, 8, - PCI_DMA_TODEVICE), - 8, urb, cnt++); - if (data_len > 0) { - info = usb_pipeout (urb->pipe)? - TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; - /* NOTE: mishandles transfers >8K, some >4K */ - td_fill (ohci, info, data, data_len, urb, cnt++); - } - info = usb_pipeout (urb->pipe)? - TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (ohci, info, data, 0, urb, cnt++); - if (!ohci->sleeping) - writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ - break; - - case PIPE_ISOCHRONOUS: - for (cnt = 0; cnt < urb->number_of_packets; cnt++) { - td_fill (ohci, TD_CC|TD_ISO | ((urb->start_frame + cnt) & 0xffff), - data + urb->iso_frame_desc[cnt].offset, - urb->iso_frame_desc[cnt].length, urb, cnt); - } - break; - } - if (urb_priv->length != cnt) - dbg("TD LENGTH %d != CNT %d", urb_priv->length, cnt); -} - -/*-------------------------------------------------------------------------* - * Done List handling functions - *-------------------------------------------------------------------------*/ - - -/* calculate the transfer length and update the urb */ - -static void dl_transfer_length(td_t * td) -{ - __u32 tdINFO, tdBE, tdCBP; - __u16 tdPSW; - struct urb * urb = td->urb; - urb_priv_t * urb_priv = urb->hcpriv; - int dlen = 0; - int cc = 0; - - tdINFO = le32_to_cpup (&td->hwINFO); - tdBE = le32_to_cpup (&td->hwBE); - tdCBP = le32_to_cpup (&td->hwCBP); - - - if (tdINFO & TD_ISO) { - tdPSW = le16_to_cpu (td->hwPSW[0]); - cc = (tdPSW >> 12) & 0xF; - if (cc < 0xE) { - if (usb_pipeout(urb->pipe)) { - dlen = urb->iso_frame_desc[td->index].length; - } else { - dlen = tdPSW & 0x3ff; - } - urb->actual_length += dlen; - urb->iso_frame_desc[td->index].actual_length = dlen; - if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN)) - cc = TD_CC_NOERROR; - - urb->iso_frame_desc[td->index].status = cc_to_error[cc]; - } - } else { /* BULK, INT, CONTROL DATA */ - if (!(usb_pipetype (urb->pipe) == PIPE_CONTROL && - ((td->index == 0) || (td->index == urb_priv->length - 1)))) { - if (tdBE != 0) { - if (td->hwCBP == 0) - urb->actual_length += tdBE - td->data_dma + 1; - else - urb->actual_length += tdCBP - td->data_dma; - } - } - } -} - -/* handle an urb that is being unlinked */ - -static void dl_del_urb (struct urb * urb) -{ - wait_queue_head_t * wait_head = ((urb_priv_t *)(urb->hcpriv))->wait; - - urb_rm_priv_locked (urb); - - if (urb->transfer_flags & USB_ASYNC_UNLINK) { - urb->status = -ECONNRESET; - if (urb->complete) - urb->complete (urb); - } else { - urb->status = -ENOENT; - - /* unblock sohci_unlink_urb */ - if (wait_head) - wake_up (wait_head); - } -} - -/*-------------------------------------------------------------------------*/ - -/* replies to the request have to be on a FIFO basis so - * we reverse the reversed done-list */ - -td_t * dl_reverse_done_list (ohci_t * ohci) -{ - __u32 td_list_hc; - td_t * td_rev = NULL; - td_t * td_list = NULL; - urb_priv_t * urb_priv = NULL; - unsigned long flags; - - spin_lock_irqsave (&usb_ed_lock, flags); - - td_list_hc = le32_to_cpup (&ohci->hcca->done_head) & 0xfffffff0; - ohci->hcca->done_head = 0; - - while (td_list_hc) { - td_list = dma_to_td (ohci, td_list_hc); - - if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) { - urb_priv = (urb_priv_t *) td_list->urb->hcpriv; - dbg(" USB-error/status: %x : %p", - TD_CC_GET (le32_to_cpup (&td_list->hwINFO)), td_list); - if (td_list->ed->hwHeadP & cpu_to_le32 (0x1)) { - if (urb_priv && ((td_list->index + 1) < urb_priv->length)) { - td_list->ed->hwHeadP = - (urb_priv->td[urb_priv->length - 1]->hwNextTD & cpu_to_le32 (0xfffffff0)) | - (td_list->ed->hwHeadP & cpu_to_le32 (0x2)); - urb_priv->td_cnt += urb_priv->length - td_list->index - 1; - } else - td_list->ed->hwHeadP &= cpu_to_le32 (0xfffffff2); - } - } - - td_list->next_dl_td = td_rev; - td_rev = td_list; - td_list_hc = le32_to_cpup (&td_list->hwNextTD) & 0xfffffff0; - } - spin_unlock_irqrestore (&usb_ed_lock, flags); - return td_list; -} - -/*-------------------------------------------------------------------------*/ - -/* there are some pending requests to remove - * - some of the eds (if ed->state & ED_DEL (set by sohci_free_dev) - * - some URBs/TDs if urb_priv->state == URB_DEL */ - -static void dl_del_list (ohci_t * ohci, unsigned int frame) -{ - unsigned long flags; - ed_t * ed; - __u32 edINFO; - __u32 tdINFO; - td_t * td = NULL, * td_next = NULL, * tdHeadP = NULL, * tdTailP; - __u32 * td_p; - int ctrl = 0, bulk = 0; - - spin_lock_irqsave (&usb_ed_lock, flags); - - for (ed = ohci->ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list) { - - tdTailP = dma_to_td (ohci, le32_to_cpup (&ed->hwTailP) & 0xfffffff0); - tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0); - edINFO = le32_to_cpup (&ed->hwINFO); - td_p = &ed->hwHeadP; - - for (td = tdHeadP; td != tdTailP; td = td_next) { - struct urb * urb = td->urb; - urb_priv_t * urb_priv = td->urb->hcpriv; - - td_next = dma_to_td (ohci, le32_to_cpup (&td->hwNextTD) & 0xfffffff0); - if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL)) { - tdINFO = le32_to_cpup (&td->hwINFO); - if (TD_CC_GET (tdINFO) < 0xE) - dl_transfer_length (td); - *td_p = td->hwNextTD | (*td_p & cpu_to_le32 (0x3)); - - /* URB is done; clean up */ - if (++(urb_priv->td_cnt) == urb_priv->length) - dl_del_urb (urb); - } else { - td_p = &td->hwNextTD; - } - } - - if (ed->state & ED_DEL) { /* set by sohci_free_dev */ - struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO & 0x7F]); - td_free (ohci, tdTailP); /* free dummy td */ - ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); - ed->state = ED_NEW; - hash_free_ed(ohci, ed); - /* if all eds are removed wake up sohci_free_dev */ - if (!--dev->ed_cnt) { - wait_queue_head_t *wait_head = dev->wait; - - dev->wait = 0; - if (wait_head) - wake_up (wait_head); - } - } else { - ed->state &= ~ED_URB_DEL; - tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0); - - if (tdHeadP == tdTailP) { - if (ed->state == ED_OPER) - ep_unlink(ohci, ed); - td_free (ohci, tdTailP); - ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); - ed->state = ED_NEW; - hash_free_ed(ohci, ed); - --(usb_to_ohci (ohci->dev[edINFO & 0x7F]))->ed_cnt; - } else - ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP); - } - - switch (ed->type) { - case PIPE_CONTROL: - ctrl = 1; - break; - case PIPE_BULK: - bulk = 1; - break; - } - } - - /* maybe reenable control and bulk lists */ - if (!ohci->disabled) { - if (ctrl) /* reset control list */ - writel (0, &ohci->regs->ed_controlcurrent); - if (bulk) /* reset bulk list */ - writel (0, &ohci->regs->ed_bulkcurrent); - if (!ohci->ed_rm_list[!frame] && !ohci->sleeping) { - if (ohci->ed_controltail) - ohci->hc_control |= OHCI_CTRL_CLE; - if (ohci->ed_bulktail) - ohci->hc_control |= OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); - } - } - - ohci->ed_rm_list[frame] = NULL; - spin_unlock_irqrestore (&usb_ed_lock, flags); -} - - - -/*-------------------------------------------------------------------------*/ - -/* td done list */ - -void dl_done_list (ohci_t * ohci, td_t * td_list) -{ - td_t * td_list_next = NULL; - ed_t * ed; - int cc = 0; - struct urb * urb; - urb_priv_t * urb_priv; - __u32 tdINFO, edHeadP, edTailP; - - unsigned long flags; - - while (td_list) { - td_list_next = td_list->next_dl_td; - - urb = td_list->urb; - urb_priv = urb->hcpriv; - tdINFO = le32_to_cpup (&td_list->hwINFO); - - ed = td_list->ed; - - dl_transfer_length(td_list); - - /* error code of transfer */ - cc = TD_CC_GET (tdINFO); - if (cc == TD_CC_STALL) - usb_endpoint_halt(urb->dev, - usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe)); - - if (!(urb->transfer_flags & USB_DISABLE_SPD) - && (cc == TD_DATAUNDERRUN)) - cc = TD_CC_NOERROR; - - if (++(urb_priv->td_cnt) == urb_priv->length) { - if ((ed->state & (ED_OPER | ED_UNLINK)) - && (urb_priv->state != URB_DEL)) { - urb->status = cc_to_error[cc]; - sohci_return_urb (ohci, urb); - } else { - spin_lock_irqsave (&usb_ed_lock, flags); - dl_del_urb (urb); - spin_unlock_irqrestore (&usb_ed_lock, flags); - } - } - - spin_lock_irqsave (&usb_ed_lock, flags); - if (ed->state != ED_NEW) { - edHeadP = le32_to_cpup (&ed->hwHeadP) & 0xfffffff0; - edTailP = le32_to_cpup (&ed->hwTailP); - - /* unlink eds if they are not busy */ - if ((edHeadP == edTailP) && (ed->state == ED_OPER)) - ep_unlink (ohci, ed); - } - spin_unlock_irqrestore (&usb_ed_lock, flags); - - td_list = td_list_next; - } -} - - - - -/*-------------------------------------------------------------------------* - * Virtual Root Hub - *-------------------------------------------------------------------------*/ - -/* Device descriptor */ -static __u8 root_hub_dev_des[] = -{ - 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ - 0x10, /* __u16 bcdUSB; v1.1 */ - 0x01, - 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ - 0x00, /* __u8 bDeviceSubClass; */ - 0x00, /* __u8 bDeviceProtocol; */ - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ - 0x00, /* __u16 idVendor; */ - 0x00, - 0x00, /* __u16 idProduct; */ - 0x00, - 0x00, /* __u16 bcdDevice; */ - 0x00, - 0x00, /* __u8 iManufacturer; */ - 0x02, /* __u8 iProduct; */ - 0x01, /* __u8 iSerialNumber; */ - 0x01 /* __u8 bNumConfigurations; */ -}; - - -/* Configuration descriptor */ -static __u8 root_hub_config_des[] = -{ - 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ - 0x19, /* __u16 wTotalLength; */ - 0x00, - 0x01, /* __u8 bNumInterfaces; */ - 0x01, /* __u8 bConfigurationValue; */ - 0x00, /* __u8 iConfiguration; */ - 0x40, /* __u8 bmAttributes; - Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ - 0x00, /* __u8 MaxPower; */ - - /* interface */ - 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ - 0x00, /* __u8 if_bInterfaceNumber; */ - 0x00, /* __u8 if_bAlternateSetting; */ - 0x01, /* __u8 if_bNumEndpoints; */ - 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ - 0x00, /* __u8 if_bInterfaceSubClass; */ - 0x00, /* __u8 if_bInterfaceProtocol; */ - 0x00, /* __u8 if_iInterface; */ - - /* endpoint */ - 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ - 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* __u8 ep_bmAttributes; Interrupt */ - 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */ - 0x00, - 0xff /* __u8 ep_bInterval; 255 ms */ -}; - -/* Hub class-specific descriptor is constructed dynamically */ - - -/*-------------------------------------------------------------------------*/ - -/* prepare Interrupt pipe data; HUB INTERRUPT ENDPOINT */ - -static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len) -{ - int num_ports; - int i; - int ret; - int len; - - __u8 data[8]; - - num_ports = roothub_a (ohci) & RH_A_NDP; - if (num_ports > MAX_ROOT_PORTS) { - err ("bogus NDP=%d for OHCI usb-%s", num_ports, - ohci->slot_name); - err ("rereads as NDP=%d", - readl (&ohci->regs->roothub.a) & RH_A_NDP); - /* retry later; "should not happen" */ - return 0; - } - *(__u8 *) data = (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC)) - ? 1: 0; - ret = *(__u8 *) data; - - for ( i = 0; i < num_ports; i++) { - *(__u8 *) (data + (i + 1) / 8) |= - ((roothub_portstatus (ohci, i) & - (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC)) - ? 1: 0) << ((i + 1) % 8); - ret += *(__u8 *) (data + (i + 1) / 8); - } - len = i/8 + 1; - - if (ret > 0) { - memcpy(rh_data, data, - min_t(unsigned int, len, - min_t(unsigned int, rh_len, sizeof(data)))); - return len; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* Virtual Root Hub INTs are polled by this timer every "interval" ms */ - -static void rh_int_timer_do (unsigned long ptr) -{ - int len; - - struct urb * urb = (struct urb *) ptr; - ohci_t * ohci = urb->dev->bus->hcpriv; - - if (ohci->disabled) - return; - - /* ignore timers firing during PM suspend, etc */ - if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) - goto out; - - if(ohci->rh.send) { - len = rh_send_irq (ohci, urb->transfer_buffer, urb->transfer_buffer_length); - if (len > 0) { - urb->actual_length = len; -#ifdef DEBUG - urb_print (urb, "RET-t(rh)", usb_pipeout (urb->pipe)); -#endif - if (urb->complete) - urb->complete (urb); - } - } - out: - rh_init_int_timer (urb); -} - -/*-------------------------------------------------------------------------*/ - -/* Root Hub INTs are polled by this timer */ - -static int rh_init_int_timer (struct urb * urb) -{ - ohci_t * ohci = urb->dev->bus->hcpriv; - - ohci->rh.interval = urb->interval; - init_timer (&ohci->rh.rh_int_timer); - ohci->rh.rh_int_timer.function = rh_int_timer_do; - ohci->rh.rh_int_timer.data = (unsigned long) urb; - ohci->rh.rh_int_timer.expires = - jiffies + (HZ * (urb->interval < 30? 30: urb->interval)) / 1000; - add_timer (&ohci->rh.rh_int_timer); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -#define OK(x) len = (x); break -#define WR_RH_STAT(x) writel((x), &ohci->regs->roothub.status) -#define WR_RH_PORTSTAT(x) writel((x), &ohci->regs->roothub.portstatus[wIndex-1]) -#define RD_RH_STAT roothub_status(ohci) -#define RD_RH_PORTSTAT roothub_portstatus(ohci,wIndex-1) - -/* request to virtual root hub */ - -static int rh_submit_urb (struct urb * urb) -{ - struct usb_device * usb_dev = urb->dev; - ohci_t * ohci = usb_dev->bus->hcpriv; - unsigned int pipe = urb->pipe; - struct usb_ctrlrequest * cmd = (struct usb_ctrlrequest *) urb->setup_packet; - void * data = urb->transfer_buffer; - int leni = urb->transfer_buffer_length; - int len = 0; - int status = TD_CC_NOERROR; - - __u32 datab[4]; - __u8 * data_buf = (__u8 *) datab; - - __u16 bmRType_bReq; - __u16 wValue; - __u16 wIndex; - __u16 wLength; - - if (usb_pipeint(pipe)) { - ohci->rh.urb = urb; - ohci->rh.send = 1; - ohci->rh.interval = urb->interval; - rh_init_int_timer(urb); - urb->status = cc_to_error [TD_CC_NOERROR]; - - return 0; - } - - bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8); - wValue = le16_to_cpu (cmd->wValue); - wIndex = le16_to_cpu (cmd->wIndex); - wLength = le16_to_cpu (cmd->wLength); - - switch (bmRType_bReq) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ - - case RH_GET_STATUS: - *(__u16 *) data_buf = cpu_to_le16 (1); OK (2); - case RH_GET_STATUS | RH_INTERFACE: - *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); - case RH_GET_STATUS | RH_ENDPOINT: - *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); - case RH_GET_STATUS | RH_CLASS: - *(__u32 *) data_buf = cpu_to_le32 ( - RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); - OK (4); - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - *(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4); - - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - case RH_C_HUB_LOCAL_POWER: - OK(0); - case (RH_C_HUB_OVER_CURRENT): - WR_RH_STAT(RH_HS_OCIC); OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_POCI); OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); - case (RH_C_PORT_CONNECTION): - WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); - case (RH_C_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_PESC); OK (0); - case (RH_C_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); - case (RH_C_PORT_OVER_CURRENT): - WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); - case (RH_C_PORT_RESET): - WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); - } - break; - - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); - case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT (RH_PS_PRS); - OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_PPS ); OK (0); - case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT (RH_PS_PES ); - OK (0); - } - break; - - case RH_SET_ADDRESS: ohci->rh.devnum = wValue; OK(0); - - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_dev_des), - wLength)); - data_buf = root_hub_dev_des; OK(len); - case (0x02): /* configuration descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_config_des), - wLength)); - data_buf = root_hub_config_des; OK(len); - case (0x03): /* string descriptors */ - len = usb_root_hub_string (wValue & 0xff, - (int)(long) ohci->regs, "OHCI", - data, wLength); - if (len > 0) { - data_buf = data; - OK(min_t(int, leni, len)); - } - // else fallthrough - default: - status = TD_CC_STALL; - } - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: - { - __u32 temp = roothub_a (ohci); - - data_buf [0] = 9; // min length; - data_buf [1] = 0x29; - data_buf [2] = temp & RH_A_NDP; - data_buf [3] = 0; - if (temp & RH_A_PSM) /* per-port power switching? */ - data_buf [3] |= 0x1; - if (temp & RH_A_NOCP) /* no overcurrent reporting? */ - data_buf [3] |= 0x10; - else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */ - data_buf [3] |= 0x8; - - datab [1] = 0; - data_buf [5] = (temp & RH_A_POTPGT) >> 24; - temp = roothub_b (ohci); - data_buf [7] = temp & RH_B_DR; - if (data_buf [2] < 7) { - data_buf [8] = 0xff; - } else { - data_buf [0] += 2; - data_buf [8] = (temp & RH_B_DR) >> 8; - data_buf [10] = data_buf [9] = 0xff; - } - - len = min_t(unsigned int, leni, - min_t(unsigned int, data_buf [0], wLength)); - OK (len); - } - - case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1); - - case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0); - - default: - dbg ("unsupported root hub command"); - status = TD_CC_STALL; - } - -#ifdef DEBUG - // ohci_dump_roothub (ohci, 0); -#endif - - len = min_t(int, len, leni); - if (data != data_buf) - memcpy (data, data_buf, len); - urb->actual_length = len; - urb->status = cc_to_error [status]; - -#ifdef DEBUG - urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe)); -#endif - - urb->hcpriv = NULL; - usb_put_dev (usb_dev); - urb->dev = NULL; - if (urb->complete) - urb->complete (urb); - usb_put_urb (urb); - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int rh_unlink_urb (struct urb * urb) -{ - ohci_t * ohci = urb->dev->bus->hcpriv; - - if (ohci->rh.urb == urb) { - ohci->rh.send = 0; - del_timer (&ohci->rh.rh_int_timer); - ohci->rh.urb = NULL; - - urb->hcpriv = NULL; - usb_put_dev (urb->dev); - urb->dev = NULL; - if (urb->transfer_flags & USB_ASYNC_UNLINK) { - urb->status = -ECONNRESET; - if (urb->complete) - urb->complete (urb); - } else - urb->status = -ENOENT; - usb_put_urb (urb); - } - return 0; -} - -/*-------------------------------------------------------------------------* - * HC functions - *-------------------------------------------------------------------------*/ - -/* reset the HC and BUS */ - -int hc_reset (ohci_t * ohci) -{ - int timeout = 30; - int smm_timeout = 50; /* 0,5 sec */ - - if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ - writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ - dbg("USB HC TakeOver from SMM"); - while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { - wait_ms (10); - if (--smm_timeout == 0) { - err("USB HC TakeOver failed!"); - return -1; - } - } - } - - /* Disable HC interrupts */ - writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); - - dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;", - ohci->slot_name, - readl (&ohci->regs->control)); - - /* Reset USB (needed by some controllers) */ - writel (0, &ohci->regs->control); - - /* HC Reset requires max 10 ms delay */ - writel (OHCI_HCR, &ohci->regs->cmdstatus); - while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { - if (--timeout == 0) { - err("USB HC reset timed out!"); - return -1; - } - udelay (1); - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* Start an OHCI controller, set the BUS operational - * enable interrupts - * connect the virtual root hub */ - -int hc_start (ohci_t * ohci, struct device *parent_dev) -{ - __u32 mask; - unsigned int fminterval; - struct usb_device * usb_dev; - struct ohci_device * dev; - - ohci->disabled = 1; - - /* Tell the controller where the control and bulk lists are - * The lists are empty now. */ - - writel (0, &ohci->regs->ed_controlhead); - writel (0, &ohci->regs->ed_bulkhead); - - writel (ohci->hcca_dma, &ohci->regs->hcca); /* a reset clears this */ - - fminterval = 0x2edf; - writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); - fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel (fminterval, &ohci->regs->fminterval); - writel (0x628, &ohci->regs->lsthresh); - - /* start controller operations */ - ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; - ohci->disabled = 0; - writel (ohci->hc_control, &ohci->regs->control); - - /* Choose the interrupts we care about now, others later on demand */ - mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; - writel (mask, &ohci->regs->intrenable); - writel (mask, &ohci->regs->intrstatus); - -#ifdef OHCI_USE_NPS - /* required for AMD-756 and some Mac platforms */ - writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, - &ohci->regs->roothub.a); - writel (RH_HS_LPSC, &ohci->regs->roothub.status); -#endif /* OHCI_USE_NPS */ - - // POTPGT delay is bits 24-31, in 2 ms units. - mdelay ((roothub_a (ohci) >> 23) & 0x1fe); - - /* connect the virtual root hub */ - ohci->rh.devnum = 0; - usb_dev = usb_alloc_dev (NULL, ohci->bus); - if (!usb_dev) { - ohci->disabled = 1; - return -ENOMEM; - } - - dev = usb_to_ohci (usb_dev); - ohci->bus->root_hub = usb_dev; - usb_connect (usb_dev); - if (usb_register_root_hub (usb_dev, parent_dev) != 0) { - usb_free_dev (usb_dev); - ohci->disabled = 1; - return -ENODEV; - } - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* called only from interrupt handler */ - -static void check_timeouts (struct ohci *ohci) -{ - spin_lock (&usb_ed_lock); - while (!list_empty (&ohci->timeout_list)) { - struct urb *urb; - - urb = list_entry (ohci->timeout_list.next, struct urb, urb_list); - if (time_after (jiffies, urb->timeout)) - break; - - list_del_init (&urb->urb_list); - if (urb->status != -EINPROGRESS) - continue; - - urb->transfer_flags |= USB_TIMEOUT_KILLED | USB_ASYNC_UNLINK; - spin_unlock (&usb_ed_lock); - - // outside the interrupt handler (in a timer...) - // this reference would race interrupts - sohci_unlink_urb (urb); - - spin_lock (&usb_ed_lock); - } - spin_unlock (&usb_ed_lock); -} - - -/*-------------------------------------------------------------------------*/ - -/* an interrupt happens */ - -static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r) -{ - ohci_t * ohci = __ohci; - struct ohci_regs * regs = ohci->regs; - int ints; - - if ((ohci->hcca->done_head != 0) && !(le32_to_cpup (&ohci->hcca->done_head) & 0x01)) { - ints = OHCI_INTR_WDH; - } else if ((ints = (readl (®s->intrstatus) & readl (®s->intrenable))) == 0) { - return; - } - - // dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); - - if (ints & OHCI_INTR_UE) { - ohci->disabled++; - err ("OHCI Unrecoverable Error, controller usb-%s disabled", - ohci->slot_name); - // e.g. due to PCI Master/Target Abort - -#ifdef DEBUG - ohci_dump (ohci, 1); -#else - // FIXME: be optimistic, hope that bug won't repeat often. - // Make some non-interrupt context restart the controller. - // Count and limit the retries though; either hardware or - // software errors can go forever... -#endif - hc_reset (ohci); - } - - if (ints & OHCI_INTR_WDH) { - writel (OHCI_INTR_WDH, ®s->intrdisable); - dl_done_list (ohci, dl_reverse_done_list (ohci)); - writel (OHCI_INTR_WDH, ®s->intrenable); - } - - if (ints & OHCI_INTR_SO) { - dbg("USB Schedule overrun"); - writel (OHCI_INTR_SO, ®s->intrenable); - } - - // FIXME: this assumes SOF (1/ms) interrupts don't get lost... - if (ints & OHCI_INTR_SF) { - unsigned int frame = le16_to_cpu (ohci->hcca->frame_no) & 1; - writel (OHCI_INTR_SF, ®s->intrdisable); - if (ohci->ed_rm_list[!frame] != NULL) { - dl_del_list (ohci, !frame); - } - if (ohci->ed_rm_list[frame] != NULL) - writel (OHCI_INTR_SF, ®s->intrenable); - } - - if (!list_empty (&ohci->timeout_list)) { - check_timeouts (ohci); -// FIXME: enable SF as needed in a timer; -// don't make lots of 1ms interrupts -// On unloaded USB, think 4k ~= 4-5msec - if (!list_empty (&ohci->timeout_list)) - writel (OHCI_INTR_SF, ®s->intrenable); - } - - writel (ints, ®s->intrstatus); - writel (OHCI_INTR_MIE, ®s->intrenable); -} - -/*-------------------------------------------------------------------------*/ - -/* allocate OHCI */ - -static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base) -{ - ohci_t * ohci; - - ohci = (ohci_t *) kmalloc (sizeof *ohci, GFP_KERNEL); - if (!ohci) - return NULL; - - memset (ohci, 0, sizeof (ohci_t)); - - ohci->hcca = pci_alloc_consistent (dev, sizeof *ohci->hcca, - &ohci->hcca_dma); - if (!ohci->hcca) { - kfree (ohci); - return NULL; - } - memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); - - ohci->disabled = 1; - ohci->sleeping = 0; - ohci->irq = -1; - ohci->regs = mem_base; - - ohci->ohci_dev = dev; -#ifdef CONFIG_PCI - pci_set_drvdata(dev, ohci); -#endif - - INIT_LIST_HEAD (&ohci->ohci_hcd_list); - list_add (&ohci->ohci_hcd_list, &ohci_hcd_list); - - INIT_LIST_HEAD (&ohci->timeout_list); - - ohci->bus = usb_alloc_bus (&sohci_device_operations); - if (!ohci->bus) { -#ifdef CONFIG_PCI - pci_set_drvdata (dev, NULL); -#endif - pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca, - ohci->hcca, ohci->hcca_dma); - kfree (ohci); - return NULL; - } - ohci->bus->hcpriv = (void *) ohci; -#ifdef CONFIG_PCI - ohci->bus->bus_name = dev->slot_name; -#else - ohci->bus->bus_name = "ohci-hc"; -#endif - - return ohci; -} - - -/*-------------------------------------------------------------------------*/ - -/* De-allocate all resources.. */ - -static void hc_release_ohci (ohci_t * ohci) -{ - dbg ("USB HC release ohci usb-%s", ohci->slot_name); - - /* disconnect all devices */ - if (ohci->bus->root_hub) - usb_disconnect (&ohci->bus->root_hub); - - if (!ohci->disabled) - hc_reset (ohci); - - if (ohci->irq >= 0) { - free_irq (ohci->irq, ohci); - ohci->irq = -1; - } -#ifdef CONFIG_PCI - pci_set_drvdata(ohci->ohci_dev, NULL); -#endif - if (ohci->bus) { - if (ohci->bus->busnum) - usb_deregister_bus (ohci->bus); - usb_free_bus (ohci->bus); - } - - list_del (&ohci->ohci_hcd_list); - INIT_LIST_HEAD (&ohci->ohci_hcd_list); - - ohci_mem_cleanup (ohci); - - pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca, - ohci->hcca, ohci->hcca_dma); - kfree (ohci); -} - -/*-------------------------------------------------------------------------*/ - -/* - * Host bus independent add one OHCI host controller. - */ -int -hc_add_ohci(struct pci_dev *dev, int irq, void *mem_base, unsigned long flags, - ohci_t **ohcip, const char *name, const char *slot_name) -{ - char buf[8], *bufp = buf; - ohci_t * ohci; - int ret; - -#ifndef __sparc__ - sprintf(buf, "%d", irq); -#else - bufp = __irq_itoa(irq); -#endif - printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n", - (unsigned long) mem_base, bufp); - - ohci = hc_alloc_ohci (dev, mem_base); - if (!ohci) { - return -ENOMEM; - } - ohci->slot_name = slot_name; - if ((ret = ohci_mem_init (ohci)) < 0) { - hc_release_ohci (ohci); - return ret; - } - ohci->flags = flags; - if (ohci->flags & OHCI_QUIRK_AMD756) - printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n"); - - if (hc_reset (ohci) < 0) { - hc_release_ohci (ohci); - return -ENODEV; - } - - /* FIXME this is a second HC reset; why?? */ - writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); - wait_ms (10); - - usb_register_bus (ohci->bus); - - if (request_irq (irq, hc_interrupt, SA_SHIRQ, name, ohci) != 0) { - err ("request interrupt %s failed", bufp); - hc_release_ohci (ohci); - return -EBUSY; - } - ohci->irq = irq; - - *ohcip = ohci; - - return 0; -} - -/* - * Host bus independent remove one OHCI host controller. - */ -void hc_remove_ohci(ohci_t *ohci) -{ -#ifdef DEBUG - ohci_dump (ohci, 1); -#endif - - /* don't wake up sleeping controllers, or block in interrupt context */ - if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER || in_interrupt ()) { - dbg ("controller being disabled"); - ohci->disabled = 1; - } - - /* on return, USB will always be reset (if present) */ - if (ohci->disabled) - writel (ohci->hc_control = OHCI_USB_RESET, - &ohci->regs->control); - - hc_release_ohci (ohci); -} - -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(hc_add_ohci); -EXPORT_SYMBOL(hc_remove_ohci); -EXPORT_SYMBOL(hc_start); -EXPORT_SYMBOL(hc_reset); -EXPORT_SYMBOL(dl_done_list); -EXPORT_SYMBOL(dl_reverse_done_list); -EXPORT_SYMBOL(usb_ed_lock); diff --git a/drivers/usb/host/usb-ohci.h b/drivers/usb/host/usb-ohci.h deleted file mode 100644 index c04bb49a003f..000000000000 --- a/drivers/usb/host/usb-ohci.h +++ /dev/null @@ -1,648 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> - * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net> - * - * usb-ohci.h - */ - - -static int cc_to_error[16] = { - -/* mapping of the OHCI CC status to error codes */ - /* No Error */ 0, - /* CRC Error */ -EILSEQ, - /* Bit Stuff */ -EPROTO, - /* Data Togg */ -EILSEQ, - /* Stall */ -EPIPE, - /* DevNotResp */ -ETIMEDOUT, - /* PIDCheck */ -EPROTO, - /* UnExpPID */ -EPROTO, - /* DataOver */ -EOVERFLOW, - /* DataUnder */ -EREMOTEIO, - /* reservd */ -ETIMEDOUT, - /* reservd */ -ETIMEDOUT, - /* BufferOver */ -ECOMM, - /* BuffUnder */ -ENOSR, - /* Not Access */ -ETIMEDOUT, - /* Not Access */ -ETIMEDOUT -}; - -#include <linux/config.h> - -/* ED States */ - -#define ED_NEW 0x00 -#define ED_UNLINK 0x01 -#define ED_OPER 0x02 -#define ED_DEL 0x04 -#define ED_URB_DEL 0x08 - -/* usb_ohci_ed */ -struct ed { - __u32 hwINFO; - __u32 hwTailP; - __u32 hwHeadP; - __u32 hwNextED; - - struct ed * ed_prev; - __u8 int_period; - __u8 int_branch; - __u8 int_load; - __u8 int_interval; - __u8 state; - __u8 type; - __u16 last_iso; - struct ed * ed_rm_list; - - dma_addr_t dma; - __u32 unused[3]; -} __attribute((aligned(16))); -typedef struct ed ed_t; - - -/* TD info field */ -#define TD_CC 0xf0000000 -#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) -#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) -#define TD_EC 0x0C000000 -#define TD_T 0x03000000 -#define TD_T_DATA0 0x02000000 -#define TD_T_DATA1 0x03000000 -#define TD_T_TOGGLE 0x00000000 -#define TD_R 0x00040000 -#define TD_DI 0x00E00000 -#define TD_DI_SET(X) (((X) & 0x07)<< 21) -#define TD_DP 0x00180000 -#define TD_DP_SETUP 0x00000000 -#define TD_DP_IN 0x00100000 -#define TD_DP_OUT 0x00080000 - -#define TD_ISO 0x00010000 -#define TD_DEL 0x00020000 - -/* CC Codes */ -#define TD_CC_NOERROR 0x00 -#define TD_CC_CRC 0x01 -#define TD_CC_BITSTUFFING 0x02 -#define TD_CC_DATATOGGLEM 0x03 -#define TD_CC_STALL 0x04 -#define TD_DEVNOTRESP 0x05 -#define TD_PIDCHECKFAIL 0x06 -#define TD_UNEXPECTEDPID 0x07 -#define TD_DATAOVERRUN 0x08 -#define TD_DATAUNDERRUN 0x09 -#define TD_BUFFEROVERRUN 0x0C -#define TD_BUFFERUNDERRUN 0x0D -#define TD_NOTACCESSED 0x0F - - -#define MAXPSW 1 - -struct td { - __u32 hwINFO; - __u32 hwCBP; /* Current Buffer Pointer */ - __u32 hwNextTD; /* Next TD Pointer */ - __u32 hwBE; /* Memory Buffer End Pointer */ - - __u16 hwPSW[MAXPSW]; - __u8 unused; - __u8 index; - struct ed * ed; - struct td * next_dl_td; - struct urb * urb; - - dma_addr_t td_dma; - dma_addr_t data_dma; - __u32 unused2[2]; -} __attribute((aligned(32))); /* normally 16, iso needs 32 */ -typedef struct td td_t; - -#define OHCI_ED_SKIP (1 << 14) - -/* - * The HCCA (Host Controller Communications Area) is a 256 byte - * structure defined in the OHCI spec. that the host controller is - * told the base address of. It must be 256-byte aligned. - */ - -#define NUM_INTS 32 /* part of the OHCI standard */ -struct ohci_hcca { - __u32 int_table[NUM_INTS]; /* Interrupt ED table */ - __u16 frame_no; /* current frame number */ - __u16 pad1; /* set to 0 on each frame_no change */ - __u32 done_head; /* info returned for an interrupt */ - u8 reserved_for_hc[116]; -} __attribute((aligned(256))); - - -/* - * Maximum number of root hub ports. - */ -#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */ - -/* - * This is the structure of the OHCI controller's memory mapped I/O - * region. This is Memory Mapped I/O. You must use the readl() and - * writel() macros defined in asm/io.h to access these!! - */ -struct ohci_regs { - /* control and status registers */ - __u32 revision; - __u32 control; - __u32 cmdstatus; - __u32 intrstatus; - __u32 intrenable; - __u32 intrdisable; - /* memory pointers */ - __u32 hcca; - __u32 ed_periodcurrent; - __u32 ed_controlhead; - __u32 ed_controlcurrent; - __u32 ed_bulkhead; - __u32 ed_bulkcurrent; - __u32 donehead; - /* frame counters */ - __u32 fminterval; - __u32 fmremaining; - __u32 fmnumber; - __u32 periodicstart; - __u32 lsthresh; - /* Root hub ports */ - struct ohci_roothub_regs { - __u32 a; - __u32 b; - __u32 status; - __u32 portstatus[MAX_ROOT_PORTS]; - } roothub; -} __attribute((aligned(32))); - - -/* OHCI CONTROL AND STATUS REGISTER MASKS */ - -/* - * HcControl (control) register masks - */ -#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */ -#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */ -#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */ -#define OHCI_CTRL_CLE (1 << 4) /* control list enable */ -#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */ -#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ -#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ -#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ -#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ - -/* pre-shifted values for HCFS */ -# define OHCI_USB_RESET (0 << 6) -# define OHCI_USB_RESUME (1 << 6) -# define OHCI_USB_OPER (2 << 6) -# define OHCI_USB_SUSPEND (3 << 6) - -/* - * HcCommandStatus (cmdstatus) register masks - */ -#define OHCI_HCR (1 << 0) /* host controller reset */ -#define OHCI_CLF (1 << 1) /* control list filled */ -#define OHCI_BLF (1 << 2) /* bulk list filled */ -#define OHCI_OCR (1 << 3) /* ownership change request */ -#define OHCI_SOC (3 << 16) /* scheduling overrun count */ - -/* - * masks used with interrupt registers: - * HcInterruptStatus (intrstatus) - * HcInterruptEnable (intrenable) - * HcInterruptDisable (intrdisable) - */ -#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ -#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ -#define OHCI_INTR_SF (1 << 2) /* start frame */ -#define OHCI_INTR_RD (1 << 3) /* resume detect */ -#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ -#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ -#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ -#define OHCI_INTR_OC (1 << 30) /* ownership change */ -#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ - - - -/* Virtual Root HUB */ -struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - void * urb; - void * int_addr; - int send; - int interval; - struct timer_list rh_int_timer; -}; - - -/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ - -/* destination of request */ -#define RH_INTERFACE 0x01 -#define RH_ENDPOINT 0x02 -#define RH_OTHER 0x03 - -#define RH_CLASS 0x20 -#define RH_VENDOR 0x40 - -/* Requests: bRequest << 8 | bmRequestType */ -#define RH_GET_STATUS 0x0080 -#define RH_CLEAR_FEATURE 0x0100 -#define RH_SET_FEATURE 0x0300 -#define RH_SET_ADDRESS 0x0500 -#define RH_GET_DESCRIPTOR 0x0680 -#define RH_SET_DESCRIPTOR 0x0700 -#define RH_GET_CONFIGURATION 0x0880 -#define RH_SET_CONFIGURATION 0x0900 -#define RH_GET_STATE 0x0280 -#define RH_GET_INTERFACE 0x0A80 -#define RH_SET_INTERFACE 0x0B00 -#define RH_SYNC_FRAME 0x0C80 -/* Our Vendor Specific Request */ -#define RH_SET_EP 0x2000 - - -/* Hub port features */ -#define RH_PORT_CONNECTION 0x00 -#define RH_PORT_ENABLE 0x01 -#define RH_PORT_SUSPEND 0x02 -#define RH_PORT_OVER_CURRENT 0x03 -#define RH_PORT_RESET 0x04 -#define RH_PORT_POWER 0x08 -#define RH_PORT_LOW_SPEED 0x09 - -#define RH_C_PORT_CONNECTION 0x10 -#define RH_C_PORT_ENABLE 0x11 -#define RH_C_PORT_SUSPEND 0x12 -#define RH_C_PORT_OVER_CURRENT 0x13 -#define RH_C_PORT_RESET 0x14 - -/* Hub features */ -#define RH_C_HUB_LOCAL_POWER 0x00 -#define RH_C_HUB_OVER_CURRENT 0x01 - -#define RH_DEVICE_REMOTE_WAKEUP 0x00 -#define RH_ENDPOINT_STALL 0x01 - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - - -/* OHCI ROOT HUB REGISTER MASKS */ - -/* roothub.portstatus [i] bits */ -#define RH_PS_CCS 0x00000001 /* current connect status */ -#define RH_PS_PES 0x00000002 /* port enable status*/ -#define RH_PS_PSS 0x00000004 /* port suspend status */ -#define RH_PS_POCI 0x00000008 /* port over current indicator */ -#define RH_PS_PRS 0x00000010 /* port reset status */ -#define RH_PS_PPS 0x00000100 /* port power status */ -#define RH_PS_LSDA 0x00000200 /* low speed device attached */ -#define RH_PS_CSC 0x00010000 /* connect status change */ -#define RH_PS_PESC 0x00020000 /* port enable status change */ -#define RH_PS_PSSC 0x00040000 /* port suspend status change */ -#define RH_PS_OCIC 0x00080000 /* over current indicator change */ -#define RH_PS_PRSC 0x00100000 /* port reset status change */ - -/* roothub.status bits */ -#define RH_HS_LPS 0x00000001 /* local power status */ -#define RH_HS_OCI 0x00000002 /* over current indicator */ -#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ -#define RH_HS_LPSC 0x00010000 /* local power status change */ -#define RH_HS_OCIC 0x00020000 /* over current indicator change */ -#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ - -/* roothub.b masks */ -#define RH_B_DR 0x0000ffff /* device removable flags */ -#define RH_B_PPCM 0xffff0000 /* port power control mask */ - -/* roothub.a masks */ -#define RH_A_NDP (0xff << 0) /* number of downstream ports */ -#define RH_A_PSM (1 << 8) /* power switching mode */ -#define RH_A_NPS (1 << 9) /* no power switching */ -#define RH_A_DT (1 << 10) /* device type (mbz) */ -#define RH_A_OCPM (1 << 11) /* over current protection mode */ -#define RH_A_NOCP (1 << 12) /* no over current protection */ -#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ - -/* urb */ -typedef struct -{ - ed_t * ed; - __u16 length; // number of tds associated with this request - __u16 td_cnt; // number of tds already serviced - int state; - wait_queue_head_t * wait; - td_t * td[0]; // list pointer to all corresponding TDs associated with this request - -} urb_priv_t; -#define URB_DEL 1 - - -/* Hash struct used for TD/ED hashing */ -struct hash_t { - void *virt; - dma_addr_t dma; - struct hash_t *next; // chaining for collision cases -}; - -/* List of TD/ED hash entries */ -struct hash_list_t { - struct hash_t *head; - struct hash_t *tail; -}; - -#define TD_HASH_SIZE 64 /* power'o'two */ -#define ED_HASH_SIZE 64 /* power'o'two */ - -#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 5)) % TD_HASH_SIZE) -#define ED_HASH_FUNC(ed_dma) ((ed_dma ^ (ed_dma >> 5)) % ED_HASH_SIZE) - - -/* - * This is the full ohci controller description - * - * Note how the "proper" USB information is just - * a subset of what the full implementation needs. (Linus) - */ - - -typedef struct ohci { - struct ohci_hcca *hcca; /* hcca */ - dma_addr_t hcca_dma; - - int irq; - int disabled; /* e.g. got a UE, we're hung */ - int sleeping; - atomic_t resume_count; /* defending against multiple resumes */ - unsigned long flags; /* for HC bugs */ -#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ - - struct ohci_regs * regs; /* OHCI controller's memory */ - struct list_head ohci_hcd_list; /* list of all ohci_hcd */ - - struct ohci * next; // chain of ohci device contexts - struct list_head timeout_list; - // struct list_head urb_list; // list of all pending urbs - // spinlock_t urb_list_lock; // lock to keep consistency - - int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load balancing)*/ - ed_t * ed_rm_list[2]; /* lists of all endpoints to be removed */ - ed_t * ed_bulktail; /* last endpoint of bulk list */ - ed_t * ed_controltail; /* last endpoint of control list */ - ed_t * ed_isotail; /* last endpoint of iso list */ - int intrstatus; - __u32 hc_control; /* copy of the hc control reg */ - struct usb_bus * bus; - struct usb_device * dev[128]; - struct virt_root_hub rh; - - /* PCI device handle, settings, ... */ - struct pci_dev *ohci_dev; - const char *slot_name; - u8 pci_latency; - struct pci_pool *td_cache; - struct pci_pool *dev_cache; - struct hash_list_t td_hash[TD_HASH_SIZE]; - struct hash_list_t ed_hash[ED_HASH_SIZE]; - -} ohci_t; - -#define NUM_EDS 32 /* num of preallocated endpoint descriptors */ - -struct ohci_device { - ed_t ed[NUM_EDS]; - dma_addr_t dma; - int ed_cnt; - wait_queue_head_t * wait; -}; - -// #define ohci_to_usb(ohci) ((ohci)->usb) -#define usb_to_ohci(usb) ((struct ohci_device *)(usb)->hcpriv) - -/* For initializing controller (mask in an HCFS mode too) */ -#define OHCI_CONTROL_INIT \ - (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE - -/* hcd */ -/* endpoint */ -static int ep_link(ohci_t * ohci, ed_t * ed); -static int ep_unlink(ohci_t * ohci, ed_t * ed); -static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned int pipe, int interval, int load, int mem_flags); -static void ep_rm_ed(struct usb_device * usb_dev, ed_t * ed); -/* td */ -static void td_fill(ohci_t * ohci, unsigned int info, dma_addr_t data, int len, struct urb * urb, int index); -static void td_submit_urb(struct urb * urb); -/* root hub */ -static int rh_submit_urb(struct urb * urb); -static int rh_unlink_urb(struct urb * urb); -static int rh_init_int_timer(struct urb * urb); - -/*-------------------------------------------------------------------------*/ - -#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL) - -#ifdef DEBUG -# define OHCI_MEM_FLAGS SLAB_POISON -#else -# define OHCI_MEM_FLAGS 0 -#endif - - -/* Recover a TD/ED using its collision chain */ -static void * -dma_to_ed_td (struct hash_list_t * entry, dma_addr_t dma) -{ - struct hash_t * scan = entry->head; - while (scan && scan->dma != dma) - scan = scan->next; - if (!scan) - BUG(); - return scan->virt; -} - -static struct ed * -dma_to_ed (struct ohci * hc, dma_addr_t ed_dma) -{ - return (struct ed *) dma_to_ed_td(&(hc->ed_hash[ED_HASH_FUNC(ed_dma)]), - ed_dma); -} - -static struct td * -dma_to_td (struct ohci * hc, dma_addr_t td_dma) -{ - return (struct td *) dma_to_ed_td(&(hc->td_hash[TD_HASH_FUNC(td_dma)]), - td_dma); -} - -/* Add a hash entry for a TD/ED; return true on success */ -static int -hash_add_ed_td(struct hash_list_t * entry, void * virt, dma_addr_t dma) -{ - struct hash_t * scan; - - scan = (struct hash_t *)kmalloc(sizeof(struct hash_t), ALLOC_FLAGS); - if (!scan) - return 0; - - if (!entry->tail) { - entry->head = entry->tail = scan; - } else { - entry->tail->next = scan; - entry->tail = scan; - } - - scan->virt = virt; - scan->dma = dma; - scan->next = NULL; - return 1; -} - -static int -hash_add_ed (struct ohci * hc, struct ed * ed) -{ - return hash_add_ed_td (&(hc->ed_hash[ED_HASH_FUNC(ed->dma)]), - ed, ed->dma); -} - -static int -hash_add_td (struct ohci * hc, struct td * td) -{ - return hash_add_ed_td (&(hc->td_hash[TD_HASH_FUNC(td->td_dma)]), - td, td->td_dma); -} - - -static void -hash_free_ed_td (struct hash_list_t * entry, void * virt) -{ - struct hash_t *scan, *prev; - scan = prev = entry->head; - - // Find and unlink hash entry - while (scan && scan->virt != virt) { - prev = scan; - scan = scan->next; - } - if (scan) { - if (scan == entry->head) { - if (entry->head == entry->tail) - entry->head = entry->tail = NULL; - else - entry->head = scan->next; - } else if (scan == entry->tail) { - entry->tail = prev; - prev->next = NULL; - } else - prev->next = scan->next; - kfree(scan); - } -} - -static void -hash_free_ed (struct ohci * hc, struct ed * ed) -{ - hash_free_ed_td (&(hc->ed_hash[ED_HASH_FUNC(ed->dma)]), ed); -} - -static void -hash_free_td (struct ohci * hc, struct td * td) -{ - hash_free_ed_td (&(hc->td_hash[TD_HASH_FUNC(td->td_dma)]), td); -} - - -static int ohci_mem_init (struct ohci *ohci) -{ - ohci->td_cache = pci_pool_create ("ohci_td", ohci->ohci_dev, - sizeof (struct td), - 32 /* byte alignment */, - 0 /* no page-crossing issues */, - GFP_KERNEL | OHCI_MEM_FLAGS); - if (!ohci->td_cache) - return -ENOMEM; - ohci->dev_cache = pci_pool_create ("ohci_dev", ohci->ohci_dev, - sizeof (struct ohci_device), - 16 /* byte alignment */, - 0 /* no page-crossing issues */, - GFP_KERNEL | OHCI_MEM_FLAGS); - if (!ohci->dev_cache) - return -ENOMEM; - return 0; -} - -static void ohci_mem_cleanup (struct ohci *ohci) -{ - if (ohci->td_cache) { - pci_pool_destroy (ohci->td_cache); - ohci->td_cache = 0; - } - if (ohci->dev_cache) { - pci_pool_destroy (ohci->dev_cache); - ohci->dev_cache = 0; - } -} - -/* TDs ... */ -static struct td * -td_alloc (struct ohci *hc, int mem_flags) -{ - dma_addr_t dma; - struct td *td; - - td = pci_pool_alloc (hc->td_cache, mem_flags, &dma); - if (td) { - td->td_dma = dma; - - /* hash it for later reverse mapping */ - if (!hash_add_td (hc, td)) { - pci_pool_free (hc->td_cache, td, dma); - return NULL; - } - } - return td; -} - -static inline void -td_free (struct ohci *hc, struct td *td) -{ - hash_free_td (hc, td); - pci_pool_free (hc->td_cache, td, td->td_dma); -} - - -/* DEV + EDs ... only the EDs need to be consistent */ -static struct ohci_device * -dev_alloc (struct ohci *hc, int mem_flags) -{ - dma_addr_t dma; - struct ohci_device *dev; - int i, offset; - - dev = pci_pool_alloc (hc->dev_cache, mem_flags, &dma); - if (dev) { - memset (dev, 0, sizeof (*dev)); - dev->dma = dma; - offset = ((char *)&dev->ed) - ((char *)dev); - for (i = 0; i < NUM_EDS; i++, offset += sizeof dev->ed [0]) - dev->ed [i].dma = dma + offset; - /* add to hashtable if used */ - } - return dev; -} - -static inline void -dev_free (struct ohci *hc, struct ohci_device *dev) -{ - pci_pool_free (hc->dev_cache, dev, dev->dma); -} - -extern spinlock_t usb_ed_lock; -extern void dl_done_list (ohci_t * ohci, td_t * td_list); -extern td_t * dl_reverse_done_list (ohci_t * ohci); - - diff --git a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c index 58c311db3c4e..5d02c88fcf1b 100644 --- a/drivers/usb/image/hpusbscsi.c +++ b/drivers/usb/image/hpusbscsi.c @@ -164,10 +164,10 @@ MODULE_LICENSE("GPL"); static struct usb_driver hpusbscsi_usb_driver = { - name:"hpusbscsi", - probe:hpusbscsi_usb_probe, - disconnect:hpusbscsi_usb_disconnect, - id_table:hpusbscsi_usb_ids, + .name ="hpusbscsi", + .probe =hpusbscsi_usb_probe, + .disconnect =hpusbscsi_usb_disconnect, + .id_table =hpusbscsi_usb_ids, }; /* module initialisation */ diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 6514054a8813..662dba287d3d 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -923,11 +923,11 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l /* File Operations of this drivers */ static struct file_operations mdc800_device_ops = { - owner: THIS_MODULE, - read: mdc800_device_read, - write: mdc800_device_write, - open: mdc800_device_open, - release: mdc800_device_release, + .owner = THIS_MODULE, + .read = mdc800_device_read, + .write = mdc800_device_write, + .open = mdc800_device_open, + .release = mdc800_device_release, }; @@ -943,11 +943,11 @@ MODULE_DEVICE_TABLE (usb, mdc800_table); */ static struct usb_driver mdc800_usb_driver = { - owner: THIS_MODULE, - name: "mdc800", - probe: mdc800_usb_probe, - disconnect: mdc800_usb_disconnect, - id_table: mdc800_table + .owner = THIS_MODULE, + .name = "mdc800", + .probe = mdc800_usb_probe, + .disconnect = mdc800_usb_disconnect, + .id_table = mdc800_table }; diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 6b2591e7e071..dd454fd08fab 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -161,10 +161,10 @@ static void mts_usb_disconnect(struct usb_device *dev, void *ptr); static struct usb_device_id mts_usb_ids []; static struct usb_driver mts_usb_driver = { - name: "microtekX6", - probe: mts_usb_probe, - disconnect: mts_usb_disconnect, - id_table: mts_usb_ids, + .name = "microtekX6", + .probe = mts_usb_probe, + .disconnect = mts_usb_disconnect, + .id_table = mts_usb_ids, }; @@ -743,22 +743,22 @@ out: static Scsi_Host_Template mts_scsi_host_template = { - name: "microtekX6", - detect: mts_scsi_detect, - release: mts_scsi_release, - queuecommand: mts_scsi_queuecommand, - - eh_abort_handler: mts_scsi_abort, - eh_host_reset_handler: mts_scsi_host_reset, - - sg_tablesize: SG_ALL, - can_queue: 1, - this_id: -1, - cmd_per_lun: 1, - present: 0, - unchecked_isa_dma: FALSE, - use_clustering: TRUE, - emulated: TRUE + .name = "microtekX6", + .detect = mts_scsi_detect, + .release = mts_scsi_release, + .queuecommand = mts_scsi_queuecommand, + + .eh_abort_handler = mts_scsi_abort, + .eh_host_reset_handler =mts_scsi_host_reset, + + .sg_tablesize = SG_ALL, + .can_queue = 1, + .this_id = -1, + .cmd_per_lun = 1, + .present = 0, + .unchecked_isa_dma = FALSE, + .use_clustering = TRUE, + .emulated = TRUE }; diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c index 2bb1de40e3c0..9c9550e5cce7 100644 --- a/drivers/usb/image/scanner.c +++ b/drivers/usb/image/scanner.c @@ -811,11 +811,11 @@ ioctl_scanner(struct inode *inode, struct file *file, static struct file_operations usb_scanner_fops = { - read: read_scanner, - write: write_scanner, - ioctl: ioctl_scanner, - open: open_scanner, - release: close_scanner, + .read = read_scanner, + .write = write_scanner, + .ioctl = ioctl_scanner, + .open = open_scanner, + .release = close_scanner, }; static void * @@ -1116,10 +1116,10 @@ disconnect_scanner(struct usb_device *dev, void *ptr) static struct usb_driver scanner_driver = { - name: "usbscanner", - probe: probe_scanner, - disconnect: disconnect_scanner, - id_table: NULL, /* This would be scanner_device_ids, but we + .name = "usbscanner", + .probe = probe_scanner, + .disconnect = disconnect_scanner, + .id_table = NULL, /* This would be scanner_device_ids, but we need to check every USB device, in case we match a user defined vendor/product ID. */ }; diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index cbed3efbb7c4..764f52074649 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c @@ -313,10 +313,10 @@ aiptek_disconnect(struct usb_device *dev, void *ptr) } static struct usb_driver aiptek_driver = { - name:"aiptek", - probe:aiptek_probe, - disconnect:aiptek_disconnect, - id_table:aiptek_ids, + .name ="aiptek", + .probe =aiptek_probe, + .disconnect =aiptek_disconnect, + .id_table =aiptek_ids, }; static int __init diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 068417749db6..19b6ff130baf 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1556,10 +1556,10 @@ static struct usb_device_id hid_usb_ids [] = { MODULE_DEVICE_TABLE (usb, hid_usb_ids); static struct usb_driver hid_driver = { - name: "hid", - probe: hid_probe, - disconnect: hid_disconnect, - id_table: hid_usb_ids, + .name = "hid", + .probe = hid_probe, + .disconnect = hid_disconnect, + .id_table = hid_usb_ids, }; static int __init hid_init(void) diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 563285d58541..93dcc5184758 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -657,14 +657,14 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd } static struct file_operations hiddev_fops = { - owner: THIS_MODULE, - read: hiddev_read, - write: hiddev_write, - poll: hiddev_poll, - open: hiddev_open, - release: hiddev_release, - ioctl: hiddev_ioctl, - fasync: hiddev_fasync, + .owner = THIS_MODULE, + .read = hiddev_read, + .write = hiddev_write, + .poll = hiddev_poll, + .open = hiddev_open, + .release = hiddev_release, + .ioctl = hiddev_ioctl, + .fasync = hiddev_fasync, }; /* @@ -759,8 +759,8 @@ static void *hiddev_usbd_probe(struct usb_device *dev, unsigned int ifnum, static /* const */ struct usb_driver hiddev_driver = { - name: "hiddev", - probe: hiddev_usbd_probe, + .name = "hiddev", + .probe = hiddev_usbd_probe, }; int __init hiddev_init(void) diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index 378cfa3c0717..9dd719300002 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c @@ -334,10 +334,10 @@ static struct usb_device_id powermate_devices [] = { MODULE_DEVICE_TABLE (usb, powermate_devices); static struct usb_driver powermate_driver = { - name: "powermate", - probe: powermate_probe, - disconnect: powermate_disconnect, - id_table: powermate_devices, + .name = "powermate", + .probe = powermate_probe, + .disconnect = powermate_disconnect, + .id_table = powermate_devices, }; int powermate_init(void) diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index 31edd4e7b52b..b9b3e0923cb5 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c @@ -287,10 +287,10 @@ static struct usb_device_id usb_kbd_id_table [] = { MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); static struct usb_driver usb_kbd_driver = { - name: "keyboard", - probe: usb_kbd_probe, - disconnect: usb_kbd_disconnect, - id_table: usb_kbd_id_table, + .name = "keyboard", + .probe = usb_kbd_probe, + .disconnect = usb_kbd_disconnect, + .id_table = usb_kbd_id_table, }; static int __init usb_kbd_init(void) diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 22673b42d60a..cfec38752242 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c @@ -195,10 +195,10 @@ static struct usb_device_id usb_mouse_id_table [] = { MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); static struct usb_driver usb_mouse_driver = { - name: "usb_mouse", - probe: usb_mouse_probe, - disconnect: usb_mouse_disconnect, - id_table: usb_mouse_id_table, + .name = "usb_mouse", + .probe = usb_mouse_probe, + .disconnect = usb_mouse_disconnect, + .id_table = usb_mouse_id_table, }; static int __init usb_mouse_init(void) diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index 74bfb073e78d..2d1c8f4ec2d7 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c @@ -428,10 +428,10 @@ static void wacom_disconnect(struct usb_device *dev, void *ptr) } static struct usb_driver wacom_driver = { - name: "wacom", - probe: wacom_probe, - disconnect: wacom_disconnect, - id_table: wacom_ids, + .name = "wacom", + .probe = wacom_probe, + .disconnect = wacom_disconnect, + .id_table = wacom_ids, }; static int __init wacom_init(void) diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index ee3ae7fbd648..ace599597455 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -304,10 +304,10 @@ static void xpad_disconnect(struct usb_device *udev, void *ptr) } static struct usb_driver xpad_driver = { - name: "xpad", - probe: xpad_probe, - disconnect: xpad_disconnect, - id_table: xpad_table, + .name = "xpad", + .probe = xpad_probe, + .disconnect = xpad_disconnect, + .id_table = xpad_table, }; static int __init usb_xpad_init(void) diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 3658e693484f..50d16e4fd6c7 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c @@ -704,12 +704,12 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm static struct file_operations dabusb_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - read: dabusb_read, - ioctl: dabusb_ioctl, - open: dabusb_open, - release: dabusb_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = dabusb_read, + .ioctl = dabusb_ioctl, + .open = dabusb_open, + .release = dabusb_release, }; static int dabusb_find_struct (void) @@ -806,10 +806,10 @@ MODULE_DEVICE_TABLE (usb, dabusb_ids); static struct usb_driver dabusb_driver = { - name: "dabusb", - probe: dabusb_probe, - disconnect: dabusb_disconnect, - id_table: dabusb_ids, + .name = "dabusb", + .probe = dabusb_probe, + .disconnect = dabusb_disconnect, + .id_table = dabusb_ids, }; /* --------------------------------------------------------------------- */ diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c index f4bdcaaa1fd3..ddaef26aa8eb 100644 --- a/drivers/usb/media/dsbr100.c +++ b/drivers/usb/media/dsbr100.c @@ -100,19 +100,19 @@ typedef struct static struct file_operations usb_dsbr100_fops = { - owner: THIS_MODULE, - open: usb_dsbr100_open, - release: usb_dsbr100_close, - ioctl: usb_dsbr100_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = usb_dsbr100_open, + .release = usb_dsbr100_close, + .ioctl = usb_dsbr100_ioctl, + .llseek = no_llseek, }; static struct video_device usb_dsbr100_radio= { - owner: THIS_MODULE, - name: "D-Link DSB R-100 USB radio", - type: VID_TYPE_TUNER, - hardware: VID_HARDWARE_AZTECH, - fops: &usb_dsbr100_fops, + .owner = THIS_MODULE, + .name = "D-Link DSB R-100 USB radio", + .type = VID_TYPE_TUNER, + .hardware = VID_HARDWARE_AZTECH, + .fops = &usb_dsbr100_fops, }; static int users = 0; @@ -125,10 +125,10 @@ static struct usb_device_id usb_dsbr100_table [] = { MODULE_DEVICE_TABLE (usb, usb_dsbr100_table); static struct usb_driver usb_dsbr100_driver = { - name: "dsbr100", - probe: usb_dsbr100_probe, - disconnect: usb_dsbr100_disconnect, - id_table: usb_dsbr100_table, + .name = "dsbr100", + .probe = usb_dsbr100_probe, + .disconnect = usb_dsbr100_disconnect, + .id_table = usb_dsbr100_table, }; diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index e5b3f9144fb4..9dff57ad4f38 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c @@ -9,7 +9,6 @@ * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org> * Changes by Claudio Matsuoka <claudio@conectiva.com> * Original SAA7111A code by Dave Perks <dperks@ibm.net> - * Kernel I2C interface adapted from nt1003 driver * URB error messages from pwc driver by Nemosoft * generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox * Memory management (rvmalloc) code from bttv driver, by Gerd Knorr and others @@ -61,7 +60,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.60a for Linux 2.5" +#define DRIVER_VERSION "v1.61 for Linux 2.5" #define EMAIL "mmcclell@bigfoot.com" #define DRIVER_AUTHOR "Mark McClelland <mmcclell@bigfoot.com> & Bret Wallach \ & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \ @@ -72,7 +71,6 @@ #define ENABLE_Y_QUANTABLE 1 #define ENABLE_UV_QUANTABLE 1 -/* If you change this, you must also change the MODULE_PARM definition */ #define OV511_MAX_UNIT_VIDEO 16 /* Pixel count * bytes per YUV420 pixel (1.5) */ @@ -127,7 +125,6 @@ static int framedrop = -1; static int fastset; static int force_palette; -static int tuner = -1; static int backlight; static int unit_video[OV511_MAX_UNIT_VIDEO]; static int remove_zeros; @@ -194,11 +191,9 @@ MODULE_PARM(fastset, "i"); MODULE_PARM_DESC(fastset, "Allows picture settings to take effect immediately"); MODULE_PARM(force_palette, "i"); MODULE_PARM_DESC(force_palette, "Force the palette to a specific value"); -MODULE_PARM(tuner, "i"); -MODULE_PARM_DESC(tuner, "Set tuner type, if not autodetected"); MODULE_PARM(backlight, "i"); MODULE_PARM_DESC(backlight, "For objects that are lit from behind"); -MODULE_PARM(unit_video, "0-16i"); +MODULE_PARM(unit_video, "1-" __MODULE_STRING(OV511_MAX_UNIT_VIDEO) "i"); MODULE_PARM_DESC(unit_video, "Force use of specific minor number(s). 0 is not allowed."); MODULE_PARM(remove_zeros, "i"); @@ -337,12 +332,14 @@ static struct symbolic_list urb_errlist[] = { **********************************************************************/ static void ov51x_clear_snapshot(struct usb_ov511 *); -static int ov51x_check_snapshot(struct usb_ov511 *); -static inline int sensor_get_picture(struct usb_ov511 *, +static inline int sensor_get_picture(struct usb_ov511 *, struct video_picture *); +#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) static int sensor_get_exposure(struct usb_ov511 *, unsigned char *); static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +static int ov51x_check_snapshot(struct usb_ov511 *); +#endif /********************************************************************** * Memory management @@ -351,7 +348,7 @@ static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int, /* Here we want the physical address of the memory. * This is used when initializing the contents of the area. */ -static inline unsigned long +static inline unsigned long kvirt_to_pa(unsigned long adr) { unsigned long kva, ret; @@ -384,7 +381,7 @@ rvmalloc(unsigned long size) return mem; } -static void +static void rvfree(void *mem, unsigned long size) { unsigned long adr; @@ -412,13 +409,13 @@ static struct proc_dir_entry *ov511_proc_entry = NULL; extern struct proc_dir_entry *video_proc_entry; static struct file_operations ov511_control_fops = { - ioctl: ov51x_control_ioctl, + .ioctl = ov51x_control_ioctl, }; #define YES_NO(x) ((x) ? "yes" : "no") /* /proc/video/ov511/<minor#>/info */ -static int +static int ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -490,13 +487,13 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof, * When the camera's button is pressed, the output of this will change from a * 0 to a 1 (ASCII). It will retain this value until it is read, after which * it will reset to zero. - * + * * SECURITY NOTE: Since reading this file can change the state of the snapshot * status, it is important for applications that open it to keep it locked * against access by other processes, using flock() or a similar mechanism. No * locking is provided by this driver. */ -static int +static int ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -528,7 +525,7 @@ ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof, return len; } -static void +static void create_proc_ov511_cam(struct usb_ov511 *ov) { char dirname[10]; @@ -579,11 +576,11 @@ create_proc_ov511_cam(struct usb_ov511 *ov) unlock_kernel(); } -static void +static void destroy_proc_ov511_cam(struct usb_ov511 *ov) { char dirname[10]; - + if (!ov || !ov->proc_devdir) return; @@ -616,7 +613,7 @@ destroy_proc_ov511_cam(struct usb_ov511 *ov) ov->proc_devdir = NULL; } -static void +static void proc_ov511_create(void) { /* No current standard here. Alan prefers /proc/video/ as it keeps @@ -637,7 +634,7 @@ proc_ov511_create(void) err("Unable to create /proc/video/ov511"); } -static void +static void proc_ov511_destroy(void) { PDEBUG(3, "removing /proc/video/ov511"); @@ -656,7 +653,7 @@ proc_ov511_destroy(void) **********************************************************************/ /* Write an OV51x register */ -static int +static int reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) { int rc; @@ -669,7 +666,7 @@ reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) usb_sndctrlpipe(ov->dev, 0), (ov->bclass == BCL_OV518)?1:2 /* REG_IO */, USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, (__u16)reg, &ov->cbuf[0], 1, HZ); + 0, (__u16)reg, &ov->cbuf[0], 1, HZ); up(&ov->cbuf_lock); if (rc < 0) @@ -680,7 +677,7 @@ reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) /* Read from an OV51x register */ /* returns: negative is error, pos or zero is data */ -static int +static int reg_r(struct usb_ov511 *ov, unsigned char reg) { int rc; @@ -691,13 +688,13 @@ reg_r(struct usb_ov511 *ov, unsigned char reg) (ov->bclass == BCL_OV518)?1:3 /* REG_IO */, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, (__u16)reg, &ov->cbuf[0], 1, HZ); - - PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]); - - if (rc < 0) + + if (rc < 0) { err("reg read: error %d: %s", rc, symbolic(urb_errlist, rc)); - else - rc = ov->cbuf[0]; + } else { + rc = ov->cbuf[0]; + PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]); + } up(&ov->cbuf_lock); @@ -707,10 +704,10 @@ reg_r(struct usb_ov511 *ov, unsigned char reg) /* * Writes bits at positions specified by mask to an OV51x reg. Bits that are in * the same position as 1's in "mask" are cleared and set to "value". Bits - * that are in the same position as 0's in "mask" are preserved, regardless + * that are in the same position as 0's in "mask" are preserved, regardless * of their respective state in "value". */ -static int +static int reg_w_mask(struct usb_ov511 *ov, unsigned char reg, unsigned char value, @@ -735,7 +732,7 @@ reg_w_mask(struct usb_ov511 *ov, * Writes multiple (n) byte value to a single register. Only valid with certain * registers (0x30 and 0xc4 - 0xce). */ -static int +static int ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n) { int rc; @@ -760,7 +757,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n) return rc; } -static int +static int ov511_upload_quan_tables(struct usb_ov511 *ov) { unsigned char *pYTable = yQuanTable511; @@ -770,10 +767,8 @@ ov511_upload_quan_tables(struct usb_ov511 *ov) PDEBUG(4, "Uploading quantization tables"); - for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) - { - if (ENABLE_Y_QUANTABLE) - { + for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) { + if (ENABLE_Y_QUANTABLE) { val0 = *pYTable++; val1 = *pYTable++; val0 &= 0x0f; @@ -784,8 +779,7 @@ ov511_upload_quan_tables(struct usb_ov511 *ov) return rc; } - if (ENABLE_UV_QUANTABLE) - { + if (ENABLE_UV_QUANTABLE) { val0 = *pUVTable++; val1 = *pUVTable++; val0 &= 0x0f; @@ -803,7 +797,7 @@ ov511_upload_quan_tables(struct usb_ov511 *ov) } /* OV518 quantization tables are 8x4 (instead of 8x8) */ -static int +static int ov518_upload_quan_tables(struct usb_ov511 *ov) { unsigned char *pYTable = yQuanTable518; @@ -813,10 +807,8 @@ ov518_upload_quan_tables(struct usb_ov511 *ov) PDEBUG(4, "Uploading quantization tables"); - for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) - { - if (ENABLE_Y_QUANTABLE) - { + for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) { + if (ENABLE_Y_QUANTABLE) { val0 = *pYTable++; val1 = *pYTable++; val0 &= 0x0f; @@ -827,8 +819,7 @@ ov518_upload_quan_tables(struct usb_ov511 *ov) return rc; } - if (ENABLE_UV_QUANTABLE) - { + if (ENABLE_UV_QUANTABLE) { val0 = *pUVTable++; val1 = *pUVTable++; val0 &= 0x0f; @@ -845,16 +836,16 @@ ov518_upload_quan_tables(struct usb_ov511 *ov) return 0; } -static int +static int ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type) { int rc; - + /* Setting bit 0 not allowed on 518/518Plus */ if (ov->bclass == BCL_OV518) reset_type &= 0xfe; - PDEBUG(4, "Reset: type=0x%X", reset_type); + PDEBUG(4, "Reset: type=0x%02X", reset_type); rc = reg_w(ov, R51x_SYS_RESET, reset_type); rc = reg_w(ov, R51x_SYS_RESET, 0); @@ -876,7 +867,7 @@ ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type) * This is normally only called from i2c_w(). Note that this function * always succeeds regardless of whether the sensor is present and working. */ -static int +static int ov518_i2c_write_internal(struct usb_ov511 *ov, unsigned char reg, unsigned char value) @@ -901,7 +892,7 @@ ov518_i2c_write_internal(struct usb_ov511 *ov, } /* NOTE: Do not call this function directly! */ -static int +static int ov511_i2c_write_internal(struct usb_ov511 *ov, unsigned char reg, unsigned char value) @@ -917,7 +908,7 @@ ov511_i2c_write_internal(struct usb_ov511 *ov, if (rc < 0) return rc; /* Write "value" to I2C data port of OV511 */ - rc = reg_w(ov, R51x_I2C_DATA, value); + rc = reg_w(ov, R51x_I2C_DATA, value); if (rc < 0) return rc; /* Initiate 3-byte write cycle */ @@ -931,7 +922,7 @@ ov511_i2c_write_internal(struct usb_ov511 *ov, if ((rc&2) == 0) /* Ack? */ break; #if 0 - /* I2C abort */ + /* I2C abort */ reg_w(ov, R511_I2C_CTL, 0x10); #endif if (--retries < 0) { @@ -948,7 +939,7 @@ ov511_i2c_write_internal(struct usb_ov511 *ov, * This is normally only called from i2c_r(). Note that this function * always succeeds regardless of whether the sensor is present and working. */ -static int +static int ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) { int rc, value; @@ -974,7 +965,7 @@ ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) /* NOTE: Do not call this function directly! * returns: negative is error, pos or zero is data */ -static int +static int ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) { int rc, value, retries; @@ -996,7 +987,7 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) if ((rc&2) == 0) /* Ack? */ break; - /* I2C abort */ + /* I2C abort */ reg_w(ov, R511_I2C_CTL, 0x10); if (--retries < 0) { @@ -1018,7 +1009,7 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) if ((rc&2) == 0) /* Ack? */ break; - /* I2C abort */ + /* I2C abort */ rc = reg_w(ov, R511_I2C_CTL, 0x10); if (rc < 0) return rc; @@ -1031,17 +1022,17 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) value = reg_r(ov, R51x_I2C_DATA); PDEBUG(5, "0x%02X:0x%02X", reg, value); - + /* This is needed to make i2c_w() work */ rc = reg_w(ov, R511_I2C_CTL, 0x05); if (rc < 0) return rc; - + return value; } /* returns: negative is error, pos or zero is data */ -static int +static int i2c_r(struct usb_ov511 *ov, unsigned char reg) { int rc; @@ -1058,7 +1049,7 @@ i2c_r(struct usb_ov511 *ov, unsigned char reg) return rc; } -static int +static int i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) { int rc; @@ -1076,7 +1067,7 @@ i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) } /* Do not call this function directly! */ -static int +static int ov51x_i2c_write_mask_internal(struct usb_ov511 *ov, unsigned char reg, unsigned char value, @@ -1109,10 +1100,10 @@ ov51x_i2c_write_mask_internal(struct usb_ov511 *ov, /* Writes bits at positions specified by mask to an I2C reg. Bits that are in * the same position as 1's in "mask" are cleared and set to "value". Bits - * that are in the same position as 0's in "mask" are preserved, regardless + * that are in the same position as 0's in "mask" are preserved, regardless * of their respective state in "value". */ -static int +static int i2c_w_mask(struct usb_ov511 *ov, unsigned char reg, unsigned char value, @@ -1132,7 +1123,7 @@ i2c_w_mask(struct usb_ov511 *ov, * when calling this. This should not be called from outside the i2c I/O * functions. */ -static inline int +static inline int i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave) { int rc; @@ -1146,8 +1137,10 @@ i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave) return 0; } +#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) + /* Write to a specific I2C slave ID and register, using the specified mask */ -static int +static int i2c_w_slave(struct usb_ov511 *ov, unsigned char slave, unsigned char reg, @@ -1166,7 +1159,7 @@ i2c_w_slave(struct usb_ov511 *ov, out: /* Restore primary IDs */ - if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) + if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) err("Couldn't restore primary I2C slave"); up(&ov->i2c_lock); @@ -1174,7 +1167,7 @@ out: } /* Read from a specific I2C slave ID and register */ -static int +static int i2c_r_slave(struct usb_ov511 *ov, unsigned char slave, unsigned char reg) @@ -1194,15 +1187,17 @@ i2c_r_slave(struct usb_ov511 *ov, out: /* Restore primary IDs */ - if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) + if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) err("Couldn't restore primary I2C slave"); up(&ov->i2c_lock); return rc; } +#endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) */ + /* Sets I2C read and write slave IDs. Returns <0 for error */ -static int +static int ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) { int rc; @@ -1221,7 +1216,7 @@ out: return rc; } -static int +static int write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals) { int rc; @@ -1242,8 +1237,8 @@ write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals) return 0; } -#ifdef OV511_DEBUG -static void +#ifdef OV511_DEBUG +static void dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn) { int i; @@ -1251,18 +1246,18 @@ dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn) for (i = reg1; i <= regn; i++) { rc = i2c_r(ov, i); - info("Sensor[0x%X] = 0x%X", i, rc); + info("Sensor[0x%02X] = 0x%02X", i, rc); } } -static void +static void dump_i2c_regs(struct usb_ov511 *ov) { info("I2C REGS"); dump_i2c_range(ov, 0x00, 0x7C); } -static void +static void dump_reg_range(struct usb_ov511 *ov, int reg1, int regn) { int i; @@ -1270,12 +1265,12 @@ dump_reg_range(struct usb_ov511 *ov, int reg1, int regn) for (i = reg1; i <= regn; i++) { rc = reg_r(ov, i); - info("OV511[0x%X] = 0x%X", i, rc); + info("OV511[0x%02X] = 0x%02X", i, rc); } } /* FIXME: Should there be an OV518 version of this? */ -static void +static void ov511_dump_regs(struct usb_ov511 *ov) { info("CAMERA INTERFACE REGS"); @@ -1302,29 +1297,15 @@ ov511_dump_regs(struct usb_ov511 *ov) } #endif -/********************************************************************** - * - * Kernel I2C Interface (not supported with OV518/OV518+) - * - **********************************************************************/ - -/* For as-yet unimplemented I2C interface */ -static void -call_i2c_clients(struct usb_ov511 *ov, unsigned int cmd, - void *arg) -{ - /* Do nothing */ -} - /*****************************************************************************/ /* Temporarily stops OV511 from functioning. Must do this before changing * registers while the camera is streaming */ -static inline int +static inline int ov51x_stop(struct usb_ov511 *ov) { PDEBUG(4, "stopping"); - ov->stopped = 1; + ov->stopped = 1; if (ov->bclass == BCL_OV518) return (reg_w_mask(ov, R51x_SYS_RESET, 0x3a, 0x3a)); else @@ -1333,12 +1314,12 @@ ov51x_stop(struct usb_ov511 *ov) /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not * actually stopped (for performance). */ -static inline int +static inline int ov51x_restart(struct usb_ov511 *ov) { if (ov->stopped) { PDEBUG(4, "restarting"); - ov->stopped = 0; + ov->stopped = 0; /* Reinitialize the stream */ if (ov->bclass == BCL_OV518) @@ -1351,7 +1332,7 @@ ov51x_restart(struct usb_ov511 *ov) } /* Resets the hardware snapshot button */ -static void +static void ov51x_clear_snapshot(struct usb_ov511 *ov) { if (ov->bclass == BCL_OV511) { @@ -1363,12 +1344,12 @@ ov51x_clear_snapshot(struct usb_ov511 *ov) } else { err("clear snap: invalid bridge type"); } - } +#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) /* Checks the status of the snapshot button. Returns 1 if it was pressed since * it was last cleared, and zero in all other cases (including errors) */ -static int +static int ov51x_check_snapshot(struct usb_ov511 *ov) { int ret, status = 0; @@ -1388,19 +1369,20 @@ ov51x_check_snapshot(struct usb_ov511 *ov) return status; } +#endif /* This does an initial reset of an OmniVision sensor and ensures that I2C * is synchronized. Returns <0 for failure. */ -static int +static int init_ov_sensor(struct usb_ov511 *ov) { int i, success; - /* Reset the sensor */ + /* Reset the sensor */ if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO; - /* Wait for it to initialize */ + /* Wait for it to initialize */ schedule_timeout (1 + 150 * HZ / 1000); for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { @@ -1410,9 +1392,9 @@ init_ov_sensor(struct usb_ov511 *ov) continue; } - /* Reset the sensor */ + /* Reset the sensor */ if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO; - /* Wait for it to initialize */ + /* Wait for it to initialize */ schedule_timeout(1 + 150 * HZ / 1000); /* Dummy read to sync I2C */ if (i2c_r(ov, 0x00) < 0) return -EIO; @@ -1420,13 +1402,13 @@ init_ov_sensor(struct usb_ov511 *ov) if (!success) return -EIO; - + PDEBUG(1, "I2C synced in %d attempt(s)", i); return 0; } -static int +static int ov511_set_packet_size(struct usb_ov511 *ov, int size) { int alt, mult; @@ -1468,7 +1450,7 @@ ov511_set_packet_size(struct usb_ov511 *ov, int size) if (reg_w(ov, R51x_FIFO_PSIZE, mult) < 0) return -EIO; - + if (usb_set_interface(ov->dev, ov->iface, alt) < 0) { err("Set packet size: set interface error"); return -EBUSY; @@ -1488,7 +1470,7 @@ ov511_set_packet_size(struct usb_ov511 *ov, int size) /* Note: Unlike the OV511/OV511+, the size argument does NOT include the * optional packet number byte. The actual size *is* stored in ov->packet_size, * though. */ -static int +static int ov518_set_packet_size(struct usb_ov511 *ov, int size) { int alt; @@ -1550,7 +1532,6 @@ ov511_init_compression(struct usb_ov511 *ov) int rc = 0; if (!ov->compress_inited) { - reg_w(ov, 0x70, phy); reg_w(ov, 0x71, phuv); reg_w(ov, 0x72, pvy); @@ -1568,7 +1549,7 @@ ov511_init_compression(struct usb_ov511 *ov) } ov->compress_inited = 1; -out: +out: return rc; } @@ -1579,7 +1560,6 @@ ov518_init_compression(struct usb_ov511 *ov) int rc = 0; if (!ov->compress_inited) { - if (ov518_upload_quan_tables(ov) < 0) { err("Error uploading quantization tables"); rc = -EIO; @@ -1588,7 +1568,7 @@ ov518_init_compression(struct usb_ov511 *ov) } ov->compress_inited = 1; -out: +out: return rc; } @@ -2130,7 +2110,7 @@ sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val) #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */ /* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */ -static inline void +static inline void ov51x_led_control(struct usb_ov511 *ov, int enable) { PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); @@ -2181,7 +2161,7 @@ sensor_set_light_freq(struct usb_ov511 *ov, int freq) i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80); i2c_w(ov, 0x2b, sixty?0x00:0xac); i2c_w_mask(ov, 0x76, 0x01, 0x01); - break; + break; case SEN_OV6620: case SEN_OV6630: i2c_w(ov, 0x2b, sixty?0xa8:0x28); @@ -2269,7 +2249,7 @@ sensor_set_auto_brightness(struct usb_ov511 *ov, int enable) */ static inline int sensor_set_auto_exposure(struct usb_ov511 *ov, int enable) -{ +{ PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); switch (ov->sensor) { @@ -2281,7 +2261,7 @@ sensor_set_auto_exposure(struct usb_ov511 *ov, int enable) case SEN_OV76BE: case SEN_OV8600: i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01); - break; + break; case SEN_OV6630: i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10); break; @@ -2318,7 +2298,7 @@ sensor_set_backlight(struct usb_ov511 *ov, int enable) i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0); i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02); - break; + break; case SEN_OV6620: i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0); i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); @@ -2378,7 +2358,7 @@ sensor_set_mirror(struct usb_ov511 *ov, int enable) /* Returns number of bits per pixel (regardless of where they are located; * planar or not), or zero for unsupported format. */ -static inline int +static inline int get_depth(int palette) { switch (palette) { @@ -2390,7 +2370,7 @@ get_depth(int palette) } /* Bytes per frame. Used by read(). Return of 0 indicates error */ -static inline long int +static inline long int get_frame_length(struct ov511_frame *frame) { if (!frame) @@ -2785,12 +2765,12 @@ ov518_mode_init_regs(struct usb_ov511 *ov, return -EINVAL; } else { hi_res = 0; - } + } if (ov51x_stop(ov) < 0) return -EIO; - /******** Set the mode ********/ + /******** Set the mode ********/ reg_w(ov, 0x2b, 0); reg_w(ov, 0x2c, 0); @@ -2906,10 +2886,10 @@ mode_init_regs(struct usb_ov511 *ov, rc = -EINVAL; break; case SEN_SAA7111A: -// rc = mode_init_saa_sensor_regs(ov, width, height, mode, +// rc = mode_init_saa_sensor_regs(ov, width, height, mode, // sub_flag); - PDEBUG(1, "SAA status = 0X%x", i2c_r(ov, 0x1f)); + PDEBUG(1, "SAA status = 0x%02X", i2c_r(ov, 0x1f)); break; default: err("Unknown sensor"); @@ -2952,7 +2932,7 @@ mode_init_regs(struct usb_ov511 *ov, /* This sets the default image parameters. This is useful for apps that use * read() and do not set these. */ -static int +static int ov51x_set_default_params(struct usb_ov511 *ov) { int i; @@ -2988,7 +2968,7 @@ ov51x_set_default_params(struct usb_ov511 *ov) **********************************************************************/ /* Set analog input port of decoder */ -static int +static int decoder_set_input(struct usb_ov511 *ov, int input) { PDEBUG(4, "port %d", input); @@ -3010,7 +2990,7 @@ decoder_set_input(struct usb_ov511 *ov, int input) } /* Get ASCII name of video input */ -static int +static int decoder_get_input_name(struct usb_ov511 *ov, int input, char *name) { switch (ov->sensor) { @@ -3022,7 +3002,6 @@ decoder_get_input_name(struct usb_ov511 *ov, int input, char *name) sprintf(name, "CVBS-%d", input); else // if (input < 8) sprintf(name, "S-Video-%d", input - 4); - break; } default: @@ -3033,7 +3012,7 @@ decoder_get_input_name(struct usb_ov511 *ov, int input, char *name) } /* Set norm (NTSC, PAL, SECAM, AUTO) */ -static int +static int decoder_set_norm(struct usb_ov511 *ov, int norm) { PDEBUG(4, "%d", norm); @@ -3048,7 +3027,7 @@ decoder_set_norm(struct usb_ov511 *ov, int norm) reg_e = 0x00; /* NTSC M / PAL BGHI */ } else if (norm == VIDEO_MODE_PAL) { reg_8 = 0x00; /* 50 Hz */ - reg_e = 0x00; /* NTSC M / PAL BGHI */ + reg_e = 0x00; /* NTSC M / PAL BGHI */ } else if (norm == VIDEO_MODE_AUTO) { reg_8 = 0x80; /* Auto field detect */ reg_e = 0x00; /* NTSC M / PAL BGHI */ @@ -3079,7 +3058,7 @@ decoder_set_norm(struct usb_ov511 *ov, int norm) /* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the * image at pOut is specified by w. */ -static inline void +static inline void make_8x8(unsigned char *pIn, unsigned char *pOut, int w) { unsigned char *pOut1 = pOut; @@ -3092,7 +3071,6 @@ make_8x8(unsigned char *pIn, unsigned char *pOut, int w) } pOut += w; } - } /* @@ -3214,7 +3192,7 @@ yuv420raw_to_yuv420p(struct ov511_frame *frame, * accordingly. Returns -ENXIO if decompressor is not available, otherwise * returns 0 if no other error. */ -static int +static int request_decompressor(struct usb_ov511 *ov) { if (!ov) @@ -3270,7 +3248,7 @@ request_decompressor(struct usb_ov511 *ov) /* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even * if ov->decomp_ops is NULL. */ -static void +static void release_decompressor(struct usb_ov511 *ov) { int released = 0; /* Did we actually do anything? */ @@ -3286,14 +3264,14 @@ release_decompressor(struct usb_ov511 *ov) } ov->decomp_ops = NULL; - + unlock_kernel(); if (released) PDEBUG(3, "Decompressor released"); } -static void +static void decompress(struct usb_ov511 *ov, struct ov511_frame *frame, unsigned char *pIn0, unsigned char *pOut0) { @@ -3303,7 +3281,7 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame, PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd); - if (frame->format == VIDEO_PALETTE_GREY + if (frame->format == VIDEO_PALETTE_GREY && ov->decomp_ops->decomp_400) { int ret = ov->decomp_ops->decomp_400( pIn0, @@ -3313,7 +3291,7 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame, frame->rawheight, frame->bytes_recvd); PDEBUG(4, "DEBUG: decomp_400 returned %d", ret); - } else if (frame->format != VIDEO_PALETTE_GREY + } else if (frame->format != VIDEO_PALETTE_GREY && ov->decomp_ops->decomp_420) { int ret = ov->decomp_ops->decomp_420( pIn0, @@ -3328,6 +3306,12 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame, } } +/********************************************************************** + * + * Format conversion + * + **********************************************************************/ + /* Fuses even and odd fields together, and doubles width. * INPUT: an odd field followed by an even field at pIn0, in YUV planar format * OUTPUT: a normal YUV planar image, with correct aspect ratio @@ -3432,7 +3416,7 @@ ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame) if (frame->compressed) decompress(ov, frame, frame->rawdata, frame->tempdata); else - yuv420raw_to_yuv420p(frame, frame->rawdata, + yuv420raw_to_yuv420p(frame, frame->rawdata, frame->tempdata); deinterlace(frame, RAWFMT_YUV420, frame->tempdata, @@ -3452,11 +3436,11 @@ ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame) * 3. Convert from YUV planar to destination format, if necessary * 4. Fix the RGB offset, if necessary */ -static void +static void ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame) { if (dumppix) { - memset(frame->data, 0, + memset(frame->data, 0, MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)); PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd); memcpy(frame->data, frame->rawdata, frame->bytes_recvd); @@ -3482,7 +3466,7 @@ ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame) * **********************************************************************/ -static inline void +static inline void ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) { int num, offset; @@ -3518,7 +3502,7 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) /* Frame end */ if (in[8] & 0x80) { - ts = (struct timeval *)(frame->data + ts = (struct timeval *)(frame->data + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight)); do_gettimeofday(ts); @@ -3656,7 +3640,7 @@ check_middle: } } -static inline void +static inline void ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n) { int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight); @@ -3796,7 +3780,7 @@ check_middle: } else { if (frame->bytes_recvd + copied + 8 <= max_raw) { - memcpy(frame->rawdata + memcpy(frame->rawdata + frame->bytes_recvd + copied, in + read, 8); copied += 8; @@ -3810,7 +3794,7 @@ check_middle: } } -static void +static void ov51x_isoc_irq(struct urb *urb) { int i; @@ -3896,7 +3880,7 @@ ov51x_isoc_irq(struct urb *urb) * ***************************************************************************/ -static int +static int ov51x_init_isoc(struct usb_ov511 *ov) { struct urb *urb; @@ -3991,7 +3975,7 @@ ov51x_init_isoc(struct usb_ov511 *ov) return 0; } -static void +static void ov51x_unlink_isoc(struct usb_ov511 *ov) { int n; @@ -4006,7 +3990,7 @@ ov51x_unlink_isoc(struct usb_ov511 *ov) } } -static void +static void ov51x_stop_isoc(struct usb_ov511 *ov) { if (!ov->streaming || !ov->dev) @@ -4024,7 +4008,7 @@ ov51x_stop_isoc(struct usb_ov511 *ov) ov51x_unlink_isoc(ov); } -static int +static int ov51x_new_frame(struct usb_ov511 *ov, int framenum) { struct ov511_frame *frame; @@ -4046,7 +4030,7 @@ ov51x_new_frame(struct usb_ov511 *ov, int framenum) frame = &ov->frame[framenum]; - PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum, + PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum, frame->width, frame->height); frame->grabstate = FRAME_GRABBING; @@ -4075,12 +4059,12 @@ ov51x_new_frame(struct usb_ov511 *ov, int framenum) * ***************************************************************************/ -/* +/* * - You must acquire buf_lock before entering this function. * - Because this code will free any non-null pointer, you must be sure to null * them if you explicitly free them somewhere else! */ -static void +static void ov51x_do_dealloc(struct usb_ov511 *ov) { int i; @@ -4124,7 +4108,7 @@ ov51x_do_dealloc(struct usb_ov511 *ov) PDEBUG(4, "leaving"); } -static int +static int ov51x_alloc(struct usb_ov511 *ov) { int i; @@ -4171,12 +4155,12 @@ ov51x_alloc(struct usb_ov511 *ov) for (i = 0; i < OV511_NUMFRAMES; i++) { ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h); - ov->frame[i].rawdata = ov->rawfbuf + ov->frame[i].rawdata = ov->rawfbuf + i * MAX_RAW_DATA_SIZE(w, h); - ov->frame[i].tempdata = ov->tempfbuf + ov->frame[i].tempdata = ov->tempfbuf + i * MAX_RAW_DATA_SIZE(w, h); - ov->frame[i].compbuf = + ov->frame[i].compbuf = (unsigned char *) __get_free_page(GFP_KERNEL); if (!ov->frame[i].compbuf) goto error; @@ -4196,7 +4180,7 @@ error: return -ENOMEM; } -static void +static void ov51x_dealloc(struct usb_ov511 *ov, int now) { PDEBUG(4, "entered"); @@ -4212,7 +4196,7 @@ ov51x_dealloc(struct usb_ov511 *ov, int now) * ***************************************************************************/ -static int +static int ov51x_v4l1_open(struct inode *inode, struct file *file) { struct video_device *vdev = video_devdata(file); @@ -4224,17 +4208,18 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) down(&ov->lock); err = -EBUSY; - if (ov->user) + if (ov->user) goto out; - err = -ENOMEM; - if (ov51x_alloc(ov)) + err = ov51x_alloc(ov); + if (err < 0) goto out; ov->sub_flag = 0; /* In case app doesn't set them... */ - if (ov51x_set_default_params(ov) < 0) + err = ov51x_set_default_params(ov); + if (err < 0) goto out; /* Make sure frames are reset */ @@ -4243,7 +4228,7 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) ov->frame[i].bytes_read = 0; } - /* If compression is on, make sure now that a + /* If compression is on, make sure now that a * decompressor can be loaded */ if (ov->compress && !ov->decomp_ops) { err = request_decompressor(ov); @@ -4268,14 +4253,14 @@ out: return err; } -static int +static int ov51x_v4l1_close(struct inode *inode, struct file *file) { struct video_device *vdev = file->private_data; struct usb_ov511 *ov = vdev->priv; PDEBUG(4, "ov511_close"); - + down(&ov->lock); ov->user--; @@ -4303,6 +4288,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) kfree(ov); ov = NULL; } + file->private_data = NULL; return 0; @@ -4318,7 +4304,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, PDEBUG(5, "IOCtl: 0x%X", cmd); if (!ov->dev) - return -EIO; + return -EIO; switch (cmd) { case VIDIOCGCAP: @@ -4331,10 +4317,8 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, sprintf(b->name, "%s USB Camera", symbolic(brglist, ov->bridge)); b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE; - if (ov->has_tuner) - b->type |= VID_TYPE_TUNER; b->channels = ov->num_inputs; - b->audios = ov->has_audio_proc ? 1:0; + b->audios = 0; b->maxwidth = ov->maxwidth; b->maxheight = ov->maxheight; b->minwidth = ov->minwidth; @@ -4354,11 +4338,10 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, } v->norm = ov->norm; - v->type = (ov->has_tuner) ? VIDEO_TYPE_TV : VIDEO_TYPE_CAMERA; - v->flags = (ov->has_tuner) ? VIDEO_VC_TUNER : 0; - v->flags |= (ov->has_audio_proc) ? VIDEO_VC_AUDIO : 0; + v->type = VIDEO_TYPE_CAMERA; + v->flags = 0; // v->flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0; - v->tuners = (ov->has_tuner) ? 1:0; + v->tuners = 0; decoder_get_input_name(ov, v->channel, v->name); return 0; @@ -4585,7 +4568,7 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, return -EINVAL; } - if (vm->width > ov->maxwidth + if (vm->width > ov->maxwidth || vm->height > ov->maxheight) { err("VIDIOCMCAPTURE: requested dimensions too big"); return -EINVAL; @@ -4641,7 +4624,6 @@ ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, struct ov511_frame *frame; int rc; - if (fnum >= OV511_NUMFRAMES) { err("VIDIOCSYNC: invalid frame (%d)", fnum); return -EINVAL; @@ -4676,7 +4658,7 @@ redo: return ret; goto redo; } - /* Fall through */ + /* Fall through */ case FRAME_DONE: if (ov->snap_enabled && !frame->snapshot) { int ret; @@ -4728,92 +4710,6 @@ redo: return 0; } - case VIDIOCGTUNER: - { - struct video_tuner *v = arg; - - PDEBUG(4, "VIDIOCGTUNER"); - - if (!ov->has_tuner || v->tuner) // Only tuner 0 - return -EINVAL; - - strcpy(v->name, "Television"); - - // FIXME: Need a way to get the real values - v->rangelow = 0; - v->rangehigh = ~0; - - v->flags = VIDEO_TUNER_PAL | VIDEO_TUNER_NTSC - | VIDEO_TUNER_SECAM; - v->mode = 0; /* FIXME: Not sure what this is yet */ - v->signal = 0xFFFF; /* unknown */ - - call_i2c_clients(ov, cmd, v); - - return 0; - } - case VIDIOCSTUNER: - { - struct video_tuner *v = arg; - int err; - - PDEBUG(4, "VIDIOCSTUNER"); - - /* Only no or one tuner for now */ - if (!ov->has_tuner || v->tuner) - return -EINVAL; - - /* and it only has certain valid modes */ - if (v->mode != VIDEO_MODE_PAL && - v->mode != VIDEO_MODE_NTSC && - v->mode != VIDEO_MODE_SECAM) - return -EOPNOTSUPP; - - /* Is this right/necessary? */ - err = decoder_set_norm(ov, v->mode); - if (err) - return err; - - call_i2c_clients(ov, cmd, v); - - return 0; - } - case VIDIOCGFREQ: - { - unsigned long v = *((unsigned long *) arg); - - PDEBUG(4, "VIDIOCGFREQ"); - - if (!ov->has_tuner) - return -EINVAL; - - v = ov->freq; -#if 0 - /* FIXME: this is necessary for testing */ - v = 46*16; -#endif - return 0; - } - case VIDIOCSFREQ: - { - unsigned long v = *((unsigned long *) arg); - - PDEBUG(4, "VIDIOCSFREQ: %lx", v); - - if (!ov->has_tuner) - return -EINVAL; - - ov->freq = v; - call_i2c_clients(ov, cmd, &v); - - return 0; - } - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - { - /* FIXME: Implement this... */ - return 0; - } default: PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd); return -ENOIOCTLCMD; @@ -4822,7 +4718,7 @@ redo: return 0; } -static int +static int ov51x_v4l1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -4839,7 +4735,7 @@ ov51x_v4l1_ioctl(struct inode *inode, struct file *file, return rc; } -static inline int +static inline int ov51x_v4l1_read(struct file *file, char *buf, size_t cnt, loff_t *ppos) { struct video_device *vdev = file->private_data; @@ -4904,7 +4800,7 @@ restart: /* Wait while we're grabbing the image */ PDEBUG(4, "Waiting image grabbing"); - rc = wait_event_interruptible(frame->wq, + rc = wait_event_interruptible(frame->wq, (frame->grabstate == FRAME_DONE) || (frame->grabstate == FRAME_ERROR)); @@ -4951,7 +4847,7 @@ restart: get_frame_length(frame)); /* copy bytes to user space; we allow for partials reads */ -// if ((count + frame->bytes_read) +// if ((count + frame->bytes_read) // > get_frame_length((struct ov511_frame *)frame)) // count = frame->scanlength - frame->bytes_read; @@ -5036,25 +4932,25 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) } static struct file_operations ov511_fops = { - owner: THIS_MODULE, - open: ov51x_v4l1_open, - release: ov51x_v4l1_close, - read: ov51x_v4l1_read, - mmap: ov51x_v4l1_mmap, - ioctl: ov51x_v4l1_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = ov51x_v4l1_open, + .release = ov51x_v4l1_close, + .read = ov51x_v4l1_read, + .mmap = ov51x_v4l1_mmap, + .ioctl = ov51x_v4l1_ioctl, + .llseek = no_llseek, }; static struct video_device vdev_template = { - owner: THIS_MODULE, - name: "OV511 USB Camera", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_OV511, - fops: &ov511_fops, + .owner = THIS_MODULE, + .name = "OV511 USB Camera", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_OV511, + .fops = &ov511_fops, }; #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) -static int +static int ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ularg) { @@ -5278,7 +5174,7 @@ ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses * the same register settings as the OV7610, since they are very similar. */ -static int +static int ov7xx0_configure(struct usb_ov511 *ov) { int i, success; @@ -5429,7 +5325,7 @@ ov7xx0_configure(struct usb_ov511 *ov) err("this to " EMAIL); err("This is only a warning. You can attempt to use"); err("your camera anyway"); -// Only issue a warning for now +// Only issue a warning for now // return -1; } else { PDEBUG(1, "OV7xx0 initialized (method 2, %dx)", i+1); @@ -5449,8 +5345,6 @@ ov7xx0_configure(struct usb_ov511 *ov) /* I don't know what's different about the 76BE yet. */ if (i2c_r(ov, 0x15) & 1) { info("Sensor is an OV7620AE"); - info("PLEASE REPORT THE EXISTENCE OF THIS SENSOR TO"); - info("THE DRIVER AUTHOR"); } else { info("Sensor is an OV76BE"); } @@ -5498,7 +5392,7 @@ ov7xx0_configure(struct usb_ov511 *ov) } /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ -static int +static int ov6xx0_configure(struct usb_ov511 *ov) { int rc; @@ -5513,7 +5407,7 @@ ov6xx0_configure(struct usb_ov511 *ov) { OV511_I2C_BUS, 0x0c, 0x24 }, { OV511_I2C_BUS, 0x0d, 0x24 }, { OV511_I2C_BUS, 0x0f, 0x15 }, /* COMS */ - { OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */ + { OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */ { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */ { OV511_I2C_BUS, 0x14, 0x04 }, /* 0x16: 0x06 helps frame stability with moving objects */ @@ -5525,11 +5419,11 @@ ov6xx0_configure(struct usb_ov511 *ov) { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */ // { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */ { OV511_I2C_BUS, 0x2d, 0x99 }, - { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Procesing Parameter */ + { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Procesing Parameter */ { OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */ { OV511_I2C_BUS, 0x38, 0x8b }, { OV511_I2C_BUS, 0x39, 0x40 }, - + { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */ { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */ { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */ @@ -5609,7 +5503,7 @@ ov6xx0_configure(struct usb_ov511 *ov) * control the color balance */ // /*OK?*/ { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these // /*OK?*/ { OV511_I2C_BUS, 0x4b, 0x80 }, -// /*U*/ { OV511_I2C_BUS, 0x4c, 0xd0 }, +// /*U*/ { OV511_I2C_BUS, 0x4c, 0xd0 }, /*d2?*/ { OV511_I2C_BUS, 0x4d, 0x10 }, /* This reduces noise a bit */ /*c1?*/ { OV511_I2C_BUS, 0x4e, 0x40 }, /*04?*/ { OV511_I2C_BUS, 0x4f, 0x07 }, @@ -5627,7 +5521,7 @@ ov6xx0_configure(struct usb_ov511 *ov) }; PDEBUG(4, "starting sensor configuration"); - + if (init_ov_sensor(ov) < 0) { err("Failed to read sensor ID. You might not have an OV6xx0,"); err("or it may be not responding. Report this to " EMAIL); @@ -5642,7 +5536,7 @@ ov6xx0_configure(struct usb_ov511 *ov) if (rc < 0) { err("Error detecting sensor type"); return -1; - } + } if ((rc & 3) == 0) ov->sensor = SEN_OV6630; @@ -5676,7 +5570,7 @@ ov6xx0_configure(struct usb_ov511 *ov) if (write_regvals(ov, aRegvalsNorm6x30)) return -1; } - + return 0; } @@ -5738,7 +5632,7 @@ ks0127_configure(struct usb_ov511 *ov) } /* This initializes the SAA7111A video decoder. */ -static int +static int saa7111a_configure(struct usb_ov511 *ov) { int rc; @@ -5890,12 +5784,8 @@ ov511_configure(struct usb_ov511 *ov) err("Also include the output of the detection process."); } - if (ov->customid == 6) { /* USB Life TV (NTSC) */ - ov->tuner_type = 8; /* Temic 4036FY5 3X 1981 */ - } else if (ov->customid == 70) { /* USB Life TV (PAL/SECAM) */ - ov->tuner_type = 3; /* Philips FI1216MF */ + if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */ ov->pal = 1; - } if (write_regvals(ov, aRegvalsInit511)) goto error; @@ -5917,7 +5807,7 @@ ov511_configure(struct usb_ov511 *ov) ov->packet_numbering = 1; ov511_set_packet_size(ov, 0); - ov->snap_enabled = snapshot; + ov->snap_enabled = snapshot; /* Test for 7xx0 */ PDEBUG(3, "Testing for 0V7xx0"); @@ -5994,7 +5884,7 @@ error: } /* This initializes the OV518/OV518+ and the sensor */ -static int +static int ov518_configure(struct usb_ov511 *ov) { /* For 518 and 518+ */ @@ -6190,7 +6080,6 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum, ov->lightfreq = lightfreq; ov->num_inputs = 1; /* Video decoder init functs. change this */ ov->stop_during_set = !fastset; - ov->tuner_type = tuner; ov->backlight = backlight; ov->mirror = mirror; ov->auto_brt = autobright; @@ -6221,7 +6110,7 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum, ov->bclass = BCL_OV511; break; default: - err("Unknown product ID 0x%x", dev->descriptor.idProduct); + err("Unknown product ID 0x%04x", dev->descriptor.idProduct); goto error_dealloc; } @@ -6373,11 +6262,11 @@ ov51x_disconnect(struct usb_device *dev, void *ptr) } static struct usb_driver ov511_driver = { - owner: THIS_MODULE, - name: "ov511", - id_table: device_table, - probe: ov51x_probe, - disconnect: ov51x_disconnect + .owner = THIS_MODULE, + .name = "ov511", + .id_table = device_table, + .probe = ov51x_probe, + .disconnect = ov51x_disconnect }; @@ -6388,7 +6277,7 @@ static struct usb_driver ov511_driver = { ***************************************************************************/ /* Returns 0 for success */ -int +int ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518, int mmx) { @@ -6445,7 +6334,7 @@ err_in_use: return -EBUSY; } -void +void ov511_deregister_decomp_module(int ov518, int mmx) { lock_kernel(); @@ -6461,13 +6350,13 @@ ov511_deregister_decomp_module(int ov518, int mmx) else ov511_decomp_ops = NULL; } - + MOD_DEC_USE_COUNT; unlock_kernel(); } -static int __init +static int __init usb_ov511_init(void) { #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) @@ -6482,7 +6371,7 @@ usb_ov511_init(void) return 0; } -static void __exit +static void __exit usb_ov511_exit(void) { usb_deregister(&ov511_driver); diff --git a/drivers/usb/media/ov511.h b/drivers/usb/media/ov511.h index 02a8c2c4139f..20e4011b1794 100644 --- a/drivers/usb/media/ov511.h +++ b/drivers/usb/media/ov511.h @@ -551,17 +551,11 @@ struct usb_ov511 { int num_inputs; /* Number of inputs */ int norm; /* NTSC / PAL / SECAM */ int has_decoder; /* Device has a video decoder */ - int has_tuner; /* Device has a TV tuner */ - int has_audio_proc; /* Device has an audio processor */ - int freq; /* Current tuner frequency */ - int tuner_type; /* Specific tuner model */ int pal; /* Device is designed for PAL resolution */ - /* I2C interface to kernel */ + /* I2C interface */ struct semaphore i2c_lock; /* Protect I2C controller regs */ unsigned char primary_i2c_slave; /* I2C write id of sensor */ - unsigned char tuner_i2c_slave; /* I2C write id of tuner */ - unsigned char audio_i2c_slave; /* I2C write id of audio processor */ /* Control transaction stuff */ unsigned char *cbuf; /* Buffer for payload */ diff --git a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c index 7f49d02d7316..72d110a78f05 100644 --- a/drivers/usb/media/pwc-if.c +++ b/drivers/usb/media/pwc-if.c @@ -91,10 +91,10 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr); static struct usb_driver pwc_driver = { - name: "Philips webcam", /* name */ - id_table: pwc_device_table, - probe: usb_pwc_probe, /* probe() */ - disconnect: usb_pwc_disconnect, /* disconnect() */ + .name = "Philips webcam", /* name */ + .id_table = pwc_device_table, + .probe = usb_pwc_probe, /* probe() */ + .disconnect = usb_pwc_disconnect, /* disconnect() */ }; #define MAX_DEV_HINTS 10 @@ -130,21 +130,21 @@ static int pwc_video_ioctl(struct inode *inode, struct file *file, static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); static struct file_operations pwc_fops = { - owner: THIS_MODULE, - open: pwc_video_open, - release: pwc_video_close, - read: pwc_video_read, - poll: pwc_video_poll, - mmap: pwc_video_mmap, - ioctl: pwc_video_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = pwc_video_open, + .release = pwc_video_close, + .read = pwc_video_read, + .poll = pwc_video_poll, + .mmap = pwc_video_mmap, + .ioctl = pwc_video_ioctl, + .llseek = no_llseek, }; static struct video_device pwc_template = { - owner: THIS_MODULE, - name: "Philips Webcam", /* Filled in later */ - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_PWC, - fops: &pwc_fops, + .owner = THIS_MODULE, + .name = "Philips Webcam", /* Filled in later */ + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_PWC, + .fops = &pwc_fops, }; /***************************************************************************/ @@ -1756,40 +1756,40 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr) pdev = (struct pwc_device *)ptr; if (pdev == NULL) { Err("pwc_disconnect() Called without private pointer.\n"); - return; + goto out_err; } if (pdev->udev == NULL) { Err("pwc_disconnect() already called for %p\n", pdev); - return; + goto out_err; } if (pdev->udev != udev) { Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n"); - return; + goto out_err; } #ifdef PWC_MAGIC if (pdev->magic != PWC_MAGIC) { Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n"); - return; + goto out_err; } -#endif - +#endif + pdev->unplugged = 1; if (pdev->vdev != NULL) { - video_unregister_device(pdev->vdev); + video_unregister_device(pdev->vdev); if (pdev->vopen) { Info("Disconnected while device/video is open!\n"); - + /* Wake up any processes that might be waiting for a frame, let them return an error condition */ wake_up(&pdev->frameq); - + /* Wait until we get a 'go' from _close(). This used to have a gigantic race condition, since we kfree() - stuff here, but we have to wait until close() - is finished. + stuff here, but we have to wait until close() + is finished. */ - + Trace(TRACE_PROBE, "Sleeping on remove_ok.\n"); add_wait_queue(&pdev->remove_ok, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -1815,6 +1815,7 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr) device_hint[hint].pdev = NULL; pdev->udev = NULL; +out_err: unlock_kernel(); kfree(pdev); } diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c index 9c303e3d3a64..36dd251148bd 100644 --- a/drivers/usb/media/se401.c +++ b/drivers/usb/media/se401.c @@ -1283,20 +1283,20 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) } static struct file_operations se401_fops = { - owner: THIS_MODULE, - open: se401_open, - release: se401_close, - read: se401_read, - mmap: se401_mmap, - ioctl: se401_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = se401_open, + .release = se401_close, + .read = se401_read, + .mmap = se401_mmap, + .ioctl = se401_ioctl, + .llseek = no_llseek, }; static struct video_device se401_template = { - owner: THIS_MODULE, - name: "se401 USB camera", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_SE401, - fops: &se401_fops, + .owner = THIS_MODULE, + .name = "se401 USB camera", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_SE401, + .fops = &se401_fops, }; @@ -1523,7 +1523,7 @@ static inline void usb_se401_remove_disconnected (struct usb_se401 *se401) static struct usb_driver se401_driver = { name: "se401", id_table: device_table, - probe: se401_probe, + .probe = se401_probe, disconnect: se401_disconnect }; diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c index 65ad3a3514e0..ce5134c3dbde 100644 --- a/drivers/usb/media/stv680.c +++ b/drivers/usb/media/stv680.c @@ -1432,20 +1432,20 @@ static int stv680_read (struct file *file, char *buf, } /* stv680_read */ static struct file_operations stv680_fops = { - owner: THIS_MODULE, - open: stv_open, - release: stv_close, - read: stv680_read, - mmap: stv680_mmap, - ioctl: stv680_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = stv_open, + .release = stv_close, + .read = stv680_read, + .mmap = stv680_mmap, + .ioctl = stv680_ioctl, + .llseek = no_llseek, }; static struct video_device stv680_template = { - owner: THIS_MODULE, - name: "STV0680 USB camera", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_SE401, - fops: &stv680_fops, + .owner = THIS_MODULE, + .name = "STV0680 USB camera", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_SE401, + .fops = &stv680_fops, }; static void *stv680_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) @@ -1545,10 +1545,10 @@ static void stv680_disconnect (struct usb_device *dev, void *ptr) } static struct usb_driver stv680_driver = { - name: "stv680", - probe: stv680_probe, - disconnect: stv680_disconnect, - id_table: device_table + .name = "stv680", + .probe = stv680_probe, + .disconnect = stv680_disconnect, + .id_table = device_table }; /******************************************************************** diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c index f2ad752d6090..17103d7a69a1 100644 --- a/drivers/usb/media/usbvideo.c +++ b/drivers/usb/media/usbvideo.c @@ -1054,19 +1054,19 @@ static int usbvideo_find_struct(usbvideo_t *cams) } static struct file_operations usbvideo_fops = { - owner: THIS_MODULE, - open: usbvideo_v4l_open, - release: usbvideo_v4l_close, - read: usbvideo_v4l_read, - mmap: usbvideo_v4l_mmap, - ioctl: usbvideo_v4l_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = usbvideo_v4l_open, + .release =usbvideo_v4l_close, + .read = usbvideo_v4l_read, + .mmap = usbvideo_v4l_mmap, + .ioctl = usbvideo_v4l_ioctl, + .llseek = no_llseek, }; static struct video_device usbvideo_template = { - owner: THIS_MODULE, - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_CPIA, - fops: &usbvideo_fops, + .owner = THIS_MODULE, + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_CPIA, + .fops = &usbvideo_fops, }; uvd_t *usbvideo_AllocateDevice(usbvideo_t *cams) diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 51ed32717520..4426717cb016 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c @@ -640,20 +640,20 @@ static int vicam_v4l_mmap(struct file *file, struct vm_area_struct *vma) /* FIXME - vicam_template - important */ static struct file_operations vicam_fops = { - owner: THIS_MODULE, - open: vicam_v4l_open, - release: vicam_v4l_close, - read: vicam_v4l_read, - mmap: vicam_v4l_mmap, - ioctl: vicam_v4l_ioctl, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = vicam_v4l_open, + .release = vicam_v4l_close, + .read = vicam_v4l_read, + .mmap = vicam_v4l_mmap, + .ioctl = vicam_v4l_ioctl, + .llseek = no_llseek, }; static struct video_device vicam_template = { - owner: THIS_MODULE, - name: "vicam USB camera", - type: VID_TYPE_CAPTURE, - hardware: VID_HARDWARE_SE401, /* need to ask for own id */ - fops: &vicam_fops, + .owner = THIS_MODULE, + .name = "vicam USB camera", + .type = VID_TYPE_CAPTURE, + .hardware = VID_HARDWARE_SE401, /* need to ask for own id */ + .fops = &vicam_fops, }; /****************************************************************************** @@ -876,11 +876,11 @@ static void vicam_disconnect(struct usb_device *udev, void *ptr) /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver vicam_driver = { - owner: THIS_MODULE, - name: "vicam", - probe: vicam_probe, - disconnect: vicam_disconnect, - id_table: vicam_table, + .owner = THIS_MODULE, + .name = "vicam", + .probe = vicam_probe, + .disconnect = vicam_disconnect, + .id_table = vicam_table, }; /****************************************************************************** diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 0d55087b038b..aeb5ca4f3086 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -1879,13 +1879,13 @@ static int auerchar_release (struct inode *inode, struct file *file) /* File operation structure */ static struct file_operations auerswald_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - read: auerchar_read, - write: auerchar_write, - ioctl: auerchar_ioctl, - open: auerchar_open, - release: auerchar_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = auerchar_read, + .write = auerchar_write, + .ioctl = auerchar_ioctl, + .open = auerchar_open, + .release = auerchar_release, }; @@ -2138,10 +2138,10 @@ MODULE_DEVICE_TABLE (usb, auerswald_ids); /* Standard usb driver struct */ static struct usb_driver auerswald_driver = { - name: "auerswald", - probe: auerswald_probe, - disconnect: auerswald_disconnect, - id_table: auerswald_ids, + .name = "auerswald", + .probe = auerswald_probe, + .disconnect = auerswald_disconnect, + .id_table = auerswald_ids, }; diff --git a/drivers/usb/misc/brlvger.c b/drivers/usb/misc/brlvger.c index 52b815eb57a3..47195779469f 100644 --- a/drivers/usb/misc/brlvger.c +++ b/drivers/usb/misc/brlvger.c @@ -230,23 +230,23 @@ MODULE_DEVICE_TABLE (usb, brlvger_ids); static struct file_operations brlvger_fops = { - owner: THIS_MODULE, - llseek: brlvger_llseek, - read: brlvger_read, - write: brlvger_write, - ioctl: brlvger_ioctl, - open: brlvger_open, - release: brlvger_release, - poll: brlvger_poll, + .owner = THIS_MODULE, + .llseek = brlvger_llseek, + .read = brlvger_read, + .write = brlvger_write, + .ioctl = brlvger_ioctl, + .open = brlvger_open, + .release = brlvger_release, + .poll = brlvger_poll, }; static struct usb_driver brlvger_driver = { - owner: THIS_MODULE, - name: "brlvger", - probe: brlvger_probe, - disconnect: brlvger_disconnect, - id_table: brlvger_ids, + .owner = THIS_MODULE, + .name = "brlvger", + .probe = brlvger_probe, + .disconnect = brlvger_disconnect, + .id_table = brlvger_ids, }; static int diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 705f753b8ed2..70388454d8f5 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -443,11 +443,11 @@ read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos) static struct file_operations usb_rio_fops = { - read: read_rio, - write: write_rio, - ioctl: ioctl_rio, - open: open_rio, - release: close_rio, + .read = read_rio, + .write = write_rio, + .ioctl = ioctl_rio, + .open = open_rio, + .release = close_rio, }; static void *probe_rio(struct usb_device *dev, unsigned int ifnum, @@ -525,10 +525,10 @@ static struct usb_device_id rio_table [] = { MODULE_DEVICE_TABLE (usb, rio_table); static struct usb_driver rio_driver = { - name: "rio500", - probe: probe_rio, - disconnect: disconnect_rio, - id_table: rio_table, + .name = "rio500", + .probe = probe_rio, + .disconnect = disconnect_rio, + .id_table = rio_table, }; int usb_rio_init(void) diff --git a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c index 00fd9f31353f..e6cb63af2341 100644 --- a/drivers/usb/misc/tiglusb.c +++ b/drivers/usb/misc/tiglusb.c @@ -295,13 +295,13 @@ static int tiglusb_ioctl (struct inode *inode, struct file *file, /* ----- kernel module registering ------------------------------------ */ static struct file_operations tiglusb_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - read: tiglusb_read, - write: tiglusb_write, - ioctl: tiglusb_ioctl, - open: tiglusb_open, - release: tiglusb_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = tiglusb_read, + .write = tiglusb_write, + .ioctl = tiglusb_ioctl, + .open = tiglusb_open, + .release = tiglusb_release, }; static int tiglusb_find_struct (void) @@ -407,11 +407,11 @@ static struct usb_device_id tiglusb_ids[] = { MODULE_DEVICE_TABLE (usb, tiglusb_ids); static struct usb_driver tiglusb_driver = { - owner: THIS_MODULE, - name: "tiglusb", - probe: tiglusb_probe, - disconnect: tiglusb_disconnect, - id_table: tiglusb_ids, + .owner = THIS_MODULE, + .name = "tiglusb", + .probe = tiglusb_probe, + .disconnect = tiglusb_disconnect, + .id_table = tiglusb_ids, }; /* --- initialisation code ------------------------------------- */ diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index ebf8e985bcec..3940bb1fbe5c 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -646,10 +646,10 @@ MODULE_DEVICE_TABLE (usb, uss720_table); static struct usb_driver uss720_driver = { - name: "uss720", - probe: uss720_probe, - disconnect: uss720_disconnect, - id_table: uss720_table, + .name = "uss720", + .probe = uss720_probe, + .disconnect = uss720_disconnect, + .id_table = uss720_table, }; /* --------------------------------------------------------------------- */ diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index 0b2336935381..b270dc757afb 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c @@ -941,10 +941,10 @@ static struct usb_device_id catc_id_table [] = { MODULE_DEVICE_TABLE(usb, catc_id_table); static struct usb_driver catc_driver = { - name: "catc", - probe: catc_probe, - disconnect: catc_disconnect, - id_table: catc_id_table, + .name = "catc", + .probe = catc_probe, + .disconnect = catc_disconnect, + .id_table = catc_id_table, }; static int __init catc_init(void) diff --git a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c index 1d3ac4508363..236a0d80cf22 100644 --- a/drivers/usb/net/cdc-ether.c +++ b/drivers/usb/net/cdc-ether.c @@ -1325,10 +1325,10 @@ static void CDCEther_disconnect( struct usb_device *usb, void *ptr ) ////////////////////////////////////////////////////////////////////////////// static struct usb_driver CDCEther_driver = { - name: "CDCEther", - probe: CDCEther_probe, - disconnect: CDCEther_disconnect, - id_table: CDCEther_ids, + .name = "CDCEther", + .probe = CDCEther_probe, + .disconnect = CDCEther_disconnect, + .id_table = CDCEther_ids, }; ////////////////////////////////////////////////////////////////////////////// diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index 096a8b1aded2..738baabda267 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -165,11 +165,11 @@ MODULE_DEVICE_TABLE (usb, usb_klsi_table); * kaweth_driver ****************************************************************/ static struct usb_driver kaweth_driver = { - owner: THIS_MODULE, - name: "kaweth", - probe: kaweth_probe, - disconnect: kaweth_disconnect, - id_table: usb_klsi_table, + .owner = THIS_MODULE, + .name = "kaweth", + .probe = kaweth_probe, + .disconnect = kaweth_disconnect, + .id_table = usb_klsi_table, }; typedef __u8 eth_addr_t[6]; diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index a7d9c72cdbcc..6728f5cfd6ce 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -1148,10 +1148,10 @@ static void pegasus_disconnect(struct usb_device *dev, void *ptr) } 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/rtl8150.c b/drivers/usb/net/rtl8150.c index ffd2737fee5b..89645c118480 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -110,10 +110,10 @@ static void *rtl8150_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id); static struct usb_driver rtl8150_driver = { - name: "rtl8150", - probe: rtl8150_probe, - disconnect: rtl8150_disconnect, - id_table: rtl8150_table, + .name = "rtl8150", + .probe = rtl8150_probe, + .disconnect = rtl8150_disconnect, + .id_table = rtl8150_table, }; /* diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index b6b9fc8b51e9..c6ac7dd2821e 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -26,12 +26,7 @@ * See the LINUXDEV support. * * - * TODO: - * - * This needs to be retested for bulk queuing problems ... earlier versions - * seemed to find different types of problems in each HCD. Once they're fixed, - * re-enable queues to get higher bandwidth utilization (without needing - * to tweak MTU for larger packets). + * Status: * * - AN2720 ... not widely available, but reportedly works well * @@ -45,8 +40,8 @@ * but the Sharp Zaurus uses an incompatible protocol (extra checksums). * No reason not to merge the Zaurus protocol here too (got patch? :) * - * - For Netchip, use keventd to poll via control requests to detect hardware - * level "carrier detect". + * - For Netchip, should use keventd to poll via control requests to detect + * hardware level "carrier detect". * * - PL-230x ... the initialization protocol doesn't seem to match chip data * sheets, sometimes it's not needed and sometimes it hangs. Prolific has @@ -60,9 +55,9 @@ * * There are reports that bridging gives lower-than-usual throughput. * - * Craft smarter hotplug policy scripts ... ones that know how to arrange + * Need smarter hotplug policy scripts ... ones that know how to arrange * bridging with "brctl", and can handle static and dynamic ("pump") setups. - * Use those "peer connected" events. + * Use those eventual "peer connected" events. * * * CHANGELOG: @@ -122,7 +117,7 @@ // #define DEBUG // error path messages, extra info // #define VERBOSE // more; success messages -// #define REALLY_QUEUE +#define REALLY_QUEUE #if !defined (DEBUG) && defined (CONFIG_USB_DEBUG) # define DEBUG @@ -139,7 +134,7 @@ #define CONFIG_USB_PL2301 -#define DRIVER_VERSION "07-May-2002" +#define DRIVER_VERSION "17-Jul-2002" /*-------------------------------------------------------------------------*/ @@ -301,12 +296,12 @@ MODULE_PARM_DESC (msg_level, "Initial message level (default = 1)"); *-------------------------------------------------------------------------*/ static const struct driver_info an2720_info = { - description: "AnchorChips/Cypress 2720", + .description = "AnchorChips/Cypress 2720", // no reset available! // no check_connect available! - in: 2, out: 2, // direction distinguishes these - epsize: 64, + .in = 2, out: 2, // direction distinguishes these + .epsize =64, }; #endif /* CONFIG_USB_AN2720 */ @@ -324,10 +319,10 @@ static const struct driver_info an2720_info = { *-------------------------------------------------------------------------*/ static const struct driver_info belkin_info = { - description: "Belkin, eTEK, or compatible", + .description = "Belkin, eTEK, or compatible", - in: 1, out: 1, // direction distinguishes these - epsize: 64, + .in = 1, out: 1, // direction distinguishes these + .epsize =64, }; #endif /* CONFIG_USB_BELKIN */ @@ -635,17 +630,17 @@ genelink_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags) } static const struct driver_info genelink_info = { - description: "Genesys GeneLink", - flags: FLAG_FRAMING_GL | FLAG_NO_SETINT, - reset: genelink_reset, - rx_fixup: genelink_rx_fixup, - tx_fixup: genelink_tx_fixup, + .description = "Genesys GeneLink", + .flags = FLAG_FRAMING_GL | FLAG_NO_SETINT, + .reset = genelink_reset, + .rx_fixup = genelink_rx_fixup, + .tx_fixup = genelink_tx_fixup, - in: 1, out: 2, - epsize: 64, + .in = 1, out: 2, + .epsize =64, #ifdef GENELINK_ACK - check_connect: genelink_check_connect, + .check_connect =genelink_check_connect, #endif }; @@ -676,11 +671,11 @@ static int linuxdev_check_connect (struct usbnet *dev) } static const struct driver_info linuxdev_info = { - description: "Linux Device", + .description = "Linux Device", // no reset defined (yet?) - check_connect: linuxdev_check_connect, - in: 2, out: 1, - epsize: 64, + .check_connect =linuxdev_check_connect, + .in = 2, out: 1, + .epsize =64, }; #endif /* CONFIG_USB_LINUXDEV */ @@ -1123,15 +1118,15 @@ net1080_tx_fixup (struct usbnet *dev, struct sk_buff *skb, int flags) } static const struct driver_info net1080_info = { - description: "NetChip TurboCONNECT", - flags: FLAG_FRAMING_NC, - reset: net1080_reset, - check_connect: net1080_check_connect, - rx_fixup: net1080_rx_fixup, - tx_fixup: net1080_tx_fixup, - - in: 1, out: 1, // direction distinguishes these - epsize: 64, + .description = "NetChip TurboCONNECT", + .flags = FLAG_FRAMING_NC, + .reset = net1080_reset, + .check_connect =net1080_check_connect, + .rx_fixup = net1080_rx_fixup, + .tx_fixup = net1080_tx_fixup, + + .in = 1, out: 1, // direction distinguishes these + .epsize =64, }; #endif /* CONFIG_USB_NET1080 */ @@ -1192,13 +1187,13 @@ static int pl_reset (struct usbnet *dev) } static const struct driver_info prolific_info = { - description: "Prolific PL-2301/PL-2302", - flags: FLAG_NO_SETINT, + .description = "Prolific PL-2301/PL-2302", + .flags = FLAG_NO_SETINT, /* some PL-2302 versions seem to fail usb_set_interface() */ - reset: pl_reset, + .reset = pl_reset, - in: 3, out: 2, - epsize: 64, + .in = 3, out: 2, + .epsize =64, }; #endif /* CONFIG_USB_PL2301 */ @@ -1815,20 +1810,19 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) } #endif /* CONFIG_USB_NET1080 */ - netif_stop_queue (net); switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { case -EPIPE: + netif_stop_queue (net); defer_kevent (dev, EVENT_TX_HALT); break; default: - netif_start_queue (net); dbg ("%s tx: submit urb err %d", net->name, retval); break; case 0: net->trans_start = jiffies; __skb_queue_tail (&dev->txq, skb); - if (dev->txq.qlen < TX_QLEN) - netif_start_queue (net); + if (dev->txq.qlen >= TX_QLEN) + netif_stop_queue (net); } spin_unlock_irqrestore (&dev->txq.lock, flags); @@ -2054,32 +2048,32 @@ static const struct usb_device_id products [] = { #ifdef CONFIG_USB_AN2720 { USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults - driver_info: (unsigned long) &an2720_info, + .driver_info = (unsigned long) &an2720_info, }, { USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET - driver_info: (unsigned long) &an2720_info, + .driver_info = (unsigned long) &an2720_info, }, #endif #ifdef CONFIG_USB_BELKIN { USB_DEVICE (0x050d, 0x0004), // Belkin - driver_info: (unsigned long) &belkin_info, + .driver_info = (unsigned long) &belkin_info, }, { USB_DEVICE (0x056c, 0x8100), // eTEK - driver_info: (unsigned long) &belkin_info, + .driver_info = (unsigned long) &belkin_info, }, { USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK) - driver_info: (unsigned long) &belkin_info, + .driver_info = (unsigned long) &belkin_info, }, #endif #ifdef CONFIG_USB_GENESYS { USB_DEVICE (0x05e3, 0x0502), // GL620USB-A - driver_info: (unsigned long) &genelink_info, + .driver_info = (unsigned long) &genelink_info, }, #endif @@ -2091,28 +2085,28 @@ static const struct usb_device_id products [] = { { // 1183 = 0x049F, both used as hex values? USB_DEVICE (0x049F, 0x505A), // Compaq "Itsy" - driver_info: (unsigned long) &linuxdev_info, + .driver_info = (unsigned long) &linuxdev_info, }, #endif #ifdef CONFIG_USB_NET1080 { USB_DEVICE (0x0525, 0x1080), // NetChip ref design - driver_info: (unsigned long) &net1080_info, + .driver_info = (unsigned long) &net1080_info, }, { USB_DEVICE (0x06D0, 0x0622), // Laplink Gold - driver_info: (unsigned long) &net1080_info, + .driver_info = (unsigned long) &net1080_info, }, #endif #ifdef CONFIG_USB_PL2301 { USB_DEVICE (0x067b, 0x0000), // PL-2301 - driver_info: (unsigned long) &prolific_info, + .driver_info = (unsigned long) &prolific_info, }, { USB_DEVICE (0x067b, 0x0001), // PL-2302 - driver_info: (unsigned long) &prolific_info, + .driver_info = (unsigned long) &prolific_info, }, #endif @@ -2123,10 +2117,10 @@ static const struct usb_device_id products [] = { MODULE_DEVICE_TABLE (usb, products); static struct usb_driver usbnet_driver = { - name: driver_name, - id_table: products, - probe: usbnet_probe, - disconnect: usbnet_disconnect, + .name = driver_name, + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 1b95a25f286b..fa8c7f874dd6 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -116,21 +116,21 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); /* All of the device info needed for the serial converters */ static struct usb_serial_device_type belkin_device = { - owner: THIS_MODULE, - name: "Belkin / Peracom / GoHubs USB Serial Adapter", - id_table: id_table_combined, - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: belkin_sa_open, - close: belkin_sa_close, - read_int_callback: belkin_sa_read_int_callback, /* How we get the status info */ - ioctl: belkin_sa_ioctl, - set_termios: belkin_sa_set_termios, - break_ctl: belkin_sa_break_ctl, - attach: belkin_sa_startup, - shutdown: belkin_sa_shutdown, + .owner = THIS_MODULE, + .name = "Belkin / Peracom / GoHubs USB Serial Adapter", + .id_table = id_table_combined, + .num_interrupt_in = 1, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = belkin_sa_open, + .close = belkin_sa_close, + .read_int_callback = belkin_sa_read_int_callback, /* How we get the status info */ + .ioctl = belkin_sa_ioctl, + .set_termios = belkin_sa_set_termios, + .break_ctl = belkin_sa_break_ctl, + .attach = belkin_sa_startup, + .shutdown = belkin_sa_shutdown, }; diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 9ca8b075f007..7a15cc3564a4 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -74,21 +74,21 @@ static struct usb_device_id id_table [] = { MODULE_DEVICE_TABLE (usb, id_table); static struct usb_serial_device_type cyberjack_device = { - owner: THIS_MODULE, - name: "Reiner SCT Cyberjack USB card reader", - id_table: id_table, - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - attach: cyberjack_startup, - shutdown: cyberjack_shutdown, - open: cyberjack_open, - close: cyberjack_close, - write: cyberjack_write, - read_int_callback: cyberjack_read_int_callback, - read_bulk_callback: cyberjack_read_bulk_callback, - write_bulk_callback: cyberjack_write_bulk_callback, + .owner = THIS_MODULE, + .name = "Reiner SCT Cyberjack USB card reader", + .id_table = id_table, + .num_interrupt_in = 1, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .attach = cyberjack_startup, + .shutdown = cyberjack_shutdown, + .open = cyberjack_open, + .close = cyberjack_close, + .write = cyberjack_write, + .read_int_callback = cyberjack_read_int_callback, + .read_bulk_callback = cyberjack_read_bulk_callback, + .write_bulk_callback = cyberjack_write_bulk_callback, }; struct cyberjack_private { diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 4dd615fda3f7..eee56288d2ea 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -498,51 +498,51 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); /* device info needed for the Digi serial converter */ static struct usb_serial_device_type digi_acceleport_2_device = { - owner: THIS_MODULE, - name: "Digi USB", - id_table: id_table_2, - num_interrupt_in: 0, - num_bulk_in: 4, - num_bulk_out: 4, - num_ports: 3, - open: digi_open, - close: digi_close, - write: digi_write, - write_room: digi_write_room, - write_bulk_callback: digi_write_bulk_callback, - read_bulk_callback: digi_read_bulk_callback, - chars_in_buffer: digi_chars_in_buffer, - throttle: digi_rx_throttle, - unthrottle: digi_rx_unthrottle, - ioctl: digi_ioctl, - set_termios: digi_set_termios, - break_ctl: digi_break_ctl, - attach: digi_startup, - shutdown: digi_shutdown, + .owner = THIS_MODULE, + .name = "Digi USB", + .id_table = id_table_2, + .num_interrupt_in = 0, + .num_bulk_in = 4, + .num_bulk_out = 4, + .num_ports = 3, + .open = digi_open, + .close = digi_close, + .write = digi_write, + .write_room = digi_write_room, + .write_bulk_callback = digi_write_bulk_callback, + .read_bulk_callback = digi_read_bulk_callback, + .chars_in_buffer = digi_chars_in_buffer, + .throttle = digi_rx_throttle, + .unthrottle = digi_rx_unthrottle, + .ioctl = digi_ioctl, + .set_termios = digi_set_termios, + .break_ctl = digi_break_ctl, + .attach = digi_startup, + .shutdown = digi_shutdown, }; static struct usb_serial_device_type digi_acceleport_4_device = { - owner: THIS_MODULE, - name: "Digi USB", - id_table: id_table_4, - num_interrupt_in: 0, - num_bulk_in: 5, - num_bulk_out: 5, - num_ports: 4, - open: digi_open, - close: digi_close, - write: digi_write, - write_room: digi_write_room, - write_bulk_callback: digi_write_bulk_callback, - read_bulk_callback: digi_read_bulk_callback, - chars_in_buffer: digi_chars_in_buffer, - throttle: digi_rx_throttle, - unthrottle: digi_rx_unthrottle, - ioctl: digi_ioctl, - set_termios: digi_set_termios, - break_ctl: digi_break_ctl, - attach: digi_startup, - shutdown: digi_shutdown, + .owner = THIS_MODULE, + .name = "Digi USB", + .id_table = id_table_4, + .num_interrupt_in = 0, + .num_bulk_in = 5, + .num_bulk_out = 5, + .num_ports = 4, + .open = digi_open, + .close = digi_close, + .write = digi_write, + .write_room = digi_write_room, + .write_bulk_callback = digi_write_bulk_callback, + .read_bulk_callback = digi_read_bulk_callback, + .chars_in_buffer = digi_chars_in_buffer, + .throttle = digi_rx_throttle, + .unthrottle = digi_rx_unthrottle, + .ioctl = digi_ioctl, + .set_termios = digi_set_termios, + .break_ctl = digi_break_ctl, + .attach = digi_startup, + .shutdown = digi_shutdown, }; diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index c6b255a36326..4f66d87f9a10 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -111,26 +111,26 @@ static struct usb_device_id id_table [] = { MODULE_DEVICE_TABLE (usb, id_table); static struct usb_serial_device_type empeg_device = { - owner: THIS_MODULE, - name: "Empeg", - id_table: id_table, - num_interrupt_in: 0, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: empeg_open, - close: empeg_close, - throttle: empeg_throttle, - unthrottle: empeg_unthrottle, - attach: empeg_startup, - shutdown: empeg_shutdown, - ioctl: empeg_ioctl, - set_termios: empeg_set_termios, - write: empeg_write, - write_room: empeg_write_room, - chars_in_buffer: empeg_chars_in_buffer, - write_bulk_callback: empeg_write_bulk_callback, - read_bulk_callback: empeg_read_bulk_callback, + .owner = THIS_MODULE, + .name = "Empeg", + .id_table = id_table, + .num_interrupt_in = 0, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = empeg_open, + .close = empeg_close, + .throttle = empeg_throttle, + .unthrottle = empeg_unthrottle, + .attach = empeg_startup, + .shutdown = empeg_shutdown, + .ioctl = empeg_ioctl, + .set_termios = empeg_set_termios, + .write = empeg_write, + .write_room = empeg_write_room, + .chars_in_buffer = empeg_chars_in_buffer, + .write_bulk_callback = empeg_write_bulk_callback, + .read_bulk_callback = empeg_read_bulk_callback, }; #define NUM_URBS 16 diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index b833b4577406..fb20bd131723 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -173,45 +173,45 @@ static void ftdi_sio_break_ctl (struct usb_serial_port *port, int break_state ) which share common code */ static struct usb_serial_device_type ftdi_sio_device = { - owner: THIS_MODULE, - name: "FTDI SIO", - id_table: id_table_sio, - num_interrupt_in: 0, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: ftdi_sio_open, - close: ftdi_sio_close, - write: ftdi_sio_write, - write_room: ftdi_sio_write_room, - read_bulk_callback: ftdi_sio_read_bulk_callback, - write_bulk_callback: ftdi_sio_write_bulk_callback, - ioctl: ftdi_sio_ioctl, - set_termios: ftdi_sio_set_termios, - break_ctl: ftdi_sio_break_ctl, - attach: ftdi_sio_startup, - shutdown: ftdi_sio_shutdown, + .owner = THIS_MODULE, + .name = "FTDI SIO", + .id_table = id_table_sio, + .num_interrupt_in = 0, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = ftdi_sio_open, + .close = ftdi_sio_close, + .write = ftdi_sio_write, + .write_room = ftdi_sio_write_room, + .read_bulk_callback = ftdi_sio_read_bulk_callback, + .write_bulk_callback = ftdi_sio_write_bulk_callback, + .ioctl = ftdi_sio_ioctl, + .set_termios = ftdi_sio_set_termios, + .break_ctl = ftdi_sio_break_ctl, + .attach = ftdi_sio_startup, + .shutdown = ftdi_sio_shutdown, }; static struct usb_serial_device_type ftdi_8U232AM_device = { - owner: THIS_MODULE, - name: "FTDI 8U232AM", - id_table: id_table_8U232AM, - num_interrupt_in: 0, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: ftdi_sio_open, - close: ftdi_sio_close, - write: ftdi_sio_write, - write_room: ftdi_sio_write_room, - read_bulk_callback: ftdi_sio_read_bulk_callback, - write_bulk_callback: ftdi_sio_write_bulk_callback, - ioctl: ftdi_sio_ioctl, - set_termios: ftdi_sio_set_termios, - break_ctl: ftdi_sio_break_ctl, - attach: ftdi_8U232AM_startup, - shutdown: ftdi_sio_shutdown, + .owner = THIS_MODULE, + .name = "FTDI 8U232AM", + .id_table = id_table_8U232AM, + .num_interrupt_in = 0, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = ftdi_sio_open, + .close = ftdi_sio_close, + .write = ftdi_sio_write, + .write_room = ftdi_sio_write_room, + .read_bulk_callback = ftdi_sio_read_bulk_callback, + .write_bulk_callback = ftdi_sio_write_bulk_callback, + .ioctl = ftdi_sio_ioctl, + .set_termios = ftdi_sio_set_termios, + .break_ctl = ftdi_sio_break_ctl, + .attach = ftdi_8U232AM_startup, + .shutdown = ftdi_sio_shutdown, }; diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 9323ffefb9d2..aae807c97f65 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -90,22 +90,22 @@ MODULE_DEVICE_TABLE (usb, ipaq_id_table); /* All of the device info needed for the Compaq iPAQ */ struct usb_serial_device_type ipaq_device = { - owner: THIS_MODULE, - name: "Compaq iPAQ", - id_table: ipaq_id_table, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: ipaq_open, - close: ipaq_close, - attach: ipaq_startup, - shutdown: ipaq_shutdown, - write: ipaq_write, - write_room: ipaq_write_room, - chars_in_buffer: ipaq_chars_in_buffer, - read_bulk_callback: ipaq_read_bulk_callback, - write_bulk_callback: ipaq_write_bulk_callback, + .owner = THIS_MODULE, + .name = "Compaq iPAQ", + .id_table = ipaq_id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = ipaq_open, + .close = ipaq_close, + .attach = ipaq_startup, + .shutdown = ipaq_shutdown, + .write = ipaq_write, + .write_room = ipaq_write_room, + .chars_in_buffer = ipaq_chars_in_buffer, + .read_bulk_callback = ipaq_read_bulk_callback, + .write_bulk_callback = ipaq_write_bulk_callback, }; static spinlock_t write_list_lock; diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 5fbd5ea1bfa7..f89ebb682280 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -131,20 +131,20 @@ MODULE_DEVICE_TABLE (usb, id_table); struct usb_serial_device_type ir_device = { - owner: THIS_MODULE, - name: "IR Dongle", - id_table: id_table, - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - set_termios: ir_set_termios, - attach: ir_startup, - open: ir_open, - close: ir_close, - write: ir_write, - write_bulk_callback: ir_write_bulk_callback, - read_bulk_callback: ir_read_bulk_callback, + .owner = THIS_MODULE, + .name = "IR Dongle", + .id_table = id_table, + .num_interrupt_in = 1, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .set_termios = ir_set_termios, + .attach = ir_startup, + .open = ir_open, + .close = ir_close, + .write = ir_write, + .write_bulk_callback = ir_write_bulk_callback, + .read_bulk_callback = ir_read_bulk_callback, }; static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc) diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 4804b7d8f0ce..adb378a75ca3 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -1103,28 +1103,28 @@ static struct callbacks { } keyspan_callbacks[] = { { /* msg_usa26 callbacks */ - instat_callback: usa26_instat_callback, - glocont_callback: usa26_glocont_callback, - indat_callback: usa26_indat_callback, - outdat_callback: usa2x_outdat_callback, - inack_callback: usa26_inack_callback, - outcont_callback: usa26_outcont_callback, + .instat_callback = usa26_instat_callback, + .glocont_callback = usa26_glocont_callback, + .indat_callback = usa26_indat_callback, + .outdat_callback = usa2x_outdat_callback, + .inack_callback = usa26_inack_callback, + .outcont_callback = usa26_outcont_callback, }, { /* msg_usa28 callbacks */ - instat_callback: usa28_instat_callback, - glocont_callback: usa28_glocont_callback, - indat_callback: usa28_indat_callback, - outdat_callback: usa2x_outdat_callback, - inack_callback: usa28_inack_callback, - outcont_callback: usa28_outcont_callback, + .instat_callback = usa28_instat_callback, + .glocont_callback = usa28_glocont_callback, + .indat_callback = usa28_indat_callback, + .outdat_callback = usa2x_outdat_callback, + .inack_callback = usa28_inack_callback, + .outcont_callback = usa28_outcont_callback, }, { /* msg_usa49 callbacks */ - instat_callback: usa49_instat_callback, - glocont_callback: usa49_glocont_callback, - indat_callback: usa49_indat_callback, - outdat_callback: usa2x_outdat_callback, - inack_callback: usa49_inack_callback, - outcont_callback: usa49_outcont_callback, + .instat_callback = usa49_instat_callback, + .glocont_callback = usa49_glocont_callback, + .indat_callback = usa49_indat_callback, + .outdat_callback = usa2x_outdat_callback, + .inack_callback = usa49_inack_callback, + .outcont_callback = usa49_outcont_callback, } }; diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index b0dac088b979..2ee0a07f28fb 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -804,52 +804,52 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) #ifdef KEYSPAN static struct usb_serial_device_type keyspan_pda_fake_device = { - owner: THIS_MODULE, - name: "Keyspan PDA - (prerenumeration)", - id_table: id_table_fake, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, - num_ports: 1, - attach: keyspan_pda_fake_startup, + .owner = THIS_MODULE, + .name = "Keyspan PDA - (prerenumeration)", + .id_table = id_table_fake, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, + .attach = keyspan_pda_fake_startup, }; #endif #ifdef XIRCOM static struct usb_serial_device_type xircom_pgs_fake_device = { - owner: THIS_MODULE, - name: "Xircom / Entregra PGS - (prerenumeration)", - id_table: id_table_fake_xircom, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, - num_ports: 1, - attach: keyspan_pda_fake_startup, + .owner = THIS_MODULE, + .name = "Xircom / Entregra PGS - (prerenumeration)", + .id_table = id_table_fake_xircom, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, + .attach = keyspan_pda_fake_startup, }; #endif static struct usb_serial_device_type keyspan_pda_device = { - owner: THIS_MODULE, - name: "Keyspan PDA", - id_table: id_table_std, - num_interrupt_in: 1, - num_bulk_in: 0, - num_bulk_out: 1, - num_ports: 1, - open: keyspan_pda_open, - close: keyspan_pda_close, - write: keyspan_pda_write, - write_room: keyspan_pda_write_room, - write_bulk_callback: keyspan_pda_write_bulk_callback, - read_int_callback: keyspan_pda_rx_interrupt, - chars_in_buffer: keyspan_pda_chars_in_buffer, - throttle: keyspan_pda_rx_throttle, - unthrottle: keyspan_pda_rx_unthrottle, - ioctl: keyspan_pda_ioctl, - set_termios: keyspan_pda_set_termios, - break_ctl: keyspan_pda_break_ctl, - attach: keyspan_pda_startup, - shutdown: keyspan_pda_shutdown, + .owner = THIS_MODULE, + .name = "Keyspan PDA", + .id_table = id_table_std, + .num_interrupt_in = 1, + .num_bulk_in = 0, + .num_bulk_out = 1, + .num_ports = 1, + .open = keyspan_pda_open, + .close = keyspan_pda_close, + .write = keyspan_pda_write, + .write_room = keyspan_pda_write_room, + .write_bulk_callback = keyspan_pda_write_bulk_callback, + .read_int_callback = keyspan_pda_rx_interrupt, + .chars_in_buffer = keyspan_pda_chars_in_buffer, + .throttle = keyspan_pda_rx_throttle, + .unthrottle = keyspan_pda_rx_unthrottle, + .ioctl = keyspan_pda_ioctl, + .set_termios = keyspan_pda_set_termios, + .break_ctl = keyspan_pda_break_ctl, + .attach = keyspan_pda_startup, + .shutdown = keyspan_pda_shutdown, }; diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 22a965066c3d..58e83e62c6de 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -119,27 +119,27 @@ MODULE_DEVICE_TABLE (usb, id_table); static struct usb_serial_device_type kl5kusb105d_device = { - owner: THIS_MODULE, - name: "KL5KUSB105D / PalmConnect", - id_table: id_table, - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: klsi_105_open, - close: klsi_105_close, - write: klsi_105_write, - write_bulk_callback: klsi_105_write_bulk_callback, - chars_in_buffer: klsi_105_chars_in_buffer, - write_room: klsi_105_write_room, - read_bulk_callback: klsi_105_read_bulk_callback, - ioctl: klsi_105_ioctl, - set_termios: klsi_105_set_termios, + .owner = THIS_MODULE, + .name = "KL5KUSB105D / PalmConnect", + .id_table = id_table, + .num_interrupt_in = 1, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = klsi_105_open, + .close = klsi_105_close, + .write = klsi_105_write, + .write_bulk_callback = klsi_105_write_bulk_callback, + .chars_in_buffer = klsi_105_chars_in_buffer, + .write_room = klsi_105_write_room, + .read_bulk_callback =klsi_105_read_bulk_callback, + .ioctl = klsi_105_ioctl, + .set_termios = klsi_105_set_termios, /*break_ctl: klsi_105_break_ctl,*/ - attach: klsi_105_startup, - shutdown: klsi_105_shutdown, - throttle: klsi_105_throttle, - unthrottle: klsi_105_unthrottle, + .attach = klsi_105_startup, + .shutdown = klsi_105_shutdown, + .throttle = klsi_105_throttle, + .unthrottle = klsi_105_unthrottle, }; struct klsi_105_port_settings { diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 1cfae6462896..9225f9396f42 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -141,25 +141,25 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); static struct usb_serial_device_type mct_u232_device = { - owner: THIS_MODULE, - name: "Magic Control Technology USB-RS232", - id_table: id_table_combined, - num_interrupt_in: 2, - num_bulk_in: 0, - num_bulk_out: 1, - num_ports: 1, - open: mct_u232_open, - close: mct_u232_close, + .owner = THIS_MODULE, + .name = "Magic Control Technology USB-RS232", + .id_table = id_table_combined, + .num_interrupt_in = 2, + .num_bulk_in = 0, + .num_bulk_out = 1, + .num_ports = 1, + .open = mct_u232_open, + .close = mct_u232_close, #ifdef FIX_WRITE_RETURN_CODE_PROBLEM - write: mct_u232_write, - write_bulk_callback: mct_u232_write_bulk_callback, + .write = mct_u232_write, + .write_bulk_callback = mct_u232_write_bulk_callback, #endif - read_int_callback: mct_u232_read_int_callback, - ioctl: mct_u232_ioctl, - set_termios: mct_u232_set_termios, - break_ctl: mct_u232_break_ctl, - attach: mct_u232_startup, - shutdown: mct_u232_shutdown, + .read_int_callback = mct_u232_read_int_callback, + .ioctl = mct_u232_ioctl, + .set_termios = mct_u232_set_termios, + .break_ctl = mct_u232_break_ctl, + .attach = mct_u232_startup, + .shutdown = mct_u232_shutdown, }; diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index fbce2098e4fd..2cea1f883c9f 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -85,20 +85,20 @@ MODULE_DEVICE_TABLE (usb, id_table); static struct usb_serial_device_type zyxel_omninet_device = { - owner: THIS_MODULE, - name: "ZyXEL - omni.net lcd plus usb", - id_table: id_table, - num_interrupt_in: 1, - num_bulk_in: 1, - num_bulk_out: 2, - num_ports: 1, - open: omninet_open, - close: omninet_close, - write: omninet_write, - write_room: omninet_write_room, - read_bulk_callback: omninet_read_bulk_callback, - write_bulk_callback: omninet_write_bulk_callback, - shutdown: omninet_shutdown, + .owner = THIS_MODULE, + .name = "ZyXEL - omni.net lcd plus usb", + .id_table = id_table, + .num_interrupt_in = 1, + .num_bulk_in = 1, + .num_bulk_out = 2, + .num_ports = 1, + .open = omninet_open, + .close = omninet_close, + .write = omninet_write, + .write_room = omninet_write_room, + .read_bulk_callback = omninet_read_bulk_callback, + .write_bulk_callback = omninet_write_bulk_callback, + .shutdown = omninet_shutdown, }; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index fb3ffd06ad2d..b4882dba51ec 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -118,24 +118,24 @@ static void pl2303_shutdown (struct usb_serial *serial); /* All of the device info needed for the PL2303 SIO serial converter */ static struct usb_serial_device_type pl2303_device = { - owner: THIS_MODULE, - name: "PL-2303", - id_table: id_table, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: pl2303_open, - close: pl2303_close, - write: pl2303_write, - ioctl: pl2303_ioctl, - break_ctl: pl2303_break_ctl, - set_termios: pl2303_set_termios, - read_bulk_callback: pl2303_read_bulk_callback, - read_int_callback: pl2303_read_int_callback, - write_bulk_callback: pl2303_write_bulk_callback, - attach: pl2303_startup, - shutdown: pl2303_shutdown, + .owner = THIS_MODULE, + .name = "PL-2303", + .id_table = id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = pl2303_open, + .close = pl2303_close, + .write = pl2303_write, + .ioctl = pl2303_ioctl, + .break_ctl = pl2303_break_ctl, + .set_termios = pl2303_set_termios, + .read_bulk_callback = pl2303_read_bulk_callback, + .read_int_callback = pl2303_read_int_callback, + .write_bulk_callback = pl2303_write_bulk_callback, + .attach = pl2303_startup, + .shutdown = pl2303_shutdown, }; struct pl2303_private { diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index bc1fe0713ab9..54da202b1b95 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -399,17 +399,17 @@ static int safe_startup (struct usb_serial *serial) } static struct usb_serial_device_type safe_device = { - owner: THIS_MODULE, - name: "Safe", - id_table: id_table, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, - num_ports: 1, - write: safe_write, - write_room: safe_write_room, - read_bulk_callback: safe_read_bulk_callback, - attach: safe_startup, + .owner = THIS_MODULE, + .name = "Safe", + .id_table = id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, + .write = safe_write, + .write_room = safe_write_room, + .read_bulk_callback = safe_read_bulk_callback, + .attach = safe_startup, }; static int __init safe_init (void) diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c index 2e556292db6a..ae7f1f3da7a5 100644 --- a/drivers/usb/serial/usbserial.c +++ b/drivers/usb/serial/usbserial.c @@ -366,14 +366,14 @@ static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ /* All of the device info needed for the Generic Serial Converter */ static struct usb_serial_device_type generic_device = { - owner: THIS_MODULE, - name: "Generic", - id_table: generic_device_ids, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, - num_ports: 1, - shutdown: generic_shutdown, + .owner = THIS_MODULE, + .name = "Generic", + .id_table = generic_device_ids, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, + .shutdown = generic_shutdown, }; #endif @@ -395,10 +395,10 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, static void usb_serial_disconnect(struct usb_device *dev, void *ptr); static struct usb_driver usb_serial_driver = { - name: "serial", - probe: usb_serial_probe, - disconnect: usb_serial_disconnect, - id_table: NULL, /* check all devices */ + .name = "serial", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = NULL, /* check all devices */ }; /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead @@ -447,24 +447,18 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po good_spot = 1; for (j = 1; j <= num_ports-1; ++j) - if (serial_table[i+j]) + if ((serial_table[i+j]) || (i+j >= SERIAL_TTY_MINORS)) { good_spot = 0; + i += j; + break; + } if (good_spot == 0) continue; - if (!serial) { - serial = kmalloc(sizeof(*serial), GFP_KERNEL); - if (!serial) { - err(__FUNCTION__ " - Out of memory"); - return NULL; - } - memset(serial, 0, sizeof(*serial)); - } serial->magic = USB_SERIAL_MAGIC; - serial_table[i] = serial; *minor = i; dbg(__FUNCTION__ " - minor base = %d", *minor); - for (i = *minor+1; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) + for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) serial_table[i] = serial; return serial; } @@ -1207,14 +1201,14 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, return(NULL); } + serial = create_serial (dev, interface, type); + if (!serial) { + err ("%s - out of memory", __FUNCTION__); + return NULL; + } + /* if this device type has a probe function, call it */ if (type->probe) { - serial = create_serial (dev, interface, type); - if (!serial) { - err ("%s - out of memory", __FUNCTION__); - return NULL; - } - if (type->owner) __MOD_INC_USE_COUNT(type->owner); retval = type->probe (serial); @@ -1293,6 +1287,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, num_ports = num_bulk_out; if (num_ports == 0) { err("Generic device with no bulk out, not allowed."); + kfree (serial); return NULL; } } @@ -1300,14 +1295,6 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, if (!num_ports) { /* if this device type has a calc_num_ports function, call it */ if (type->calc_num_ports) { - if (!serial) { - serial = create_serial (dev, interface, type); - if (!serial) { - err ("%s - out of memory", __FUNCTION__); - return NULL; - } - } - if (type->owner) __MOD_INC_USE_COUNT(type->owner); num_ports = type->calc_num_ports (serial); @@ -1318,22 +1305,17 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum, num_ports = type->num_ports; } - serial = get_free_serial (serial, num_ports, &minor); - if (serial == NULL) { + if (get_free_serial (serial, num_ports, &minor) == NULL) { err("No more free serial devices"); + kfree (serial); return NULL; } - serial->dev = dev; - serial->type = type; - serial->interface = interface; serial->minor = minor; serial->num_ports = num_ports; serial->num_bulk_in = num_bulk_in; serial->num_bulk_out = num_bulk_out; serial->num_interrupt_in = num_interrupt_in; - serial->vendor = dev->descriptor.idVendor; - serial->product = dev->descriptor.idProduct; /* set up the endpoint information */ for (i = 0; i < num_bulk_in; ++i) { @@ -1577,32 +1559,32 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr) static struct tty_driver serial_tty_driver = { - magic: TTY_DRIVER_MAGIC, - driver_name: "usb-serial", - name: "usb/tts/%d", - major: SERIAL_TTY_MAJOR, - minor_start: 0, - num: SERIAL_TTY_MINORS, - type: TTY_DRIVER_TYPE_SERIAL, - subtype: SERIAL_TYPE_NORMAL, - flags: TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, - - refcount: &serial_refcount, - table: serial_tty, - termios: serial_termios, - termios_locked: serial_termios_locked, - - open: serial_open, - close: serial_close, - write: serial_write, - write_room: serial_write_room, - ioctl: serial_ioctl, - set_termios: serial_set_termios, - throttle: serial_throttle, - unthrottle: serial_unthrottle, - break_ctl: serial_break, - chars_in_buffer: serial_chars_in_buffer, - read_proc: serial_read_proc, + .magic = TTY_DRIVER_MAGIC, + .driver_name = "usb-serial", + .name = "usb/tts/%d", + .major = SERIAL_TTY_MAJOR, + .minor_start = 0, + .num = SERIAL_TTY_MINORS, + .type = TTY_DRIVER_TYPE_SERIAL, + .subtype = SERIAL_TYPE_NORMAL, + .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, + + .refcount = &serial_refcount, + .table = serial_tty, + .termios = serial_termios, + .termios_locked = serial_termios_locked, + + .open = serial_open, + .close = serial_close, + .write = serial_write, + .write_room = serial_write_room, + .ioctl = serial_ioctl, + .set_termios = serial_set_termios, + .throttle = serial_throttle, + .unthrottle = serial_unthrottle, + .break_ctl = serial_break, + .chars_in_buffer = serial_chars_in_buffer, + .read_proc = serial_read_proc, }; @@ -1931,15 +1913,15 @@ static int usb_console_wait_key(struct console *co) #endif static struct console usbcons = { - name: "ttyUSB", /* only [8] */ - write: usb_console_write, + .name = "ttyUSB", /* only [8] */ + .write = usb_console_write, #if 0 - device: usb_console_device, /* TBD */ - wait_key: usb_console_wait_key, /* TBD */ + .device = usb_console_device, /* TBD */ + .wait_key = usb_console_wait_key, /* TBD */ #endif - setup: usb_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .setup = usb_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; #endif /* CONFIG_USB_SERIAL_CONSOLE */ diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 3eaefb051c5c..146394d96d91 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -218,50 +218,50 @@ MODULE_DEVICE_TABLE (usb, id_table_combined); /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ static struct usb_serial_device_type handspring_device = { - owner: THIS_MODULE, - name: "Handspring Visor / Palm 4.0 / Clié 4.x", - id_table: id_table, - num_interrupt_in: 0, - num_bulk_in: 2, - num_bulk_out: 2, - num_ports: 2, - open: visor_open, - close: visor_close, - throttle: visor_throttle, - unthrottle: visor_unthrottle, - probe: visor_probe, - calc_num_ports: visor_calc_num_ports, - shutdown: visor_shutdown, - ioctl: visor_ioctl, - set_termios: visor_set_termios, - write: visor_write, - write_room: visor_write_room, - chars_in_buffer: visor_chars_in_buffer, - write_bulk_callback: visor_write_bulk_callback, - read_bulk_callback: visor_read_bulk_callback, + .owner = THIS_MODULE, + .name = "Handspring Visor / Palm 4.0 / Clié 4.x", + .id_table = id_table, + .num_interrupt_in = 0, + .num_bulk_in = 2, + .num_bulk_out = 2, + .num_ports = 2, + .open = visor_open, + .close = visor_close, + .throttle = visor_throttle, + .unthrottle = visor_unthrottle, + .probe = visor_probe, + .calc_num_ports = visor_calc_num_ports, + .shutdown = visor_shutdown, + .ioctl = visor_ioctl, + .set_termios = visor_set_termios, + .write = visor_write, + .write_room = visor_write_room, + .chars_in_buffer = visor_chars_in_buffer, + .write_bulk_callback = visor_write_bulk_callback, + .read_bulk_callback = visor_read_bulk_callback, }; /* device info for the Sony Clie OS version 3.5 */ static struct usb_serial_device_type clie_3_5_device = { - owner: THIS_MODULE, - name: "Sony Clié 3.5", - id_table: clie_id_3_5_table, - num_interrupt_in: 0, - num_bulk_in: 1, - num_bulk_out: 1, - num_ports: 1, - open: visor_open, - close: visor_close, - throttle: visor_throttle, - unthrottle: visor_unthrottle, - attach: clie_3_5_startup, - ioctl: visor_ioctl, - set_termios: visor_set_termios, - write: visor_write, - write_room: visor_write_room, - chars_in_buffer: visor_chars_in_buffer, - write_bulk_callback: visor_write_bulk_callback, - read_bulk_callback: visor_read_bulk_callback, + .owner = THIS_MODULE, + .name = "Sony Clié 3.5", + .id_table = clie_id_3_5_table, + .num_interrupt_in = 0, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = visor_open, + .close = visor_close, + .throttle = visor_throttle, + .unthrottle = visor_unthrottle, + .attach = clie_3_5_startup, + .ioctl = visor_ioctl, + .set_termios = visor_set_termios, + .write = visor_write, + .write_room = visor_write_room, + .chars_in_buffer = visor_chars_in_buffer, + .write_bulk_callback = visor_write_bulk_callback, + .read_bulk_callback = visor_read_bulk_callback, }; diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 483dfa361700..1e41ef169a87 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -130,32 +130,32 @@ static int whiteheat_attach (struct usb_serial *serial); static void whiteheat_shutdown (struct usb_serial *serial); static struct usb_serial_device_type whiteheat_fake_device = { - owner: THIS_MODULE, - name: "Connect Tech - WhiteHEAT - (prerenumeration)", - id_table: id_table_prerenumeration, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, - num_ports: 1, - probe: whiteheat_firmware_download, + .owner = THIS_MODULE, + .name = "Connect Tech - WhiteHEAT - (prerenumeration)", + .id_table = id_table_prerenumeration, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, + .probe = whiteheat_firmware_download, }; static struct usb_serial_device_type whiteheat_device = { - owner: THIS_MODULE, - name: "Connect Tech - WhiteHEAT", - id_table: id_table_std, - num_interrupt_in: NUM_DONT_CARE, - num_bulk_in: NUM_DONT_CARE, - num_bulk_out: NUM_DONT_CARE, - num_ports: 4, - open: whiteheat_open, - close: whiteheat_close, - throttle: whiteheat_throttle, - unthrottle: whiteheat_unthrottle, - ioctl: whiteheat_ioctl, - set_termios: whiteheat_set_termios, - attach: whiteheat_attach, - shutdown: whiteheat_shutdown, + .owner = THIS_MODULE, + .name = "Connect Tech - WhiteHEAT", + .id_table = id_table_std, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 4, + .open = whiteheat_open, + .close = whiteheat_close, + .throttle = whiteheat_throttle, + .unthrottle = whiteheat_unthrottle, + .ioctl = whiteheat_ioctl, + .set_termios = whiteheat_set_termios, + .attach = whiteheat_attach, + .shutdown = whiteheat_shutdown, }; struct whiteheat_private { diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index e1fc6507734a..21fb4e6c1835 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -354,29 +354,29 @@ static int proc_info (char *buffer, char **start, off_t offset, int length, */ Scsi_Host_Template usb_stor_host_template = { - name: "usb-storage", - proc_info: proc_info, - info: host_info, - - detect: detect, - release: release, - command: command, - queuecommand: queuecommand, - - eh_abort_handler: command_abort, - eh_device_reset_handler:device_reset, - eh_bus_reset_handler: bus_reset, - eh_host_reset_handler: host_reset, - - can_queue: 1, - this_id: -1, - - sg_tablesize: SG_ALL, - cmd_per_lun: 1, - present: 0, - unchecked_isa_dma: FALSE, - use_clustering: TRUE, - emulated: TRUE + .name = "usb-storage", + .proc_info = proc_info, + .info = host_info, + + .detect = detect, + .release = release, + .command = command, + .queuecommand = queuecommand, + + .eh_abort_handler = command_abort, + .eh_device_reset_handler =device_reset, + .eh_bus_reset_handler = bus_reset, + .eh_host_reset_handler =host_reset, + + .can_queue = 1, + .this_id = -1, + + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .present = 0, + .unchecked_isa_dma = FALSE, + .use_clustering = TRUE, + .emulated = TRUE }; unsigned char usb_stor_sense_notready[18] = { diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 2e8b68f47517..c0bdea0c4e6e 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -170,12 +170,12 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); vendor_name, product_name, use_protocol, use_transport, \ init_function, Flags) \ { \ - vendorName: vendor_name, \ - productName: product_name, \ - useProtocol: use_protocol, \ - useTransport: use_transport, \ + .vendorName = vendor_name, \ + .productName = product_name, \ + .useProtocol = use_protocol, \ + .useTransport = use_transport, \ initFunction : init_function, \ - flags: Flags, \ + .flags = Flags, \ } static struct us_unusual_dev us_unusual_dev_list[] = { @@ -228,10 +228,10 @@ static struct us_unusual_dev us_unusual_dev_list[] = { }; struct usb_driver usb_storage_driver = { - name: "usb-storage", - probe: storage_probe, - disconnect: storage_disconnect, - id_table: storage_usb_ids, + .name = "usb-storage", + .probe = storage_probe, + .disconnect = storage_disconnect, + .id_table = storage_usb_ids, }; /* diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 64fb0078a6cc..f73d6ba9d43b 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -174,22 +174,22 @@ static struct file_operations skel_fops = { * and decrement it again in the release() function * yourself. */ - owner: THIS_MODULE, + .owner = THIS_MODULE, - read: skel_read, - write: skel_write, - ioctl: skel_ioctl, - open: skel_open, - release: skel_release, + .read = skel_read, + .write = skel_write, + .ioctl = skel_ioctl, + .open = skel_open, + .release = skel_release, }; /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver skel_driver = { - name: "skeleton", - probe: skel_probe, - disconnect: skel_disconnect, - id_table: skel_table, + .name = "skeleton", + .probe = skel_probe, + .disconnect = skel_disconnect, + .id_table = skel_table, }; diff --git a/include/linux/usb.h b/include/linux/usb.h index 11836df8a6ab..92496658baf5 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -431,6 +431,10 @@ extern void usb_free_dev(struct usb_device *); /* for when layers above USB add new non-USB drivers */ extern void usb_scan_devices(void); +/* for probe/disconnect with correct module usage counting */ +void *usb_bind_driver(struct usb_driver *driver, struct usb_device *dev, unsigned int ifnum); +void usb_unbind_driver(struct usb_device *device, struct usb_interface *intf); + /* mostly for devices emulating SCSI over USB */ extern int usb_reset_device(struct usb_device *dev); |
