Commit 20b397bb authored by Linus Torvalds's avatar Linus Torvalds

Merge

parents 46b11ba9 fb6d52e5
...@@ -212,6 +212,14 @@ config NET_ETHERNET ...@@ -212,6 +212,14 @@ config NET_ETHERNET
kernel: saying N will just cause the configurator to skip all kernel: saying N will just cause the configurator to skip all
the questions about Ethernet network cards. If unsure, say N. the questions about Ethernet network cards. If unsure, say N.
config MII
tristate "generic Media Independent Interface device support"
depends on NET_ETHERNET
help
Most ethernet controllers have MII transceiver either as an external
or internal device. It is safe to say Y or M here even if your
ethernet card lack MII.
config ARM_AM79C961A config ARM_AM79C961A
bool "ARM EBSA110 AM79C961A support" bool "ARM EBSA110 AM79C961A support"
depends on NET_ETHERNET && ARM && ARCH_EBSA110 depends on NET_ETHERNET && ARM && ARCH_EBSA110
......
...@@ -57,6 +57,7 @@ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o mii.o ...@@ -57,6 +57,7 @@ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o mii.o
# end link order section # end link order section
# #
obj-$(CONFIG_MII) += mii.o
obj-$(CONFIG_AIRONET4500) += aironet4500_core.o obj-$(CONFIG_AIRONET4500) += aironet4500_core.o
obj-$(CONFIG_AIRONET4500_CS) += aironet4500_core.o obj-$(CONFIG_AIRONET4500_CS) += aironet4500_core.o
obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o
...@@ -193,3 +194,6 @@ obj-$(CONFIG_NET_WIRELESS) += wireless/ ...@@ -193,3 +194,6 @@ obj-$(CONFIG_NET_WIRELESS) += wireless/
obj-$(CONFIG_NET_TULIP) += tulip/ obj-$(CONFIG_NET_TULIP) += tulip/
obj-$(CONFIG_HAMRADIO) += hamradio/ obj-$(CONFIG_HAMRADIO) += hamradio/
obj-$(CONFIG_IRDA) += irda/ obj-$(CONFIG_IRDA) += irda/
include $(TOPDIR)/drivers/usb/net/Makefile.mii
...@@ -257,7 +257,7 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) ...@@ -257,7 +257,7 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
if (urb->status) if (urb->status)
dbg("nonzero read bulk status received: %d", urb->status); dbg("nonzero read bulk status received: %d", urb->status);
if (!urb->status & !acm->throttle) { if (!urb->status && !acm->throttle) {
for (i = 0; i < urb->actual_length && !acm->throttle; i++) { for (i = 0; i < urb->actual_length && !acm->throttle; i++) {
/* if we insert more than TTY_FLIPBUF_SIZE characters, /* if we insert more than TTY_FLIPBUF_SIZE characters,
* we drop them. */ * we drop them. */
...@@ -697,6 +697,7 @@ static void acm_disconnect(struct usb_interface *intf) ...@@ -697,6 +697,7 @@ static void acm_disconnect(struct usb_interface *intf)
static struct usb_device_id acm_ids[] = { static struct usb_device_id acm_ids[] = {
{ USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) }, { USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
{ USB_DEVICE_INFO(USB_CLASS_COMM, 2, 0) },
{ } { }
}; };
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
static char *format_topo = static char *format_topo =
/* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
"T: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n";
static char *format_string_manufacturer = static char *format_string_manufacturer =
/* S: Manufacturer=xxxx */ /* S: Manufacturer=xxxx */
......
...@@ -310,9 +310,9 @@ static int rh_string ( ...@@ -310,9 +310,9 @@ static int rh_string (
} else } else
return 0; return 0;
data [0] = 2 + ascii2utf (buf, data + 2, len - 2); data [0] = 2 * (strlen (buf) + 1);
data [1] = 3; /* type == string */ data [1] = 3; /* type == string */
return data [0]; return 2 + ascii2utf (buf, data + 2, len - 2);
} }
...@@ -1029,8 +1029,11 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags) ...@@ -1029,8 +1029,11 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
return status; return status;
} }
/* lower level hcd code should use *_dma exclusively */ /* lower level hcd code should use *_dma exclusively,
if (!(urb->transfer_flags & URB_NO_DMA_MAP)) { * 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 (usb_pipecontrol (urb->pipe))
urb->setup_dma = dma_map_single ( urb->setup_dma = dma_map_single (
hcd->controller, hcd->controller,
......
...@@ -111,6 +111,13 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */ ...@@ -111,6 +111,13 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */
*/ */
}; };
/* 2.4 does this a bit differently ... */
static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
{
return &hcd->self;
}
struct hcd_dev { /* usb_device.hcpriv points to this */ struct hcd_dev { /* usb_device.hcpriv points to this */
struct list_head dev_list; /* on this hcd */ struct list_head dev_list; /* on this hcd */
struct list_head urb_list; /* pending on this dev */ struct list_head urb_list; /* pending on this dev */
...@@ -343,6 +350,13 @@ extern void usb_deregister_bus (struct usb_bus *); ...@@ -343,6 +350,13 @@ extern void usb_deregister_bus (struct usb_bus *);
extern int usb_register_root_hub (struct usb_device *usb_dev, extern int usb_register_root_hub (struct usb_device *usb_dev,
struct device *parent_dev); struct device *parent_dev);
/* for portability to 2.4, hcds should call this */
static inline int hcd_register_root (struct usb_hcd *hcd)
{
return usb_register_root_hub (
hcd_to_bus (hcd)->root_hub, hcd->controller);
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* exported only within usbcore */ /* exported only within usbcore */
......
...@@ -206,7 +206,8 @@ static void sg_clean (struct usb_sg_request *io) ...@@ -206,7 +206,8 @@ static void sg_clean (struct usb_sg_request *io)
kfree (io->urbs); kfree (io->urbs);
io->urbs = 0; io->urbs = 0;
} }
usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents); if (io->dev->dev.dma_mask != 0)
usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
io->dev = 0; io->dev = 0;
} }
...@@ -301,6 +302,7 @@ int usb_sg_init ( ...@@ -301,6 +302,7 @@ int usb_sg_init (
{ {
int i; int i;
int urb_flags; int urb_flags;
int dma;
if (!io || !dev || !sg if (!io || !dev || !sg
|| usb_pipecontrol (pipe) || usb_pipecontrol (pipe)
...@@ -314,8 +316,16 @@ int usb_sg_init ( ...@@ -314,8 +316,16 @@ int usb_sg_init (
io->sg = sg; io->sg = sg;
io->nents = nents; io->nents = nents;
/* not all host controllers use DMA (like the mainstream pci ones);
* they can use PIO (sl811) or be software over another transport.
*/
dma = (dev->dev.dma_mask != 0);
if (dma)
io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
else
io->entries = nents;
/* initialize all the urbs we'll use */ /* initialize all the urbs we'll use */
io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
if (io->entries <= 0) if (io->entries <= 0)
return io->entries; return io->entries;
...@@ -347,8 +357,17 @@ int usb_sg_init ( ...@@ -347,8 +357,17 @@ int usb_sg_init (
io->urbs [i]->status = -EINPROGRESS; io->urbs [i]->status = -EINPROGRESS;
io->urbs [i]->actual_length = 0; io->urbs [i]->actual_length = 0;
io->urbs [i]->transfer_dma = sg_dma_address (sg + i); if (dma) {
len = sg_dma_len (sg + i); /* hc may use _only_ transfer_dma */
io->urbs [i]->transfer_dma = sg_dma_address (sg + i);
len = sg_dma_len (sg + i);
} else {
/* hc may use _only_ transfer_buffer */
io->urbs [i]->transfer_buffer =
page_address (sg [i].page) + sg [i].offset;
len = sg [i].length;
}
if (length) { if (length) {
len = min_t (unsigned, len, length); len = min_t (unsigned, len, length);
length -= len; length -= len;
...@@ -434,9 +453,7 @@ void usb_sg_wait (struct usb_sg_request *io) ...@@ -434,9 +453,7 @@ void usb_sg_wait (struct usb_sg_request *io)
retval = 0; retval = 0;
i--; i--;
// FIXME: should it usb_sg_cancel() on INTERRUPT? // FIXME: should it usb_sg_cancel() on INTERRUPT?
// how about imposing a backoff? yield ();
set_current_state (TASK_UNINTERRUPTIBLE);
schedule ();
break; break;
/* no error? continue immediately. /* no error? continue immediately.
......
...@@ -1224,7 +1224,8 @@ void usb_buffer_free ( ...@@ -1224,7 +1224,8 @@ void usb_buffer_free (
* *
* 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_DMA_MAP is added to urb->transfer_flags if the
* operation succeeds. * 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 * 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()
...@@ -1245,12 +1246,15 @@ struct urb *usb_buffer_map (struct urb *urb) ...@@ -1245,12 +1246,15 @@ struct urb *usb_buffer_map (struct urb *urb)
|| !(controller = bus->controller)) || !(controller = bus->controller))
return 0; return 0;
urb->transfer_dma = dma_map_single (controller, if (controller->dma_mask) {
urb->transfer_dma = dma_map_single (controller,
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);
// 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
urb->transfer_dma = ~0;
urb->transfer_flags |= URB_NO_DMA_MAP; urb->transfer_flags |= URB_NO_DMA_MAP;
return urb; return urb;
} }
...@@ -1271,7 +1275,8 @@ void usb_buffer_dmasync (struct urb *urb) ...@@ -1271,7 +1275,8 @@ void usb_buffer_dmasync (struct urb *urb)
|| !(controller = bus->controller)) || !(controller = bus->controller))
return; return;
dma_sync_single (controller, if (controller->dma_mask)
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);
...@@ -1295,10 +1300,12 @@ void usb_buffer_unmap (struct urb *urb) ...@@ -1295,10 +1300,12 @@ void usb_buffer_unmap (struct urb *urb)
|| !(controller = bus->controller)) || !(controller = bus->controller))
return; return;
dma_unmap_single (controller, if (controller->dma_mask)
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;
} }
/** /**
...@@ -1336,7 +1343,8 @@ int usb_buffer_map_sg (struct usb_device *dev, unsigned pipe, ...@@ -1336,7 +1343,8 @@ int usb_buffer_map_sg (struct usb_device *dev, unsigned pipe,
if (!dev if (!dev
|| usb_pipecontrol (pipe) || usb_pipecontrol (pipe)
|| !(bus = dev->bus) || !(bus = dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller)
|| !controller->dma_mask)
return -1; return -1;
// FIXME generic api broken like pci, can't report errors // FIXME generic api broken like pci, can't report errors
...@@ -1362,7 +1370,8 @@ void usb_buffer_dmasync_sg (struct usb_device *dev, unsigned pipe, ...@@ -1362,7 +1370,8 @@ void usb_buffer_dmasync_sg (struct usb_device *dev, unsigned pipe,
if (!dev if (!dev
|| !(bus = dev->bus) || !(bus = dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller)
|| !controller->dma_mask)
return; return;
dma_sync_sg (controller, sg, n_hw_ents, dma_sync_sg (controller, sg, n_hw_ents,
...@@ -1386,7 +1395,8 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, ...@@ -1386,7 +1395,8 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
if (!dev if (!dev
|| !(bus = dev->bus) || !(bus = dev->bus)
|| !(controller = bus->controller)) || !(controller = bus->controller)
|| !controller->dma_mask)
return; return;
dma_unmap_sg (controller, sg, n_hw_ents, dma_unmap_sg (controller, sg, n_hw_ents,
......
...@@ -277,7 +277,26 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { } ...@@ -277,7 +277,26 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { }
default: tmp = '?'; break; \ default: tmp = '?'; break; \
}; tmp; }) }; tmp; })
static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) static inline char token_mark (u32 token)
{
token = le32_to_cpu (token);
if (token & QTD_STS_ACTIVE)
return '*';
if (token & QTD_STS_HALT)
return '-';
if (QTD_PID (token) != 1 /* not IN: OUT or SETUP */
|| QTD_LENGTH (token) == 0)
return ' ';
/* tries to advance through hw_alt_next */
return '/';
}
static void qh_lines (
struct ehci_hcd *ehci,
struct ehci_qh *qh,
char **nextp,
unsigned *sizep
)
{ {
u32 scratch; u32 scratch;
u32 hw_curr; u32 hw_curr;
...@@ -286,26 +305,49 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) ...@@ -286,26 +305,49 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep)
unsigned temp; unsigned temp;
unsigned size = *sizep; unsigned size = *sizep;
char *next = *nextp; char *next = *nextp;
char mark;
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))
mark = '.'; /* use hw_qtd_next */
/* else alt_next points to some other qtd */
}
scratch = cpu_to_le32p (&qh->hw_info1); scratch = cpu_to_le32p (&qh->hw_info1);
hw_curr = cpu_to_le32p (&qh->hw_current); hw_curr = (mark == '*') ? cpu_to_le32p (&qh->hw_current) : 0;
temp = snprintf (next, size, temp = snprintf (next, size,
"qh/%p dev%d %cs ep%d %08x %08x (%08x %08x)", "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
qh, scratch & 0x007f, qh, scratch & 0x007f,
speed_char (scratch), speed_char (scratch),
(scratch >> 8) & 0x000f, (scratch >> 8) & 0x000f,
scratch, cpu_to_le32p (&qh->hw_info2), scratch, cpu_to_le32p (&qh->hw_info2),
hw_curr, cpu_to_le32p (&qh->hw_token)); cpu_to_le32p (&qh->hw_token), mark,
(cpu_to_le32 (0x8000000) & qh->hw_token)
? "data0" : "data1",
(cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f);
size -= temp; size -= temp;
next += temp; next += temp;
/* hc may be modifying the list as we read it ... */
list_for_each (entry, &qh->qtd_list) { list_for_each (entry, &qh->qtd_list) {
td = list_entry (entry, struct ehci_qtd, qtd_list); td = list_entry (entry, struct ehci_qtd, qtd_list);
scratch = cpu_to_le32p (&td->hw_token); scratch = cpu_to_le32p (&td->hw_token);
mark = ' ';
if (hw_curr == td->qtd_dma)
mark = '*';
else if (qh->hw_qtd_next == td->qtd_dma)
mark = '+';
else if (QTD_LENGTH (scratch)) {
if (td->hw_alt_next == ehci->async->hw_alt_next)
mark = '#';
else if (td->hw_alt_next != EHCI_LIST_END)
mark = '/';
}
temp = snprintf (next, size, temp = snprintf (next, size,
"\n\t%std/%p %s len=%d %08x urb %p", "\n\t%p%c%s len=%d %08x urb %p",
(hw_curr == td->qtd_dma) ? "*" : "", td, mark, ({ char *tmp;
td, ({ char *tmp;
switch ((scratch>>8)&0x03) { switch ((scratch>>8)&0x03) {
case 0: tmp = "out"; break; case 0: tmp = "out"; break;
case 1: tmp = "in"; break; case 1: tmp = "in"; break;
...@@ -315,13 +357,27 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) ...@@ -315,13 +357,27 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep)
(scratch >> 16) & 0x7fff, (scratch >> 16) & 0x7fff,
scratch, scratch,
td->urb); td->urb);
if (temp < 0)
temp = 0;
else if (size < temp)
temp = size;
size -= temp; size -= temp;
next += temp; next += temp;
if (temp == size)
goto done;
} }
temp = snprintf (next, size, "\n"); temp = snprintf (next, size, "\n");
*sizep = size - temp; if (temp < 0)
*nextp = next + temp; temp = 0;
else if (size < temp)
temp = size;
size -= temp;
next += temp;
done:
*sizep = size;
*nextp = next;
} }
static ssize_t static ssize_t
...@@ -344,14 +400,15 @@ show_async (struct device *dev, char *buf) ...@@ -344,14 +400,15 @@ show_async (struct device *dev, char *buf)
* one QH per line, and TDs we know about * one QH per line, and TDs we know about
*/ */
spin_lock_irqsave (&ehci->lock, flags); spin_lock_irqsave (&ehci->lock, flags);
for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
qh_lines (qh, &next, &size); qh_lines (ehci, qh, &next, &size);
if (ehci->reclaim) { if (ehci->reclaim && size > 0) {
temp = snprintf (next, size, "\nreclaim =\n"); temp = snprintf (next, size, "\nreclaim =\n");
size -= temp; size -= temp;
next += temp; next += temp;
qh_lines (ehci->reclaim, &next, &size); for (qh = ehci->reclaim; size > 0 && qh; qh = qh->reclaim)
qh_lines (ehci, qh, &next, &size);
} }
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
...@@ -421,7 +478,7 @@ show_periodic (struct device *dev, char *buf) ...@@ -421,7 +478,7 @@ show_periodic (struct device *dev, char *buf)
scratch & 0x007f, scratch & 0x007f,
(scratch >> 8) & 0x000f, (scratch >> 8) & 0x000f,
p.qh->usecs, p.qh->c_usecs, p.qh->usecs, p.qh->c_usecs,
scratch >> 16); 0x7ff & (scratch >> 16));
/* FIXME TD info too */ /* FIXME TD info too */
...@@ -490,7 +547,8 @@ show_registers (struct device *dev, char *buf) ...@@ -490,7 +547,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, "EHCI %x.%02x, hcd state %d\n", temp = snprintf (next, size,
"EHCI %x.%02x, hcd state %d (version " DRIVER_VERSION ")\n",
i >> 8, i & 0x0ff, ehci->hcd.state); i >> 8, i & 0x0ff, ehci->hcd.state);
size -= temp; size -= temp;
next += temp; next += temp;
......
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
* 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 "2002-Nov-29" #define DRIVER_VERSION "2003-Jan-22"
#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"
...@@ -110,10 +110,11 @@ static const char hcd_name [] = "ehci-hcd"; ...@@ -110,10 +110,11 @@ static const char hcd_name [] = "ehci-hcd";
/* magic numbers that can affect system performance */ /* magic numbers that can affect system performance */
#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */
#define EHCI_TUNE_RL_HS 0 /* nak throttle; see 4.9 */ #define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
#define EHCI_TUNE_RL_TT 0 #define EHCI_TUNE_RL_TT 0
#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
#define EHCI_TUNE_MULT_TT 1 #define EHCI_TUNE_MULT_TT 1
#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */
#define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ #define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */
#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
...@@ -416,13 +417,26 @@ static int ehci_start (struct usb_hcd *hcd) ...@@ -416,13 +417,26 @@ static int ehci_start (struct usb_hcd *hcd)
ehci_info (ehci, "enabled 64bit PCI DMA\n"); ehci_info (ehci, "enabled 64bit PCI DMA\n");
} }
/* help hc dma work well with cachelines */
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) & 0xff;
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);
// if hc can park (ehci >= 0.96), default is 3 packets per async QH // if hc can park (ehci >= 0.96), default is 3 packets per async QH
// keeping default periodic framelist size if (HCC_PGM_FRAMELISTLEN (hcc_params)) {
/* periodic schedule size can be smaller than default */
temp &= ~(3 << 2);
temp |= (EHCI_TUNE_FLS << 2);
switch (EHCI_TUNE_FLS) {
case 0: ehci->periodic_size = 1024; break;
case 1: ehci->periodic_size = 512; break;
case 2: ehci->periodic_size = 256; break;
default: BUG ();
}
}
temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE), temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE),
// Philips, Intel, and maybe others need CMD_RUN before the // Philips, Intel, and maybe others need CMD_RUN before the
// root hub will detect new devices (why?); NEC doesn't // root hub will detect new devices (why?); NEC doesn't
...@@ -759,7 +773,6 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) ...@@ -759,7 +773,6 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_hcd *ehci = hcd_to_ehci (hcd);
struct ehci_qh *qh; struct ehci_qh *qh;
unsigned long flags; unsigned long flags;
int maybe_irq = 1;
spin_lock_irqsave (&ehci->lock, flags); spin_lock_irqsave (&ehci->lock, flags);
switch (usb_pipetype (urb->pipe)) { switch (usb_pipetype (urb->pipe)) {
...@@ -769,23 +782,23 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) ...@@ -769,23 +782,23 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
qh = (struct ehci_qh *) urb->hcpriv; qh = (struct ehci_qh *) urb->hcpriv;
if (!qh) if (!qh)
break; break;
while (qh->qh_state == QH_STATE_LINKED
/* if we need to use IAA and it's busy, defer */
if (qh->qh_state == QH_STATE_LINKED
&& ehci->reclaim && ehci->reclaim
&& HCD_IS_RUNNING (ehci->hcd.state) && HCD_IS_RUNNING (ehci->hcd.state)
) { ) {
spin_unlock_irqrestore (&ehci->lock, flags); struct ehci_qh *last;
if (maybe_irq) { for (last = ehci->reclaim;
if (in_interrupt ()) last->reclaim;
return -EAGAIN; last = last->reclaim)
maybe_irq = 0; continue;
} qh->qh_state = QH_STATE_UNLINK_WAIT;
/* let pending unlinks complete, so this can start */ last->reclaim = qh;
wait_ms (1);
spin_lock_irqsave (&ehci->lock, flags); /* bypass IAA if the hc can't care */
} } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
end_unlink_async (ehci, NULL); end_unlink_async (ehci, NULL);
/* something else might have unlinked the qh by now */ /* something else might have unlinked the qh by now */
......
...@@ -75,8 +75,6 @@ static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags) ...@@ -75,8 +75,6 @@ static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags)
qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma); qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma);
if (qtd != 0) { if (qtd != 0) {
ehci_qtd_init (qtd, dma); ehci_qtd_init (qtd, dma);
if (ehci->async)
qtd->hw_alt_next = ehci->async->hw_alt_next;
} }
return qtd; return qtd;
} }
......
This diff is collapsed.
...@@ -236,12 +236,12 @@ struct ehci_qtd { ...@@ -236,12 +236,12 @@ struct ehci_qtd {
/* the rest is HCD-private */ /* the rest is HCD-private */
dma_addr_t qtd_dma; /* qtd address */ dma_addr_t qtd_dma; /* qtd address */
struct list_head qtd_list; /* sw qtd list */ struct list_head qtd_list; /* sw qtd list */
/* dma same in urb's qtds, except 1st control qtd (setup buffer) */
struct urb *urb; /* qtd's urb */ struct urb *urb; /* qtd's urb */
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 */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* type tag from {qh,itd,sitd,fstn}->hw_next */ /* type tag from {qh,itd,sitd,fstn}->hw_next */
...@@ -305,6 +305,7 @@ struct ehci_qh { ...@@ -305,6 +305,7 @@ struct ehci_qh {
union ehci_shadow qh_next; /* ptr to qh; or periodic */ union ehci_shadow qh_next; /* ptr to qh; or periodic */
struct list_head qtd_list; /* sw qtd list */ struct list_head qtd_list; /* sw qtd list */
struct ehci_qtd *dummy; struct ehci_qtd *dummy;
struct ehci_qh *reclaim; /* next to reclaim */
atomic_t refcount; atomic_t refcount;
unsigned stamp; unsigned stamp;
...@@ -313,6 +314,8 @@ struct ehci_qh { ...@@ -313,6 +314,8 @@ struct ehci_qh {
#define QH_STATE_LINKED 1 /* HC sees this */ #define QH_STATE_LINKED 1 /* HC sees this */
#define QH_STATE_UNLINK 2 /* HC may still see this */ #define QH_STATE_UNLINK 2 /* HC may still see this */
#define QH_STATE_IDLE 3 /* HC doesn't see this */ #define QH_STATE_IDLE 3 /* HC doesn't see this */
#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */
#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */
/* periodic schedule info */ /* periodic schedule info */
u8 usecs; /* intr bandwidth */ u8 usecs; /* intr bandwidth */
...@@ -426,16 +429,6 @@ static inline int hcd_register_root (struct usb_hcd *hcd) ...@@ -426,16 +429,6 @@ static inline int hcd_register_root (struct usb_hcd *hcd)
#else /* LINUX_VERSION_CODE */ #else /* LINUX_VERSION_CODE */
// hcd_to_bus() eventually moves to hcd.h on 2.5 too
static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
{ return &hcd->self; }
// ... as does hcd_register_root()
static inline int hcd_register_root (struct usb_hcd *hcd)
{
return usb_register_root_hub (
hcd_to_bus (hcd)->root_hub, &hcd->pdev->dev);
}
#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags) #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
#ifndef DEBUG #ifndef DEBUG
......
...@@ -219,7 +219,7 @@ static int hci_unlink_urb (struct urb * urb) ...@@ -219,7 +219,7 @@ static int hci_unlink_urb (struct urb * urb)
if (!list_empty (&urb->urb_list) && urb->status == -EINPROGRESS) { if (!list_empty (&urb->urb_list) && urb->status == -EINPROGRESS) {
/* URB active? */ /* URB active? */
if (urb->transfer_flags & (URB_ASYNC_UNLINK | URB_TIMEOUT_KILLED)) { if (urb->transfer_flags & URB_ASYNC_UNLINK) {
/* asynchronous with callback */ /* asynchronous with callback */
/* relink the urb to the del list */ /* relink the urb to the del list */
list_move (&urb->urb_list, &hci->del_list); list_move (&urb->urb_list, &hci->del_list);
...@@ -388,7 +388,6 @@ static void qu_urb_timeout (unsigned long lurb) ...@@ -388,7 +388,6 @@ static void qu_urb_timeout (unsigned long lurb)
struct urb *urb = (struct urb *) lurb; struct urb *urb = (struct urb *) lurb;
DBGFUNC ("enter qu_urb_timeout\n"); DBGFUNC ("enter qu_urb_timeout\n");
urb->transfer_flags |= URB_TIMEOUT_KILLED;
hci_unlink_urb (urb); hci_unlink_urb (urb);
} }
#endif #endif
......
...@@ -203,28 +203,28 @@ static int ohci_urb_enqueue ( ...@@ -203,28 +203,28 @@ static int ohci_urb_enqueue (
return -ENOMEM; return -ENOMEM;
memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *));
spin_lock_irqsave (&ohci->lock, flags);
/* don't submit to a dead HC */
if (ohci->disabled || ohci->sleeping) {
retval = -ENODEV;
goto fail;
}
/* fill the private part of the URB */ /* fill the private part of the URB */
urb_priv->length = size; urb_priv->length = size;
urb_priv->ed = ed; urb_priv->ed = ed;
/* allocate the TDs (updating hash chains) */ /* allocate the TDs (deferring hash chain updates) */
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
urb_priv->td [i] = td_alloc (ohci, SLAB_ATOMIC); urb_priv->td [i] = td_alloc (ohci, mem_flags);
if (!urb_priv->td [i]) { if (!urb_priv->td [i]) {
urb_priv->length = i; urb_priv->length = i;
retval = -ENOMEM; urb_free_priv (ohci, urb_priv);
goto fail; return -ENOMEM;
} }
} }
spin_lock_irqsave (&ohci->lock, flags);
/* don't submit to a dead HC */
if (ohci->disabled || ohci->sleeping) {
retval = -ENODEV;
goto fail;
}
/* schedule the ed if needed */ /* schedule the ed if needed */
if (ed->state == ED_IDLE) { if (ed->state == ED_IDLE) {
retval = ed_schedule (ohci, ed); retval = ed_schedule (ohci, ed);
......
...@@ -97,17 +97,11 @@ td_alloc (struct ohci_hcd *hc, int mem_flags) ...@@ -97,17 +97,11 @@ td_alloc (struct ohci_hcd *hc, int mem_flags)
td = pci_pool_alloc (hc->td_cache, mem_flags, &dma); td = pci_pool_alloc (hc->td_cache, mem_flags, &dma);
if (td) { if (td) {
int hash;
/* in case hc fetches it, make it look dead */ /* in case hc fetches it, make it look dead */
memset (td, 0, sizeof *td); memset (td, 0, sizeof *td);
td->hwNextTD = cpu_to_le32 (dma); td->hwNextTD = cpu_to_le32 (dma);
td->td_dma = dma; td->td_dma = dma;
/* hashed in td_fill */
/* hash it for later reverse mapping */
hash = TD_HASH_FUNC (dma);
td->td_hash = hc->td_hash [hash];
hc->td_hash [hash] = td;
} }
return td; return td;
} }
......
...@@ -463,13 +463,14 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed) ...@@ -463,13 +463,14 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed)
/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ /* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
static void static void
td_fill (unsigned int info, td_fill (struct ohci_hcd *ohci, u32 info,
dma_addr_t data, int len, dma_addr_t data, int len,
struct urb *urb, int index) struct urb *urb, int index)
{ {
struct td *td, *td_pt; struct td *td, *td_pt;
struct urb_priv *urb_priv = urb->hcpriv; struct urb_priv *urb_priv = urb->hcpriv;
int is_iso = info & TD_ISO; int is_iso = info & TD_ISO;
int hash;
// ASSERT (index < urb_priv->length); // ASSERT (index < urb_priv->length);
...@@ -516,11 +517,16 @@ td_fill (unsigned int info, ...@@ -516,11 +517,16 @@ td_fill (unsigned int info,
td->hwBE = 0; td->hwBE = 0;
td->hwNextTD = cpu_to_le32 (td_pt->td_dma); td->hwNextTD = cpu_to_le32 (td_pt->td_dma);
/* HC might read the TD right after we link it ... */
wmb ();
/* append to queue */ /* append to queue */
list_add_tail (&td->td_list, &td->ed->td_list); list_add_tail (&td->td_list, &td->ed->td_list);
/* hash it for later reverse mapping */
hash = TD_HASH_FUNC (td->td_dma);
td->td_hash = ohci->td_hash [hash];
ohci->td_hash [hash] = td;
/* HC might read the TD (or cachelines) right away ... */
wmb ();
td->ed->hwTailP = td->hwNextTD; td->ed->hwTailP = td->hwNextTD;
} }
...@@ -578,7 +584,7 @@ static void td_submit_urb ( ...@@ -578,7 +584,7 @@ static void td_submit_urb (
: TD_T_TOGGLE | TD_CC | TD_DP_IN; : TD_T_TOGGLE | TD_CC | TD_DP_IN;
/* TDs _could_ transfer up to 8K each */ /* TDs _could_ transfer up to 8K each */
while (data_len > 4096) { while (data_len > 4096) {
td_fill (info, data, 4096, urb, cnt); td_fill (ohci, info, data, 4096, urb, cnt);
data += 4096; data += 4096;
data_len -= 4096; data_len -= 4096;
cnt++; cnt++;
...@@ -586,11 +592,11 @@ static void td_submit_urb ( ...@@ -586,11 +592,11 @@ static void td_submit_urb (
/* maybe avoid ED halt on final TD short read */ /* maybe avoid ED halt on final TD short read */
if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
info |= TD_R; info |= TD_R;
td_fill (info, data, data_len, urb, cnt); td_fill (ohci, info, data, data_len, urb, cnt);
cnt++; cnt++;
if ((urb->transfer_flags & URB_ZERO_PACKET) if ((urb->transfer_flags & URB_ZERO_PACKET)
&& cnt < urb_priv->length) { && cnt < urb_priv->length) {
td_fill (info, 0, 0, urb, cnt); td_fill (ohci, info, 0, 0, urb, cnt);
cnt++; cnt++;
} }
/* maybe kickstart bulk list */ /* maybe kickstart bulk list */
...@@ -605,17 +611,17 @@ static void td_submit_urb ( ...@@ -605,17 +611,17 @@ static void td_submit_urb (
*/ */
case PIPE_CONTROL: case PIPE_CONTROL:
info = TD_CC | TD_DP_SETUP | TD_T_DATA0; info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
td_fill (info, urb->setup_dma, 8, urb, cnt++); td_fill (ohci, info, urb->setup_dma, 8, urb, cnt++);
if (data_len > 0) { if (data_len > 0) {
info = TD_CC | TD_R | TD_T_DATA1; info = TD_CC | TD_R | TD_T_DATA1;
info |= is_out ? TD_DP_OUT : TD_DP_IN; info |= is_out ? TD_DP_OUT : TD_DP_IN;
/* NOTE: mishandles transfers >8K, some >4K */ /* NOTE: mishandles transfers >8K, some >4K */
td_fill (info, data, data_len, urb, cnt++); td_fill (ohci, info, data, data_len, urb, cnt++);
} }
info = is_out info = is_out
? TD_CC | TD_DP_IN | TD_T_DATA1 ? TD_CC | TD_DP_IN | TD_T_DATA1
: TD_CC | TD_DP_OUT | TD_T_DATA1; : TD_CC | TD_DP_OUT | TD_T_DATA1;
td_fill (info, data, 0, urb, cnt++); td_fill (ohci, info, data, 0, urb, cnt++);
/* maybe kickstart control list */ /* maybe kickstart control list */
wmb (); wmb ();
writel (OHCI_CLF, &ohci->regs->cmdstatus); writel (OHCI_CLF, &ohci->regs->cmdstatus);
...@@ -634,7 +640,7 @@ static void td_submit_urb ( ...@@ -634,7 +640,7 @@ static void td_submit_urb (
// a 2^16 iso range, vs other HCs max of 2^10) // a 2^16 iso range, vs other HCs max of 2^10)
frame += cnt * urb->interval; frame += cnt * urb->interval;
frame &= 0xffff; frame &= 0xffff;
td_fill (TD_CC | TD_ISO | frame, td_fill (ohci, TD_CC | TD_ISO | frame,
data + urb->iso_frame_desc [cnt].offset, data + urb->iso_frame_desc [cnt].offset,
urb->iso_frame_desc [cnt].length, urb, cnt); urb->iso_frame_desc [cnt].length, urb, cnt);
} }
......
...@@ -1747,7 +1747,6 @@ static void stall_callback(unsigned long ptr) ...@@ -1747,7 +1747,6 @@ static void stall_callback(unsigned long ptr)
tmp = tmp->next; tmp = tmp->next;
u->transfer_flags |= URB_TIMEOUT_KILLED;
uhci_urb_dequeue(hcd, u); uhci_urb_dequeue(hcd, u);
} }
......
/* -*- linux-c -*- */ /* -*- linux-c -*- */
/* /*
* Driver for USB Scanners (linux-2.5.54) * Driver for USB Scanners (linux-2.5.60)
* *
* Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
* Copyright (C) 2002, 2003 Henning Meier-Geinitz
* *
* Portions may be copyright Brad Keryan and Michael Gee. * Portions may be copyright Brad Keryan and Michael Gee.
* *
* Brian Beattie <beattie@beattie-home.net> * Previously maintained by Brian Beattie
*
* Current maintainer: Henning Meier-Geinitz <henning@meier-geinitz.de>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -300,8 +303,6 @@ ...@@ -300,8 +303,6 @@
* Frank Zago <fzago@greshamstorage.com> and * Frank Zago <fzago@greshamstorage.com> and
* Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing. * Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing.
* *
* 05/21/02 Currently maintained by Brian Beattie <beattie@beattie-home.net>
*
* 0.4.8 5/30/2002 * 0.4.8 5/30/2002
* - Added Mustek BearPaw 2400 TA. Thanks to Sergey * - Added Mustek BearPaw 2400 TA. Thanks to Sergey
* Vlasov <vsu@mivlgu.murom.ru>. * Vlasov <vsu@mivlgu.murom.ru>.
...@@ -332,12 +333,18 @@ ...@@ -332,12 +333,18 @@
* <oliver@neukum.name>. * <oliver@neukum.name>.
* *
* 0.4.10 01/07/2003 * 0.4.10 01/07/2003
* - Added vendor/product ids for Visioneer scanners. * - Added vendor/product ids for Artec, Canon, Compaq, Epson, HP, Microtek
* and Visioneer scanners. Thanks to William Lam <wklam@triad.rr.com>,
* Till Kamppeter <till.kamppeter@gmx.net> and others for all the ids.
* - Cleaned up list of vendor/product ids.
* - Print information about user-supplied ids only once at startup instead * - Print information about user-supplied ids only once at startup instead
* of everytime any USB device is plugged in. * of everytime any USB device is plugged in.
* - Removed PV8630 ioctls. Use the standard ioctls instead. * - Removed PV8630 ioctls. Use the standard ioctls instead.
* - Made endpoint detection more generic. Basically, only one bulk-in * - Made endpoint detection more generic. Basically, only one bulk-in
* endpoint is required, everything else is optional. * endpoint is required, everything else is optional.
* - New maintainer: Henning Meier-Geinitz.
* - Print ids and device number when a device was detected.
* - Don't print errors when the device is busy.
* *
* TODO * TODO
* - Performance * - Performance
...@@ -360,7 +367,7 @@ ...@@ -360,7 +367,7 @@
* - All the developers that are working on USB SANE backends or other * - All the developers that are working on USB SANE backends or other
* applications to use USB scanners. * applications to use USB scanners.
* - Thanks to Greg KH <greg@kroah.com> for setting up Brian Beattie * - Thanks to Greg KH <greg@kroah.com> for setting up Brian Beattie
* to be the new USB Scanner maintainer. * and Henning Meier-Geinitz to be the new USB Scanner maintainer.
* *
* Performance: * Performance:
* *
...@@ -369,6 +376,14 @@ ...@@ -369,6 +376,14 @@
* 24 Bit Color ~ 70 secs - 3.6 Mbit/sec * 24 Bit Color ~ 70 secs - 3.6 Mbit/sec
* 8 Bit Gray ~ 17 secs - 4.2 Mbit/sec */ * 8 Bit Gray ~ 17 secs - 4.2 Mbit/sec */
/*
* For documentation, see Documentation/usb/scanner.txt.
* Website: http://www.meier-geinitz.de/kernel/
* Please contact the maintainer if your scanner is not detected by this
* driver automatically.
*/
#include <asm/byteorder.h> #include <asm/byteorder.h>
/* /*
...@@ -461,7 +476,7 @@ open_scanner(struct inode * inode, struct file * file) ...@@ -461,7 +476,7 @@ open_scanner(struct inode * inode, struct file * file)
} }
if (scn->isopen) { if (scn->isopen) {
err("open_scanner(%d): Scanner device is already open", scn_minor); dbg("open_scanner(%d): Scanner device is already open", scn_minor);
err = -EBUSY; err = -EBUSY;
goto out_error; goto out_error;
} }
...@@ -1047,6 +1062,9 @@ probe_scanner(struct usb_interface *intf, ...@@ -1047,6 +1062,9 @@ probe_scanner(struct usb_interface *intf,
if (scn->devfs == NULL) if (scn->devfs == NULL)
dbg("scanner%d: device node registration failed", scn_minor); dbg("scanner%d: device node registration failed", scn_minor);
info ("USB scanner device (0x%04x/0x%04x) now attached to %s",
dev->descriptor.idVendor, dev->descriptor.idProduct, name);
up(&scn_mutex); up(&scn_mutex);
usb_set_intfdata(intf, scn); usb_set_intfdata(intf, scn);
......
This diff is collapsed.
...@@ -1324,6 +1324,9 @@ void hid_init_reports(struct hid_device *hid) ...@@ -1324,6 +1324,9 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_MGE_UPS 0xffff #define USB_DEVICE_ID_MGE_UPS 0xffff
#define USB_DEVICE_ID_MGE_UPS1 0x0001 #define USB_DEVICE_ID_MGE_UPS1 0x0001
#define USB_VENDOR_ID_ONTRAK 0x0a07
#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
struct hid_blacklist { struct hid_blacklist {
__u16 idVendor; __u16 idVendor;
__u16 idProduct; __u16 idProduct;
...@@ -1359,6 +1362,12 @@ struct hid_blacklist { ...@@ -1359,6 +1362,12 @@ struct hid_blacklist {
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV },
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
{ 0, 0 } { 0, 0 }
}; };
......
...@@ -381,6 +381,83 @@ void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc) ...@@ -381,6 +381,83 @@ void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc)
** **
***********************/ ***********************/
/* encapsulate in an AAL5 frame, which is then split into ATM cells */
unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length)
{
unsigned int num_cells = (pdu_length + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD;
unsigned int num_pdu_cells = pdu_length / ATM_CELL_PAYLOAD + 1;
unsigned int aal5_length = num_cells * ATM_CELL_PAYLOAD;
unsigned int zero_padding = aal5_length - pdu_length - ATM_AAL5_TRAILER;
unsigned int final_length = num_cells * ATM_CELL_SIZE;
unsigned char aal5_trailer [ATM_AAL5_TRAILER];
unsigned char cell_header [ATM_CELL_HEADER];
u32 crc;
int i;
PDEBUG ("atmsar_encode entered\n");
PDEBUG ("pdu_length %d, num_cells %d, num_pdu_cells %d, aal5_length %d, zero_padding %d, final_length %d\n", pdu_length, num_cells, num_pdu_cells, aal5_length, zero_padding, final_length);
PDEBUG ("source 0x=%p, target 0x%p\n", source, target);
aal5_trailer [0] = 0; /* UU = 0 */
aal5_trailer [1] = 0; /* CPI = 0 */
aal5_trailer [2] = pdu_length >> 8;
aal5_trailer [3] = pdu_length;
crc = crc32 (~0, source, pdu_length);
for (i = 0; i < zero_padding; i++)
crc = CRC32 (0, crc);
crc = crc32 (crc, aal5_trailer, 4);
crc = ~crc;
aal5_trailer [4] = crc >> 24;
aal5_trailer [5] = crc >> 16;
aal5_trailer [6] = crc >> 8;
aal5_trailer [7] = crc;
cell_header [0] = ctx->atmHeader >> 24;
cell_header [1] = ctx->atmHeader >> 16;
cell_header [2] = ctx->atmHeader >> 8;
cell_header [3] = ctx->atmHeader;
cell_header [4] = 0xec;
for (i = 1; i < num_pdu_cells; i++) {
memcpy (target, cell_header, ATM_CELL_HEADER);
target += ATM_CELL_HEADER;
memcpy (target, source, ATM_CELL_PAYLOAD);
target += ATM_CELL_PAYLOAD;
source += ATM_CELL_PAYLOAD;
PDEBUG ("source 0x=%p, target 0x%p\n", source, target);
}
memcpy (target, cell_header, ATM_CELL_HEADER);
target += ATM_CELL_HEADER;
memcpy (target, source, pdu_length % ATM_CELL_PAYLOAD);
target += pdu_length % ATM_CELL_PAYLOAD;
if (num_pdu_cells < num_cells) {
memset (target, 0, zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD);
target += zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD;
memcpy (target, cell_header, ATM_CELL_HEADER);
target += ATM_CELL_HEADER;
zero_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
}
memset (target, 0, zero_padding);
target += zero_padding;
memcpy (target, aal5_trailer, ATM_AAL5_TRAILER);
/* set pti bit in last cell */
*(target + ATM_AAL5_TRAILER + 3 - ATM_CELL_SIZE) |= 0x2;
/* update stats */
if (ctx->stats)
atomic_inc (&ctx->stats->tx);
if (ctx->stats && (ctx->type <= ATMSAR_TYPE_AAL1))
atomic_add (num_cells, &(ctx->stats->tx));
return final_length;
}
struct sk_buff *atmsar_encode_rawcell (struct atmsar_vcc_data *ctx, struct sk_buff *skb) struct sk_buff *atmsar_encode_rawcell (struct atmsar_vcc_data *ctx, struct sk_buff *skb)
{ {
int number_of_cells = (skb->len) / 48; int number_of_cells = (skb->len) / 48;
...@@ -624,9 +701,8 @@ struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_b ...@@ -624,9 +701,8 @@ struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_b
} else { } else {
/* If data is corrupt and skb doesn't hold a whole cell, flush the lot */ /* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) == if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) ==
NULL) { NULL)
skb_trim (skb, 0); return NULL;
}
} }
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#define ATMSAR_USE_53BYTE_CELL 0x1L #define ATMSAR_USE_53BYTE_CELL 0x1L
#define ATMSAR_SET_PTI 0x2L #define ATMSAR_SET_PTI 0x2L
#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
/* types */ /* types */
#define ATMSAR_TYPE_AAL0 ATM_AAL0 #define ATMSAR_TYPE_AAL0 ATM_AAL0
...@@ -89,4 +90,6 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff ...@@ -89,4 +90,6 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff
struct sk_buff *atmsar_alloc_tx (struct atmsar_vcc_data *vcc, unsigned int size); struct sk_buff *atmsar_alloc_tx (struct atmsar_vcc_data *vcc, unsigned int size);
unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length);
#endif /* _ATMSAR_H_ */ #endif /* _ATMSAR_H_ */
This diff is collapsed.
#
# Makefile for USB Network drivers which require generic MII code.
#
obj-$(CONFIG_USB_PEGASUS) += mii.o
...@@ -135,6 +135,7 @@ static struct usb_device_id id_table_sio [] = { ...@@ -135,6 +135,7 @@ static struct usb_device_id id_table_sio [] = {
static struct usb_device_id id_table_8U232AM [] = { static struct usb_device_id id_table_8U232AM [] = {
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -143,6 +144,7 @@ static struct usb_device_id id_table_8U232AM [] = { ...@@ -143,6 +144,7 @@ static struct usb_device_id id_table_8U232AM [] = {
static struct usb_device_id id_table_combined [] = { static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -17,11 +17,14 @@ ...@@ -17,11 +17,14 @@
* Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc.- wrote the * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc.- wrote the
* FTDI_SIO implementation. * FTDI_SIO implementation.
* *
* Philipp Ghring - pg@futureware.at - added the Device ID of the USB relais
* from Rudolf Gugler
*/ */
#define FTDI_VID 0x0403 /* Vendor Id */ #define FTDI_VID 0x0403 /* Vendor Id */
#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */
#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */
#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */
......
...@@ -106,6 +106,7 @@ static struct usb_device_id ipaq_id_table [] = { ...@@ -106,6 +106,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(CASIO_VENDOR_ID, CASIO_EM500_ID) }, { USB_DEVICE(CASIO_VENDOR_ID, CASIO_EM500_ID) },
{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) }, { USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) },
{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_0032_ID) }, { USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_0032_ID) },
{ USB_DEVICE(DELL_VENDOR_ID, DELL_AXIM_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_2016_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_2016_ID) },
...@@ -126,6 +127,7 @@ static struct usb_device_id ipaq_id_table [] = { ...@@ -126,6 +127,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_WIRELESS_ID) }, { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_WIRELESS_ID) },
{ USB_DEVICE(SOCKET_VENDOR_ID, SOCKET_PRODUCT_ID) }, { USB_DEVICE(SOCKET_VENDOR_ID, SOCKET_PRODUCT_ID) },
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_ID) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_ID) },
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E740_ID) },
{ USB_DEVICE(HTC_VENDOR_ID, HTC_PRODUCT_ID) }, { USB_DEVICE(HTC_VENDOR_ID, HTC_PRODUCT_ID) },
{ USB_DEVICE(NEC_VENDOR_ID, NEC_PRODUCT_ID) }, { USB_DEVICE(NEC_VENDOR_ID, NEC_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
......
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
#define COMPAQ_IPAQ_ID 0x0003 #define COMPAQ_IPAQ_ID 0x0003
#define COMPAQ_0032_ID 0x0032 #define COMPAQ_0032_ID 0x0032
#define DELL_VENDOR_ID 0x413c
#define DELL_AXIM_ID 0x4001
#define HP_VENDOR_ID 0x03f0 #define HP_VENDOR_ID 0x03f0
#define HP_JORNADA_548_ID 0x1016 #define HP_JORNADA_548_ID 0x1016
#define HP_JORNADA_568_ID 0x1116 #define HP_JORNADA_568_ID 0x1116
...@@ -63,6 +66,7 @@ ...@@ -63,6 +66,7 @@
#define TOSHIBA_VENDOR_ID 0x0930 #define TOSHIBA_VENDOR_ID 0x0930
#define TOSHIBA_PRODUCT_ID 0x0700 #define TOSHIBA_PRODUCT_ID 0x0700
#define TOSHIBA_E740_ID 0x0706
#define HTC_VENDOR_ID 0x0bb4 #define HTC_VENDOR_ID 0x0bb4
#define HTC_PRODUCT_ID 0x00ce #define HTC_PRODUCT_ID 0x00ce
......
...@@ -74,6 +74,7 @@ static struct usb_device_id id_table [] = { ...@@ -74,6 +74,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) }, { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
{ USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -28,3 +28,6 @@ ...@@ -28,3 +28,6 @@
#define RATOC_VENDOR_ID 0x0584 #define RATOC_VENDOR_ID 0x0584
#define RATOC_PRODUCT_ID 0xb000 #define RATOC_PRODUCT_ID 0xb000
#define TRIPP_VENDOR_ID 0x2478
#define TRIPP_PRODUCT_ID 0x2008
...@@ -27,14 +27,14 @@ ...@@ -27,14 +27,14 @@
extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us); extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us);
struct datafab_info { struct datafab_info {
unsigned long sectors; // total sector count unsigned long sectors; // total sector count
unsigned long ssize; // sector size in bytes unsigned long ssize; // sector size in bytes
char lun; // used for dual-slot readers char lun; // used for dual-slot readers
// the following aren't used yet // the following aren't used yet
unsigned char sense_key; unsigned char sense_key;
unsigned long sense_asc; // additional sense code unsigned long sense_asc; // additional sense code
unsigned long sense_ascq; // additional sense code qualifier unsigned long sense_ascq; // additional sense code qualifier
}; };
#endif #endif
This diff is collapsed.
This diff is collapsed.
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#define US_SC_UFI 0x04 /* Floppy */ #define US_SC_UFI 0x04 /* Floppy */
#define US_SC_8070 0x05 /* Removable media */ #define US_SC_8070 0x05 /* Removable media */
#define US_SC_SCSI 0x06 /* Transparent */ #define US_SC_SCSI 0x06 /* Transparent */
#define US_SC_ISD200 0x07 /* ISD200 ATA */ #define US_SC_ISD200 0x07 /* ISD200 ATA */
#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
......
...@@ -50,23 +50,25 @@ ...@@ -50,23 +50,25 @@
#include "transport.h" #include "transport.h"
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h>
/*********************************************************************** /***********************************************************************
* Host functions * Host functions
***********************************************************************/ ***********************************************************************/
static const char* host_info(struct Scsi_Host *host) static const char* usb_storage_info(struct Scsi_Host *host)
{ {
return "SCSI emulation for USB Mass Storage devices"; return "SCSI emulation for USB Mass Storage devices";
} }
#if 0
/* detect a virtual adapter (always works) /* detect a virtual adapter (always works)
* Synchronization: 2.4: with the io_request_lock * Synchronization: 2.4: with the io_request_lock
* 2.5: no locks. * 2.5: no locks.
* fortunately we don't care. * fortunately we don't care.
* */ * */
static int detect(struct SHT *sht) static int usb_storage_detect(struct SHT *sht)
{ {
struct us_data *us; struct us_data *us;
char local_name[32]; char local_name[32];
...@@ -109,7 +111,7 @@ static int detect(struct SHT *sht) ...@@ -109,7 +111,7 @@ static int detect(struct SHT *sht)
* the driver and we're doing each virtual host in turn, not in parallel * the driver and we're doing each virtual host in turn, not in parallel
* Synchronization: BKL, no spinlock. * Synchronization: BKL, no spinlock.
*/ */
static int release(struct Scsi_Host *psh) static int usb_storage_release(struct Scsi_Host *psh)
{ {
struct us_data *us = (struct us_data *)psh->hostdata[0]; struct us_data *us = (struct us_data *)psh->hostdata[0];
...@@ -132,18 +134,11 @@ static int release(struct Scsi_Host *psh) ...@@ -132,18 +134,11 @@ static int release(struct Scsi_Host *psh)
/* we always have a successful release */ /* we always have a successful release */
return 0; return 0;
} }
#endif
/* run command */
static int command( Scsi_Cmnd *srb )
{
US_DEBUGP("Bad use of us_command\n");
return DID_BAD_TARGET << 16;
}
/* queue a command */ /* queue a command */
/* This is always called with scsi_lock(srb->host) held */ /* This is always called with scsi_lock(srb->host) held */
static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) static int usb_storage_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
{ {
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
...@@ -168,7 +163,7 @@ static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) ...@@ -168,7 +163,7 @@ static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
/* Command abort */ /* Command abort */
/* This is always called with scsi_lock(srb->host) held */ /* This is always called with scsi_lock(srb->host) held */
static int command_abort( Scsi_Cmnd *srb ) static int usb_storage_command_abort( Scsi_Cmnd *srb )
{ {
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
...@@ -187,7 +182,7 @@ static int command_abort( Scsi_Cmnd *srb ) ...@@ -187,7 +182,7 @@ static int command_abort( Scsi_Cmnd *srb )
/* This invokes the transport reset mechanism to reset the state of the /* This invokes the transport reset mechanism to reset the state of the
* device */ * device */
/* This is always called with scsi_lock(srb->host) held */ /* This is always called with scsi_lock(srb->host) held */
static int device_reset( Scsi_Cmnd *srb ) static int usb_storage_device_reset( Scsi_Cmnd *srb )
{ {
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
int result; int result;
...@@ -202,11 +197,10 @@ static int device_reset( Scsi_Cmnd *srb ) ...@@ -202,11 +197,10 @@ static int device_reset( Scsi_Cmnd *srb )
/* lock the device pointers */ /* lock the device pointers */
down(&(us->dev_semaphore)); down(&(us->dev_semaphore));
/* if the device was removed, then we're already reset */ /* do the reset */
if (!(us->flags & US_FL_DEV_ATTACHED)) result = us->transport_reset(us);
result = SUCCESS;
else /* unlock */
result = us->transport_reset(us);
up(&(us->dev_semaphore)); up(&(us->dev_semaphore));
/* lock access to the state and clear it */ /* lock access to the state and clear it */
...@@ -219,31 +213,26 @@ static int device_reset( Scsi_Cmnd *srb ) ...@@ -219,31 +213,26 @@ static int device_reset( Scsi_Cmnd *srb )
* disconnect/reconnect for all drivers which have claimed * disconnect/reconnect for all drivers which have claimed
* interfaces, including ourself. */ * interfaces, including ourself. */
/* This is always called with scsi_lock(srb->host) held */ /* This is always called with scsi_lock(srb->host) held */
static int bus_reset( Scsi_Cmnd *srb )
/* FIXME: This needs to be re-examined in the face of the new
* hotplug system -- this will implicitly cause a detach/reattach of
* usb-storage, which is not what we want now.
*
* Can we just skip over usb-storage in the while loop?
*/
static int usb_storage_bus_reset( Scsi_Cmnd *srb )
{ {
struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; struct us_data *us;
int i; int i;
int result; int result;
struct usb_device *pusb_dev_save;
/* we use the usb_reset_device() function to handle this for us */ /* we use the usb_reset_device() function to handle this for us */
US_DEBUGP("bus_reset() called\n"); US_DEBUGP("bus_reset() called\n");
scsi_unlock(srb->device->host); us = (struct us_data *)srb->device->host->hostdata[0];
/* if the device has been removed, this worked */
down(&us->dev_semaphore);
if (!(us->flags & US_FL_DEV_ATTACHED)) {
US_DEBUGP("-- device removed already\n");
up(&us->dev_semaphore);
scsi_lock(srb->device->host);
return SUCCESS;
}
pusb_dev_save = us->pusb_dev;
up(&us->dev_semaphore);
/* attempt to reset the port */ /* attempt to reset the port */
result = usb_reset_device(pusb_dev_save); result = usb_reset_device(us->pusb_dev);
US_DEBUGP("usb_reset_device returns %d\n", result); US_DEBUGP("usb_reset_device returns %d\n", result);
if (result < 0) { if (result < 0) {
scsi_lock(srb->device->host); scsi_lock(srb->device->host);
...@@ -253,9 +242,9 @@ static int bus_reset( Scsi_Cmnd *srb ) ...@@ -253,9 +242,9 @@ static int bus_reset( Scsi_Cmnd *srb )
/* FIXME: This needs to lock out driver probing while it's working /* FIXME: This needs to lock out driver probing while it's working
* or we can have race conditions */ * or we can have race conditions */
/* This functionality really should be provided by the khubd thread */ /* This functionality really should be provided by the khubd thread */
for (i = 0; i < pusb_dev_save->actconfig->desc.bNumInterfaces; i++) { for (i = 0; i < us->pusb_dev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf = struct usb_interface *intf =
&pusb_dev_save->actconfig->interface[i]; &us->pusb_dev->actconfig->interface[i];
/* if this is an unclaimed interface, skip it */ /* if this is an unclaimed interface, skip it */
if (!intf->driver) { if (!intf->driver) {
...@@ -274,14 +263,6 @@ static int bus_reset( Scsi_Cmnd *srb ) ...@@ -274,14 +263,6 @@ static int bus_reset( Scsi_Cmnd *srb )
return SUCCESS; return SUCCESS;
} }
/* FIXME: This doesn't do anything right now */
static int host_reset( Scsi_Cmnd *srb )
{
printk(KERN_CRIT "usb-storage: host_reset() requested but not implemented\n" );
bus_reset(srb);
return FAILED;
}
/*********************************************************************** /***********************************************************************
* /proc/scsi/ functions * /proc/scsi/ functions
***********************************************************************/ ***********************************************************************/
...@@ -291,29 +272,23 @@ static int host_reset( Scsi_Cmnd *srb ) ...@@ -291,29 +272,23 @@ static int host_reset( Scsi_Cmnd *srb )
#define SPRINTF(args...) \ #define SPRINTF(args...) \
do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
static int proc_info (char *buffer, char **start, off_t offset, int length, static int usb_storage_proc_info (char *buffer, char **start, off_t offset,
int hostno, int inout) int length, int hostno, int inout)
{ {
struct us_data *us; struct us_data *us;
char *pos = buffer; char *pos = buffer;
struct Scsi_Host *hostptr;
/* if someone is sending us data, just throw it away */ /* if someone is sending us data, just throw it away */
if (inout) if (inout)
return length; return length;
/* lock the data structures */ /* find our data from the given hostno */
down(&us_list_semaphore); hostptr = scsi_host_hn_get(hostno);
if (!hostptr) { /* if we couldn't find it, we return an error */
/* find our data from hostno */ return -ESRCH;
us = us_list;
while (us) {
if (us->host_no == hostno)
break;
us = us->next;
} }
us = (struct us_data*)hostptr->hostdata[0];
/* release our lock on the data structures */
up(&us_list_semaphore);
/* if we couldn't find it, we return an error */ /* if we couldn't find it, we return an error */
if (!us) { if (!us) {
...@@ -332,10 +307,8 @@ static int proc_info (char *buffer, char **start, off_t offset, int length, ...@@ -332,10 +307,8 @@ static int proc_info (char *buffer, char **start, off_t offset, int length,
SPRINTF(" Protocol: %s\n", us->protocol_name); SPRINTF(" Protocol: %s\n", us->protocol_name);
SPRINTF(" Transport: %s\n", us->transport_name); SPRINTF(" Transport: %s\n", us->transport_name);
/* show the GUID of the device */ /* release the reference count on this host */
SPRINTF(" GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid)); scsi_host_put(hostptr);
SPRINTF(" Attached: %s\n", (us->flags & US_FL_DEV_ATTACHED ?
"Yes" : "No"));
/* /*
* Calculate start of next buffer, and return value. * Calculate start of next buffer, and return value.
...@@ -351,33 +324,69 @@ static int proc_info (char *buffer, char **start, off_t offset, int length, ...@@ -351,33 +324,69 @@ static int proc_info (char *buffer, char **start, off_t offset, int length,
} }
/* /*
* this defines our 'host' * this defines our host template, with which we'll allocate hosts
*/ */
Scsi_Host_Template usb_stor_host_template = { struct SHT usb_stor_host_template = {
.name = "usb-storage", /* basic userland interface stuff */
.proc_info = proc_info, .name = "usb-storage",
.info = host_info, .proc_name = "usb-storage",
.proc_info = usb_storage_proc_info,
.detect = detect, .proc_dir = NULL,
.release = release, .info = usb_storage_info,
.command = command, .ioctl = NULL,
.queuecommand = queuecommand,
/* old-style detect and release */
.eh_abort_handler = command_abort, .detect = NULL,
.eh_device_reset_handler =device_reset, .release = NULL,
.eh_bus_reset_handler = bus_reset,
.eh_host_reset_handler =host_reset, /* command interface -- queued only */
.command = NULL,
.can_queue = 1, .queuecommand = usb_storage_queuecommand,
.this_id = -1,
/* error and abort handlers */
.sg_tablesize = SG_ALL, .eh_abort_handler = usb_storage_command_abort,
.cmd_per_lun = 1, .eh_device_reset_handler = usb_storage_device_reset,
.present = 0, .eh_bus_reset_handler = usb_storage_bus_reset,
.unchecked_isa_dma = FALSE, .eh_host_reset_handler = NULL,
.use_clustering = TRUE, .eh_strategy_handler = NULL,
.emulated = TRUE
/* queue commands only, only one command per LUN */
.can_queue = 1,
.cmd_per_lun = 1,
/* unknown initiator id */
.this_id = -1,
/* no limit on commands */
.max_sectors = 0,
/* pre- and post- device scan functions */
.slave_alloc = NULL,
.slave_configure = NULL,
.slave_destroy = NULL,
/* lots of sg segments can be handled */
.sg_tablesize = SG_ALL,
/* use 32-bit address space for DMA */
.unchecked_isa_dma = FALSE,
.highmem_io = FALSE,
/* merge commands... this seems to help performance, but
* periodically someone should test to see which setting is more
* optimal.
*/
.use_clustering = TRUE,
/* emulated HBA */
.emulated = TRUE,
/* sorry, no BIOS to help us */
.bios_param = NULL,
/* module management */
.module = THIS_MODULE
}; };
/* For a device that is "Not Ready" */ /* For a device that is "Not Ready" */
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
extern unsigned char usb_stor_sense_notready[18]; extern unsigned char usb_stor_sense_notready[18];
extern unsigned char usb_stor_sense_invalidCDB[18]; extern unsigned char usb_stor_sense_invalidCDB[18];
extern Scsi_Host_Template usb_stor_host_template; extern struct SHT usb_stor_host_template;
extern int usb_stor_scsiSense10to6(Scsi_Cmnd*); extern int usb_stor_scsiSense10to6(Scsi_Cmnd*);
extern int usb_stor_scsiSense6to10(Scsi_Cmnd*); extern int usb_stor_scsiSense6to10(Scsi_Cmnd*);
......
...@@ -55,8 +55,7 @@ ...@@ -55,8 +55,7 @@
#define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */ #define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */
#endif #endif
#ifdef CONFIG_USB_STORAGE_SDDR09 #ifdef CONFIG_USB_STORAGE_SDDR09
#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
SDDR-09 */
#endif #endif
#ifdef CONFIG_USB_STORAGE_SDDR55 #ifdef CONFIG_USB_STORAGE_SDDR55
#define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */
...@@ -64,15 +63,15 @@ ...@@ -64,15 +63,15 @@
#define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */
#ifdef CONFIG_USB_STORAGE_FREECOM #ifdef CONFIG_USB_STORAGE_FREECOM
#define US_PR_FREECOM 0xf1 /* Freecom */ #define US_PR_FREECOM 0xf1 /* Freecom */
#endif #endif
#ifdef CONFIG_USB_STORAGE_DATAFAB #ifdef CONFIG_USB_STORAGE_DATAFAB
#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ #define US_PR_DATAFAB 0xf2 /* Datafab chipsets */
#endif #endif
#ifdef CONFIG_USB_STORAGE_JUMPSHOT #ifdef CONFIG_USB_STORAGE_JUMPSHOT
#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
#endif #endif
/* /*
...@@ -118,10 +117,10 @@ struct bulk_cs_wrap { ...@@ -118,10 +117,10 @@ struct bulk_cs_wrap {
* usb_stor_bulk_transfer_xxx() return codes, in order of severity * usb_stor_bulk_transfer_xxx() return codes, in order of severity
*/ */
#define USB_STOR_XFER_GOOD 0 /* good transfer */ #define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */ #define USB_STOR_XFER_SHORT 1 /* transfered less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ #define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */ #define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */
/* /*
* Transport return codes * Transport return codes
......
...@@ -264,7 +264,7 @@ UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999, ...@@ -264,7 +264,7 @@ UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999,
/* 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,
"Sony", "Sony",
"PEG Mass Storage", "PEG Mass Storage",
US_SC_8070, US_PR_CBI, NULL, US_SC_8070, US_PR_CBI, NULL,
US_FL_FIX_INQUIRY ), US_FL_FIX_INQUIRY ),
...@@ -546,10 +546,10 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009, ...@@ -546,10 +546,10 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
/* aeb */ /* aeb */
UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
"Feiya", "Feiya",
"5-in-1 Card Reader", "5-in-1 Card Reader",
US_SC_SCSI, US_PR_BULK, NULL, US_SC_SCSI, US_PR_BULK, NULL,
US_FL_FIX_CAPACITY ), US_FL_FIX_CAPACITY ),
UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001, UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001,
"Minds@Work", "Minds@Work",
......
This diff is collapsed.
...@@ -52,33 +52,6 @@ ...@@ -52,33 +52,6 @@
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
/*
* GUID definitions
*/
#define GUID(x) __u32 x[3]
#define GUID_EQUAL(x, y) (x[0] == y[0] && x[1] == y[1] && x[2] == y[2])
#define GUID_CLEAR(x) x[0] = x[1] = x[2] = 0;
#define GUID_NONE(x) (!x[0] && !x[1] && !x[2])
#define GUID_FORMAT "%08x%08x%08x"
#define GUID_ARGS(x) x[0], x[1], x[2]
static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *serial)
{
pg[0] = (vendor << 16) | product;
pg[1] = pg[2] = 0;
while (*serial) {
pg[1] <<= 4;
pg[1] |= pg[2] >> 28;
pg[2] <<= 4;
if (*serial >= 'a')
*serial -= 'a' - 'A';
pg[2] |= (*serial <= '9' && *serial >= '0') ? *serial - '0'
: *serial - 'A' + 10;
serial++;
}
}
struct us_data; struct us_data;
/* /*
...@@ -104,7 +77,6 @@ struct us_unusual_dev { ...@@ -104,7 +77,6 @@ struct us_unusual_dev {
#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 */
#define US_FL_DEV_ATTACHED 0x00010000 /* is the device attached? */
#define US_FLIDX_CAN_CANCEL 18 /* 0x00040000 okay to cancel current_urb? */ #define US_FLIDX_CAN_CANCEL 18 /* 0x00040000 okay to cancel current_urb? */
#define US_FLIDX_CANCEL_SG 19 /* 0x00080000 okay to cancel current_sg? */ #define US_FLIDX_CANCEL_SG 19 /* 0x00080000 okay to cancel current_sg? */
...@@ -124,12 +96,9 @@ typedef void (*extra_data_destructor)(void *); /* extra data destructor */ ...@@ -124,12 +96,9 @@ typedef void (*extra_data_destructor)(void *); /* extra data destructor */
/* we allocate one of these for every device that we remember */ /* we allocate one of these for every device that we remember */
struct us_data { struct us_data {
struct us_data *next; /* next device */
/* The device we're working with /* The device we're working with
* It's important to note: * It's important to note:
* (o) you must hold dev_semaphore to change pusb_dev * (o) you must hold dev_semaphore to change pusb_dev
* (o) DEV_ATTACHED in flags should change whenever pusb_dev does
*/ */
struct semaphore dev_semaphore; /* protect pusb_dev */ struct semaphore dev_semaphore; /* protect pusb_dev */
struct usb_device *pusb_dev; /* this usb_device */ struct usb_device *pusb_dev; /* this usb_device */
...@@ -163,11 +132,7 @@ struct us_data { ...@@ -163,11 +132,7 @@ struct us_data {
proto_cmnd proto_handler; /* protocol handler */ proto_cmnd proto_handler; /* protocol handler */
/* SCSI interfaces */ /* SCSI interfaces */
GUID(guid); /* unique dev id */
struct Scsi_Host *host; /* our dummy host data */ struct Scsi_Host *host; /* our dummy host data */
Scsi_Host_Template htmplt; /* own host template */
int host_number; /* to find us */
int host_no; /* allocated by scsi */
Scsi_Cmnd *srb; /* current srb */ Scsi_Cmnd *srb; /* current srb */
/* thread information */ /* thread information */
...@@ -192,10 +157,6 @@ struct us_data { ...@@ -192,10 +157,6 @@ struct us_data {
extra_data_destructor extra_destructor;/* extra data destructor */ extra_data_destructor extra_destructor;/* extra data destructor */
}; };
/* The list of structures and the protective lock for them */
extern struct us_data *us_list;
extern struct semaphore us_list_semaphore;
/* The structure which defines our driver */ /* The structure which defines our driver */
extern struct usb_driver usb_storage_driver; extern struct usb_driver usb_storage_driver;
......
...@@ -554,7 +554,6 @@ extern int usb_disabled(void); ...@@ -554,7 +554,6 @@ extern int usb_disabled(void);
#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 */
#define URB_TIMEOUT_KILLED 0x1000 /* only set by HCD! */
struct usb_iso_packet_descriptor { struct usb_iso_packet_descriptor {
unsigned int offset; unsigned int offset;
......
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