Commit 8a80abf7 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

merge

parents 45c22f8f 8eb7d852
...@@ -15,10 +15,12 @@ OR: they can now be DMA-aware. ...@@ -15,10 +15,12 @@ OR: they can now be DMA-aware.
manage dma mappings for existing dma-ready buffers (see below). manage dma mappings for existing dma-ready buffers (see below).
- URBs have an additional "transfer_dma" field, as well as a transfer_flags - URBs have an additional "transfer_dma" field, as well as a transfer_flags
bit saying if it's valid. (Control requests also needed "setup_dma".) bit saying if it's valid. (Control requests also have "setup_dma" and a
corresponding transfer_flags bit.)
- "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do it - "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do
first and set URB_NO_DMA_MAP. HCDs don't manage dma mappings for urbs. it first and set URB_NO_TRANSFER_DMA_MAP or URB_NO_SETUP_DMA_MAP. HCDs
don't manage dma mappings for URBs.
- There's a new "generic DMA API", parts of which are usable by USB device - There's a new "generic DMA API", parts of which are usable by USB device
drivers. Never use dma_set_mask() on any USB interface or device; that drivers. Never use dma_set_mask() on any USB interface or device; that
...@@ -33,8 +35,9 @@ and effects like cache-trashing can impose subtle penalties. ...@@ -33,8 +35,9 @@ and effects like cache-trashing can impose subtle penalties.
- When you're allocating a buffer for DMA purposes anyway, use the buffer - When you're allocating a buffer for DMA purposes anyway, use the buffer
primitives. Think of them as kmalloc and kfree that give you the right primitives. Think of them as kmalloc and kfree that give you the right
kind of addresses to store in urb->transfer_buffer and urb->transfer_dma, kind of addresses to store in urb->transfer_buffer and urb->transfer_dma,
while guaranteeing that hidden copies through DMA "bounce" buffers won't while guaranteeing that no hidden copies through DMA "bounce" buffers will
slow things down. You'd also set URB_NO_DMA_MAP in urb->transfer_flags: slow things down. You'd also set URB_NO_TRANSFER_DMA_MAP in
urb->transfer_flags:
void *usb_buffer_alloc (struct usb_device *dev, size_t size, void *usb_buffer_alloc (struct usb_device *dev, size_t size,
int mem_flags, dma_addr_t *dma); int mem_flags, dma_addr_t *dma);
...@@ -42,10 +45,18 @@ and effects like cache-trashing can impose subtle penalties. ...@@ -42,10 +45,18 @@ and effects like cache-trashing can impose subtle penalties.
void usb_buffer_free (struct usb_device *dev, size_t size, void usb_buffer_free (struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma); void *addr, dma_addr_t dma);
For control transfers you can use the buffer primitives or not for each
of the transfer buffer and setup buffer independently. Set the flag bits
URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP to indicate which
buffers you have prepared. For non-control transfers URB_NO_SETUP_DMA_MAP
is ignored.
The memory buffer returned is "dma-coherent"; sometimes you might need to The memory buffer returned is "dma-coherent"; sometimes you might need to
force a consistent memory access ordering by using memory barriers. It's force a consistent memory access ordering by using memory barriers. It's
not using a streaming DMA mapping, so it's good for small transfers on not using a streaming DMA mapping, so it's good for small transfers on
systems where the I/O would otherwise tie up an IOMMU mapping. systems where the I/O would otherwise tie up an IOMMU mapping. (See
Documentation/DMA-mapping.txt for definitions of "coherent" and "streaming"
DMA mappings.)
Asking for 1/Nth of a page (as well as asking for N pages) is reasonably Asking for 1/Nth of a page (as well as asking for N pages) is reasonably
space-efficient. space-efficient.
...@@ -91,7 +102,8 @@ DMA address space of the device. ...@@ -91,7 +102,8 @@ DMA address space of the device.
These calls all work with initialized urbs: urb->dev, urb->pipe, These calls all work with initialized urbs: urb->dev, urb->pipe,
urb->transfer_buffer, and urb->transfer_buffer_length must all be urb->transfer_buffer, and urb->transfer_buffer_length must all be
valid when these calls are used: valid when these calls are used (urb->setup_packet must be valid too
if urb is a control request):
struct urb *usb_buffer_map (struct urb *urb); struct urb *usb_buffer_map (struct urb *urb);
...@@ -99,6 +111,6 @@ DMA address space of the device. ...@@ -99,6 +111,6 @@ DMA address space of the device.
void usb_buffer_unmap (struct urb *urb); void usb_buffer_unmap (struct urb *urb);
The calls manage urb->transfer_dma for you, and set URB_NO_DMA_MAP so that The calls manage urb->transfer_dma for you, and set URB_NO_TRANSFER_DMA_MAP
usbcore won't map or unmap the buffer. so that usbcore won't map or unmap the buffer. The same goes for
urb->setup_dma and URB_NO_SETUP_DMA_MAP for control requests.
obj-$(CONFIG_USB_AX8817X) += crc32.o
obj-$(CONFIG_USB_CATC) += crc32.o obj-$(CONFIG_USB_CATC) += crc32.o
obj-$(CONFIG_USB_SPEEDTOUCH) += crc32.o obj-$(CONFIG_USB_SPEEDTOUCH) += crc32.o
obj-$(CONFIG_USB_USBNET) += crc32.o obj-$(CONFIG_USB_USBNET) += crc32.o
...@@ -541,7 +541,7 @@ static void dmabuf_copyin(struct dmabuf *db, const void *buffer, unsigned int si ...@@ -541,7 +541,7 @@ static void dmabuf_copyin(struct dmabuf *db, const void *buffer, unsigned int si
pgrem = rem; pgrem = rem;
memcpy((db->sgbuf[db->wrptr >> PAGE_SHIFT]) + (db->wrptr & (PAGE_SIZE-1)), buffer, pgrem); memcpy((db->sgbuf[db->wrptr >> PAGE_SHIFT]) + (db->wrptr & (PAGE_SIZE-1)), buffer, pgrem);
size -= pgrem; size -= pgrem;
(char *)buffer += pgrem; buffer += pgrem;
db->wrptr += pgrem; db->wrptr += pgrem;
if (db->wrptr >= db->dmasize) if (db->wrptr >= db->dmasize)
db->wrptr = 0; db->wrptr = 0;
...@@ -564,14 +564,14 @@ static void dmabuf_copyout(struct dmabuf *db, void *buffer, unsigned int size) ...@@ -564,14 +564,14 @@ static void dmabuf_copyout(struct dmabuf *db, void *buffer, unsigned int size)
pgrem = rem; pgrem = rem;
memcpy(buffer, (db->sgbuf[db->rdptr >> PAGE_SHIFT]) + (db->rdptr & (PAGE_SIZE-1)), pgrem); memcpy(buffer, (db->sgbuf[db->rdptr >> PAGE_SHIFT]) + (db->rdptr & (PAGE_SIZE-1)), pgrem);
size -= pgrem; size -= pgrem;
(char *)buffer += pgrem; buffer += pgrem;
db->rdptr += pgrem; db->rdptr += pgrem;
if (db->rdptr >= db->dmasize) if (db->rdptr >= db->dmasize)
db->rdptr = 0; db->rdptr = 0;
} }
} }
static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void *buffer, unsigned int size) static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void __user *buffer, unsigned int size)
{ {
unsigned int pgrem, rem; unsigned int pgrem, rem;
...@@ -589,14 +589,14 @@ static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void *b ...@@ -589,14 +589,14 @@ static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void *b
if (copy_from_user((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem)) if (copy_from_user((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem))
return -EFAULT; return -EFAULT;
size -= pgrem; size -= pgrem;
(char *)buffer += pgrem; buffer += pgrem;
ptr += pgrem; ptr += pgrem;
if (ptr >= db->dmasize) if (ptr >= db->dmasize)
ptr = 0; ptr = 0;
} }
} }
static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void *buffer, unsigned int size) static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void __user *buffer, unsigned int size)
{ {
unsigned int pgrem, rem; unsigned int pgrem, rem;
...@@ -614,7 +614,7 @@ static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void *buffer ...@@ -614,7 +614,7 @@ static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void *buffer
if (copy_to_user(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem)) if (copy_to_user(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem))
return -EFAULT; return -EFAULT;
size -= pgrem; size -= pgrem;
(char *)buffer += pgrem; buffer += pgrem;
ptr += pgrem; ptr += pgrem;
if (ptr >= db->dmasize) if (ptr >= db->dmasize)
ptr = 0; ptr = 0;
...@@ -2010,7 +2010,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign ...@@ -2010,7 +2010,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
strncpy(info.id, "USB_AUDIO", sizeof(info.id)); strncpy(info.id, "USB_AUDIO", sizeof(info.id));
strncpy(info.name, "USB Audio Class Driver", sizeof(info.name)); strncpy(info.name, "USB Audio Class Driver", sizeof(info.name));
info.modify_counter = ms->modcnt; info.modify_counter = ms->modcnt;
if (copy_to_user((void *)arg, &info, sizeof(info))) if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
...@@ -2018,7 +2018,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign ...@@ -2018,7 +2018,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
_old_mixer_info info; _old_mixer_info info;
strncpy(info.id, "USB_AUDIO", sizeof(info.id)); strncpy(info.id, "USB_AUDIO", sizeof(info.id));
strncpy(info.name, "USB Audio Class Driver", sizeof(info.name)); strncpy(info.name, "USB Audio Class Driver", sizeof(info.name));
if (copy_to_user((void *)arg, &info, sizeof(info))) if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
...@@ -2140,7 +2140,7 @@ static int drain_out(struct usb_audiodev *as, int nonblock) ...@@ -2140,7 +2140,7 @@ static int drain_out(struct usb_audiodev *as, int nonblock)
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
static ssize_t usb_audio_read(struct file *file, char *buffer, size_t count, loff_t *ppos) static ssize_t usb_audio_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{ {
struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
...@@ -2208,7 +2208,7 @@ static ssize_t usb_audio_read(struct file *file, char *buffer, size_t count, lof ...@@ -2208,7 +2208,7 @@ static ssize_t usb_audio_read(struct file *file, char *buffer, size_t count, lof
return ret; return ret;
} }
static ssize_t usb_audio_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) static ssize_t usb_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{ {
struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
...@@ -2507,7 +2507,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -2507,7 +2507,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
abinfo.fragstotal = as->usbout.dma.numfrag; abinfo.fragstotal = as->usbout.dma.numfrag;
abinfo.fragments = abinfo.bytes >> as->usbout.dma.fragshift; abinfo.fragments = abinfo.bytes >> as->usbout.dma.fragshift;
spin_unlock_irqrestore(&as->lock, flags); spin_unlock_irqrestore(&as->lock, flags);
return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE: case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ)) if (!(file->f_mode & FMODE_READ))
...@@ -2520,7 +2520,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -2520,7 +2520,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
abinfo.fragstotal = as->usbin.dma.numfrag; abinfo.fragstotal = as->usbin.dma.numfrag;
abinfo.fragments = abinfo.bytes >> as->usbin.dma.fragshift; abinfo.fragments = abinfo.bytes >> as->usbin.dma.fragshift;
spin_unlock_irqrestore(&as->lock, flags); spin_unlock_irqrestore(&as->lock, flags);
return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK: case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK; file->f_flags |= O_NONBLOCK;
...@@ -2544,7 +2544,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -2544,7 +2544,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
if (as->usbin.dma.mapped) if (as->usbin.dma.mapped)
as->usbin.dma.count &= as->usbin.dma.fragsize-1; as->usbin.dma.count &= as->usbin.dma.fragsize-1;
spin_unlock_irqrestore(&as->lock, flags); spin_unlock_irqrestore(&as->lock, flags);
if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo))) if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -2558,7 +2558,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -2558,7 +2558,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
if (as->usbout.dma.mapped) if (as->usbout.dma.mapped)
as->usbout.dma.count &= as->usbout.dma.fragsize-1; as->usbout.dma.count &= as->usbout.dma.fragsize-1;
spin_unlock_irqrestore(&as->lock, flags); spin_unlock_irqrestore(&as->lock, flags);
if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo))) if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
return -EFAULT; return -EFAULT;
return 0; return 0;
......
...@@ -484,7 +484,7 @@ static int bluetooth_write (struct tty_struct * tty, int from_user, const unsign ...@@ -484,7 +484,7 @@ static int bluetooth_write (struct tty_struct * tty, int from_user, const unsign
retval = -ENOMEM; retval = -ENOMEM;
goto exit; goto exit;
} }
if (copy_from_user (temp_buffer, buf, count)) { if (copy_from_user (temp_buffer, (void __user *)buf, count)) {
retval = -EFAULT; retval = -EFAULT;
goto exit; goto exit;
} }
......
...@@ -388,7 +388,7 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c ...@@ -388,7 +388,7 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c
count = (count > acm->writesize) ? acm->writesize : count; count = (count > acm->writesize) ? acm->writesize : count;
if (from_user) { if (from_user) {
if (copy_from_user(acm->writeurb->transfer_buffer, buf, count)) if (copy_from_user(acm->writeurb->transfer_buffer, (void __user *)buf, count))
return -EFAULT; return -EFAULT;
} else } else
memcpy(acm->writeurb->transfer_buffer, buf, count); memcpy(acm->writeurb->transfer_buffer, buf, count);
...@@ -548,7 +548,7 @@ static int acm_probe (struct usb_interface *intf, ...@@ -548,7 +548,7 @@ static int acm_probe (struct usb_interface *intf,
struct usb_host_config *cfacm; struct usb_host_config *cfacm;
struct usb_host_interface *ifcom, *ifdata; struct usb_host_interface *ifcom, *ifdata;
struct usb_endpoint_descriptor *epctrl, *epread, *epwrite; struct usb_endpoint_descriptor *epctrl, *epread, *epwrite;
int readsize, ctrlsize, minor, i; int readsize, ctrlsize, minor, i, j;
unsigned char *buf; unsigned char *buf;
dev = interface_to_usbdev (intf); dev = interface_to_usbdev (intf);
...@@ -558,23 +558,25 @@ static int acm_probe (struct usb_interface *intf, ...@@ -558,23 +558,25 @@ static int acm_probe (struct usb_interface *intf,
dbg("probing config %d", cfacm->desc.bConfigurationValue); dbg("probing config %d", cfacm->desc.bConfigurationValue);
if (cfacm->desc.bNumInterfaces != 2 || for (j = 0; j < cfacm->desc.bNumInterfaces - 1; j++) {
usb_interface_claimed(cfacm->interface + 0) ||
usb_interface_claimed(cfacm->interface + 1)) if (usb_interface_claimed(cfacm->interface + j) ||
usb_interface_claimed(cfacm->interface + j + 1))
continue; continue;
ifcom = cfacm->interface[0].altsetting + 0; ifcom = cfacm->interface[j].altsetting + 0;
ifdata = cfacm->interface[1].altsetting + 0; ifdata = cfacm->interface[j + 1].altsetting + 0;
if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) { if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) {
ifcom = cfacm->interface[1].altsetting + 0; ifcom = cfacm->interface[j + 1].altsetting + 0;
ifdata = cfacm->interface[0].altsetting + 0; ifdata = cfacm->interface[j].altsetting + 0;
if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2)
continue; continue;
} }
if (ifcom->desc.bInterfaceClass != 2 || ifcom->desc.bInterfaceSubClass != 2 || if (ifcom->desc.bInterfaceClass != 2 || ifcom->desc.bInterfaceSubClass != 2 ||
ifcom->desc.bInterfaceProtocol != 1 || ifcom->desc.bNumEndpoints < 1) ifcom->desc.bInterfaceProtocol < 1 || ifcom->desc.bInterfaceProtocol > 6 ||
ifcom->desc.bNumEndpoints < 1)
continue; continue;
epctrl = &ifcom->endpoint[0].desc; epctrl = &ifcom->endpoint[0].desc;
...@@ -608,7 +610,7 @@ static int acm_probe (struct usb_interface *intf, ...@@ -608,7 +610,7 @@ static int acm_probe (struct usb_interface *intf,
ctrlsize = epctrl->wMaxPacketSize; ctrlsize = epctrl->wMaxPacketSize;
readsize = epread->wMaxPacketSize; readsize = epread->wMaxPacketSize;
acm->writesize = epwrite->wMaxPacketSize; acm->writesize = epwrite->wMaxPacketSize;
acm->iface = cfacm->interface; acm->iface = cfacm->interface + j;
acm->minor = minor; acm->minor = minor;
acm->dev = dev; acm->dev = dev;
...@@ -673,6 +675,7 @@ static int acm_probe (struct usb_interface *intf, ...@@ -673,6 +675,7 @@ static int acm_probe (struct usb_interface *intf,
usb_set_intfdata (intf, acm); usb_set_intfdata (intf, acm);
return 0; return 0;
} }
}
return -EIO; return -EIO;
} }
......
...@@ -642,7 +642,7 @@ static loff_t usb_midi_llseek(struct file *file, loff_t offset, int origin) ...@@ -642,7 +642,7 @@ static loff_t usb_midi_llseek(struct file *file, loff_t offset, int origin)
* *
**/ **/
static ssize_t usb_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) static ssize_t usb_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{ {
struct usb_mididev *m = (struct usb_mididev *)file->private_data; struct usb_mididev *m = (struct usb_mididev *)file->private_data;
struct midi_in_endpoint *ep = m->min.ep; struct midi_in_endpoint *ep = m->min.ep;
...@@ -725,7 +725,7 @@ static ssize_t usb_midi_read(struct file *file, char *buffer, size_t count, loff ...@@ -725,7 +725,7 @@ static ssize_t usb_midi_read(struct file *file, char *buffer, size_t count, loff
* *
**/ **/
static ssize_t usb_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) static ssize_t usb_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{ {
struct usb_mididev *m = (struct usb_mididev *)file->private_data; struct usb_mididev *m = (struct usb_mididev *)file->private_data;
ssize_t ret; ssize_t ret;
......
...@@ -296,13 +296,13 @@ static int usblp_check_status(struct usblp *usblp, int err) ...@@ -296,13 +296,13 @@ static int usblp_check_status(struct usblp *usblp, int err)
} }
status = *usblp->statusbuf; status = *usblp->statusbuf;
if (~status & LP_PERRORP) {
if (~status & LP_PERRORP)
newerr = 3; newerr = 3;
if (status & LP_POUTPA) if (status & LP_POUTPA)
newerr = 1; newerr = 1;
if (~status & LP_PSELECD) if (~status & LP_PSELECD)
newerr = 2; newerr = 2;
}
if (newerr != err) if (newerr != err)
info("usblp%d: %s", usblp->minor, usblp_messages[newerr]); info("usblp%d: %s", usblp->minor, usblp_messages[newerr]);
...@@ -426,7 +426,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -426,7 +426,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{ {
struct usblp *usblp = file->private_data; struct usblp *usblp = file->private_data;
int length, err, i; int length, err, i;
unsigned char lpstatus, newChannel; unsigned char newChannel;
int status; int status;
int twoints[2]; int twoints[2];
int retval = 0; int retval = 0;
...@@ -455,7 +455,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -455,7 +455,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (length > _IOC_SIZE(cmd)) if (length > _IOC_SIZE(cmd))
length = _IOC_SIZE(cmd); /* truncate */ length = _IOC_SIZE(cmd); /* truncate */
if (copy_to_user((unsigned char *) arg, if (copy_to_user((void __user *) arg,
usblp->device_id_string, usblp->device_id_string,
(unsigned long) length)) { (unsigned long) length)) {
retval = -EFAULT; retval = -EFAULT;
...@@ -479,7 +479,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -479,7 +479,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
twoints[1] |= (1<<i); twoints[1] |= (1<<i);
} }
if (copy_to_user((unsigned char *)arg, if (copy_to_user((void __user *)arg,
(unsigned char *)twoints, (unsigned char *)twoints,
sizeof(twoints))) { sizeof(twoints))) {
retval = -EFAULT; retval = -EFAULT;
...@@ -540,7 +540,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -540,7 +540,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
twoints[0] = usblp->dev->bus->busnum; twoints[0] = usblp->dev->bus->busnum;
twoints[1] = usblp->dev->devnum; twoints[1] = usblp->dev->devnum;
if (copy_to_user((unsigned char *)arg, if (copy_to_user((void __user *)arg,
(unsigned char *)twoints, (unsigned char *)twoints,
sizeof(twoints))) { sizeof(twoints))) {
retval = -EFAULT; retval = -EFAULT;
...@@ -560,7 +560,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -560,7 +560,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
twoints[0] = usblp->dev->descriptor.idVendor; twoints[0] = usblp->dev->descriptor.idVendor;
twoints[1] = usblp->dev->descriptor.idProduct; twoints[1] = usblp->dev->descriptor.idProduct;
if (copy_to_user((unsigned char *)arg, if (copy_to_user((void __user *)arg,
(unsigned char *)twoints, (unsigned char *)twoints,
sizeof(twoints))) { sizeof(twoints))) {
retval = -EFAULT; retval = -EFAULT;
...@@ -578,13 +578,13 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -578,13 +578,13 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (cmd) { switch (cmd) {
case LPGETSTATUS: case LPGETSTATUS:
if (usblp_read_status(usblp, &lpstatus)) { if (usblp_read_status(usblp, usblp->statusbuf)) {
err("usblp%d: failed reading printer status", usblp->minor); err("usblp%d: failed reading printer status", usblp->minor);
retval = -EIO; retval = -EIO;
goto done; goto done;
} }
status = lpstatus; status = *usblp->statusbuf;
if (copy_to_user ((int *)arg, &status, sizeof(int))) if (copy_to_user ((void __user *)arg, &status, sizeof(int)))
retval = -EFAULT; retval = -EFAULT;
break; break;
...@@ -597,7 +597,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -597,7 +597,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return retval; return retval;
} }
static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{ {
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
struct usblp *usblp = file->private_data; struct usblp *usblp = file->private_data;
...@@ -682,7 +682,7 @@ static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, ...@@ -682,7 +682,7 @@ static ssize_t usblp_write(struct file *file, const char *buffer, size_t count,
return count; return count;
} }
static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t *ppos) static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{ {
struct usblp *usblp = file->private_data; struct usblp *usblp = file->private_data;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
...@@ -858,8 +858,8 @@ static int usblp_probe(struct usb_interface *intf, ...@@ -858,8 +858,8 @@ static int usblp_probe(struct usb_interface *intf,
} }
usblp->writebuf = usblp->readbuf = NULL; usblp->writebuf = usblp->readbuf = NULL;
usblp->writeurb->transfer_flags = URB_NO_DMA_MAP; usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
usblp->readurb->transfer_flags = URB_NO_DMA_MAP; usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
/* Malloc write & read buffers. We somewhat wastefully /* Malloc write & read buffers. We somewhat wastefully
* malloc both regardless of bidirectionality, because the * malloc both regardless of bidirectionality, because the
* alternate setting can be changed later via an ioctl. */ * alternate setting can be changed later via an ioctl. */
......
...@@ -459,7 +459,8 @@ static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb) ...@@ -459,7 +459,8 @@ static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb)
/* rh_timer protected by hcd_data_lock */ /* rh_timer protected by hcd_data_lock */
if (hcd->rh_timer.data if (hcd->rh_timer.data
|| urb->status != -EINPROGRESS || urb->status != -EINPROGRESS
|| urb->transfer_buffer_length < len) { || urb->transfer_buffer_length < len
|| !HCD_IS_RUNNING (hcd->state)) {
dev_dbg (hcd->controller, dev_dbg (hcd->controller,
"not queuing rh status urb, stat %d\n", "not queuing rh status urb, stat %d\n",
urb->status); urb->status);
...@@ -489,11 +490,10 @@ static void rh_report_status (unsigned long ptr) ...@@ -489,11 +490,10 @@ static void rh_report_status (unsigned long ptr)
local_irq_save (flags); local_irq_save (flags);
spin_lock (&urb->lock); spin_lock (&urb->lock);
/* do nothing if the hc is gone or the urb's been unlinked */ /* do nothing if the urb's been unlinked */
if (!urb->dev if (!urb->dev
|| urb->status != -EINPROGRESS || urb->status != -EINPROGRESS
|| (hcd = urb->dev->bus->hcpriv) == 0 || (hcd = urb->dev->bus->hcpriv) == 0) {
|| !HCD_IS_RUNNING (hcd->state)) {
spin_unlock (&urb->lock); spin_unlock (&urb->lock);
local_irq_restore (flags); local_irq_restore (flags);
return; return;
...@@ -1027,7 +1027,8 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1027,7 +1027,8 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
* valid and usb_buffer_{sync,unmap}() not be needed, since * valid and usb_buffer_{sync,unmap}() not be needed, since
* they could clobber root hub response data. * they could clobber root hub response data.
*/ */
urb->transfer_flags |= URB_NO_DMA_MAP; urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
| URB_NO_SETUP_DMA_MAP);
status = rh_urb_enqueue (hcd, urb); status = rh_urb_enqueue (hcd, urb);
goto done; goto done;
} }
...@@ -1035,15 +1036,16 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1035,15 +1036,16 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
/* lower level hcd code should use *_dma exclusively, /* lower level hcd code should use *_dma exclusively,
* unless it uses pio or talks to another transport. * unless it uses pio or talks to another transport.
*/ */
if (!(urb->transfer_flags & URB_NO_DMA_MAP) if (hcd->controller->dma_mask) {
&& hcd->controller->dma_mask) { if (usb_pipecontrol (urb->pipe)
if (usb_pipecontrol (urb->pipe)) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
urb->setup_dma = dma_map_single ( urb->setup_dma = dma_map_single (
hcd->controller, hcd->controller,
urb->setup_packet, urb->setup_packet,
sizeof (struct usb_ctrlrequest), sizeof (struct usb_ctrlrequest),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (urb->transfer_buffer_length != 0) if (urb->transfer_buffer_length != 0
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
urb->transfer_dma = dma_map_single ( urb->transfer_dma = dma_map_single (
hcd->controller, hcd->controller,
urb->transfer_buffer, urb->transfer_buffer,
...@@ -1410,12 +1412,14 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs ...@@ -1410,12 +1412,14 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs
// It would catch exit/unlink paths for all urbs. // It would catch exit/unlink paths for all urbs.
/* lower level hcd code should use *_dma exclusively */ /* lower level hcd code should use *_dma exclusively */
if (!(urb->transfer_flags & URB_NO_DMA_MAP)) { if (hcd->controller->dma_mask) {
if (usb_pipecontrol (urb->pipe)) if (usb_pipecontrol (urb->pipe)
&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
pci_unmap_single (hcd->pdev, urb->setup_dma, pci_unmap_single (hcd->pdev, urb->setup_dma,
sizeof (struct usb_ctrlrequest), sizeof (struct usb_ctrlrequest),
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
if (urb->transfer_buffer_length != 0) if (urb->transfer_buffer_length != 0
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
pci_unmap_single (hcd->pdev, urb->transfer_dma, pci_unmap_single (hcd->pdev, urb->transfer_dma,
urb->transfer_buffer_length, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
......
...@@ -461,7 +461,7 @@ static int hub_configure(struct usb_hub *hub, ...@@ -461,7 +461,7 @@ static int hub_configure(struct usb_hub *hub,
usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq, usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq,
hub, endpoint->bInterval); hub, endpoint->bInterval);
hub->urb->transfer_dma = hub->buffer_dma; hub->urb->transfer_dma = hub->buffer_dma;
hub->urb->transfer_flags |= URB_NO_DMA_MAP; hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
ret = usb_submit_urb(hub->urb, GFP_KERNEL); ret = usb_submit_urb(hub->urb, GFP_KERNEL);
if (ret) { if (ret) {
message = "couldn't submit status urb"; message = "couldn't submit status urb";
......
...@@ -344,7 +344,8 @@ int usb_sg_init ( ...@@ -344,7 +344,8 @@ int usb_sg_init (
if (!io->urbs) if (!io->urbs)
goto nomem; goto nomem;
urb_flags = URB_ASYNC_UNLINK | URB_NO_DMA_MAP | URB_NO_INTERRUPT; urb_flags = URB_ASYNC_UNLINK | URB_NO_TRANSFER_DMA_MAP
| URB_NO_INTERRUPT;
if (usb_pipein (pipe)) if (usb_pipein (pipe))
urb_flags |= URB_SHORT_NOT_OK; urb_flags |= URB_SHORT_NOT_OK;
......
...@@ -297,7 +297,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags) ...@@ -297,7 +297,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
/* enforce simple/standard policy */ /* enforce simple/standard policy */
allowed = URB_ASYNC_UNLINK; // affects later unlinks allowed = URB_ASYNC_UNLINK; // affects later unlinks
allowed |= URB_NO_DMA_MAP; allowed |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
allowed |= URB_NO_INTERRUPT; allowed |= URB_NO_INTERRUPT;
switch (temp) { switch (temp) {
case PIPE_BULK: case PIPE_BULK:
......
...@@ -1234,7 +1234,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1234,7 +1234,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
} }
/** /**
* usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
* @dev: device the buffer will be used with * @dev: device the buffer will be used with
* @size: requested buffer size * @size: requested buffer size
* @mem_flags: affect whether allocation may block * @mem_flags: affect whether allocation may block
...@@ -1245,9 +1245,9 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1245,9 +1245,9 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
* specified device. Such cpu-space buffers are returned along with the DMA * specified device. Such cpu-space buffers are returned along with the DMA
* address (through the pointer provided). * address (through the pointer provided).
* *
* These buffers are used with URB_NO_DMA_MAP set in urb->transfer_flags to * These buffers are used with URB_NO_xxx_DMA_MAP set in urb->transfer_flags
* avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping * to avoid behaviors like using "DMA bounce buffers", or tying down I/O
* hardware for long idle periods. The implementation varies between * mapping hardware for long idle periods. The implementation varies between
* platforms, depending on details of how DMA will work to this device. * platforms, depending on details of how DMA will work to this device.
* Using these buffers also helps prevent cacheline sharing problems on * Using these buffers also helps prevent cacheline sharing problems on
* architectures where CPU caches are not DMA-coherent. * architectures where CPU caches are not DMA-coherent.
...@@ -1291,17 +1291,17 @@ void usb_buffer_free ( ...@@ -1291,17 +1291,17 @@ void usb_buffer_free (
/** /**
* usb_buffer_map - create DMA mapping(s) for an urb * usb_buffer_map - create DMA mapping(s) for an urb
* @urb: urb whose transfer_buffer will be mapped * @urb: urb whose transfer_buffer/setup_packet will be mapped
* *
* Return value is either null (indicating no buffer could be mapped), or * Return value is either null (indicating no buffer could be mapped), or
* the parameter. URB_NO_DMA_MAP is added to urb->transfer_flags if the * the parameter. URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP are
* operation succeeds. If the device is connected to this system through * added to urb->transfer_flags if the operation succeeds. If the device
* a non-DMA controller, this operation always succeeds. * is connected to this system through a non-DMA controller, this operation
* always succeeds.
* *
* This call would normally be used for an urb which is reused, perhaps * This call would normally be used for an urb which is reused, perhaps
* as the target of a large periodic transfer, with usb_buffer_dmasync() * as the target of a large periodic transfer, with usb_buffer_dmasync()
* calls to synchronize memory and dma state. It may not be used for * calls to synchronize memory and dma state.
* control requests.
* *
* Reverse the effect of this call with usb_buffer_unmap(). * Reverse the effect of this call with usb_buffer_unmap().
*/ */
...@@ -1311,7 +1311,6 @@ struct urb *usb_buffer_map (struct urb *urb) ...@@ -1311,7 +1311,6 @@ struct urb *usb_buffer_map (struct urb *urb)
struct device *controller; struct device *controller;
if (!urb if (!urb
|| usb_pipecontrol (urb->pipe)
|| !urb->dev || !urb->dev
|| !(bus = urb->dev->bus) || !(bus = urb->dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller))
...@@ -1322,17 +1321,23 @@ struct urb *usb_buffer_map (struct urb *urb) ...@@ -1322,17 +1321,23 @@ struct urb *usb_buffer_map (struct urb *urb)
urb->transfer_buffer, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
? DMA_FROM_DEVICE : DMA_TO_DEVICE); ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
if (usb_pipecontrol (urb->pipe))
urb->setup_dma = dma_map_single (controller,
urb->setup_packet,
sizeof (struct usb_ctrlrequest),
DMA_TO_DEVICE);
// FIXME generic api broken like pci, can't report errors // FIXME generic api broken like pci, can't report errors
// if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
} else } else
urb->transfer_dma = ~0; urb->transfer_dma = ~0;
urb->transfer_flags |= URB_NO_DMA_MAP; urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
| URB_NO_SETUP_DMA_MAP);
return urb; return urb;
} }
/** /**
* usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s)
* @urb: urb whose transfer_buffer will be synchronized * @urb: urb whose transfer_buffer/setup_packet will be synchronized
*/ */
void usb_buffer_dmasync (struct urb *urb) void usb_buffer_dmasync (struct urb *urb)
{ {
...@@ -1340,17 +1345,23 @@ void usb_buffer_dmasync (struct urb *urb) ...@@ -1340,17 +1345,23 @@ void usb_buffer_dmasync (struct urb *urb)
struct device *controller; struct device *controller;
if (!urb if (!urb
|| !(urb->transfer_flags & URB_NO_DMA_MAP) || !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
|| !urb->dev || !urb->dev
|| !(bus = urb->dev->bus) || !(bus = urb->dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller))
return; return;
if (controller->dma_mask) if (controller->dma_mask) {
dma_sync_single (controller, dma_sync_single (controller,
urb->transfer_dma, urb->transfer_buffer_length, urb->transfer_dma, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
? DMA_FROM_DEVICE : DMA_TO_DEVICE); ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
if (usb_pipecontrol (urb->pipe))
dma_sync_single (controller,
urb->setup_dma,
sizeof (struct usb_ctrlrequest),
DMA_TO_DEVICE);
}
} }
/** /**
...@@ -1365,18 +1376,25 @@ void usb_buffer_unmap (struct urb *urb) ...@@ -1365,18 +1376,25 @@ void usb_buffer_unmap (struct urb *urb)
struct device *controller; struct device *controller;
if (!urb if (!urb
|| !(urb->transfer_flags & URB_NO_DMA_MAP) || !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
|| !urb->dev || !urb->dev
|| !(bus = urb->dev->bus) || !(bus = urb->dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller))
return; return;
if (controller->dma_mask) if (controller->dma_mask) {
dma_unmap_single (controller, dma_unmap_single (controller,
urb->transfer_dma, urb->transfer_buffer_length, urb->transfer_dma, urb->transfer_buffer_length,
usb_pipein (urb->pipe) usb_pipein (urb->pipe)
? DMA_FROM_DEVICE : DMA_TO_DEVICE); ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
urb->transfer_flags &= ~URB_NO_DMA_MAP; if (usb_pipecontrol (urb->pipe))
dma_unmap_single (controller,
urb->setup_dma,
sizeof (struct usb_ctrlrequest),
DMA_TO_DEVICE);
}
urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP
| URB_NO_SETUP_DMA_MAP);
} }
/** /**
...@@ -1391,7 +1409,7 @@ void usb_buffer_unmap (struct urb *urb) ...@@ -1391,7 +1409,7 @@ void usb_buffer_unmap (struct urb *urb)
* *
* The caller is responsible for placing the resulting DMA addresses from * The caller is responsible for placing the resulting DMA addresses from
* the scatterlist into URB transfer buffer pointers, and for setting the * the scatterlist into URB transfer buffer pointers, and for setting the
* URB_NO_DMA_MAP transfer flag in each of those URBs. * URB_NO_TRANSFER_DMA_MAP transfer flag in each of those URBs.
* *
* Top I/O rates come from queuing URBs, instead of waiting for each one * Top I/O rates come from queuing URBs, instead of waiting for each one
* to complete before starting the next I/O. This is particularly easy * to complete before starting the next I/O. This is particularly easy
......
...@@ -2222,7 +2222,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) ...@@ -2222,7 +2222,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
/* hw handles device features */ /* hw handles device features */
if (u.r.bRequestType != USB_RECIP_ENDPOINT) if (u.r.bRequestType != USB_RECIP_ENDPOINT)
goto delegate; goto delegate;
if (u.r.wIndex != 0 /* HALT feature */ if (u.r.wValue != 0 /* HALT feature */
|| u.r.wLength != 0) || u.r.wLength != 0)
goto do_stall; goto do_stall;
if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0) if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
...@@ -2239,7 +2239,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) ...@@ -2239,7 +2239,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
/* hw handles device features */ /* hw handles device features */
if (u.r.bRequestType != USB_RECIP_ENDPOINT) if (u.r.bRequestType != USB_RECIP_ENDPOINT)
goto delegate; goto delegate;
if (u.r.wIndex != 0 /* HALT feature */ if (u.r.wValue != 0 /* HALT feature */
|| u.r.wLength != 0) || u.r.wLength != 0)
goto do_stall; goto do_stall;
if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0) if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
......
...@@ -114,20 +114,29 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {} ...@@ -114,20 +114,29 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {}
#ifdef DEBUG #ifdef DEBUG
static void __attribute__((__unused__))
dbg_qtd (char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
{
ehci_dbg (ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
cpu_to_le32p (&qtd->hw_next),
cpu_to_le32p (&qtd->hw_alt_next),
cpu_to_le32p (&qtd->hw_token),
cpu_to_le32p (&qtd->hw_buf [0]));
if (qtd->hw_buf [1])
ehci_dbg (ehci, " p1=%08x p2=%08x p3=%08x p4=%08x\n",
cpu_to_le32p (&qtd->hw_buf [1]),
cpu_to_le32p (&qtd->hw_buf [2]),
cpu_to_le32p (&qtd->hw_buf [3]),
cpu_to_le32p (&qtd->hw_buf [4]));
}
static void __attribute__((__unused__)) static void __attribute__((__unused__))
dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
{ {
dbg ("%s %p n%08x info1 %x info2 %x hw_curr %x qtd_next %x", label, ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
qh, qh->hw_next, qh->hw_info1, qh->hw_info2, qh, qh->hw_next, qh->hw_info1, qh->hw_info2,
qh->hw_current, qh->hw_qtd_next); qh->hw_current);
dbg (" alt+nak+t= %x, token= %x, page0= %x, page1= %x", dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->hw_qtd_next);
qh->hw_alt_next, qh->hw_token,
qh->hw_buf [0], qh->hw_buf [1]);
if (qh->hw_buf [2]) {
dbg (" page2= %x, page3= %x, page4= %x",
qh->hw_buf [2], qh->hw_buf [3],
qh->hw_buf [4]);
}
} }
static int __attribute__((__unused__)) static int __attribute__((__unused__))
...@@ -284,8 +293,7 @@ static inline char token_mark (u32 token) ...@@ -284,8 +293,7 @@ static inline char token_mark (u32 token)
return '*'; return '*';
if (token & QTD_STS_HALT) if (token & QTD_STS_HALT)
return '-'; return '-';
if (QTD_PID (token) != 1 /* not IN: OUT or SETUP */ if (!IS_SHORT_READ (token))
|| QTD_LENGTH (token) == 0)
return ' '; return ' ';
/* tries to advance through hw_alt_next */ /* tries to advance through hw_alt_next */
return '/'; return '/';
...@@ -307,11 +315,14 @@ static void qh_lines ( ...@@ -307,11 +315,14 @@ static void qh_lines (
char *next = *nextp; char *next = *nextp;
char mark; char mark;
if (qh->hw_qtd_next == EHCI_LIST_END) /* NEC does this */
mark = '@';
else
mark = token_mark (qh->hw_token); mark = token_mark (qh->hw_token);
if (mark == '/') { /* qh_alt_next controls qh advance? */ if (mark == '/') { /* qh_alt_next controls qh advance? */
if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next) if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next)
mark = '#'; /* blocked */ mark = '#'; /* blocked */
else if (qh->hw_alt_next & cpu_to_le32 (0x01)) else if (qh->hw_alt_next == EHCI_LIST_END)
mark = '.'; /* use hw_qtd_next */ mark = '.'; /* use hw_qtd_next */
/* else alt_next points to some other qtd */ /* else alt_next points to some other qtd */
} }
...@@ -324,7 +335,7 @@ static void qh_lines ( ...@@ -324,7 +335,7 @@ static void qh_lines (
(scratch >> 8) & 0x000f, (scratch >> 8) & 0x000f,
scratch, cpu_to_le32p (&qh->hw_info2), scratch, cpu_to_le32p (&qh->hw_info2),
cpu_to_le32p (&qh->hw_token), mark, cpu_to_le32p (&qh->hw_token), mark,
(cpu_to_le32 (0x8000000) & qh->hw_token) (__constant_cpu_to_le32 (QTD_TOGGLE) & qh->hw_token)
? "data0" : "data1", ? "data0" : "data1",
(cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f); (cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f);
size -= temp; size -= temp;
...@@ -390,6 +401,8 @@ show_async (struct device *dev, char *buf) ...@@ -390,6 +401,8 @@ show_async (struct device *dev, char *buf)
char *next; char *next;
struct ehci_qh *qh; struct ehci_qh *qh;
*buf = 0;
pdev = container_of (dev, struct pci_dev, dev); pdev = container_of (dev, struct pci_dev, dev);
ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
next = buf; next = buf;
...@@ -412,7 +425,7 @@ show_async (struct device *dev, char *buf) ...@@ -412,7 +425,7 @@ show_async (struct device *dev, char *buf)
} }
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
return PAGE_SIZE - size; return strlen (buf);
} }
static DEVICE_ATTR (async, S_IRUGO, show_async, NULL); static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
...@@ -548,7 +561,8 @@ show_registers (struct device *dev, char *buf) ...@@ -548,7 +561,8 @@ show_registers (struct device *dev, char *buf)
/* Capability Registers */ /* Capability Registers */
i = readw (&ehci->caps->hci_version); i = readw (&ehci->caps->hci_version);
temp = snprintf (next, size, temp = snprintf (next, size,
"EHCI %x.%02x, hcd state %d (version " DRIVER_VERSION ")\n", "%s\nEHCI %x.%02x, hcd state %d (driver " DRIVER_VERSION ")\n",
pdev->dev.name,
i >> 8, i & 0x0ff, ehci->hcd.state); i >> 8, i & 0x0ff, ehci->hcd.state);
size -= temp; size -= temp;
next += temp; next += temp;
......
...@@ -39,13 +39,10 @@ ...@@ -39,13 +39,10 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/moduleparam.h>
#include <linux/version.h> #include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
#include "../hcd.h"
#else
#include "../core/hcd.h" #include "../core/hcd.h"
#endif
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -94,11 +91,11 @@ ...@@ -94,11 +91,11 @@
* 2001-June Works with usb-storage and NEC EHCI on 2.4 * 2001-June Works with usb-storage and NEC EHCI on 2.4
*/ */
#define DRIVER_VERSION "2003-Jan-22" #define DRIVER_VERSION "2003-Jun-13"
#define DRIVER_AUTHOR "David Brownell" #define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
static const char hcd_name [] = "ehci-hcd"; static const char hcd_name [] = "ehci_hcd";
// #define EHCI_VERBOSE_DEBUG // #define EHCI_VERBOSE_DEBUG
...@@ -123,7 +120,7 @@ static const char hcd_name [] = "ehci-hcd"; ...@@ -123,7 +120,7 @@ static const char hcd_name [] = "ehci-hcd";
/* Initial IRQ latency: lower than default */ /* Initial IRQ latency: lower than default */
static int log2_irq_thresh = 0; // 0 to 6 static int log2_irq_thresh = 0; // 0 to 6
MODULE_PARM (log2_irq_thresh, "i"); module_param (log2_irq_thresh, int, S_IRUGO);
MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes"); MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
#define INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT) #define INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT)
...@@ -434,7 +431,7 @@ static int ehci_start (struct usb_hcd *hcd) ...@@ -434,7 +431,7 @@ static int ehci_start (struct usb_hcd *hcd)
pci_set_mwi (ehci->hcd.pdev); pci_set_mwi (ehci->hcd.pdev);
/* clear interrupt enables, set irq latency */ /* clear interrupt enables, set irq latency */
temp = readl (&ehci->regs->command) & 0xff; temp = readl (&ehci->regs->command) & 0x0fff;
if (log2_irq_thresh < 0 || log2_irq_thresh > 6) if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
log2_irq_thresh = 0; log2_irq_thresh = 0;
temp |= 1 << (16 + log2_irq_thresh); temp |= 1 << (16 + log2_irq_thresh);
...@@ -1020,7 +1017,8 @@ static int __init init (void) ...@@ -1020,7 +1017,8 @@ static int __init init (void)
if (usb_disabled()) if (usb_disabled())
return -ENODEV; return -ENODEV;
dbg ("block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd", pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
hcd_name,
sizeof (struct ehci_qh), sizeof (struct ehci_qtd), sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
......
...@@ -88,7 +88,6 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, ...@@ -88,7 +88,6 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
static inline void static inline void
qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
{ {
qh->hw_current = 0;
qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma); qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
qh->hw_alt_next = EHCI_LIST_END; qh->hw_alt_next = EHCI_LIST_END;
...@@ -99,8 +98,6 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) ...@@ -99,8 +98,6 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
static void qtd_copy_status ( static void qtd_copy_status (
struct ehci_hcd *ehci, struct ehci_hcd *ehci,
struct urb *urb, struct urb *urb,
...@@ -279,16 +276,15 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) ...@@ -279,16 +276,15 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
/* hardware copies qtd out of qh overlay */ /* hardware copies qtd out of qh overlay */
rmb (); rmb ();
token = le32_to_cpu (qtd->hw_token); token = le32_to_cpu (qtd->hw_token);
stopped = stopped
|| (HALT_BIT & qh->hw_token) != 0
|| (ehci->hcd.state == USB_STATE_HALT);
/* always clean up qtds the hc de-activated */ /* always clean up qtds the hc de-activated */
if ((token & QTD_STS_ACTIVE) == 0) { if ((token & QTD_STS_ACTIVE) == 0) {
/* magic dummy for short reads; won't advance */ if ((token & QTD_STS_HALT) != 0) {
if (IS_SHORT_READ (token) stopped = 1;
&& !(token & QTD_STS_HALT)
/* magic dummy for some short reads; qh won't advance */
} else if (IS_SHORT_READ (token)
&& (qh->hw_alt_next & QTD_MASK) && (qh->hw_alt_next & QTD_MASK)
== ehci->async->hw_alt_next) { == ehci->async->hw_alt_next) {
stopped = 1; stopped = 1;
...@@ -296,10 +292,13 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) ...@@ -296,10 +292,13 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
} }
/* stop scanning when we reach qtds the hc is using */ /* stop scanning when we reach qtds the hc is using */
} else if (likely (!stopped)) { } else if (likely (!stopped
&& HCD_IS_RUNNING (ehci->hcd.state))) {
break; break;
} else { } else {
stopped = 1;
/* ignore active urbs unless some previous qtd /* ignore active urbs unless some previous qtd
* for the urb faulted (including short read) or * for the urb faulted (including short read) or
* its urb was canceled. we may patch qh or qtds. * its urb was canceled. we may patch qh or qtds.
...@@ -358,12 +357,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) ...@@ -358,12 +357,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
qh->qh_state = state; qh->qh_state = state;
/* update qh after fault cleanup */ /* update qh after fault cleanup */
if (unlikely ((HALT_BIT & qh->hw_token) != 0)) { if (unlikely (stopped != 0)
qh_update (ehci, qh, /* some EHCI 0.95 impls will overlay dummy qtds */
list_empty (&qh->qtd_list) || qh->hw_qtd_next == EHCI_LIST_END) {
? qh->dummy if (list_empty (&qh->qtd_list))
: list_entry (qh->qtd_list.next, end = qh->dummy;
struct ehci_qtd, qtd_list)); else {
end = list_entry (qh->qtd_list.next,
struct ehci_qtd, qtd_list);
/* first qtd may already be partially processed */
if (cpu_to_le32 (end->qtd_dma) == qh->hw_current)
end = 0;
}
if (end)
qh_update (ehci, qh, end);
} }
return count; return count;
...@@ -683,12 +690,11 @@ qh_make ( ...@@ -683,12 +690,11 @@ qh_make (
/* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */ /* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */
/* init as halted, toggle clear, advance to dummy */ /* init as live, toggle clear, advance to dummy */
qh->qh_state = QH_STATE_IDLE; qh->qh_state = QH_STATE_IDLE;
qh->hw_info1 = cpu_to_le32 (info1); qh->hw_info1 = cpu_to_le32 (info1);
qh->hw_info2 = cpu_to_le32 (info2); qh->hw_info2 = cpu_to_le32 (info2);
qh_update (ehci, qh, qh->dummy); qh_update (ehci, qh, qh->dummy);
qh->hw_token = cpu_to_le32 (QTD_STS_HALT);
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
return qh; return qh;
} }
...@@ -788,11 +794,6 @@ static struct ehci_qh *qh_append_tds ( ...@@ -788,11 +794,6 @@ static struct ehci_qh *qh_append_tds (
} }
} }
/* FIXME: changing config or interface setting is not
* supported yet. preferred fix is for usbcore to tell
* us to clear out each endpoint's state, but...
*/
/* usb_clear_halt() means qh data toggle gets reset */ /* usb_clear_halt() means qh data toggle gets reset */
if (unlikely (!usb_gettoggle (urb->dev, if (unlikely (!usb_gettoggle (urb->dev,
(epnum & 0x0f), !(epnum & 0x10))) (epnum & 0x0f), !(epnum & 0x10)))
......
...@@ -290,7 +290,10 @@ struct ehci_qtd { ...@@ -290,7 +290,10 @@ struct ehci_qtd {
size_t length; /* length of buffer */ size_t length; /* length of buffer */
} __attribute__ ((aligned (32))); } __attribute__ ((aligned (32)));
#define QTD_MASK cpu_to_le32 (~0x1f) /* mask NakCnt+T in qh->hw_alt_next */ /* mask NakCnt+T in qh->hw_alt_next */
#define QTD_MASK __constant_cpu_to_le32 (~0x1f)
#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -330,7 +330,7 @@ aiptek_probe(struct usb_interface *intf, ...@@ -330,7 +330,7 @@ aiptek_probe(struct usb_interface *intf,
aiptek->data, aiptek->features->pktlen, aiptek->data, aiptek->features->pktlen,
aiptek->features->irq, aiptek, endpoint->bInterval); aiptek->features->irq, aiptek, endpoint->bInterval);
aiptek->irq->transfer_dma = aiptek->data_dma; aiptek->irq->transfer_dma = aiptek->data_dma;
aiptek->irq->transfer_flags |= URB_NO_DMA_MAP; aiptek->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
input_register_device(&aiptek->dev); input_register_device(&aiptek->dev);
......
...@@ -1518,7 +1518,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1518,7 +1518,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
hid_irq_in, hid, endpoint->bInterval); hid_irq_in, hid, endpoint->bInterval);
hid->urbin->transfer_dma = hid->inbuf_dma; hid->urbin->transfer_dma = hid->inbuf_dma;
hid->urbin->transfer_flags |= URB_NO_DMA_MAP; hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
} else { } else {
if (hid->urbout) if (hid->urbout)
continue; continue;
...@@ -1528,7 +1528,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1528,7 +1528,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
usb_fill_bulk_urb(hid->urbout, dev, pipe, hid->outbuf, 0, usb_fill_bulk_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
hid_irq_out, hid); hid_irq_out, hid);
hid->urbout->transfer_dma = hid->outbuf_dma; hid->urbout->transfer_dma = hid->outbuf_dma;
hid->urbout->transfer_flags |= URB_NO_DMA_MAP; hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
} }
} }
...@@ -1577,7 +1577,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1577,7 +1577,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
hid->ctrlbuf, 1, hid_ctrl, hid); hid->ctrlbuf, 1, hid_ctrl, hid);
hid->urbctrl->setup_dma = hid->cr_dma; hid->urbctrl->setup_dma = hid->cr_dma;
hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
hid->urbctrl->transfer_flags |= URB_NO_DMA_MAP; hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
| URB_NO_SETUP_DMA_MAP);
return hid; return hid;
......
...@@ -181,7 +181,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -181,7 +181,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
kbtab->data, 8, kbtab->data, 8,
kbtab_irq, kbtab, endpoint->bInterval); kbtab_irq, kbtab, endpoint->bInterval);
kbtab->irq->transfer_dma = kbtab->data_dma; kbtab->irq->transfer_dma = kbtab->data_dma;
kbtab->irq->transfer_flags |= URB_NO_DMA_MAP; kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
input_register_device(&kbtab->dev); input_register_device(&kbtab->dev);
......
...@@ -180,7 +180,7 @@ static void powermate_sync_state(struct powermate_device *pm) ...@@ -180,7 +180,7 @@ static void powermate_sync_state(struct powermate_device *pm)
(void *) pm->configcr, 0, 0, (void *) pm->configcr, 0, 0,
powermate_config_complete, pm); powermate_config_complete, pm);
pm->config->setup_dma = pm->configcr_dma; pm->config->setup_dma = pm->configcr_dma;
pm->config->transfer_flags |= URB_NO_DMA_MAP; pm->config->transfer_flags |= URB_NO_SETUP_DMA_MAP;
if (usb_submit_urb(pm->config, GFP_ATOMIC)) if (usb_submit_urb(pm->config, GFP_ATOMIC))
printk(KERN_ERR "powermate: usb_submit_urb(config) failed"); printk(KERN_ERR "powermate: usb_submit_urb(config) failed");
...@@ -355,7 +355,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -355,7 +355,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
POWERMATE_PAYLOAD_SIZE, powermate_irq, POWERMATE_PAYLOAD_SIZE, powermate_irq,
pm, endpoint->bInterval); pm, endpoint->bInterval);
pm->irq->transfer_dma = pm->data_dma; pm->irq->transfer_dma = pm->data_dma;
pm->irq->transfer_flags |= URB_NO_DMA_MAP; pm->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
/* register our interrupt URB with the USB system */ /* register our interrupt URB with the USB system */
if (usb_submit_urb(pm->irq, GFP_KERNEL)) { if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
......
...@@ -282,7 +282,7 @@ static int usb_kbd_probe(struct usb_interface *iface, ...@@ -282,7 +282,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
kbd->new, (maxp > 8 ? 8 : maxp), kbd->new, (maxp > 8 ? 8 : maxp),
usb_kbd_irq, kbd, endpoint->bInterval); usb_kbd_irq, kbd, endpoint->bInterval);
kbd->irq->transfer_dma = kbd->new_dma; kbd->irq->transfer_dma = kbd->new_dma;
kbd->irq->transfer_flags |= URB_NO_DMA_MAP; kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE; kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
kbd->cr->bRequest = 0x09; kbd->cr->bRequest = 0x09;
...@@ -325,7 +325,8 @@ static int usb_kbd_probe(struct usb_interface *iface, ...@@ -325,7 +325,8 @@ static int usb_kbd_probe(struct usb_interface *iface,
usb_kbd_led, kbd); usb_kbd_led, kbd);
kbd->led->setup_dma = kbd->cr_dma; kbd->led->setup_dma = kbd->cr_dma;
kbd->led->transfer_dma = kbd->leds_dma; kbd->led->transfer_dma = kbd->leds_dma;
kbd->led->transfer_flags |= URB_NO_DMA_MAP; kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
| URB_NO_SETUP_DMA_MAP);
input_register_device(&kbd->dev); input_register_device(&kbd->dev);
......
...@@ -207,7 +207,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ ...@@ -207,7 +207,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
(maxp > 8 ? 8 : maxp), (maxp > 8 ? 8 : maxp),
usb_mouse_irq, mouse, endpoint->bInterval); usb_mouse_irq, mouse, endpoint->bInterval);
mouse->irq->transfer_dma = mouse->data_dma; mouse->irq->transfer_dma = mouse->data_dma;
mouse->irq->transfer_flags |= URB_NO_DMA_MAP; mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
input_register_device(&mouse->dev); input_register_device(&mouse->dev);
printk(KERN_INFO "input: %s on %s\n", mouse->name, path); printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
......
...@@ -590,7 +590,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -590,7 +590,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom->data, wacom->features->pktlen, wacom->data, wacom->features->pktlen,
wacom->features->irq, wacom, endpoint->bInterval); wacom->features->irq, wacom, endpoint->bInterval);
wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_dma = wacom->data_dma;
wacom->irq->transfer_flags |= URB_NO_DMA_MAP; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
input_register_device(&wacom->dev); input_register_device(&wacom->dev);
......
...@@ -259,7 +259,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -259,7 +259,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
xpad, ep_irq_in->bInterval); xpad, ep_irq_in->bInterval);
xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_dma = xpad->idata_dma;
xpad->irq_in->transfer_flags |= URB_NO_DMA_MAP; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
xpad->udev = udev; xpad->udev = udev;
......
...@@ -149,7 +149,7 @@ do { \ ...@@ -149,7 +149,7 @@ do { \
/* External data structures / Interface */ /* External data structures / Interface */
typedef struct typedef struct
{ {
char *buf; /* return buffer for string contents */ char __user *buf; /* return buffer for string contents */
unsigned int bsize; /* size of return buffer */ unsigned int bsize; /* size of return buffer */
} audevinfo_t,*paudevinfo_t; } audevinfo_t,*paudevinfo_t;
...@@ -1548,7 +1548,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int ...@@ -1548,7 +1548,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
/* get a string descriptor for the device */ /* get a string descriptor for the device */
case IOCTL_AU_DEVINFO: case IOCTL_AU_DEVINFO:
dbg ("IOCTL_AU_DEVINFO"); dbg ("IOCTL_AU_DEVINFO");
if (copy_from_user (&devinfo, (void *) arg, sizeof (audevinfo_t))) { if (copy_from_user (&devinfo, (void __user *) arg, sizeof (audevinfo_t))) {
ret = -EFAULT; ret = -EFAULT;
break; break;
} }
...@@ -1578,7 +1578,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int ...@@ -1578,7 +1578,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
} }
/* Read data from the device */ /* Read data from the device */
static ssize_t auerchar_read (struct file *file, char *buf, size_t count, loff_t * ppos) static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
{ {
unsigned long flags; unsigned long flags;
pauerchar_t ccp = (pauerchar_t) file->private_data; pauerchar_t ccp = (pauerchar_t) file->private_data;
...@@ -1708,7 +1708,7 @@ static ssize_t auerchar_read (struct file *file, char *buf, size_t count, loff_t ...@@ -1708,7 +1708,7 @@ static ssize_t auerchar_read (struct file *file, char *buf, size_t count, loff_t
/* Write a data block into the right service channel of the device */ /* Write a data block into the right service channel of the device */
static ssize_t auerchar_write (struct file *file, const char *buf, size_t len, loff_t *ppos) static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
{ {
pauerchar_t ccp = (pauerchar_t) file->private_data; pauerchar_t ccp = (pauerchar_t) file->private_data;
pauerswald_t cp = NULL; pauerswald_t cp = NULL;
......
...@@ -109,9 +109,9 @@ static int brlvger_probe (struct usb_interface *intf, ...@@ -109,9 +109,9 @@ static int brlvger_probe (struct usb_interface *intf,
static void brlvger_disconnect(struct usb_interface *intf); static void brlvger_disconnect(struct usb_interface *intf);
static int brlvger_open(struct inode *inode, struct file *file); static int brlvger_open(struct inode *inode, struct file *file);
static int brlvger_release(struct inode *inode, struct file *file); static int brlvger_release(struct inode *inode, struct file *file);
static ssize_t brlvger_write(struct file *file, const char *buffer, static ssize_t brlvger_write(struct file *file, const char __user *buffer,
size_t count, loff_t *pos); size_t count, loff_t *pos);
static ssize_t brlvger_read(struct file *file, char *buffer, static ssize_t brlvger_read(struct file *file, char __user *buffer,
size_t count, loff_t *unused_pos); size_t count, loff_t *unused_pos);
static int brlvger_ioctl(struct inode *inode, struct file *file, static int brlvger_ioctl(struct inode *inode, struct file *file,
unsigned cmd, unsigned long arg); unsigned cmd, unsigned long arg);
...@@ -546,7 +546,7 @@ brlvger_release(struct inode *inode, struct file *file) ...@@ -546,7 +546,7 @@ brlvger_release(struct inode *inode, struct file *file)
} }
static ssize_t static ssize_t
brlvger_write(struct file *file, const char *buffer, brlvger_write(struct file *file, const char __user *buffer,
size_t count, loff_t *pos) size_t count, loff_t *pos)
{ {
struct brlvger_priv *priv = file->private_data; struct brlvger_priv *priv = file->private_data;
...@@ -655,7 +655,7 @@ read_index(struct brlvger_priv *priv) ...@@ -655,7 +655,7 @@ read_index(struct brlvger_priv *priv)
} }
static ssize_t static ssize_t
brlvger_read(struct file *file, char *buffer, brlvger_read(struct file *file, char __user *buffer,
size_t count, loff_t *unused_pos) size_t count, loff_t *unused_pos)
{ {
struct brlvger_priv *priv = file->private_data; struct brlvger_priv *priv = file->private_data;
...@@ -719,7 +719,7 @@ brlvger_ioctl(struct inode *inode, struct file *file, ...@@ -719,7 +719,7 @@ brlvger_ioctl(struct inode *inode, struct file *file,
memcpy(&vi.fwver, priv->fwver, BRLVGER_FWVER_SIZE); memcpy(&vi.fwver, priv->fwver, BRLVGER_FWVER_SIZE);
memcpy(&vi.serialnum, priv->serialnum, BRLVGER_SERIAL_SIZE); memcpy(&vi.serialnum, priv->serialnum, BRLVGER_SERIAL_SIZE);
if(copy_to_user((void *)arg, &vi, sizeof(vi))) if(copy_to_user((void __user *)arg, &vi, sizeof(vi)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
......
...@@ -111,7 +111,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -111,7 +111,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
{ {
struct RioCommand rio_cmd; struct RioCommand rio_cmd;
struct rio_usb_data *rio = &rio_instance; struct rio_usb_data *rio = &rio_instance;
void *data; void __user *data;
unsigned char *buffer; unsigned char *buffer;
int result, requesttype; int result, requesttype;
int retries; int retries;
...@@ -129,7 +129,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -129,7 +129,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
switch (cmd) { switch (cmd) {
case RIO_RECV_COMMAND: case RIO_RECV_COMMAND:
data = (void *) arg; data = (void __user *) arg;
if (data == NULL) if (data == NULL)
break; break;
if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
...@@ -199,7 +199,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -199,7 +199,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
break; break;
case RIO_SEND_COMMAND: case RIO_SEND_COMMAND:
data = (void *) arg; data = (void __user *) arg;
if (data == NULL) if (data == NULL)
break; break;
if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
...@@ -266,7 +266,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -266,7 +266,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
} }
static ssize_t static ssize_t
write_rio(struct file *file, const char *buffer, write_rio(struct file *file, const char __user *buffer,
size_t count, loff_t * ppos) size_t count, loff_t * ppos)
{ {
struct rio_usb_data *rio = &rio_instance; struct rio_usb_data *rio = &rio_instance;
...@@ -352,7 +352,7 @@ write_rio(struct file *file, const char *buffer, ...@@ -352,7 +352,7 @@ write_rio(struct file *file, const char *buffer,
} }
static ssize_t static ssize_t
read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos) read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
{ {
struct rio_usb_data *rio = &rio_instance; struct rio_usb_data *rio = &rio_instance;
ssize_t read_count; ssize_t read_count;
......
...@@ -32,6 +32,6 @@ struct RioCommand { ...@@ -32,6 +32,6 @@ struct RioCommand {
int requesttype; int requesttype;
int value; int value;
int index; int index;
void *buffer; void __user *buffer;
int timeout; int timeout;
}; };
This diff is collapsed.
...@@ -155,7 +155,7 @@ tiglusb_release (struct inode *inode, struct file *filp) ...@@ -155,7 +155,7 @@ tiglusb_release (struct inode *inode, struct file *filp)
} }
static ssize_t static ssize_t
tiglusb_read (struct file *filp, char *buf, size_t count, loff_t * f_pos) tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
{ {
ptiglusb_t s = (ptiglusb_t) filp->private_data; ptiglusb_t s = (ptiglusb_t) filp->private_data;
ssize_t ret = 0; ssize_t ret = 0;
...@@ -208,7 +208,7 @@ tiglusb_read (struct file *filp, char *buf, size_t count, loff_t * f_pos) ...@@ -208,7 +208,7 @@ tiglusb_read (struct file *filp, char *buf, size_t count, loff_t * f_pos)
} }
static ssize_t static ssize_t
tiglusb_write (struct file *filp, const char *buf, size_t count, loff_t * f_pos) tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * f_pos)
{ {
ptiglusb_t s = (ptiglusb_t) filp->private_data; ptiglusb_t s = (ptiglusb_t) filp->private_data;
ssize_t ret = 0; ssize_t ret = 0;
......
...@@ -88,12 +88,12 @@ ioctl_lcd(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -88,12 +88,12 @@ ioctl_lcd(struct inode *inode, struct file *file, unsigned int cmd,
i = (lcd->lcd_dev)->descriptor.bcdDevice; i = (lcd->lcd_dev)->descriptor.bcdDevice;
sprintf(buf,"%1d%1d.%1d%1d",(i & 0xF000)>>12,(i & 0xF00)>>8, sprintf(buf,"%1d%1d.%1d%1d",(i & 0xF000)>>12,(i & 0xF00)>>8,
(i & 0xF0)>>4,(i & 0xF)); (i & 0xF0)>>4,(i & 0xF));
if (copy_to_user((void *)arg,buf,strlen(buf))!=0) if (copy_to_user((void __user *)arg,buf,strlen(buf))!=0)
return -EFAULT; return -EFAULT;
break; break;
case IOCTL_GET_DRV_VERSION: case IOCTL_GET_DRV_VERSION:
sprintf(buf,DRIVER_VERSION); sprintf(buf,DRIVER_VERSION);
if (copy_to_user((void *)arg,buf,strlen(buf))!=0) if (copy_to_user((void __user *)arg,buf,strlen(buf))!=0)
return -EFAULT; return -EFAULT;
break; break;
default: default:
...@@ -105,7 +105,7 @@ ioctl_lcd(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -105,7 +105,7 @@ ioctl_lcd(struct inode *inode, struct file *file, unsigned int cmd,
} }
static ssize_t static ssize_t
write_lcd(struct file *file, const char *buffer, write_lcd(struct file *file, const char __user *buffer,
size_t count, loff_t * ppos) size_t count, loff_t * ppos)
{ {
struct lcd_usb_data *lcd = &lcd_instance; struct lcd_usb_data *lcd = &lcd_instance;
...@@ -171,7 +171,7 @@ write_lcd(struct file *file, const char *buffer, ...@@ -171,7 +171,7 @@ write_lcd(struct file *file, const char *buffer,
} }
static ssize_t static ssize_t
read_lcd(struct file *file, char *buffer, size_t count, loff_t * ppos) read_lcd(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
{ {
struct lcd_usb_data *lcd = &lcd_instance; struct lcd_usb_data *lcd = &lcd_instance;
ssize_t read_count; ssize_t read_count;
......
...@@ -107,7 +107,7 @@ static struct urb *simple_alloc_urb ( ...@@ -107,7 +107,7 @@ static struct urb *simple_alloc_urb (
urb->interval = (udev->speed == USB_SPEED_HIGH) urb->interval = (udev->speed == USB_SPEED_HIGH)
? (INTERRUPT_RATE << 3) ? (INTERRUPT_RATE << 3)
: INTERRUPT_RATE; : INTERRUPT_RATE;
urb->transfer_flags = URB_NO_DMA_MAP; urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
if (usb_pipein (pipe)) if (usb_pipein (pipe))
urb->transfer_flags |= URB_SHORT_NOT_OK; urb->transfer_flags |= URB_SHORT_NOT_OK;
urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL, urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
......
...@@ -7,6 +7,27 @@ comment "USB Network adaptors" ...@@ -7,6 +7,27 @@ comment "USB Network adaptors"
comment "Networking support is needed for USB Networking device support" comment "Networking support is needed for USB Networking device support"
depends on USB && !NET depends on USB && !NET
config USB_AX8817X
tristate "USB ASIX AX8817X Ethernet device support (EXPERIMENTAL)"
depends on USB && NET && EXPERIMENTAL
---help---
Say Y if you want to use one of the following 10/100Mps USB
Ethernet devices based on the ASIX AX88172 chip. Supported
devices are:
ASIX AX88172
D-Link DUB-E100
Hawking UF200
Netgear FA120
This driver makes the adapter appear as a normal Ethernet interface,
typically on eth0, if it is the only ethernet device, or perhaps on
eth1, if you have a PCI or ISA ethernet card installed.
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called ax8817x.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
config USB_CATC config USB_CATC
tristate "USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)" tristate "USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)"
depends on USB && NET && EXPERIMENTAL depends on USB && NET && EXPERIMENTAL
...@@ -191,7 +212,8 @@ config USB_ARMLINUX ...@@ -191,7 +212,8 @@ config USB_ARMLINUX
help help
Choose this option to support the "usb-eth" networking driver Choose this option to support the "usb-eth" networking driver
used by most of the ARM Linux community with device controllers used by most of the ARM Linux community with device controllers
such as the SA-11x0 and PXA-25x UDCs. such as the SA-11x0 and PXA-25x UDCs, or the tftp capabilities
in some PXA versions of the "blob" boot loader.
Although the ROMs shipped with Sharp Zaurus products use a Although the ROMs shipped with Sharp Zaurus products use a
different link level framing protocol, you can have them use different link level framing protocol, you can have them use
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Makefile for USB Network drivers # Makefile for USB Network drivers
# #
obj-$(CONFIG_USB_AX8817X) += ax8817x.o
obj-$(CONFIG_USB_CATC) += catc.o obj-$(CONFIG_USB_CATC) += catc.o
obj-$(CONFIG_USB_KAWETH) += kaweth.o obj-$(CONFIG_USB_KAWETH) += kaweth.o
obj-$(CONFIG_USB_PEGASUS) += pegasus.o obj-$(CONFIG_USB_PEGASUS) += pegasus.o
......
...@@ -2,4 +2,5 @@ ...@@ -2,4 +2,5 @@
# Makefile for USB Network drivers which require generic MII code. # Makefile for USB Network drivers which require generic MII code.
# #
obj-$(CONFIG_USB_AX8817X) += mii.o
obj-$(CONFIG_USB_PEGASUS) += mii.o obj-$(CONFIG_USB_PEGASUS) += mii.o
This diff is collapsed.
...@@ -667,7 +667,7 @@ static void catc_set_multicast_list(struct net_device *netdev) ...@@ -667,7 +667,7 @@ static void catc_set_multicast_list(struct net_device *netdev)
/* /*
* ioctl's * ioctl's
*/ */
static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{ {
struct catc *catc = dev->priv; struct catc *catc = dev->priv;
u32 cmd; u32 cmd;
...@@ -726,7 +726,7 @@ static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -726,7 +726,7 @@ static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ {
switch(cmd) { switch(cmd) {
case SIOCETHTOOL: case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); return netdev_ethtool_ioctl(dev, (void __user *)rq->ifr_data);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -226,12 +226,16 @@ struct kaweth_device ...@@ -226,12 +226,16 @@ struct kaweth_device
struct urb *tx_urb; struct urb *tx_urb;
struct urb *irq_urb; struct urb *irq_urb;
dma_addr_t intbufferhandle;
__u8 *intbuffer;
dma_addr_t rxbufferhandle;
__u8 *rx_buf;
struct sk_buff *tx_skb; struct sk_buff *tx_skb;
__u8 *firmware_buf; __u8 *firmware_buf;
__u8 scratch[KAWETH_SCRATCH_SIZE]; __u8 scratch[KAWETH_SCRATCH_SIZE];
__u8 rx_buf[KAWETH_BUF_SIZE];
__u8 intbuffer[INTBUFFERSIZE];
__u16 packet_filter_bitmap; __u16 packet_filter_bitmap;
struct kaweth_ethernet_configuration configuration; struct kaweth_ethernet_configuration configuration;
...@@ -524,6 +528,8 @@ static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, ...@@ -524,6 +528,8 @@ static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
KAWETH_BUF_SIZE, KAWETH_BUF_SIZE,
kaweth_usb_receive, kaweth_usb_receive,
kaweth); kaweth);
kaweth->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
kaweth->rx_urb->transfer_dma = kaweth->rxbufferhandle;
if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) { if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) {
if (result == -ENOMEM) if (result == -ENOMEM)
...@@ -630,6 +636,8 @@ static int kaweth_open(struct net_device *net) ...@@ -630,6 +636,8 @@ static int kaweth_open(struct net_device *net)
int_callback, int_callback,
kaweth, kaweth,
HZ/4); HZ/4);
kaweth->irq_urb->transfer_dma = kaweth->intbufferhandle;
kaweth->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL); res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL);
if (res) { if (res) {
...@@ -662,7 +670,7 @@ static int kaweth_close(struct net_device *net) ...@@ -662,7 +670,7 @@ static int kaweth_close(struct net_device *net)
return 0; return 0;
} }
static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{ {
u32 ethcmd; u32 ethcmd;
...@@ -689,7 +697,7 @@ static int kaweth_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ...@@ -689,7 +697,7 @@ static int kaweth_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
{ {
switch (cmd) { switch (cmd) {
case SIOCETHTOOL: case SIOCETHTOOL:
return netdev_ethtool_ioctl(net, (void *) rq->ifr_data); return netdev_ethtool_ioctl(net, (void __user *)rq->ifr_data);
} }
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -1033,6 +1041,19 @@ static int kaweth_probe( ...@@ -1033,6 +1041,19 @@ static int kaweth_probe(
if (!kaweth->irq_urb) if (!kaweth->irq_urb)
goto err_tx_and_rx; goto err_tx_and_rx;
kaweth->intbuffer = usb_buffer_alloc( kaweth->dev,
INTBUFFERSIZE,
GFP_KERNEL,
&kaweth->intbufferhandle);
if (!kaweth->intbuffer)
goto err_tx_and_rx_and_irq;
kaweth->rx_buf = usb_buffer_alloc( kaweth->dev,
KAWETH_BUF_SIZE,
GFP_KERNEL,
&kaweth->rxbufferhandle);
if (!kaweth->rx_buf)
goto err_all_but_rxbuf;
kaweth->net = netdev; kaweth->net = netdev;
memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr)); memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr));
memcpy(kaweth->net->dev_addr, memcpy(kaweth->net->dev_addr,
...@@ -1071,6 +1092,12 @@ static int kaweth_probe( ...@@ -1071,6 +1092,12 @@ static int kaweth_probe(
err_intfdata: err_intfdata:
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
err_all:
usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
err_all_but_rxbuf:
usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
err_tx_and_rx_and_irq:
usb_free_urb(kaweth->irq_urb);
err_tx_and_rx: err_tx_and_rx:
usb_free_urb(kaweth->rx_urb); usb_free_urb(kaweth->rx_urb);
err_only_tx: err_only_tx:
...@@ -1123,6 +1150,11 @@ static void kaweth_disconnect(struct usb_interface *intf) ...@@ -1123,6 +1150,11 @@ static void kaweth_disconnect(struct usb_interface *intf)
usb_free_urb(kaweth->rx_urb); usb_free_urb(kaweth->rx_urb);
usb_free_urb(kaweth->tx_urb); usb_free_urb(kaweth->tx_urb);
usb_free_urb(kaweth->irq_urb);
usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
kfree(kaweth); kfree(kaweth);
} }
......
...@@ -945,7 +945,7 @@ static int pegasus_close(struct net_device *net) ...@@ -945,7 +945,7 @@ static int pegasus_close(struct net_device *net)
return 0; return 0;
} }
#ifdef CONFIG_MII #ifdef CONFIG_MII
static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr) static int pegasus_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{ {
u32 ethcmd; u32 ethcmd;
...@@ -1024,7 +1024,7 @@ static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr) ...@@ -1024,7 +1024,7 @@ static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr)
} }
#else #else
static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) static int pegasus_ethtool_ioctl(struct net_device *net, void __user *uaddr)
{ {
pegasus_t *pegasus; pegasus_t *pegasus;
int cmd; int cmd;
...@@ -1113,7 +1113,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ...@@ -1113,7 +1113,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
switch (cmd) { switch (cmd) {
case SIOCETHTOOL: case SIOCETHTOOL:
res = pegasus_ethtool_ioctl(net, rq->ifr_data); res = pegasus_ethtool_ioctl(net, (void __user *)rq->ifr_data);
break; break;
case SIOCDEVPRIVATE: case SIOCDEVPRIVATE:
data[0] = pegasus->phy; data[0] = pegasus->phy;
......
...@@ -673,7 +673,7 @@ static int rtl8150_close(struct net_device *netdev) ...@@ -673,7 +673,7 @@ static int rtl8150_close(struct net_device *netdev)
return res; return res;
} }
static int rtl8150_ethtool_ioctl(struct net_device *netdev, void *uaddr) static int rtl8150_ethtool_ioctl(struct net_device *netdev, void __user *uaddr)
{ {
rtl8150_t *dev; rtl8150_t *dev;
int cmd; int cmd;
...@@ -758,7 +758,7 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ...@@ -758,7 +758,7 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
switch (cmd) { switch (cmd) {
case SIOCETHTOOL: case SIOCETHTOOL:
res = rtl8150_ethtool_ioctl(netdev, rq->ifr_data); res = rtl8150_ethtool_ioctl(netdev, (void __user *)rq->ifr_data);
break; break;
case SIOCDEVPRIVATE: case SIOCDEVPRIVATE:
data[0] = dev->phy; data[0] = dev->phy;
......
...@@ -1622,6 +1622,11 @@ static const struct driver_info yopy_info = { ...@@ -1622,6 +1622,11 @@ static const struct driver_info yopy_info = {
.check_connect = always_connected, .check_connect = always_connected,
}; };
static const struct driver_info blob_info = {
.description = "Boot Loader OBject",
.check_connect = always_connected,
};
#endif /* CONFIG_USB_ARMLINUX */ #endif /* CONFIG_USB_ARMLINUX */
...@@ -2097,7 +2102,7 @@ static int usbnet_open (struct net_device *net) ...@@ -2097,7 +2102,7 @@ static int usbnet_open (struct net_device *net)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static inline int static inline int
usbnet_ethtool_ioctl (struct net_device *net, void *useraddr) usbnet_ethtool_ioctl (struct net_device *net, void __user *useraddr)
{ {
struct usbnet *dev = (struct usbnet *) net->priv; struct usbnet *dev = (struct usbnet *) net->priv;
u32 cmd; u32 cmd;
...@@ -2161,7 +2166,7 @@ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd) ...@@ -2161,7 +2166,7 @@ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
{ {
switch (cmd) { switch (cmd) {
case SIOCETHTOOL: case SIOCETHTOOL:
return usbnet_ethtool_ioctl (net, (void *)rq->ifr_data); return usbnet_ethtool_ioctl (net, (void __user *)rq->ifr_data);
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -2707,6 +2712,9 @@ static const struct usb_device_id products [] = { ...@@ -2707,6 +2712,9 @@ static const struct usb_device_id products [] = {
}, { }, {
USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy" USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
.driver_info = (unsigned long) &yopy_info, .driver_info = (unsigned long) &yopy_info,
}, {
USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
.driver_info = (unsigned long) &blob_info,
}, },
#endif #endif
......
...@@ -548,10 +548,9 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -548,10 +548,9 @@ void isd200_invoke_transport( struct us_data *us,
/* if the command gets aborted by the higher layers, we need to /* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing * short-circuit all other processing
*/ */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- transport indicates command was aborted\n"); US_DEBUGP("-- command was aborted\n");
srb->result = DID_ABORT << 16; goto Handle_Abort;
return;
} }
switch (transferStatus) { switch (transferStatus) {
...@@ -561,6 +560,11 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -561,6 +560,11 @@ void isd200_invoke_transport( struct us_data *us,
srb->result = SAM_STAT_GOOD; srb->result = SAM_STAT_GOOD;
break; break;
case USB_STOR_TRANSPORT_NO_SENSE:
US_DEBUGP("-- transport indicates protocol failure\n");
srb->result = SAM_STAT_CHECK_CONDITION;
return;
case USB_STOR_TRANSPORT_FAILED: case USB_STOR_TRANSPORT_FAILED:
US_DEBUGP("-- transport indicates command failure\n"); US_DEBUGP("-- transport indicates command failure\n");
need_auto_sense = 1; need_auto_sense = 1;
...@@ -591,10 +595,9 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -591,10 +595,9 @@ void isd200_invoke_transport( struct us_data *us,
if (need_auto_sense) { if (need_auto_sense) {
result = isd200_read_regs(us); result = isd200_read_regs(us);
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- auto-sense aborted\n"); US_DEBUGP("-- auto-sense aborted\n");
srb->result = DID_ABORT << 16; goto Handle_Abort;
return;
} }
if (result == ISD200_GOOD) { if (result == ISD200_GOOD) {
isd200_build_sense(us, srb); isd200_build_sense(us, srb);
...@@ -603,8 +606,10 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -603,8 +606,10 @@ void isd200_invoke_transport( struct us_data *us,
/* If things are really okay, then let's show that */ /* If things are really okay, then let's show that */
if ((srb->sense_buffer[2] & 0xf) == 0x0) if ((srb->sense_buffer[2] & 0xf) == 0x0)
srb->result = SAM_STAT_GOOD; srb->result = SAM_STAT_GOOD;
} else } else {
srb->result = DID_ERROR << 16; srb->result = DID_ERROR << 16;
/* Need reset here */
}
} }
/* Regardless of auto-sense, if we _know_ we have an error /* Regardless of auto-sense, if we _know_ we have an error
...@@ -612,6 +617,16 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -612,6 +617,16 @@ void isd200_invoke_transport( struct us_data *us,
*/ */
if (transferStatus == USB_STOR_TRANSPORT_FAILED) if (transferStatus == USB_STOR_TRANSPORT_FAILED)
srb->result = SAM_STAT_CHECK_CONDITION; srb->result = SAM_STAT_CHECK_CONDITION;
return;
/* abort processing: the bulk-only transport requires a reset
* following an abort */
Handle_Abort:
srb->result = DID_ABORT << 16;
/* permit the reset transfer to take place */
clear_bit(US_FLIDX_ABORTING, &us->flags);
/* Need reset here */
} }
#ifdef CONFIG_USB_STORAGE_DEBUG #ifdef CONFIG_USB_STORAGE_DEBUG
......
...@@ -82,6 +82,10 @@ static void fix_inquiry_data(Scsi_Cmnd *srb) ...@@ -82,6 +82,10 @@ static void fix_inquiry_data(Scsi_Cmnd *srb)
if (srb->cmnd[0] != INQUIRY) if (srb->cmnd[0] != INQUIRY)
return; return;
/* oddly short buffer -- bail out */
if (srb->request_bufflen < 3)
return;
data_ptr = find_data_location(srb); data_ptr = find_data_location(srb);
if ((data_ptr[2] & 7) == 2) if ((data_ptr[2] & 7) == 2)
......
...@@ -57,6 +57,8 @@ ...@@ -57,6 +57,8 @@
#define US_SC_MIN US_SC_RBC #define US_SC_MIN US_SC_RBC
#define US_SC_MAX US_SC_ISD200 #define US_SC_MAX US_SC_ISD200
#define US_SC_DEVICE 0xff /* Use device's value */
extern void usb_stor_ATAPI_command(Scsi_Cmnd*, struct us_data*); extern void usb_stor_ATAPI_command(Scsi_Cmnd*, struct us_data*);
extern void usb_stor_qic157_command(Scsi_Cmnd*, struct us_data*); extern void usb_stor_qic157_command(Scsi_Cmnd*, struct us_data*);
extern void usb_stor_ufi_command(Scsi_Cmnd*, struct us_data*); extern void usb_stor_ufi_command(Scsi_Cmnd*, struct us_data*);
......
This diff is collapsed.
...@@ -136,9 +136,9 @@ static int usb_stor_msg_common(struct us_data *us, int timeout) ...@@ -136,9 +136,9 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
struct timer_list to_timer; struct timer_list to_timer;
int status; int status;
/* don't submit URBS during abort/disconnect processing */ /* don't submit URBs during abort/disconnect processing */
if (us->flags & DONT_SUBMIT) if (us->flags & DONT_SUBMIT)
return -ECONNRESET; return -EIO;
/* set up data structures for the wakeup system */ /* set up data structures for the wakeup system */
init_completion(&urb_done); init_completion(&urb_done);
...@@ -299,17 +299,17 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe, ...@@ -299,17 +299,17 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
return USB_STOR_XFER_STALLED; return USB_STOR_XFER_STALLED;
/* NAK - that means we've retried this a few times already */ /* timeout or excessively long NAK */
case -ETIMEDOUT: case -ETIMEDOUT:
US_DEBUGP("-- device NAKed\n"); US_DEBUGP("-- timeout or NAK\n");
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
/* babble - the device tried to send more than we wanted to read */ /* babble - the device tried to send more than we wanted to read */
case -EOVERFLOW: case -EOVERFLOW:
US_DEBUGP("-- Babble\n"); US_DEBUGP("-- babble\n");
return USB_STOR_XFER_LONG; return USB_STOR_XFER_LONG;
/* the transfer was cancelled, presumably by an abort */ /* the transfer was cancelled by abort, disconnect, or timeout */
case -ECONNRESET: case -ECONNRESET:
US_DEBUGP("-- transfer cancelled\n"); US_DEBUGP("-- transfer cancelled\n");
return USB_STOR_XFER_ERROR; return USB_STOR_XFER_ERROR;
...@@ -319,6 +319,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe, ...@@ -319,6 +319,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
US_DEBUGP("-- short read transfer\n"); US_DEBUGP("-- short read transfer\n");
return USB_STOR_XFER_SHORT; return USB_STOR_XFER_SHORT;
/* abort or disconnect in progress */
case -EIO:
US_DEBUGP("-- abort or disconnect in progress\n");
return USB_STOR_XFER_ERROR;
/* the catch-all error case */ /* the catch-all error case */
default: default:
US_DEBUGP("-- unknown error\n"); US_DEBUGP("-- unknown error\n");
...@@ -430,7 +435,7 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, ...@@ -430,7 +435,7 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
/* initialize the scatter-gather request block */ /* initialize the scatter-gather request block */
US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__, US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__,
length, num_sg); length, num_sg);
result = usb_sg_init(us->current_sg, us->pusb_dev, pipe, 0, result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
sg, num_sg, length, SLAB_NOIO); sg, num_sg, length, SLAB_NOIO);
if (result) { if (result) {
US_DEBUGP("usb_sg_init returned %d\n", result); US_DEBUGP("usb_sg_init returned %d\n", result);
...@@ -447,19 +452,19 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, ...@@ -447,19 +452,19 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
/* cancel the request, if it hasn't been cancelled already */ /* cancel the request, if it hasn't been cancelled already */
if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) { if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
US_DEBUGP("-- cancelling sg request\n"); US_DEBUGP("-- cancelling sg request\n");
usb_sg_cancel(us->current_sg); usb_sg_cancel(&us->current_sg);
} }
} }
/* wait for the completion of the transfer */ /* wait for the completion of the transfer */
usb_sg_wait(us->current_sg); usb_sg_wait(&us->current_sg);
clear_bit(US_FLIDX_SG_ACTIVE, &us->flags); clear_bit(US_FLIDX_SG_ACTIVE, &us->flags);
result = us->current_sg->status; result = us->current_sg.status;
if (act_len) if (act_len)
*act_len = us->current_sg->bytes; *act_len = us->current_sg.bytes;
return interpret_urb_result(us, pipe, length, result, return interpret_urb_result(us, pipe, length, result,
us->current_sg->bytes); us->current_sg.bytes);
} }
/* /*
...@@ -518,7 +523,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -518,7 +523,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
/* if the command gets aborted by the higher layers, we need to /* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing * short-circuit all other processing
*/ */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- command was aborted\n"); US_DEBUGP("-- command was aborted\n");
goto Handle_Abort; goto Handle_Abort;
} }
...@@ -650,7 +655,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -650,7 +655,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->cmd_len = old_cmd_len; srb->cmd_len = old_cmd_len;
memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE); memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- auto-sense aborted\n"); US_DEBUGP("-- auto-sense aborted\n");
goto Handle_Abort; goto Handle_Abort;
} }
...@@ -734,7 +739,7 @@ void usb_stor_stop_transport(struct us_data *us) ...@@ -734,7 +739,7 @@ void usb_stor_stop_transport(struct us_data *us)
/* If we are waiting for a scatter-gather operation, cancel it. */ /* If we are waiting for a scatter-gather operation, cancel it. */
if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) { if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
US_DEBUGP("-- cancelling sg request\n"); US_DEBUGP("-- cancelling sg request\n");
usb_sg_cancel(us->current_sg); usb_sg_cancel(&us->current_sg);
} }
} }
......
...@@ -74,6 +74,8 @@ ...@@ -74,6 +74,8 @@
#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
#endif #endif
#define US_PR_DEVICE 0xff /* Use device's value */
/* /*
* Bulk only data structures * Bulk only data structures
*/ */
......
...@@ -75,28 +75,26 @@ UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, ...@@ -75,28 +75,26 @@ UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
/* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
* Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
* always fails and confuses drive; without US_FL_START_STOP, drive accesses * always fails and confuses drive.
* (read or write) all fail.
*/ */
UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113,
"Buffalo", "Buffalo",
"DUB-P40G HDD", "DUB-P40G HDD",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY | US_FL_START_STOP), US_FL_FIX_INQUIRY ),
#ifdef CONFIG_USB_STORAGE_DPCM #ifdef CONFIG_USB_STORAGE_DPCM
UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
"Microtech", "Microtech",
"CameraMate (DPCM_USB)", "CameraMate (DPCM_USB)",
US_SC_SCSI, US_PR_DPCM_USB, NULL, US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
US_FL_START_STOP ),
#endif #endif
/* Made with the help of Edd Dumbill <edd@usefulinc.com> */ /* Made with the help of Edd Dumbill <edd@usefulinc.com> */
UNUSUAL_DEV( 0x0451, 0x5409, 0x0001, 0x0001, UNUSUAL_DEV( 0x0451, 0x5409, 0x0001, 0x0001,
"Frontier Labs", "Frontier Labs",
"Nex II Digital", "Nex II Digital",
US_SC_SCSI, US_PR_BULK, NULL, US_FL_START_STOP), US_SC_SCSI, US_PR_BULK, NULL, 0),
/* Patch submitted by Philipp Friedrich <philipp@void.at> */ /* Patch submitted by Philipp Friedrich <philipp@void.at> */
UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100,
...@@ -124,15 +122,6 @@ UNUSUAL_DEV( 0x04b8, 0x0602, 0x0110, 0x0110, ...@@ -124,15 +122,6 @@ UNUSUAL_DEV( 0x04b8, 0x0602, 0x0110, 0x0110,
"785EPX Storage", "785EPX Storage",
US_SC_SCSI, US_PR_BULK, NULL, US_FL_SINGLE_LUN), US_SC_SCSI, US_PR_BULK, NULL, US_FL_SINGLE_LUN),
/* Reported by Jan Willamowius <jan@willamowius.de>
* The device needs the flags only.
*/
UNUSUAL_DEV( 0x04c8, 0x0723, 0x0000, 0x9999,
"Konica",
"KD-200Z",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_START_STOP),
UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x2210, UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x2210,
"Fujifilm", "Fujifilm",
"FinePix 1400Zoom", "FinePix 1400Zoom",
...@@ -144,7 +133,7 @@ UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x2210, ...@@ -144,7 +133,7 @@ UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x2210,
UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074, UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074,
"ScanLogic", "ScanLogic",
"SL11R-IDE", "SL11R-IDE",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY), US_FL_FIX_INQUIRY),
/* Reported by Kriston Fincher <kriston@airmail.net> /* Reported by Kriston Fincher <kriston@airmail.net>
...@@ -183,14 +172,14 @@ UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, ...@@ -183,14 +172,14 @@ UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999,
"Sandisk", "Sandisk",
"ImageMate SDDR09", "ImageMate SDDR09",
US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP ), US_FL_SINGLE_LUN ),
/* This entry is from Andries.Brouwer@cwi.nl */ /* This entry is from Andries.Brouwer@cwi.nl */
UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
"SCM Microsystems", "SCM Microsystems",
"eUSB SmartMedia / CompactFlash Adapter", "eUSB SmartMedia / CompactFlash Adapter",
US_SC_SCSI, US_PR_DPCM_USB, sddr09_init, US_SC_SCSI, US_PR_DPCM_USB, sddr09_init,
US_FL_START_STOP), 0),
#endif #endif
UNUSUAL_DEV( 0x04e6, 0x0006, 0x0100, 0x0205, UNUSUAL_DEV( 0x04e6, 0x0006, 0x0100, 0x0205,
...@@ -247,40 +236,40 @@ UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100, ...@@ -247,40 +236,40 @@ UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100,
"Iomega", "Iomega",
"USB Clik! 40", "USB Clik! 40",
US_SC_8070, US_PR_BULK, NULL, US_SC_8070, US_PR_BULK, NULL,
US_FL_FIX_INQUIRY | US_FL_START_STOP ), US_FL_FIX_INQUIRY ),
/* This entry is needed because the device reports Sub=ff */ /* This entry is needed because the device reports Sub=ff */
UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450, UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450,
"Sony", "Sony",
"DSC-S30/S70/S75/505V/F505/F707/F717/P8", "DSC-S30/S70/S75/505V/F505/F707/F717/P8",
US_SC_SCSI, US_PR_CB, NULL, US_SC_SCSI, US_PR_CB, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE ), US_FL_SINGLE_LUN | US_FL_MODE_XLATE ),
/* Reported by wim@geeks.nl */ /* Reported by wim@geeks.nl */
UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100, UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100,
"Sony", "Sony",
"Memorystick NW-MS7", "Memorystick NW-MS7",
US_SC_UFI, US_PR_CB, NULL, US_SC_UFI, US_PR_CB, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP ), US_FL_SINGLE_LUN ),
UNUSUAL_DEV( 0x054c, 0x002d, 0x0100, 0x0100, UNUSUAL_DEV( 0x054c, 0x002d, 0x0100, 0x0100,
"Sony", "Sony",
"Memorystick MSAC-US1", "Memorystick MSAC-US1",
US_SC_UFI, US_PR_CB, NULL, US_SC_UFI, US_PR_CB, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP ), US_FL_SINGLE_LUN ),
/* Submitted by Klaus Mueller <k.mueller@intershop.de> */ /* Submitted by Klaus Mueller <k.mueller@intershop.de> */
UNUSUAL_DEV( 0x054c, 0x002e, 0x0106, 0x0310, UNUSUAL_DEV( 0x054c, 0x002e, 0x0106, 0x0310,
"Sony", "Sony",
"Handycam", "Handycam",
US_SC_SCSI, US_PR_CB, NULL, US_SC_SCSI, US_PR_CB, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE), US_FL_SINGLE_LUN | US_FL_MODE_XLATE),
UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999, UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999,
"Sony", "Sony",
"Memorystick MSC-U01N", "Memorystick MSC-U01N",
US_SC_UFI, US_PR_CB, NULL, US_SC_UFI, US_PR_CB, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP ), US_FL_SINGLE_LUN ),
/* Submitted by Nathan Babb <nathan@lexi.com> */ /* Submitted by Nathan Babb <nathan@lexi.com> */
UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999, UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999,
...@@ -316,7 +305,7 @@ UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200, ...@@ -316,7 +305,7 @@ UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200,
UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000, UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
"Pentax", "Pentax",
"Optio 2/3/400", "Optio 2/3/400",
US_SC_8070, US_PR_CBI, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ), US_FL_FIX_INQUIRY ),
/* Submitted by Per Winkvist <per.winkvist@uk.com> */ /* Submitted by Per Winkvist <per.winkvist@uk.com> */
...@@ -380,7 +369,7 @@ UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113, ...@@ -380,7 +369,7 @@ UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113,
UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0xffff, UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0xffff,
"SIIG", "SIIG",
"CompactFlash Card Reader", "CompactFlash Card Reader",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ), US_FL_FIX_INQUIRY ),
/* Reported by Peter Marks <peter.marks@turner.com> /* Reported by Peter Marks <peter.marks@turner.com>
...@@ -393,7 +382,7 @@ UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0xffff, ...@@ -393,7 +382,7 @@ UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0xffff,
UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0x0001, UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0x0001,
"EagleTec", "EagleTec",
"External Hard Disk", "External Hard Disk",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ), US_FL_FIX_INQUIRY ),
UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0x9999, UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0x9999,
...@@ -402,6 +391,14 @@ UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0x9999, ...@@ -402,6 +391,14 @@ UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0x9999,
US_SC_SCSI, US_PR_BULK, NULL, US_SC_SCSI, US_PR_BULK, NULL,
US_FL_FIX_INQUIRY | US_FL_MODE_XLATE), US_FL_FIX_INQUIRY | US_FL_MODE_XLATE),
/* Reported by Hanno Boeck <hanno@gmx.de>
* Taken from the Lycoris Kernel */
UNUSUAL_DEV( 0x0636, 0x0003, 0x0000, 0x9999,
"Vivitar",
"Vivicam 35Xx",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_FIX_INQUIRY | US_FL_MODE_XLATE),
UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100, UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100,
"TEAC", "TEAC",
"Floppy Drive", "Floppy Drive",
...@@ -412,25 +409,9 @@ UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, ...@@ -412,25 +409,9 @@ UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100,
"Olympus", "Olympus",
"Camedia MAUSB-2", "Camedia MAUSB-2",
US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP ), US_FL_SINGLE_LUN ),
#endif #endif
/* Submitted by kedar@centillium
* Needed for START_STOP flag, but that is unconfirmed */
UNUSUAL_DEV( 0x0686, 0x4006, 0x0001, 0x0001,
"Minolta",
"Dimage S304",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_START_STOP ),
/* Submitted by f.brugmans@hccnet.nl
* Needed for START_STOP flag */
UNUSUAL_DEV( 0x0686, 0x4007, 0x0001, 0x0001,
"Minolta",
"Dimage S304",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_START_STOP ),
UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100, UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100,
"Hagiwara", "Hagiwara",
"FlashGate SmartMedia", "FlashGate SmartMedia",
...@@ -445,13 +426,12 @@ UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, ...@@ -445,13 +426,12 @@ UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200,
"Sandisk", "Sandisk",
"ImageMate SDDR-05a", "ImageMate SDDR-05a",
US_SC_SCSI, US_PR_CB, NULL, US_SC_SCSI, US_PR_CB, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP), US_FL_SINGLE_LUN ),
UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009, UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009,
"Sandisk", "Sandisk",
"ImageMate SDDR-31", "ImageMate SDDR-31",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_SCSI, US_PR_BULK, NULL, 0 ),
US_FL_IGNORE_SER),
UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100,
"Sandisk", "Sandisk",
...@@ -464,7 +444,7 @@ UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, ...@@ -464,7 +444,7 @@ UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999,
"Sandisk", "Sandisk",
"ImageMate SDDR-09", "ImageMate SDDR-09",
US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP ), US_FL_SINGLE_LUN ),
#endif #endif
#ifdef CONFIG_USB_STORAGE_FREECOM #ifdef CONFIG_USB_STORAGE_FREECOM
...@@ -490,8 +470,7 @@ UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, ...@@ -490,8 +470,7 @@ UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100,
UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
"Microtech", "Microtech",
"CameraMate (DPCM_USB)", "CameraMate (DPCM_USB)",
US_SC_SCSI, US_PR_DPCM_USB, NULL, US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
US_FL_START_STOP ),
#endif #endif
#ifdef CONFIG_USB_STORAGE_DATAFAB #ifdef CONFIG_USB_STORAGE_DATAFAB
...@@ -568,7 +547,7 @@ UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999, ...@@ -568,7 +547,7 @@ UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
"Datafab", "Datafab",
"KECF-USB", "KECF-USB",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ), US_FL_FIX_INQUIRY ),
/* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
...@@ -629,20 +608,7 @@ UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x0001, ...@@ -629,20 +608,7 @@ UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x0001,
"Global Channel Solutions", "Global Channel Solutions",
"EasyDisk EDxxxx", "EasyDisk EDxxxx",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_SCSI, US_PR_BULK, NULL,
US_FL_MODE_XLATE | US_FL_START_STOP | US_FL_FIX_INQUIRY ), US_FL_MODE_XLATE | US_FL_FIX_INQUIRY ),
/* Submitted by Brian Hall <brihall@pcisys.net>
* Needed for START_STOP flag */
UNUSUAL_DEV( 0x0c76, 0x0003, 0x0100, 0x0100,
"JMTek",
"USBDrive",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_START_STOP ),
UNUSUAL_DEV( 0x0c76, 0x0005, 0x0100, 0x0100,
"JMTek",
"USBDrive",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_START_STOP ),
/* Reported by Dan Pilone <pilone@slac.com> /* Reported by Dan Pilone <pilone@slac.com>
* The device needs the flags only. * The device needs the flags only.
...@@ -652,8 +618,8 @@ UNUSUAL_DEV( 0x0c76, 0x0005, 0x0100, 0x0100, ...@@ -652,8 +618,8 @@ UNUSUAL_DEV( 0x0c76, 0x0005, 0x0100, 0x0100,
UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x9999, UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x9999,
"CCYU TECHNOLOGY", "CCYU TECHNOLOGY",
"EasyDisk Portable Device", "EasyDisk Portable Device",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_MODE_XLATE | US_FL_START_STOP), US_FL_MODE_XLATE ),
#ifdef CONFIG_USB_STORAGE_SDDR55 #ifdef CONFIG_USB_STORAGE_SDDR55
UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999,
...@@ -670,5 +636,5 @@ UNUSUAL_DEV( 0x08ca, 0x2011, 0x0000, 0x9999, ...@@ -670,5 +636,5 @@ UNUSUAL_DEV( 0x08ca, 0x2011, 0x0000, 0x9999,
"AIPTEK", "AIPTEK",
"PocketCAM 3Mega", "PocketCAM 3Mega",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_SCSI, US_PR_BULK, NULL,
US_FL_MODE_XLATE | US_FL_START_STOP), US_FL_MODE_XLATE ),
...@@ -102,8 +102,6 @@ static void storage_disconnect(struct usb_interface *iface); ...@@ -102,8 +102,6 @@ static void storage_disconnect(struct usb_interface *iface);
/* The entries in this table, except for final ones here /* The entries in this table, except for final ones here
* (USB_MASS_STORAGE_CLASS and the empty entry), correspond, * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
* line for line with the entries of us_unsuaul_dev_list[]. * line for line with the entries of us_unsuaul_dev_list[].
* For now, we duplicate idVendor and idProduct in us_unsual_dev_list,
* just to avoid alignment bugs.
*/ */
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
...@@ -328,13 +326,13 @@ static int usb_stor_control_thread(void * __us) ...@@ -328,13 +326,13 @@ static int usb_stor_control_thread(void * __us)
scsi_lock(host); scsi_lock(host);
/* has the command been aborted *already* ? */ /* has the command been aborted *already* ? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (us->sm_state == US_STATE_ABORTING) {
us->srb->result = DID_ABORT << 16; us->srb->result = DID_ABORT << 16;
goto SkipForAbort; goto SkipForAbort;
} }
/* set the state and release the lock */ /* set the state and release the lock */
atomic_set(&us->sm_state, US_STATE_RUNNING); us->sm_state = US_STATE_RUNNING;
scsi_unlock(host); scsi_unlock(host);
/* lock the device pointers */ /* lock the device pointers */
...@@ -353,7 +351,7 @@ static int usb_stor_control_thread(void * __us) ...@@ -353,7 +351,7 @@ static int usb_stor_control_thread(void * __us)
*/ */
else if (us->srb->device->id && else if (us->srb->device->id &&
!(us->flags & US_FL_SCM_MULT_TARG)) { !(us->flags & US_FL_SCM_MULT_TARG)) {
US_DEBUGP("Bad target number (%d/%d)\n", US_DEBUGP("Bad target number (%d:%d)\n",
us->srb->device->id, us->srb->device->lun); us->srb->device->id, us->srb->device->lun);
us->srb->result = DID_BAD_TARGET << 16; us->srb->result = DID_BAD_TARGET << 16;
} }
...@@ -404,12 +402,12 @@ static int usb_stor_control_thread(void * __us) ...@@ -404,12 +402,12 @@ static int usb_stor_control_thread(void * __us)
* sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT, * sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
* because an abort request might be received after all the * because an abort request might be received after all the
* USB processing was complete. */ * USB processing was complete. */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) if (us->sm_state == US_STATE_ABORTING)
complete(&(us->notify)); complete(&(us->notify));
/* empty the queue, reset the state, and release the lock */ /* empty the queue, reset the state, and release the lock */
us->srb = NULL; us->srb = NULL;
atomic_set(&us->sm_state, US_STATE_IDLE); us->sm_state = US_STATE_IDLE;
scsi_unlock(host); scsi_unlock(host);
} /* for (;;) */ } /* for (;;) */
...@@ -424,10 +422,13 @@ static int usb_stor_control_thread(void * __us) ...@@ -424,10 +422,13 @@ static int usb_stor_control_thread(void * __us)
***********************************************************************/ ***********************************************************************/
/* Get the unusual_devs entries and the string descriptors */ /* Get the unusual_devs entries and the string descriptors */
static void get_device_info(struct us_data *us, static void get_device_info(struct us_data *us, int id_index)
struct us_unusual_dev *unusual_dev)
{ {
struct usb_device *dev = us->pusb_dev; struct usb_device *dev = us->pusb_dev;
struct usb_host_interface *altsetting =
&us->pusb_intf->altsetting[us->pusb_intf->act_altsetting];
struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index];
struct usb_device_id *id = &storage_usb_ids[id_index];
if (unusual_dev->vendorName) if (unusual_dev->vendorName)
US_DEBUGP("Vendor: %s\n", unusual_dev->vendorName); US_DEBUGP("Vendor: %s\n", unusual_dev->vendorName);
...@@ -436,10 +437,40 @@ static void get_device_info(struct us_data *us, ...@@ -436,10 +437,40 @@ static void get_device_info(struct us_data *us,
/* Store the entries */ /* Store the entries */
us->unusual_dev = unusual_dev; us->unusual_dev = unusual_dev;
us->subclass = unusual_dev->useProtocol; us->subclass = (unusual_dev->useProtocol == US_SC_DEVICE) ?
us->protocol = unusual_dev->useTransport; altsetting->desc.bInterfaceSubClass :
unusual_dev->useProtocol;
us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
altsetting->desc.bInterfaceProtocol :
unusual_dev->useTransport;
us->flags = unusual_dev->flags; us->flags = unusual_dev->flags;
/* Log a message if a non-generic unusual_dev entry contains an
* unnecessary subclass or protocol override. This may stimulate
* reports from users that will help us remove unneeded entries
* from the unusual_devs.h table.
*/
if (id->idVendor || id->idProduct) {
static char *msgs[3] = {
"an unneeded SubClass entry",
"an unneeded Protocol entry",
"unneeded SubClass and Protocol entries"};
int msg = -1;
if (unusual_dev->useProtocol != US_SC_DEVICE &&
us->subclass == altsetting->desc.bInterfaceSubClass)
msg += 1;
if (unusual_dev->useTransport != US_PR_DEVICE &&
us->protocol == altsetting->desc.bInterfaceProtocol)
msg += 2;
if (msg >= 0)
printk(KERN_NOTICE USB_STORAGE "This device "
"(%04x,%04x) has %s in unusual_devs.h\n"
" Please send a copy of this message to "
"<linux-usb-devel@lists.sourceforge.net>\n",
id->idVendor, id->idProduct, msgs[msg]);
}
/* Read the device's string descriptors */ /* Read the device's string descriptors */
if (dev->descriptor.iManufacturer) if (dev->descriptor.iManufacturer)
usb_string(dev, dev->descriptor.iManufacturer, usb_string(dev, dev->descriptor.iManufacturer,
...@@ -447,7 +478,7 @@ static void get_device_info(struct us_data *us, ...@@ -447,7 +478,7 @@ static void get_device_info(struct us_data *us,
if (dev->descriptor.iProduct) if (dev->descriptor.iProduct)
usb_string(dev, dev->descriptor.iProduct, usb_string(dev, dev->descriptor.iProduct,
us->product, sizeof(us->product)); us->product, sizeof(us->product));
if (dev->descriptor.iSerialNumber && !(us->flags & US_FL_IGNORE_SER)) if (dev->descriptor.iSerialNumber)
usb_string(dev, dev->descriptor.iSerialNumber, usb_string(dev, dev->descriptor.iSerialNumber,
us->serial, sizeof(us->serial)); us->serial, sizeof(us->serial));
...@@ -698,13 +729,6 @@ static int usb_stor_acquire_resources(struct us_data *us) ...@@ -698,13 +729,6 @@ static int usb_stor_acquire_resources(struct us_data *us)
return -ENOMEM; return -ENOMEM;
} }
US_DEBUGP("Allocating scatter-gather request block\n");
us->current_sg = kmalloc(sizeof(*us->current_sg), GFP_KERNEL);
if (!us->current_sg) {
US_DEBUGP("allocation failed\n");
return -ENOMEM;
}
/* Lock the device while we carry out the next two operations */ /* Lock the device while we carry out the next two operations */
down(&us->dev_semaphore); down(&us->dev_semaphore);
...@@ -720,7 +744,7 @@ static int usb_stor_acquire_resources(struct us_data *us) ...@@ -720,7 +744,7 @@ static int usb_stor_acquire_resources(struct us_data *us)
up(&us->dev_semaphore); up(&us->dev_semaphore);
/* Start up our control thread */ /* Start up our control thread */
atomic_set(&us->sm_state, US_STATE_IDLE); us->sm_state = US_STATE_IDLE;
p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
if (p < 0) { if (p < 0) {
printk(KERN_WARNING USB_STORAGE printk(KERN_WARNING USB_STORAGE
...@@ -782,7 +806,7 @@ void usb_stor_release_resources(struct us_data *us) ...@@ -782,7 +806,7 @@ void usb_stor_release_resources(struct us_data *us)
*/ */
if (us->pid) { if (us->pid) {
US_DEBUGP("-- sending exit command to thread\n"); US_DEBUGP("-- sending exit command to thread\n");
BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE); BUG_ON(us->sm_state != US_STATE_IDLE);
us->srb = NULL; us->srb = NULL;
up(&(us->sema)); up(&(us->sema));
wait_for_completion(&(us->notify)); wait_for_completion(&(us->notify));
...@@ -800,8 +824,6 @@ void usb_stor_release_resources(struct us_data *us) ...@@ -800,8 +824,6 @@ void usb_stor_release_resources(struct us_data *us)
} }
/* Free the USB control blocks */ /* Free the USB control blocks */
if (us->current_sg)
kfree(us->current_sg);
if (us->current_urb) if (us->current_urb)
usb_free_urb(us->current_urb); usb_free_urb(us->current_urb);
if (us->dr) if (us->dr)
...@@ -852,7 +874,7 @@ static int storage_probe(struct usb_interface *intf, ...@@ -852,7 +874,7 @@ static int storage_probe(struct usb_interface *intf,
* of the match from the usb_device_id table, so we can find the * of the match from the usb_device_id table, so we can find the
* corresponding entry in the private table. * corresponding entry in the private table.
*/ */
get_device_info(us, &us_unusual_dev_list[id_index]); get_device_info(us, id_index);
#ifdef CONFIG_USB_STORAGE_SDDR09 #ifdef CONFIG_USB_STORAGE_SDDR09
if (us->protocol == US_PR_EUSB_SDDR09 || if (us->protocol == US_PR_EUSB_SDDR09 ||
......
...@@ -71,8 +71,6 @@ struct us_unusual_dev { ...@@ -71,8 +71,6 @@ struct us_unusual_dev {
#define US_FL_SINGLE_LUN 0x00000001 /* allow access to only LUN 0 */ #define US_FL_SINGLE_LUN 0x00000001 /* allow access to only LUN 0 */
#define US_FL_MODE_XLATE 0x00000002 /* translate _6 to _10 commands for #define US_FL_MODE_XLATE 0x00000002 /* translate _6 to _10 commands for
Win/MacOS compatibility */ Win/MacOS compatibility */
#define US_FL_START_STOP 0x00000004 /* ignore START_STOP commands */
#define US_FL_IGNORE_SER 0x00000010 /* Ignore the serial number given */
#define US_FL_SCM_MULT_TARG 0x00000020 /* supports multiple targets */ #define US_FL_SCM_MULT_TARG 0x00000020 /* supports multiple targets */
#define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */ #define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */
#define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */ #define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */
...@@ -139,7 +137,7 @@ struct us_data { ...@@ -139,7 +137,7 @@ struct us_data {
/* thread information */ /* thread information */
int pid; /* control thread */ int pid; /* control thread */
atomic_t sm_state; /* what we are doing */ int sm_state; /* what we are doing */
/* interrupt communications data */ /* interrupt communications data */
unsigned char irqdata[2]; /* data from USB IRQ */ unsigned char irqdata[2]; /* data from USB IRQ */
...@@ -147,7 +145,7 @@ struct us_data { ...@@ -147,7 +145,7 @@ struct us_data {
/* control and bulk communications data */ /* control and bulk communications data */
struct urb *current_urb; /* non-int USB requests */ struct urb *current_urb; /* non-int USB requests */
struct usb_ctrlrequest *dr; /* control requests */ struct usb_ctrlrequest *dr; /* control requests */
struct usb_sg_request *current_sg; /* scatter-gather USB */ struct usb_sg_request current_sg; /* scatter-gather USB */
/* the semaphore for sleeping the control thread */ /* the semaphore for sleeping the control thread */
struct semaphore sema; /* to sleep thread on */ struct semaphore sema; /* to sleep thread on */
......
...@@ -492,8 +492,9 @@ extern int usb_disabled(void); ...@@ -492,8 +492,9 @@ extern int usb_disabled(void);
*/ */
#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */ #define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
#define URB_NO_DMA_MAP 0x0004 /* urb->*_dma are valid on submit */ #define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
#define URB_ASYNC_UNLINK 0x0008 /* usb_unlink_urb() returns asap */ #define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */
#define URB_ASYNC_UNLINK 0x0010 /* usb_unlink_urb() returns asap */
#define URB_NO_FSBR 0x0020 /* UHCI-specific */ #define URB_NO_FSBR 0x0020 /* UHCI-specific */
#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ #define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ #define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
...@@ -531,14 +532,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -531,14 +532,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* submission, unlinking, or operation are handled. Different * submission, unlinking, or operation are handled. Different
* kinds of URB can use different flags. * kinds of URB can use different flags.
* @transfer_buffer: This identifies the buffer to (or from) which * @transfer_buffer: This identifies the buffer to (or from) which
* the I/O request will be performed (unless URB_NO_DMA_MAP is set). * the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP
* This buffer must be suitable for DMA; allocate it with kmalloc() * is set). This buffer must be suitable for DMA; allocate it with
* or equivalent. For transfers to "in" endpoints, contents of * kmalloc() or equivalent. For transfers to "in" endpoints, contents
* this buffer will be modified. This buffer is used for data * of this buffer will be modified. This buffer is used for data
* phases of control transfers. * phases of control transfers.
* @transfer_dma: When transfer_flags includes URB_NO_DMA_MAP, the device * @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
* driver is saying that it provided this DMA address, which the host * the device driver is saying that it provided this DMA address,
* controller driver should use instead of the transfer_buffer. * which the host controller driver should use in preference to the
* transfer_buffer.
* @transfer_buffer_length: How big is transfer_buffer. The transfer may * @transfer_buffer_length: How big is transfer_buffer. The transfer may
* be broken up into chunks according to the current maximum packet * be broken up into chunks according to the current maximum packet
* size for the endpoint, which is a function of the configuration * size for the endpoint, which is a function of the configuration
...@@ -553,11 +555,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -553,11 +555,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* @setup_packet: Only used for control transfers, this points to eight bytes * @setup_packet: Only used for control transfers, this points to eight bytes
* of setup data. Control transfers always start by sending this data * of setup data. Control transfers always start by sending this data
* to the device. Then transfer_buffer is read or written, if needed. * to the device. Then transfer_buffer is read or written, if needed.
* (Not used when URB_NO_DMA_MAP is set.) * @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the
* @setup_dma: For control transfers with URB_NO_DMA_MAP set, the device * device driver has provided this DMA address for the setup packet.
* driver has provided this DMA address for the setup packet. The * The host controller driver should use this in preference to
* host controller driver should use this instead of setup_buffer. * setup_packet.
* If there is a data phase, its buffer is identified by transfer_dma.
* @start_frame: Returns the initial frame for interrupt or isochronous * @start_frame: Returns the initial frame for interrupt or isochronous
* transfers. * transfers.
* @number_of_packets: Lists the number of ISO transfer buffers. * @number_of_packets: Lists the number of ISO transfer buffers.
...@@ -589,13 +590,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -589,13 +590,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* bounce buffer or talking to an IOMMU), * bounce buffer or talking to an IOMMU),
* although they're cheap on commodity x86 and ppc hardware. * although they're cheap on commodity x86 and ppc hardware.
* *
* Alternatively, drivers may pass the URB_NO_DMA_MAP transfer flag, which * Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
* tells the host controller driver that no such mapping is needed since * which tell the host controller driver that no such mapping is needed since
* the device driver is DMA-aware. For example, they might allocate a DMA * the device driver is DMA-aware. For example, a device driver might
* buffer with usb_buffer_alloc(), or call usb_buffer_map(). * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
* When this transfer flag is provided, host controller drivers will use the * When these transfer flags are provided, host controller drivers will
* dma addresses found in the transfer_dma and/or setup_dma fields rather than * attempt to use the dma addresses found in the transfer_dma and/or
* determing a dma address themselves. * setup_dma fields rather than determining a dma address themselves. (Note
* that transfer_buffer and setup_packet must still be set because not all
* host controllers use DMA, nor do virtual root hubs).
* *
* Initialization: * Initialization:
* *
...@@ -614,7 +617,11 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); ...@@ -614,7 +617,11 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* should always terminate with a short packet, even if it means adding an * should always terminate with a short packet, even if it means adding an
* extra zero length packet. * extra zero length packet.
* *
* Control URBs must provide a setup_packet. * Control URBs must provide a setup_packet. The setup_packet and
* transfer_buffer may each be mapped for DMA or not, independently of
* the other. The transfer_flags bits URB_NO_TRANSFER_DMA_MAP and
* URB_NO_SETUP_DMA_MAP indicate which buffers have already been mapped.
* URB_NO_SETUP_DMA_MAP is ignored for non-control URBs.
* *
* Interrupt UBS must provide an interval, saying how often (in milliseconds * Interrupt UBS must provide an interval, saying how often (in milliseconds
* or, for highspeed devices, 125 microsecond units) * or, for highspeed devices, 125 microsecond units)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment