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

Merge

parents 46b11ba9 fb6d52e5
......@@ -212,6 +212,14 @@ config NET_ETHERNET
kernel: saying N will just cause the configurator to skip all
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
bool "ARM EBSA110 AM79C961A support"
depends on NET_ETHERNET && ARM && ARCH_EBSA110
......
......@@ -57,6 +57,7 @@ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o mii.o
# end link order section
#
obj-$(CONFIG_MII) += mii.o
obj-$(CONFIG_AIRONET4500) += aironet4500_core.o
obj-$(CONFIG_AIRONET4500_CS) += aironet4500_core.o
obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o
......@@ -193,3 +194,6 @@ obj-$(CONFIG_NET_WIRELESS) += wireless/
obj-$(CONFIG_NET_TULIP) += tulip/
obj-$(CONFIG_HAMRADIO) += hamradio/
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)
if (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++) {
/* if we insert more than TTY_FLIPBUF_SIZE characters,
* we drop them. */
......@@ -697,6 +697,7 @@ static void acm_disconnect(struct usb_interface *intf)
static struct usb_device_id acm_ids[] = {
{ USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
{ USB_DEVICE_INFO(USB_CLASS_COMM, 2, 0) },
{ }
};
......
......@@ -68,7 +68,7 @@
static char *format_topo =
/* 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 =
/* S: Manufacturer=xxxx */
......
......@@ -310,9 +310,9 @@ static int rh_string (
} else
return 0;
data [0] = 2 + ascii2utf (buf, data + 2, len - 2);
data [0] = 2 * (strlen (buf) + 1);
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)
return status;
}
/* lower level hcd code should use *_dma exclusively */
if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
/* 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))
urb->setup_dma = dma_map_single (
hcd->controller,
......
......@@ -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 list_head dev_list; /* on this hcd */
struct list_head urb_list; /* pending on this dev */
......@@ -343,6 +350,13 @@ extern void usb_deregister_bus (struct usb_bus *);
extern int usb_register_root_hub (struct usb_device *usb_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 */
......
......@@ -206,7 +206,8 @@ static void sg_clean (struct usb_sg_request *io)
kfree (io->urbs);
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;
}
......@@ -301,6 +302,7 @@ int usb_sg_init (
{
int i;
int urb_flags;
int dma;
if (!io || !dev || !sg
|| usb_pipecontrol (pipe)
......@@ -314,8 +316,16 @@ int usb_sg_init (
io->sg = sg;
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 */
io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
if (io->entries <= 0)
return io->entries;
......@@ -347,8 +357,17 @@ int usb_sg_init (
io->urbs [i]->status = -EINPROGRESS;
io->urbs [i]->actual_length = 0;
io->urbs [i]->transfer_dma = sg_dma_address (sg + i);
len = sg_dma_len (sg + i);
if (dma) {
/* 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) {
len = min_t (unsigned, len, length);
length -= len;
......@@ -434,9 +453,7 @@ void usb_sg_wait (struct usb_sg_request *io)
retval = 0;
i--;
// FIXME: should it usb_sg_cancel() on INTERRUPT?
// how about imposing a backoff?
set_current_state (TASK_UNINTERRUPTIBLE);
schedule ();
yield ();
break;
/* no error? continue immediately.
......
......@@ -1224,7 +1224,8 @@ void usb_buffer_free (
*
* 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.
* 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()
......@@ -1245,12 +1246,15 @@ struct urb *usb_buffer_map (struct urb *urb)
|| !(controller = bus->controller))
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,
usb_pipein (urb->pipe)
? DMA_FROM_DEVICE : 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;
return urb;
}
......@@ -1271,7 +1275,8 @@ void usb_buffer_dmasync (struct urb *urb)
|| !(controller = bus->controller))
return;
dma_sync_single (controller,
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);
......@@ -1295,10 +1300,12 @@ void usb_buffer_unmap (struct urb *urb)
|| !(controller = bus->controller))
return;
dma_unmap_single (controller,
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;
}
/**
......@@ -1336,7 +1343,8 @@ int usb_buffer_map_sg (struct usb_device *dev, unsigned pipe,
if (!dev
|| usb_pipecontrol (pipe)
|| !(bus = dev->bus)
|| !(controller = bus->controller))
|| !(controller = bus->controller)
|| !controller->dma_mask)
return -1;
// 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,
if (!dev
|| !(bus = dev->bus)
|| !(controller = bus->controller))
|| !(controller = bus->controller)
|| !controller->dma_mask)
return;
dma_sync_sg (controller, sg, n_hw_ents,
......@@ -1386,7 +1395,8 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
if (!dev
|| !(bus = dev->bus)
|| !(controller = bus->controller))
|| !(controller = bus->controller)
|| !controller->dma_mask)
return;
dma_unmap_sg (controller, sg, n_hw_ents,
......
......@@ -277,7 +277,26 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { }
default: tmp = '?'; break; \
}; 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 hw_curr;
......@@ -286,26 +305,49 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep)
unsigned temp;
unsigned size = *sizep;
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);
hw_curr = cpu_to_le32p (&qh->hw_current);
hw_curr = (mark == '*') ? cpu_to_le32p (&qh->hw_current) : 0;
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,
speed_char (scratch),
(scratch >> 8) & 0x000f,
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;
next += temp;
/* hc may be modifying the list as we read it ... */
list_for_each (entry, &qh->qtd_list) {
td = list_entry (entry, struct ehci_qtd, qtd_list);
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,
"\n\t%std/%p %s len=%d %08x urb %p",
(hw_curr == td->qtd_dma) ? "*" : "",
td, ({ char *tmp;
"\n\t%p%c%s len=%d %08x urb %p",
td, mark, ({ char *tmp;
switch ((scratch>>8)&0x03) {
case 0: tmp = "out"; break;
case 1: tmp = "in"; break;
......@@ -315,13 +357,27 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep)
(scratch >> 16) & 0x7fff,
scratch,
td->urb);
if (temp < 0)
temp = 0;
else if (size < temp)
temp = size;
size -= temp;
next += temp;
if (temp == size)
goto done;
}
temp = snprintf (next, size, "\n");
*sizep = size - temp;
*nextp = next + temp;
if (temp < 0)
temp = 0;
else if (size < temp)
temp = size;
size -= temp;
next += temp;
done:
*sizep = size;
*nextp = next;
}
static ssize_t
......@@ -344,14 +400,15 @@ show_async (struct device *dev, char *buf)
* one QH per line, and TDs we know about
*/
spin_lock_irqsave (&ehci->lock, flags);
for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh)
qh_lines (qh, &next, &size);
if (ehci->reclaim) {
for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
qh_lines (ehci, qh, &next, &size);
if (ehci->reclaim && size > 0) {
temp = snprintf (next, size, "\nreclaim =\n");
size -= 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);
......@@ -421,7 +478,7 @@ show_periodic (struct device *dev, char *buf)
scratch & 0x007f,
(scratch >> 8) & 0x000f,
p.qh->usecs, p.qh->c_usecs,
scratch >> 16);
0x7ff & (scratch >> 16));
/* FIXME TD info too */
......@@ -490,7 +547,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\n",
temp = snprintf (next, size,
"EHCI %x.%02x, hcd state %d (version " DRIVER_VERSION ")\n",
i >> 8, i & 0x0ff, ehci->hcd.state);
size -= temp;
next += temp;
......
......@@ -94,7 +94,7 @@
* 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_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
......@@ -110,10 +110,11 @@ static const char hcd_name [] = "ehci-hcd";
/* magic numbers that can affect system performance */
#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_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
#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_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
......@@ -416,13 +417,26 @@ static int ehci_start (struct usb_hcd *hcd)
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 */
temp = readl (&ehci->regs->command) & 0xff;
if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
log2_irq_thresh = 0;
temp |= 1 << (16 + log2_irq_thresh);
// 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),
// Philips, Intel, and maybe others need CMD_RUN before the
// 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)
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
struct ehci_qh *qh;
unsigned long flags;
int maybe_irq = 1;
spin_lock_irqsave (&ehci->lock, flags);
switch (usb_pipetype (urb->pipe)) {
......@@ -769,23 +782,23 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
qh = (struct ehci_qh *) urb->hcpriv;
if (!qh)
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
&& HCD_IS_RUNNING (ehci->hcd.state)
) {
spin_unlock_irqrestore (&ehci->lock, flags);
struct ehci_qh *last;
if (maybe_irq) {
if (in_interrupt ())
return -EAGAIN;
maybe_irq = 0;
}
/* let pending unlinks complete, so this can start */
wait_ms (1);
for (last = ehci->reclaim;
last->reclaim;
last = last->reclaim)
continue;
qh->qh_state = QH_STATE_UNLINK_WAIT;
last->reclaim = qh;
spin_lock_irqsave (&ehci->lock, flags);
}
if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
/* bypass IAA if the hc can't care */
} else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
end_unlink_async (ehci, NULL);
/* 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)
qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma);
if (qtd != 0) {
ehci_qtd_init (qtd, dma);
if (ehci->async)
qtd->hw_alt_next = ehci->async->hw_alt_next;
}
return qtd;
}
......
This diff is collapsed.
......@@ -236,12 +236,12 @@ struct ehci_qtd {
/* the rest is HCD-private */
dma_addr_t qtd_dma; /* qtd address */
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 */
size_t length; /* length of buffer */
} __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 */
......@@ -305,6 +305,7 @@ struct ehci_qh {
union ehci_shadow qh_next; /* ptr to qh; or periodic */
struct list_head qtd_list; /* sw qtd list */
struct ehci_qtd *dummy;
struct ehci_qh *reclaim; /* next to reclaim */
atomic_t refcount;
unsigned stamp;
......@@ -313,6 +314,8 @@ struct ehci_qh {
#define QH_STATE_LINKED 1 /* HC sees this */
#define QH_STATE_UNLINK 2 /* HC may still 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 */
u8 usecs; /* intr bandwidth */
......@@ -426,16 +429,6 @@ static inline int hcd_register_root (struct usb_hcd *hcd)
#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)
#ifndef DEBUG
......
......@@ -219,7 +219,7 @@ static int hci_unlink_urb (struct urb * urb)
if (!list_empty (&urb->urb_list) && urb->status == -EINPROGRESS) {
/* URB active? */
if (urb->transfer_flags & (URB_ASYNC_UNLINK | URB_TIMEOUT_KILLED)) {
if (urb->transfer_flags & URB_ASYNC_UNLINK) {
/* asynchronous with callback */
/* relink the urb to the del list */
list_move (&urb->urb_list, &hci->del_list);
......@@ -388,7 +388,6 @@ static void qu_urb_timeout (unsigned long lurb)
struct urb *urb = (struct urb *) lurb;
DBGFUNC ("enter qu_urb_timeout\n");
urb->transfer_flags |= URB_TIMEOUT_KILLED;
hci_unlink_urb (urb);
}
#endif
......
......@@ -203,28 +203,28 @@ static int ohci_urb_enqueue (
return -ENOMEM;
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 */
urb_priv->length = size;
urb_priv->ed = ed;
/* allocate the TDs (updating hash chains) */
/* allocate the TDs (deferring hash chain updates) */
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]) {
urb_priv->length = i;
retval = -ENOMEM;
goto fail;
urb_free_priv (ohci, urb_priv);
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 */
if (ed->state == ED_IDLE) {
retval = ed_schedule (ohci, ed);
......
......@@ -97,17 +97,11 @@ td_alloc (struct ohci_hcd *hc, int mem_flags)
td = pci_pool_alloc (hc->td_cache, mem_flags, &dma);
if (td) {
int hash;
/* in case hc fetches it, make it look dead */
memset (td, 0, sizeof *td);
td->hwNextTD = cpu_to_le32 (dma);
td->td_dma = dma;
/* hash it for later reverse mapping */
hash = TD_HASH_FUNC (dma);
td->td_hash = hc->td_hash [hash];
hc->td_hash [hash] = td;
/* hashed in td_fill */
}
return td;
}
......
......@@ -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) */
static void
td_fill (unsigned int info,
td_fill (struct ohci_hcd *ohci, u32 info,
dma_addr_t data, int len,
struct urb *urb, int index)
{
struct td *td, *td_pt;
struct urb_priv *urb_priv = urb->hcpriv;
int is_iso = info & TD_ISO;
int hash;
// ASSERT (index < urb_priv->length);
......@@ -516,11 +517,16 @@ td_fill (unsigned int info,
td->hwBE = 0;
td->hwNextTD = cpu_to_le32 (td_pt->td_dma);
/* HC might read the TD right after we link it ... */
wmb ();
/* append to queue */
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;
}
......@@ -578,7 +584,7 @@ static void td_submit_urb (
: TD_T_TOGGLE | TD_CC | TD_DP_IN;
/* TDs _could_ transfer up to 8K each */
while (data_len > 4096) {
td_fill (info, data, 4096, urb, cnt);
td_fill (ohci, info, data, 4096, urb, cnt);
data += 4096;
data_len -= 4096;
cnt++;
......@@ -586,11 +592,11 @@ static void td_submit_urb (
/* maybe avoid ED halt on final TD short read */
if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
info |= TD_R;
td_fill (info, data, data_len, urb, cnt);
td_fill (ohci, info, data, data_len, urb, cnt);
cnt++;
if ((urb->transfer_flags & URB_ZERO_PACKET)
&& cnt < urb_priv->length) {
td_fill (info, 0, 0, urb, cnt);
td_fill (ohci, info, 0, 0, urb, cnt);
cnt++;
}
/* maybe kickstart bulk list */
......@@ -605,17 +611,17 @@ static void td_submit_urb (
*/
case PIPE_CONTROL:
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) {
info = TD_CC | TD_R | TD_T_DATA1;
info |= is_out ? TD_DP_OUT : TD_DP_IN;
/* 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
? TD_CC | TD_DP_IN | 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 */
wmb ();
writel (OHCI_CLF, &ohci->regs->cmdstatus);
......@@ -634,7 +640,7 @@ static void td_submit_urb (
// a 2^16 iso range, vs other HCs max of 2^10)
frame += cnt * urb->interval;
frame &= 0xffff;
td_fill (TD_CC | TD_ISO | frame,
td_fill (ohci, TD_CC | TD_ISO | frame,
data + urb->iso_frame_desc [cnt].offset,
urb->iso_frame_desc [cnt].length, urb, cnt);
}
......
......@@ -1747,7 +1747,6 @@ static void stall_callback(unsigned long ptr)
tmp = tmp->next;
u->transfer_flags |= URB_TIMEOUT_KILLED;
uhci_urb_dequeue(hcd, u);
}
......
/* -*- 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) 2002, 2003 Henning Meier-Geinitz
*
* 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
* modify it under the terms of the GNU General Public License as
......@@ -300,8 +303,6 @@
* Frank Zago <fzago@greshamstorage.com> and
* 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
* - Added Mustek BearPaw 2400 TA. Thanks to Sergey
* Vlasov <vsu@mivlgu.murom.ru>.
......@@ -332,12 +333,18 @@
* <oliver@neukum.name>.
*
* 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
* of everytime any USB device is plugged in.
* - Removed PV8630 ioctls. Use the standard ioctls instead.
* - Made endpoint detection more generic. Basically, only one bulk-in
* 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
* - Performance
......@@ -360,7 +367,7 @@
* - All the developers that are working on USB SANE backends or other
* applications to use USB scanners.
* - 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:
*
......@@ -369,6 +376,14 @@
* 24 Bit Color ~ 70 secs - 3.6 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>
/*
......@@ -461,7 +476,7 @@ open_scanner(struct inode * inode, struct file * file)
}
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;
goto out_error;
}
......@@ -1047,6 +1062,9 @@ probe_scanner(struct usb_interface *intf,
if (scn->devfs == NULL)
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);
usb_set_intfdata(intf, scn);
......
This diff is collapsed.
......@@ -1324,6 +1324,9 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_MGE_UPS 0xffff
#define USB_DEVICE_ID_MGE_UPS1 0x0001
#define USB_VENDOR_ID_ONTRAK 0x0a07
#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
struct hid_blacklist {
__u16 idVendor;
__u16 idProduct;
......@@ -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_UPS1, HID_QUIRK_HIDDEV },
{ 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 }
};
......
......@@ -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)
{
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
} else {
/* 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)) ==
NULL) {
skb_trim (skb, 0);
}
NULL)
return NULL;
}
}
......
......@@ -33,6 +33,7 @@
#define ATMSAR_USE_53BYTE_CELL 0x1L
#define ATMSAR_SET_PTI 0x2L
#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
/* types */
#define ATMSAR_TYPE_AAL0 ATM_AAL0
......@@ -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);
unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length);
#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 [] = {
static struct usb_device_id id_table_8U232AM [] = {
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
{ } /* Terminating entry */
};
......@@ -143,6 +144,7 @@ static struct usb_device_id id_table_8U232AM [] = {
static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_SIO_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) },
{ } /* Terminating entry */
};
......
......@@ -17,11 +17,14 @@
* Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc.- wrote the
* 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_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
#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_PID 0x0001 /* Product Id */
......
......@@ -106,6 +106,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(CASIO_VENDOR_ID, CASIO_EM500_ID) },
{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_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_568_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_2016_ID) },
......@@ -126,6 +127,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_WIRELESS_ID) },
{ USB_DEVICE(SOCKET_VENDOR_ID, SOCKET_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(NEC_VENDOR_ID, NEC_PRODUCT_ID) },
{ } /* Terminating entry */
......
......@@ -30,6 +30,9 @@
#define COMPAQ_IPAQ_ID 0x0003
#define COMPAQ_0032_ID 0x0032
#define DELL_VENDOR_ID 0x413c
#define DELL_AXIM_ID 0x4001
#define HP_VENDOR_ID 0x03f0
#define HP_JORNADA_548_ID 0x1016
#define HP_JORNADA_568_ID 0x1116
......@@ -63,6 +66,7 @@
#define TOSHIBA_VENDOR_ID 0x0930
#define TOSHIBA_PRODUCT_ID 0x0700
#define TOSHIBA_E740_ID 0x0706
#define HTC_VENDOR_ID 0x0bb4
#define HTC_PRODUCT_ID 0x00ce
......
......@@ -74,6 +74,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
{ USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
{ } /* Terminating entry */
};
......
......@@ -28,3 +28,6 @@
#define RATOC_VENDOR_ID 0x0584
#define RATOC_PRODUCT_ID 0xb000
#define TRIPP_VENDOR_ID 0x2478
#define TRIPP_PRODUCT_ID 0x2008
......@@ -27,14 +27,14 @@
extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us);
struct datafab_info {
unsigned long sectors; // total sector count
unsigned long ssize; // sector size in bytes
char lun; // used for dual-slot readers
// the following aren't used yet
unsigned long sectors; // total sector count
unsigned long ssize; // sector size in bytes
char lun; // used for dual-slot readers
// the following aren't used yet
unsigned char sense_key;
unsigned long sense_asc; // additional sense code
unsigned long sense_ascq; // additional sense code qualifier
unsigned long sense_asc; // additional sense code
unsigned long sense_ascq; // additional sense code qualifier
};
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -53,7 +53,7 @@
#define US_SC_UFI 0x04 /* Floppy */
#define US_SC_8070 0x05 /* Removable media */
#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_MAX US_SC_ISD200
......
......@@ -50,23 +50,25 @@
#include "transport.h"
#include <linux/slab.h>
#include <linux/module.h>
/***********************************************************************
* 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";
}
#if 0
/* detect a virtual adapter (always works)
* Synchronization: 2.4: with the io_request_lock
* 2.5: no locks.
* fortunately we don't care.
* */
static int detect(struct SHT *sht)
static int usb_storage_detect(struct SHT *sht)
{
struct us_data *us;
char local_name[32];
......@@ -109,7 +111,7 @@ static int detect(struct SHT *sht)
* the driver and we're doing each virtual host in turn, not in parallel
* 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];
......@@ -132,18 +134,11 @@ static int release(struct Scsi_Host *psh)
/* we always have a successful release */
return 0;
}
/* run command */
static int command( Scsi_Cmnd *srb )
{
US_DEBUGP("Bad use of us_command\n");
return DID_BAD_TARGET << 16;
}
#endif
/* queue a command */
/* 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];
......@@ -168,7 +163,7 @@ static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
/* Command abort */
/* 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];
......@@ -187,7 +182,7 @@ static int command_abort( Scsi_Cmnd *srb )
/* This invokes the transport reset mechanism to reset the state of the
* device */
/* 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];
int result;
......@@ -202,11 +197,10 @@ static int device_reset( Scsi_Cmnd *srb )
/* lock the device pointers */
down(&(us->dev_semaphore));
/* if the device was removed, then we're already reset */
if (!(us->flags & US_FL_DEV_ATTACHED))
result = SUCCESS;
else
result = us->transport_reset(us);
/* do the reset */
result = us->transport_reset(us);
/* unlock */
up(&(us->dev_semaphore));
/* lock access to the state and clear it */
......@@ -219,31 +213,26 @@ static int device_reset( Scsi_Cmnd *srb )
* disconnect/reconnect for all drivers which have claimed
* interfaces, including ourself. */
/* 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 result;
struct usb_device *pusb_dev_save;
/* we use the usb_reset_device() function to handle this for us */
US_DEBUGP("bus_reset() called\n");
scsi_unlock(srb->device->host);
/* 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);
us = (struct us_data *)srb->device->host->hostdata[0];
/* 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);
if (result < 0) {
scsi_lock(srb->device->host);
......@@ -253,9 +242,9 @@ static int bus_reset( Scsi_Cmnd *srb )
/* FIXME: This needs to lock out driver probing while it's working
* or we can have race conditions */
/* 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 =
&pusb_dev_save->actconfig->interface[i];
&us->pusb_dev->actconfig->interface[i];
/* if this is an unclaimed interface, skip it */
if (!intf->driver) {
......@@ -274,14 +263,6 @@ static int bus_reset( Scsi_Cmnd *srb )
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
***********************************************************************/
......@@ -291,29 +272,23 @@ static int host_reset( Scsi_Cmnd *srb )
#define SPRINTF(args...) \
do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
static int proc_info (char *buffer, char **start, off_t offset, int length,
int hostno, int inout)
static int usb_storage_proc_info (char *buffer, char **start, off_t offset,
int length, int hostno, int inout)
{
struct us_data *us;
char *pos = buffer;
struct Scsi_Host *hostptr;
/* if someone is sending us data, just throw it away */
if (inout)
return length;
/* lock the data structures */
down(&us_list_semaphore);
/* find our data from hostno */
us = us_list;
while (us) {
if (us->host_no == hostno)
break;
us = us->next;
/* find our data from the given hostno */
hostptr = scsi_host_hn_get(hostno);
if (!hostptr) { /* if we couldn't find it, we return an error */
return -ESRCH;
}
/* release our lock on the data structures */
up(&us_list_semaphore);
us = (struct us_data*)hostptr->hostdata[0];
/* if we couldn't find it, we return an error */
if (!us) {
......@@ -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(" Transport: %s\n", us->transport_name);
/* show the GUID of the device */
SPRINTF(" GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid));
SPRINTF(" Attached: %s\n", (us->flags & US_FL_DEV_ATTACHED ?
"Yes" : "No"));
/* release the reference count on this host */
scsi_host_put(hostptr);
/*
* 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,
}
/*
* this defines our 'host'
* this defines our host template, with which we'll allocate hosts
*/
Scsi_Host_Template usb_stor_host_template = {
.name = "usb-storage",
.proc_info = proc_info,
.info = host_info,
.detect = detect,
.release = release,
.command = command,
.queuecommand = queuecommand,
.eh_abort_handler = command_abort,
.eh_device_reset_handler =device_reset,
.eh_bus_reset_handler = bus_reset,
.eh_host_reset_handler =host_reset,
.can_queue = 1,
.this_id = -1,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.present = 0,
.unchecked_isa_dma = FALSE,
.use_clustering = TRUE,
.emulated = TRUE
struct SHT usb_stor_host_template = {
/* basic userland interface stuff */
.name = "usb-storage",
.proc_name = "usb-storage",
.proc_info = usb_storage_proc_info,
.proc_dir = NULL,
.info = usb_storage_info,
.ioctl = NULL,
/* old-style detect and release */
.detect = NULL,
.release = NULL,
/* command interface -- queued only */
.command = NULL,
.queuecommand = usb_storage_queuecommand,
/* error and abort handlers */
.eh_abort_handler = usb_storage_command_abort,
.eh_device_reset_handler = usb_storage_device_reset,
.eh_bus_reset_handler = usb_storage_bus_reset,
.eh_host_reset_handler = NULL,
.eh_strategy_handler = NULL,
/* 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" */
......
......@@ -47,7 +47,7 @@
extern unsigned char usb_stor_sense_notready[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_scsiSense6to10(Scsi_Cmnd*);
......
......@@ -55,8 +55,7 @@
#define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */
#endif
#ifdef CONFIG_USB_STORAGE_SDDR09
#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for
SDDR-09 */
#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */
#endif
#ifdef CONFIG_USB_STORAGE_SDDR55
#define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */
......@@ -64,15 +63,15 @@
#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
/*
......@@ -118,10 +117,10 @@ struct bulk_cs_wrap {
* usb_stor_bulk_transfer_xxx() return codes, in order of severity
*/
#define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */
#define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */
/*
* Transport return codes
......
......@@ -264,7 +264,7 @@ UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999,
/* Submitted by Nathan Babb <nathan@lexi.com> */
UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999,
"Sony",
"Sony",
"PEG Mass Storage",
US_SC_8070, US_PR_CBI, NULL,
US_FL_FIX_INQUIRY ),
......@@ -546,10 +546,10 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
/* aeb */
UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
"Feiya",
"5-in-1 Card Reader",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_FIX_CAPACITY ),
"Feiya",
"5-in-1 Card Reader",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_FIX_CAPACITY ),
UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001,
"Minds@Work",
......
This diff is collapsed.
......@@ -52,33 +52,6 @@
#include "scsi.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;
/*
......@@ -104,7 +77,6 @@ struct us_unusual_dev {
#define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */
#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_CANCEL_SG 19 /* 0x00080000 okay to cancel current_sg? */
......@@ -124,12 +96,9 @@ typedef void (*extra_data_destructor)(void *); /* extra data destructor */
/* we allocate one of these for every device that we remember */
struct us_data {
struct us_data *next; /* next device */
/* The device we're working with
* It's important to note:
* (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 usb_device *pusb_dev; /* this usb_device */
......@@ -163,11 +132,7 @@ struct us_data {
proto_cmnd proto_handler; /* protocol handler */
/* SCSI interfaces */
GUID(guid); /* unique dev id */
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 */
/* thread information */
......@@ -192,10 +157,6 @@ struct us_data {
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 */
extern struct usb_driver usb_storage_driver;
......
......@@ -554,7 +554,6 @@ extern int usb_disabled(void);
#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 */
#define URB_TIMEOUT_KILLED 0x1000 /* only set by HCD! */
struct usb_iso_packet_descriptor {
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