Commit 1837f6a9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents 2d00c1cc 173f38e5
......@@ -15,10 +15,12 @@ OR: they can now be DMA-aware.
manage dma mappings for existing dma-ready buffers (see below).
- 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
first and set URB_NO_DMA_MAP. HCDs don't manage dma mappings for urbs.
- "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do
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
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.
- 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
kind of addresses to store in urb->transfer_buffer and urb->transfer_dma,
while guaranteeing that hidden copies through DMA "bounce" buffers won't
slow things down. You'd also set URB_NO_DMA_MAP in urb->transfer_flags:
while guaranteeing that no hidden copies through DMA "bounce" buffers will
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,
int mem_flags, dma_addr_t *dma);
......@@ -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 *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
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
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
space-efficient.
......@@ -91,7 +102,8 @@ DMA address space of the device.
These calls all work with initialized urbs: urb->dev, urb->pipe,
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);
......@@ -99,6 +111,6 @@ DMA address space of the device.
void usb_buffer_unmap (struct urb *urb);
The calls manage urb->transfer_dma for you, and set URB_NO_DMA_MAP so that
usbcore won't map or unmap the buffer.
The calls manage urb->transfer_dma for you, and set URB_NO_TRANSFER_DMA_MAP
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_SPEEDTOUCH) += 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
pgrem = rem;
memcpy((db->sgbuf[db->wrptr >> PAGE_SHIFT]) + (db->wrptr & (PAGE_SIZE-1)), buffer, pgrem);
size -= pgrem;
(char *)buffer += pgrem;
buffer += pgrem;
db->wrptr += pgrem;
if (db->wrptr >= db->dmasize)
db->wrptr = 0;
......@@ -564,14 +564,14 @@ static void dmabuf_copyout(struct dmabuf *db, void *buffer, unsigned int size)
pgrem = rem;
memcpy(buffer, (db->sgbuf[db->rdptr >> PAGE_SHIFT]) + (db->rdptr & (PAGE_SIZE-1)), pgrem);
size -= pgrem;
(char *)buffer += pgrem;
buffer += pgrem;
db->rdptr += pgrem;
if (db->rdptr >= db->dmasize)
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;
......@@ -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))
return -EFAULT;
size -= pgrem;
(char *)buffer += pgrem;
buffer += pgrem;
ptr += pgrem;
if (ptr >= db->dmasize)
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;
......@@ -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))
return -EFAULT;
size -= pgrem;
(char *)buffer += pgrem;
buffer += pgrem;
ptr += pgrem;
if (ptr >= db->dmasize)
ptr = 0;
......@@ -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.name, "USB Audio Class Driver", sizeof(info.name));
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 0;
}
......@@ -2018,7 +2018,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign
_old_mixer_info info;
strncpy(info.id, "USB_AUDIO", sizeof(info.id));
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 0;
}
......@@ -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;
DECLARE_WAITQUEUE(wait, current);
......@@ -2208,7 +2208,7 @@ static ssize_t usb_audio_read(struct file *file, char *buffer, size_t count, lof
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;
DECLARE_WAITQUEUE(wait, current);
......@@ -2507,7 +2507,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
abinfo.fragstotal = as->usbout.dma.numfrag;
abinfo.fragments = abinfo.bytes >> as->usbout.dma.fragshift;
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:
if (!(file->f_mode & FMODE_READ))
......@@ -2520,7 +2520,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
abinfo.fragstotal = as->usbin.dma.numfrag;
abinfo.fragments = abinfo.bytes >> as->usbin.dma.fragshift;
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:
file->f_flags |= O_NONBLOCK;
......@@ -2544,7 +2544,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
if (as->usbin.dma.mapped)
as->usbin.dma.count &= as->usbin.dma.fragsize-1;
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 0;
......@@ -2558,7 +2558,7 @@ static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int
if (as->usbout.dma.mapped)
as->usbout.dma.count &= as->usbout.dma.fragsize-1;
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 0;
......
......@@ -484,7 +484,7 @@ static int bluetooth_write (struct tty_struct * tty, int from_user, const unsign
retval = -ENOMEM;
goto exit;
}
if (copy_from_user (temp_buffer, buf, count)) {
if (copy_from_user (temp_buffer, (void __user *)buf, count)) {
retval = -EFAULT;
goto exit;
}
......
......@@ -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;
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;
} else
memcpy(acm->writeurb->transfer_buffer, buf, count);
......@@ -548,7 +548,7 @@ static int acm_probe (struct usb_interface *intf,
struct usb_host_config *cfacm;
struct usb_host_interface *ifcom, *ifdata;
struct usb_endpoint_descriptor *epctrl, *epread, *epwrite;
int readsize, ctrlsize, minor, i;
int readsize, ctrlsize, minor, i, j;
unsigned char *buf;
dev = interface_to_usbdev (intf);
......@@ -558,120 +558,123 @@ static int acm_probe (struct usb_interface *intf,
dbg("probing config %d", cfacm->desc.bConfigurationValue);
if (cfacm->desc.bNumInterfaces != 2 ||
usb_interface_claimed(cfacm->interface + 0) ||
usb_interface_claimed(cfacm->interface + 1))
for (j = 0; j < cfacm->desc.bNumInterfaces - 1; j++) {
if (usb_interface_claimed(cfacm->interface + j) ||
usb_interface_claimed(cfacm->interface + j + 1))
continue;
ifcom = cfacm->interface[0].altsetting + 0;
ifdata = cfacm->interface[1].altsetting + 0;
ifcom = cfacm->interface[j].altsetting + 0;
ifdata = cfacm->interface[j + 1].altsetting + 0;
if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) {
ifcom = cfacm->interface[1].altsetting + 0;
ifdata = cfacm->interface[0].altsetting + 0;
if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2)
continue;
}
if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) {
ifcom = cfacm->interface[j + 1].altsetting + 0;
ifdata = cfacm->interface[j].altsetting + 0;
if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2)
continue;
}
if (ifcom->desc.bInterfaceClass != 2 || ifcom->desc.bInterfaceSubClass != 2 ||
ifcom->desc.bInterfaceProtocol != 1 || ifcom->desc.bNumEndpoints < 1)
continue;
if (ifcom->desc.bInterfaceClass != 2 || ifcom->desc.bInterfaceSubClass != 2 ||
ifcom->desc.bInterfaceProtocol < 1 || ifcom->desc.bInterfaceProtocol > 6 ||
ifcom->desc.bNumEndpoints < 1)
continue;
epctrl = &ifcom->endpoint[0].desc;
epread = &ifdata->endpoint[0].desc;
epwrite = &ifdata->endpoint[1].desc;
epctrl = &ifcom->endpoint[0].desc;
epread = &ifdata->endpoint[0].desc;
epwrite = &ifdata->endpoint[1].desc;
if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
(epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
continue;
if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
(epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
continue;
if ((epread->bEndpointAddress & 0x80) != 0x80) {
epread = &ifdata->endpoint[1].desc;
epwrite = &ifdata->endpoint[0].desc;
}
if ((epread->bEndpointAddress & 0x80) != 0x80) {
epread = &ifdata->endpoint[1].desc;
epwrite = &ifdata->endpoint[0].desc;
}
usb_set_configuration(dev, cfacm->desc.bConfigurationValue);
usb_set_configuration(dev, cfacm->desc.bConfigurationValue);
for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
if (acm_table[minor]) {
err("no more free acm devices");
return -ENODEV;
}
for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
if (acm_table[minor]) {
err("no more free acm devices");
return -ENODEV;
}
if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
err("out of memory");
return -ENOMEM;
}
memset(acm, 0, sizeof(struct acm));
if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
err("out of memory");
return -ENOMEM;
}
memset(acm, 0, sizeof(struct acm));
ctrlsize = epctrl->wMaxPacketSize;
readsize = epread->wMaxPacketSize;
acm->writesize = epwrite->wMaxPacketSize;
acm->iface = cfacm->interface;
acm->minor = minor;
acm->dev = dev;
ctrlsize = epctrl->wMaxPacketSize;
readsize = epread->wMaxPacketSize;
acm->writesize = epwrite->wMaxPacketSize;
acm->iface = cfacm->interface + j;
acm->minor = minor;
acm->dev = dev;
INIT_WORK(&acm->work, acm_softint, acm);
INIT_WORK(&acm->work, acm_softint, acm);
if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
err("out of memory");
kfree(acm);
return -ENOMEM;
}
if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
err("out of memory");
kfree(acm);
return -ENOMEM;
}
acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->ctrlurb) {
err("out of memory");
kfree(acm);
kfree(buf);
return -ENOMEM;
}
acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->readurb) {
err("out of memory");
usb_free_urb(acm->ctrlurb);
kfree(acm);
kfree(buf);
return -ENOMEM;
}
acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->writeurb) {
err("out of memory");
usb_free_urb(acm->readurb);
usb_free_urb(acm->ctrlurb);
kfree(acm);
kfree(buf);
return -ENOMEM;
}
acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->ctrlurb) {
err("out of memory");
kfree(acm);
kfree(buf);
return -ENOMEM;
}
acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->readurb) {
err("out of memory");
usb_free_urb(acm->ctrlurb);
kfree(acm);
kfree(buf);
return -ENOMEM;
}
acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->writeurb) {
err("out of memory");
usb_free_urb(acm->readurb);
usb_free_urb(acm->ctrlurb);
kfree(acm);
kfree(buf);
return -ENOMEM;
}
usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
buf += ctrlsize, readsize, acm_read_bulk, acm);
acm->readurb->transfer_flags |= URB_NO_FSBR;
usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
buf += ctrlsize, readsize, acm_read_bulk, acm);
acm->readurb->transfer_flags |= URB_NO_FSBR;
usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
buf += readsize, acm->writesize, acm_write_bulk, acm);
acm->writeurb->transfer_flags |= URB_NO_FSBR;
usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
buf += readsize, acm->writesize, acm_write_bulk, acm);
acm->writeurb->transfer_flags |= URB_NO_FSBR;
info("ttyACM%d: USB ACM device", minor);
info("ttyACM%d: USB ACM device", minor);
acm_set_control(acm, acm->ctrlout);
acm_set_control(acm, acm->ctrlout);
acm->line.speed = cpu_to_le32(9600);
acm->line.databits = 8;
acm_set_line(acm, &acm->line);
acm->line.speed = cpu_to_le32(9600);
acm->line.databits = 8;
acm_set_line(acm, &acm->line);
usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
tty_register_device(acm_tty_driver, minor, &intf->dev);
tty_register_device(acm_tty_driver, minor, &intf->dev);
acm_table[minor] = acm;
usb_set_intfdata (intf, acm);
return 0;
acm_table[minor] = acm;
usb_set_intfdata (intf, acm);
return 0;
}
}
return -EIO;
......
......@@ -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 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
*
**/
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;
ssize_t ret;
......
......@@ -296,13 +296,13 @@ static int usblp_check_status(struct usblp *usblp, int err)
}
status = *usblp->statusbuf;
if (~status & LP_PERRORP) {
if (~status & LP_PERRORP)
newerr = 3;
if (status & LP_POUTPA)
newerr = 1;
if (~status & LP_PSELECD)
newerr = 2;
}
if (status & LP_POUTPA)
newerr = 1;
if (~status & LP_PSELECD)
newerr = 2;
if (newerr != err)
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,
{
struct usblp *usblp = file->private_data;
int length, err, i;
unsigned char lpstatus, newChannel;
unsigned char newChannel;
int status;
int twoints[2];
int retval = 0;
......@@ -455,7 +455,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (length > _IOC_SIZE(cmd))
length = _IOC_SIZE(cmd); /* truncate */
if (copy_to_user((unsigned char *) arg,
if (copy_to_user((void __user *) arg,
usblp->device_id_string,
(unsigned long) length)) {
retval = -EFAULT;
......@@ -479,7 +479,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
twoints[1] |= (1<<i);
}
if (copy_to_user((unsigned char *)arg,
if (copy_to_user((void __user *)arg,
(unsigned char *)twoints,
sizeof(twoints))) {
retval = -EFAULT;
......@@ -540,7 +540,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
twoints[0] = usblp->dev->bus->busnum;
twoints[1] = usblp->dev->devnum;
if (copy_to_user((unsigned char *)arg,
if (copy_to_user((void __user *)arg,
(unsigned char *)twoints,
sizeof(twoints))) {
retval = -EFAULT;
......@@ -560,7 +560,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
twoints[0] = usblp->dev->descriptor.idVendor;
twoints[1] = usblp->dev->descriptor.idProduct;
if (copy_to_user((unsigned char *)arg,
if (copy_to_user((void __user *)arg,
(unsigned char *)twoints,
sizeof(twoints))) {
retval = -EFAULT;
......@@ -578,13 +578,13 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (cmd) {
case LPGETSTATUS:
if (usblp_read_status(usblp, &lpstatus)) {
if (usblp_read_status(usblp, usblp->statusbuf)) {
err("usblp%d: failed reading printer status", usblp->minor);
retval = -EIO;
goto done;
}
status = lpstatus;
if (copy_to_user ((int *)arg, &status, sizeof(int)))
status = *usblp->statusbuf;
if (copy_to_user ((void __user *)arg, &status, sizeof(int)))
retval = -EFAULT;
break;
......@@ -597,7 +597,7 @@ static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
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);
struct usblp *usblp = file->private_data;
......@@ -682,7 +682,7 @@ static ssize_t usblp_write(struct file *file, const char *buffer, size_t 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;
DECLARE_WAITQUEUE(wait, current);
......@@ -858,8 +858,8 @@ static int usblp_probe(struct usb_interface *intf,
}
usblp->writebuf = usblp->readbuf = NULL;
usblp->writeurb->transfer_flags = URB_NO_DMA_MAP;
usblp->readurb->transfer_flags = URB_NO_DMA_MAP;
usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
/* Malloc write & read buffers. We somewhat wastefully
* malloc both regardless of bidirectionality, because the
* 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)
/* rh_timer protected by hcd_data_lock */
if (hcd->rh_timer.data
|| urb->status != -EINPROGRESS
|| urb->transfer_buffer_length < len) {
|| urb->transfer_buffer_length < len
|| !HCD_IS_RUNNING (hcd->state)) {
dev_dbg (hcd->controller,
"not queuing rh status urb, stat %d\n",
urb->status);
......@@ -489,11 +490,10 @@ static void rh_report_status (unsigned long ptr)
local_irq_save (flags);
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
|| urb->status != -EINPROGRESS
|| (hcd = urb->dev->bus->hcpriv) == 0
|| !HCD_IS_RUNNING (hcd->state)) {
|| (hcd = urb->dev->bus->hcpriv) == 0) {
spin_unlock (&urb->lock);
local_irq_restore (flags);
return;
......@@ -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
* 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);
goto done;
}
......@@ -1035,15 +1036,16 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
/* lower level hcd code should use *_dma exclusively,
* unless it uses pio or talks to another transport.
*/
if (!(urb->transfer_flags & URB_NO_DMA_MAP)
&& hcd->controller->dma_mask) {
if (usb_pipecontrol (urb->pipe))
if (hcd->controller->dma_mask) {
if (usb_pipecontrol (urb->pipe)
&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
urb->setup_dma = dma_map_single (
hcd->controller,
urb->setup_packet,
sizeof (struct usb_ctrlrequest),
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 (
hcd->controller,
urb->transfer_buffer,
......@@ -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.
/* lower level hcd code should use *_dma exclusively */
if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
if (usb_pipecontrol (urb->pipe))
if (hcd->controller->dma_mask) {
if (usb_pipecontrol (urb->pipe)
&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
pci_unmap_single (hcd->pdev, urb->setup_dma,
sizeof (struct usb_ctrlrequest),
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,
urb->transfer_buffer_length,
usb_pipein (urb->pipe)
......
......@@ -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,
hub, endpoint->bInterval);
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);
if (ret) {
message = "couldn't submit status urb";
......
......@@ -344,7 +344,8 @@ int usb_sg_init (
if (!io->urbs)
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))
urb_flags |= URB_SHORT_NOT_OK;
......
......@@ -297,7 +297,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
/* enforce simple/standard policy */
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;
switch (temp) {
case PIPE_BULK:
......
......@@ -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
* @size: requested buffer size
* @mem_flags: affect whether allocation may block
......@@ -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
* address (through the pointer provided).
*
* These buffers are used with URB_NO_DMA_MAP set in urb->transfer_flags to
* avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping
* hardware for long idle periods. The implementation varies between
* These buffers are used with URB_NO_xxx_DMA_MAP set in urb->transfer_flags
* to avoid behaviors like using "DMA bounce buffers", or tying down I/O
* mapping hardware for long idle periods. The implementation varies between
* platforms, depending on details of how DMA will work to this device.
* Using these buffers also helps prevent cacheline sharing problems on
* architectures where CPU caches are not DMA-coherent.
......@@ -1291,17 +1291,17 @@ void usb_buffer_free (
/**
* 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
* the parameter. URB_NO_DMA_MAP is added to urb->transfer_flags if the
* operation succeeds. If the device is connected to this system through
* a non-DMA controller, this operation always succeeds.
* the parameter. URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP are
* added to urb->transfer_flags if the operation succeeds. If the device
* 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
* 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
* control requests.
* calls to synchronize memory and dma state.
*
* Reverse the effect of this call with usb_buffer_unmap().
*/
......@@ -1311,7 +1311,6 @@ struct urb *usb_buffer_map (struct urb *urb)
struct device *controller;
if (!urb
|| usb_pipecontrol (urb->pipe)
|| !urb->dev
|| !(bus = urb->dev->bus)
|| !(controller = bus->controller))
......@@ -1322,17 +1321,23 @@ struct urb *usb_buffer_map (struct urb *urb)
urb->transfer_buffer, urb->transfer_buffer_length,
usb_pipein (urb->pipe)
? 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
// if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
} else
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;
}
/**
* 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)
{
......@@ -1340,17 +1345,23 @@ void usb_buffer_dmasync (struct urb *urb)
struct device *controller;
if (!urb
|| !(urb->transfer_flags & URB_NO_DMA_MAP)
|| !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
|| !urb->dev
|| !(bus = urb->dev->bus)
|| !(controller = bus->controller))
return;
if (controller->dma_mask)
if (controller->dma_mask) {
dma_sync_single (controller,
urb->transfer_dma, urb->transfer_buffer_length,
usb_pipein (urb->pipe)
? 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)
struct device *controller;
if (!urb
|| !(urb->transfer_flags & URB_NO_DMA_MAP)
|| !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
|| !urb->dev
|| !(bus = urb->dev->bus)
|| !(controller = bus->controller))
return;
if (controller->dma_mask)
if (controller->dma_mask) {
dma_unmap_single (controller,
urb->transfer_dma, urb->transfer_buffer_length,
usb_pipein (urb->pipe)
? 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)
*
* The caller is responsible for placing the resulting DMA addresses from
* 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
* 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)
/* hw handles device features */
if (u.r.bRequestType != USB_RECIP_ENDPOINT)
goto delegate;
if (u.r.wIndex != 0 /* HALT feature */
if (u.r.wValue != 0 /* HALT feature */
|| u.r.wLength != 0)
goto do_stall;
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)
/* hw handles device features */
if (u.r.bRequestType != USB_RECIP_ENDPOINT)
goto delegate;
if (u.r.wIndex != 0 /* HALT feature */
if (u.r.wValue != 0 /* HALT feature */
|| u.r.wLength != 0)
goto do_stall;
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) {}
#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__))
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->hw_current, qh->hw_qtd_next);
dbg (" alt+nak+t= %x, token= %x, page0= %x, page1= %x",
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]);
}
qh->hw_current);
dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->hw_qtd_next);
}
static int __attribute__((__unused__))
......@@ -284,8 +293,7 @@ static inline char token_mark (u32 token)
return '*';
if (token & QTD_STS_HALT)
return '-';
if (QTD_PID (token) != 1 /* not IN: OUT or SETUP */
|| QTD_LENGTH (token) == 0)
if (!IS_SHORT_READ (token))
return ' ';
/* tries to advance through hw_alt_next */
return '/';
......@@ -307,11 +315,14 @@ static void qh_lines (
char *next = *nextp;
char mark;
mark = token_mark (qh->hw_token);
if (qh->hw_qtd_next == EHCI_LIST_END) /* NEC does this */
mark = '@';
else
mark = token_mark (qh->hw_token);
if (mark == '/') { /* qh_alt_next controls qh advance? */
if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next)
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 */
/* else alt_next points to some other qtd */
}
......@@ -324,7 +335,7 @@ static void qh_lines (
(scratch >> 8) & 0x000f,
scratch, cpu_to_le32p (&qh->hw_info2),
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",
(cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f);
size -= temp;
......@@ -390,6 +401,8 @@ show_async (struct device *dev, char *buf)
char *next;
struct ehci_qh *qh;
*buf = 0;
pdev = container_of (dev, struct pci_dev, dev);
ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
next = buf;
......@@ -412,7 +425,7 @@ show_async (struct device *dev, char *buf)
}
spin_unlock_irqrestore (&ehci->lock, flags);
return PAGE_SIZE - size;
return strlen (buf);
}
static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
......@@ -548,7 +561,8 @@ show_registers (struct device *dev, char *buf)
/* Capability Registers */
i = readw (&ehci->caps->hci_version);
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);
size -= temp;
next += temp;
......
......@@ -39,13 +39,10 @@
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/usb.h>
#include <linux/moduleparam.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
#include "../hcd.h"
#else
#include "../core/hcd.h"
#endif
#include <asm/byteorder.h>
#include <asm/io.h>
......@@ -94,11 +91,11 @@
* 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_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
......@@ -123,7 +120,7 @@ static const char hcd_name [] = "ehci-hcd";
/* Initial IRQ latency: lower than default */
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");
#define INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT)
......@@ -434,7 +431,7 @@ static int ehci_start (struct usb_hcd *hcd)
pci_set_mwi (ehci->hcd.pdev);
/* 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)
log2_irq_thresh = 0;
temp |= 1 << (16 + log2_irq_thresh);
......@@ -1020,7 +1017,8 @@ static int __init init (void)
if (usb_disabled())
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_itd), sizeof (struct ehci_sitd));
......
......@@ -88,7 +88,6 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
static inline void
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_alt_next = EHCI_LIST_END;
......@@ -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 (
struct ehci_hcd *ehci,
struct urb *urb,
......@@ -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 */
rmb ();
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 */
if ((token & QTD_STS_ACTIVE) == 0) {
/* magic dummy for short reads; won't advance */
if (IS_SHORT_READ (token)
&& !(token & QTD_STS_HALT)
if ((token & QTD_STS_HALT) != 0) {
stopped = 1;
/* magic dummy for some short reads; qh won't advance */
} else if (IS_SHORT_READ (token)
&& (qh->hw_alt_next & QTD_MASK)
== ehci->async->hw_alt_next) {
stopped = 1;
......@@ -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 */
} else if (likely (!stopped)) {
} else if (likely (!stopped
&& HCD_IS_RUNNING (ehci->hcd.state))) {
break;
} else {
stopped = 1;
/* ignore active urbs unless some previous qtd
* for the urb faulted (including short read) or
* 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)
qh->qh_state = state;
/* update qh after fault cleanup */
if (unlikely ((HALT_BIT & qh->hw_token) != 0)) {
qh_update (ehci, qh,
list_empty (&qh->qtd_list)
? qh->dummy
: list_entry (qh->qtd_list.next,
struct ehci_qtd, qtd_list));
if (unlikely (stopped != 0)
/* some EHCI 0.95 impls will overlay dummy qtds */
|| qh->hw_qtd_next == EHCI_LIST_END) {
if (list_empty (&qh->qtd_list))
end = qh->dummy;
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;
......@@ -683,12 +690,11 @@ qh_make (
/* 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->hw_info1 = cpu_to_le32 (info1);
qh->hw_info2 = cpu_to_le32 (info2);
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);
return qh;
}
......@@ -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 */
if (unlikely (!usb_gettoggle (urb->dev,
(epnum & 0x0f), !(epnum & 0x10)))
......
......@@ -290,7 +290,10 @@ struct ehci_qtd {
size_t length; /* length of buffer */
} __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,
aiptek->data, aiptek->features->pktlen,
aiptek->features->irq, aiptek, endpoint->bInterval);
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);
......
......@@ -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,
hid_irq_in, hid, endpoint->bInterval);
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 {
if (hid->urbout)
continue;
......@@ -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,
hid_irq_out, hid);
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)
hid->ctrlbuf, 1, hid_ctrl, hid);
hid->urbctrl->setup_dma = hid->cr_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;
......
......@@ -181,7 +181,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
kbtab->data, 8,
kbtab_irq, kbtab, endpoint->bInterval);
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);
......
......@@ -180,7 +180,7 @@ static void powermate_sync_state(struct powermate_device *pm)
(void *) pm->configcr, 0, 0,
powermate_config_complete, pm);
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))
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
POWERMATE_PAYLOAD_SIZE, powermate_irq,
pm, endpoint->bInterval);
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 */
if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
......
......@@ -282,7 +282,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
kbd->new, (maxp > 8 ? 8 : maxp),
usb_kbd_irq, kbd, endpoint->bInterval);
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->bRequest = 0x09;
......@@ -325,7 +325,8 @@ static int usb_kbd_probe(struct usb_interface *iface,
usb_kbd_led, kbd);
kbd->led->setup_dma = kbd->cr_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);
......
......@@ -207,7 +207,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
(maxp > 8 ? 8 : maxp),
usb_mouse_irq, mouse, endpoint->bInterval);
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);
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
wacom->data, wacom->features->pktlen,
wacom->features->irq, wacom, endpoint->bInterval);
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);
......
......@@ -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, ep_irq_in->bInterval);
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;
......
......@@ -149,8 +149,8 @@ do { \
/* External data structures / Interface */
typedef struct
{
char *buf; /* return buffer for string contents */
unsigned int bsize; /* size of return buffer */
char __user *buf; /* return buffer for string contents */
unsigned int bsize; /* size of return buffer */
} audevinfo_t,*paudevinfo_t;
/* IO controls */
......@@ -1548,7 +1548,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
/* get a string descriptor for the device */
case 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;
break;
}
......@@ -1578,7 +1578,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
}
/* 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;
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
/* 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;
pauerswald_t cp = NULL;
......
......@@ -109,9 +109,9 @@ static int brlvger_probe (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_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);
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);
static int brlvger_ioctl(struct inode *inode, struct file *file,
unsigned cmd, unsigned long arg);
......@@ -546,7 +546,7 @@ brlvger_release(struct inode *inode, struct file *file)
}
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)
{
struct brlvger_priv *priv = file->private_data;
......@@ -655,7 +655,7 @@ read_index(struct brlvger_priv *priv)
}
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)
{
struct brlvger_priv *priv = file->private_data;
......@@ -719,7 +719,7 @@ brlvger_ioctl(struct inode *inode, struct file *file,
memcpy(&vi.fwver, priv->fwver, BRLVGER_FWVER_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 0;
}
......
......@@ -111,7 +111,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
{
struct RioCommand rio_cmd;
struct rio_usb_data *rio = &rio_instance;
void *data;
void __user *data;
unsigned char *buffer;
int result, requesttype;
int retries;
......@@ -129,7 +129,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
switch (cmd) {
case RIO_RECV_COMMAND:
data = (void *) arg;
data = (void __user *) arg;
if (data == NULL)
break;
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,
break;
case RIO_SEND_COMMAND:
data = (void *) arg;
data = (void __user *) arg;
if (data == NULL)
break;
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,
}
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)
{
struct rio_usb_data *rio = &rio_instance;
......@@ -352,7 +352,7 @@ write_rio(struct file *file, const char *buffer,
}
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;
ssize_t read_count;
......
......@@ -32,6 +32,6 @@ struct RioCommand {
int requesttype;
int value;
int index;
void *buffer;
void __user *buffer;
int timeout;
};
This diff is collapsed.
......@@ -155,7 +155,7 @@ tiglusb_release (struct inode *inode, struct file *filp)
}
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;
ssize_t ret = 0;
......@@ -208,7 +208,7 @@ tiglusb_read (struct file *filp, char *buf, size_t count, loff_t * f_pos)
}
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;
ssize_t ret = 0;
......
......@@ -88,12 +88,12 @@ ioctl_lcd(struct inode *inode, struct file *file, unsigned int cmd,
i = (lcd->lcd_dev)->descriptor.bcdDevice;
sprintf(buf,"%1d%1d.%1d%1d",(i & 0xF000)>>12,(i & 0xF00)>>8,
(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;
break;
case IOCTL_GET_DRV_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;
break;
default:
......@@ -105,7 +105,7 @@ ioctl_lcd(struct inode *inode, struct file *file, unsigned int cmd,
}
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)
{
struct lcd_usb_data *lcd = &lcd_instance;
......@@ -171,7 +171,7 @@ write_lcd(struct file *file, const char *buffer,
}
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;
ssize_t read_count;
......
......@@ -107,7 +107,7 @@ static struct urb *simple_alloc_urb (
urb->interval = (udev->speed == USB_SPEED_HIGH)
? (INTERRUPT_RATE << 3)
: INTERRUPT_RATE;
urb->transfer_flags = URB_NO_DMA_MAP;
urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
if (usb_pipein (pipe))
urb->transfer_flags |= URB_SHORT_NOT_OK;
urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
......
......@@ -7,6 +7,27 @@ comment "USB Network adaptors"
comment "Networking support is needed for USB Networking device support"
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
tristate "USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)"
depends on USB && NET && EXPERIMENTAL
......
......@@ -2,6 +2,7 @@
# Makefile for USB Network drivers
#
obj-$(CONFIG_USB_AX8817X) += ax8817x.o
obj-$(CONFIG_USB_CATC) += catc.o
obj-$(CONFIG_USB_KAWETH) += kaweth.o
obj-$(CONFIG_USB_PEGASUS) += pegasus.o
......
......@@ -2,4 +2,5 @@
# Makefile for USB Network drivers which require generic MII code.
#
obj-$(CONFIG_USB_AX8817X) += 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)
/*
* 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;
u32 cmd;
......@@ -726,7 +726,7 @@ static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
switch(cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
return netdev_ethtool_ioctl(dev, (void __user *)rq->ifr_data);
default:
return -EOPNOTSUPP;
}
......
......@@ -662,7 +662,7 @@ static int kaweth_close(struct net_device *net)
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;
......@@ -689,7 +689,7 @@ static int kaweth_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
{
switch (cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(net, (void *) rq->ifr_data);
return netdev_ethtool_ioctl(net, (void __user *)rq->ifr_data);
}
return -EOPNOTSUPP;
}
......
......@@ -945,7 +945,7 @@ static int pegasus_close(struct net_device *net)
return 0;
}
#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;
......@@ -1024,7 +1024,7 @@ static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr)
}
#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;
int cmd;
......@@ -1113,7 +1113,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
switch (cmd) {
case SIOCETHTOOL:
res = pegasus_ethtool_ioctl(net, rq->ifr_data);
res = pegasus_ethtool_ioctl(net, (void __user *)rq->ifr_data);
break;
case SIOCDEVPRIVATE:
data[0] = pegasus->phy;
......
......@@ -673,7 +673,7 @@ static int rtl8150_close(struct net_device *netdev)
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;
int cmd;
......@@ -758,7 +758,7 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
switch (cmd) {
case SIOCETHTOOL:
res = rtl8150_ethtool_ioctl(netdev, rq->ifr_data);
res = rtl8150_ethtool_ioctl(netdev, (void __user *)rq->ifr_data);
break;
case SIOCDEVPRIVATE:
data[0] = dev->phy;
......
......@@ -2097,7 +2097,7 @@ static int usbnet_open (struct net_device *net)
/*-------------------------------------------------------------------------*/
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;
u32 cmd;
......@@ -2161,7 +2161,7 @@ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
{
switch (cmd) {
case SIOCETHTOOL:
return usbnet_ethtool_ioctl (net, (void *)rq->ifr_data);
return usbnet_ethtool_ioctl (net, (void __user *)rq->ifr_data);
default:
return -EOPNOTSUPP;
}
......
......@@ -548,10 +548,9 @@ void isd200_invoke_transport( struct us_data *us,
/* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing
*/
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("-- transport indicates command was aborted\n");
srb->result = DID_ABORT << 16;
return;
if (us->sm_state == US_STATE_ABORTING) {
US_DEBUGP("-- command was aborted\n");
goto Handle_Abort;
}
switch (transferStatus) {
......@@ -561,6 +560,11 @@ void isd200_invoke_transport( struct us_data *us,
srb->result = SAM_STAT_GOOD;
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:
US_DEBUGP("-- transport indicates command failure\n");
need_auto_sense = 1;
......@@ -591,10 +595,9 @@ void isd200_invoke_transport( struct us_data *us,
if (need_auto_sense) {
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");
srb->result = DID_ABORT << 16;
return;
goto Handle_Abort;
}
if (result == ISD200_GOOD) {
isd200_build_sense(us, srb);
......@@ -603,8 +606,10 @@ void isd200_invoke_transport( struct us_data *us,
/* If things are really okay, then let's show that */
if ((srb->sense_buffer[2] & 0xf) == 0x0)
srb->result = SAM_STAT_GOOD;
} else
} else {
srb->result = DID_ERROR << 16;
/* Need reset here */
}
}
/* Regardless of auto-sense, if we _know_ we have an error
......@@ -612,6 +617,16 @@ void isd200_invoke_transport( struct us_data *us,
*/
if (transferStatus == USB_STOR_TRANSPORT_FAILED)
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
......
......@@ -82,6 +82,10 @@ static void fix_inquiry_data(Scsi_Cmnd *srb)
if (srb->cmnd[0] != INQUIRY)
return;
/* oddly short buffer -- bail out */
if (srb->request_bufflen < 3)
return;
data_ptr = find_data_location(srb);
if ((data_ptr[2] & 7) == 2)
......
......@@ -57,6 +57,8 @@
#define US_SC_MIN US_SC_RBC
#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_qic157_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)
struct timer_list to_timer;
int status;
/* don't submit URBS during abort/disconnect processing */
/* don't submit URBs during abort/disconnect processing */
if (us->flags & DONT_SUBMIT)
return -ECONNRESET;
return -EIO;
/* set up data structures for the wakeup system */
init_completion(&urb_done);
......@@ -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_STALLED;
/* NAK - that means we've retried this a few times already */
/* timeout or excessively long NAK */
case -ETIMEDOUT:
US_DEBUGP("-- device NAKed\n");
US_DEBUGP("-- timeout or NAK\n");
return USB_STOR_XFER_ERROR;
/* babble - the device tried to send more than we wanted to read */
case -EOVERFLOW:
US_DEBUGP("-- Babble\n");
US_DEBUGP("-- babble\n");
return USB_STOR_XFER_LONG;
/* the transfer was cancelled, presumably by an abort */
/* the transfer was cancelled by abort, disconnect, or timeout */
case -ECONNRESET:
US_DEBUGP("-- transfer cancelled\n");
return USB_STOR_XFER_ERROR;
......@@ -319,6 +319,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
US_DEBUGP("-- short read transfer\n");
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 */
default:
US_DEBUGP("-- unknown error\n");
......@@ -430,7 +435,7 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
/* initialize the scatter-gather request block */
US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__,
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);
if (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,
/* cancel the request, if it hasn't been cancelled already */
if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
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 */
usb_sg_wait(us->current_sg);
usb_sg_wait(&us->current_sg);
clear_bit(US_FLIDX_SG_ACTIVE, &us->flags);
result = us->current_sg->status;
result = us->current_sg.status;
if (act_len)
*act_len = us->current_sg->bytes;
*act_len = us->current_sg.bytes;
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)
/* if the command gets aborted by the higher layers, we need to
* 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");
goto Handle_Abort;
}
......@@ -650,7 +655,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->cmd_len = old_cmd_len;
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");
goto Handle_Abort;
}
......@@ -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 (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
US_DEBUGP("-- cancelling sg request\n");
usb_sg_cancel(us->current_sg);
usb_sg_cancel(&us->current_sg);
}
}
......
......@@ -63,17 +63,19 @@
#define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
#ifdef CONFIG_USB_STORAGE_FREECOM
#define US_PR_FREECOM 0xf1 /* Freecom */
#define US_PR_FREECOM 0xf1 /* Freecom */
#endif
#ifdef CONFIG_USB_STORAGE_DATAFAB
#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */
#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */
#endif
#ifdef CONFIG_USB_STORAGE_JUMPSHOT
#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
#endif
#define US_PR_DEVICE 0xff /* Use device's value */
/*
* Bulk only data structures
*/
......
......@@ -75,28 +75,26 @@ UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
/* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
* Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
* always fails and confuses drive; without US_FL_START_STOP, drive accesses
* (read or write) all fail.
* always fails and confuses drive.
*/
UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113,
"Buffalo",
"DUB-P40G HDD",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_FIX_INQUIRY | US_FL_START_STOP),
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
#ifdef CONFIG_USB_STORAGE_DPCM
UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
"Microtech",
"CameraMate (DPCM_USB)",
US_SC_SCSI, US_PR_DPCM_USB, NULL,
US_FL_START_STOP ),
US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
#endif
/* Made with the help of Edd Dumbill <edd@usefulinc.com> */
UNUSUAL_DEV( 0x0451, 0x5409, 0x0001, 0x0001,
"Frontier Labs",
"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> */
UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100,
......@@ -124,15 +122,6 @@ UNUSUAL_DEV( 0x04b8, 0x0602, 0x0110, 0x0110,
"785EPX Storage",
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,
"Fujifilm",
"FinePix 1400Zoom",
......@@ -144,7 +133,7 @@ UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x2210,
UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074,
"ScanLogic",
"SL11R-IDE",
US_SC_SCSI, US_PR_BULK, NULL,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY),
/* Reported by Kriston Fincher <kriston@airmail.net>
......@@ -183,14 +172,14 @@ UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999,
"Sandisk",
"ImageMate SDDR09",
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 */
UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
"SCM Microsystems",
"eUSB SmartMedia / CompactFlash Adapter",
US_SC_SCSI, US_PR_DPCM_USB, sddr09_init,
US_FL_START_STOP),
0),
#endif
UNUSUAL_DEV( 0x04e6, 0x0006, 0x0100, 0x0205,
......@@ -247,40 +236,40 @@ UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100,
"Iomega",
"USB Clik! 40",
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 */
UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450,
"Sony",
"DSC-S30/S70/S75/505V/F505/F707/F717/P8",
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 */
UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100,
"Sony",
"Memorystick NW-MS7",
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,
"Sony",
"Memorystick MSAC-US1",
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> */
UNUSUAL_DEV( 0x054c, 0x002e, 0x0106, 0x0310,
"Sony",
"Handycam",
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,
"Sony",
"Memorystick MSC-U01N",
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> */
UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999,
......@@ -316,7 +305,7 @@ UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200,
UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
"Pentax",
"Optio 2/3/400",
US_SC_8070, US_PR_CBI, NULL,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
/* Submitted by Per Winkvist <per.winkvist@uk.com> */
......@@ -380,7 +369,7 @@ UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113,
UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0xffff,
"SIIG",
"CompactFlash Card Reader",
US_SC_SCSI, US_PR_BULK, NULL,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
/* Reported by Peter Marks <peter.marks@turner.com>
......@@ -393,7 +382,7 @@ UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0xffff,
UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0x0001,
"EagleTec",
"External Hard Disk",
US_SC_SCSI, US_PR_BULK, NULL,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0x9999,
......@@ -402,6 +391,14 @@ UNUSUAL_DEV( 0x05e3, 0x0700, 0x0000, 0x9999,
US_SC_SCSI, US_PR_BULK, NULL,
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,
"TEAC",
"Floppy Drive",
......@@ -412,25 +409,9 @@ UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100,
"Olympus",
"Camedia MAUSB-2",
US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP ),
US_FL_SINGLE_LUN ),
#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,
"Hagiwara",
"FlashGate SmartMedia",
......@@ -445,13 +426,12 @@ UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200,
"Sandisk",
"ImageMate SDDR-05a",
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,
"Sandisk",
"ImageMate SDDR-31",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_IGNORE_SER),
US_SC_SCSI, US_PR_BULK, NULL, 0 ),
UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100,
"Sandisk",
......@@ -464,7 +444,7 @@ UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999,
"Sandisk",
"ImageMate SDDR-09",
US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP ),
US_FL_SINGLE_LUN ),
#endif
#ifdef CONFIG_USB_STORAGE_FREECOM
......@@ -490,8 +470,7 @@ UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100,
UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
"Microtech",
"CameraMate (DPCM_USB)",
US_SC_SCSI, US_PR_DPCM_USB, NULL,
US_FL_START_STOP ),
US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
#endif
#ifdef CONFIG_USB_STORAGE_DATAFAB
......@@ -568,7 +547,7 @@ UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
"Datafab",
"KECF-USB",
US_SC_SCSI, US_PR_BULK, NULL,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
/* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
......@@ -629,20 +608,7 @@ UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x0001,
"Global Channel Solutions",
"EasyDisk EDxxxx",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_MODE_XLATE | US_FL_START_STOP | 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 ),
US_FL_MODE_XLATE | US_FL_FIX_INQUIRY ),
/* Reported by Dan Pilone <pilone@slac.com>
* The device needs the flags only.
......@@ -652,8 +618,8 @@ UNUSUAL_DEV( 0x0c76, 0x0005, 0x0100, 0x0100,
UNUSUAL_DEV( 0x1065, 0x2136, 0x0000, 0x9999,
"CCYU TECHNOLOGY",
"EasyDisk Portable Device",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_MODE_XLATE | US_FL_START_STOP),
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_MODE_XLATE ),
#ifdef CONFIG_USB_STORAGE_SDDR55
UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999,
......@@ -670,5 +636,5 @@ UNUSUAL_DEV( 0x08ca, 0x2011, 0x0000, 0x9999,
"AIPTEK",
"PocketCAM 3Mega",
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);
/* The entries in this table, except for final ones here
* (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
* 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, \
......@@ -328,13 +326,13 @@ static int usb_stor_control_thread(void * __us)
scsi_lock(host);
/* 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;
goto SkipForAbort;
}
/* set the state and release the lock */
atomic_set(&us->sm_state, US_STATE_RUNNING);
us->sm_state = US_STATE_RUNNING;
scsi_unlock(host);
/* lock the device pointers */
......@@ -353,7 +351,7 @@ static int usb_stor_control_thread(void * __us)
*/
else if (us->srb->device->id &&
!(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->result = DID_BAD_TARGET << 16;
}
......@@ -404,12 +402,12 @@ static int usb_stor_control_thread(void * __us)
* sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
* because an abort request might be received after all the
* USB processing was complete. */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING)
if (us->sm_state == US_STATE_ABORTING)
complete(&(us->notify));
/* empty the queue, reset the state, and release the lock */
us->srb = NULL;
atomic_set(&us->sm_state, US_STATE_IDLE);
us->sm_state = US_STATE_IDLE;
scsi_unlock(host);
} /* for (;;) */
......@@ -424,10 +422,13 @@ static int usb_stor_control_thread(void * __us)
***********************************************************************/
/* Get the unusual_devs entries and the string descriptors */
static void get_device_info(struct us_data *us,
struct us_unusual_dev *unusual_dev)
static void get_device_info(struct us_data *us, int id_index)
{
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)
US_DEBUGP("Vendor: %s\n", unusual_dev->vendorName);
......@@ -436,10 +437,40 @@ static void get_device_info(struct us_data *us,
/* Store the entries */
us->unusual_dev = unusual_dev;
us->subclass = unusual_dev->useProtocol;
us->protocol = unusual_dev->useTransport;
us->subclass = (unusual_dev->useProtocol == US_SC_DEVICE) ?
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;
/* 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 */
if (dev->descriptor.iManufacturer)
usb_string(dev, dev->descriptor.iManufacturer,
......@@ -447,7 +478,7 @@ static void get_device_info(struct us_data *us,
if (dev->descriptor.iProduct)
usb_string(dev, dev->descriptor.iProduct,
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,
us->serial, sizeof(us->serial));
......@@ -698,13 +729,6 @@ static int usb_stor_acquire_resources(struct us_data *us)
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 */
down(&us->dev_semaphore);
......@@ -720,7 +744,7 @@ static int usb_stor_acquire_resources(struct us_data *us)
up(&us->dev_semaphore);
/* 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);
if (p < 0) {
printk(KERN_WARNING USB_STORAGE
......@@ -782,7 +806,7 @@ void usb_stor_release_resources(struct us_data *us)
*/
if (us->pid) {
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;
up(&(us->sema));
wait_for_completion(&(us->notify));
......@@ -800,8 +824,6 @@ void usb_stor_release_resources(struct us_data *us)
}
/* Free the USB control blocks */
if (us->current_sg)
kfree(us->current_sg);
if (us->current_urb)
usb_free_urb(us->current_urb);
if (us->dr)
......@@ -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
* 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
if (us->protocol == US_PR_EUSB_SDDR09 ||
......
......@@ -71,8 +71,6 @@ struct us_unusual_dev {
#define US_FL_SINGLE_LUN 0x00000001 /* allow access to only LUN 0 */
#define US_FL_MODE_XLATE 0x00000002 /* translate _6 to _10 commands for
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_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */
#define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */
......@@ -139,7 +137,7 @@ struct us_data {
/* thread information */
int pid; /* control thread */
atomic_t sm_state; /* what we are doing */
int sm_state; /* what we are doing */
/* interrupt communications data */
unsigned char irqdata[2]; /* data from USB IRQ */
......@@ -147,7 +145,7 @@ struct us_data {
/* control and bulk communications data */
struct urb *current_urb; /* non-int USB 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 */
struct semaphore sema; /* to sleep thread on */
......
......@@ -492,8 +492,9 @@ extern int usb_disabled(void);
*/
#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
#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_ASYNC_UNLINK 0x0008 /* usb_unlink_urb() returns asap */
#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
#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_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */
#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 *);
* submission, unlinking, or operation are handled. Different
* kinds of URB can use different flags.
* @transfer_buffer: This identifies the buffer to (or from) which
* the I/O request will be performed (unless URB_NO_DMA_MAP is set).
* This buffer must be suitable for DMA; allocate it with kmalloc()
* or equivalent. For transfers to "in" endpoints, contents of
* this buffer will be modified. This buffer is used for data
* the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP
* is set). This buffer must be suitable for DMA; allocate it with
* kmalloc() or equivalent. For transfers to "in" endpoints, contents
* of this buffer will be modified. This buffer is used for data
* phases of control transfers.
* @transfer_dma: When transfer_flags includes URB_NO_DMA_MAP, the device
* driver is saying that it provided this DMA address, which the host
* controller driver should use instead of the transfer_buffer.
* @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
* the device driver is saying that it provided this DMA address,
* which the host controller driver should use in preference to the
* transfer_buffer.
* @transfer_buffer_length: How big is transfer_buffer. The transfer may
* be broken up into chunks according to the current maximum packet
* 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 *);
* @setup_packet: Only used for control transfers, this points to eight bytes
* of setup data. Control transfers always start by sending this data
* 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_DMA_MAP set, the device
* driver has provided this DMA address for the setup packet. The
* host controller driver should use this instead of setup_buffer.
* If there is a data phase, its buffer is identified by transfer_dma.
* @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the
* device driver has provided this DMA address for the setup packet.
* The host controller driver should use this in preference to
* setup_packet.
* @start_frame: Returns the initial frame for interrupt or isochronous
* transfers.
* @number_of_packets: Lists the number of ISO transfer buffers.
......@@ -589,13 +590,15 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* bounce buffer or talking to an IOMMU),
* although they're cheap on commodity x86 and ppc hardware.
*
* Alternatively, drivers may pass the URB_NO_DMA_MAP transfer flag, which
* tells the host controller driver that no such mapping is needed since
* the device driver is DMA-aware. For example, they might 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
* dma addresses found in the transfer_dma and/or setup_dma fields rather than
* determing a dma address themselves.
* Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
* which tell the host controller driver that no such mapping is needed since
* the device driver is DMA-aware. For example, a device driver might
* allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
* When these transfer flags are provided, host controller drivers will
* attempt to use the dma addresses found in the transfer_dma and/or
* 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:
*
......@@ -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
* 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
* 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