mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
Fix low-level OHCI transfers for ARM920t and MPC5xxx
A new, Windows compatible init sequence was also backported from Linux 2.6, but disabled with #undef NEW_INIT_SEQ as it wouldn't change the behaviour of the memopry sticks we tested. Maybe it's not relevant for mass storage devices. For recerence, see file common/usb.c, function usb_new_device(), section #ifdef NEW_INIT_SEQ.
This commit is contained in:
parent
f530187dbd
commit
9c998aa831
9 changed files with 400 additions and 153 deletions
|
@ -448,11 +448,17 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
block_dev_desc_t *stor_dev;
|
||||
#endif
|
||||
|
||||
if ((strncmp(argv[1],"reset",5) == 0) ||
|
||||
(strncmp(argv[1],"start",5) == 0)){
|
||||
if ((strncmp(argv[1], "reset", 5) == 0) ||
|
||||
(strncmp(argv[1], "start", 5) == 0)){
|
||||
usb_stop();
|
||||
printf("(Re)start USB...\n");
|
||||
usb_init();
|
||||
i = usb_init();
|
||||
#ifdef CONFIG_USB_STORAGE
|
||||
/* try to recognize storage devices immediately */
|
||||
if (i >= 0)
|
||||
usb_stor_curr_dev = usb_stor_scan(1);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(argv[1],"stop",4) == 0) {
|
||||
|
@ -513,15 +519,18 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_USB_STORAGE
|
||||
if (strncmp(argv[1],"scan",4) == 0) {
|
||||
printf("Scan for storage device:\n");
|
||||
usb_stor_curr_dev=usb_stor_scan(1);
|
||||
if (usb_stor_curr_dev==-1) {
|
||||
printf("No device found. Not initialized?\n");
|
||||
return 1;
|
||||
}
|
||||
if (strncmp(argv[1], "scan", 4) == 0) {
|
||||
printf(" NOTE: this command is obsolete and will be phased out\n");
|
||||
printf(" please use 'usb storage' for USB storage devices information\n\n");
|
||||
usb_stor_info();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(argv[1], "stor", 4) == 0) {
|
||||
usb_stor_info();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(argv[1],"part",4) == 0) {
|
||||
int devno, ok;
|
||||
for (ok=0, devno=0; devno<USB_MAX_STOR_DEV; ++devno) {
|
||||
|
@ -560,8 +569,8 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
if (strcmp(argv[1],"dev") == 0) {
|
||||
if (argc==3) {
|
||||
if (strncmp(argv[1], "dev", 3) == 0) {
|
||||
if (argc == 3) {
|
||||
int dev = (int)simple_strtoul(argv[2], NULL, 10);
|
||||
printf ("\nUSB device %d: ", dev);
|
||||
if (dev >= USB_MAX_STOR_DEV) {
|
||||
|
@ -608,7 +617,7 @@ U_BOOT_CMD(
|
|||
"usb stop [f] - stop USB [f]=force stop\n"
|
||||
"usb tree - show USB device tree\n"
|
||||
"usb info [dev] - show available USB devices\n"
|
||||
"usb scan - (re-)scan USB bus for storage devices\n"
|
||||
"usb storage - show details of USB storage devices\n"
|
||||
"usb dev [dev] - show or set current USB storage device\n"
|
||||
"usb part [dev] - print partition table of one or all USB storage devices\n"
|
||||
"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
|
||||
|
|
256
common/usb.c
256
common/usb.c
|
@ -37,6 +37,7 @@
|
|||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/processor.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_USB)
|
||||
|
||||
|
@ -46,7 +47,7 @@
|
|||
#endif
|
||||
|
||||
|
||||
/* #define USB_DEBUG */
|
||||
#undef USB_DEBUG
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
#define USB_PRINTF(fmt,args...) printf (fmt ,##args)
|
||||
|
@ -70,6 +71,7 @@ void usb_scan_devices(void);
|
|||
int usb_hub_probe(struct usb_device *dev, int ifnum);
|
||||
void usb_hub_reset(void);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* wait_ms
|
||||
*/
|
||||
|
@ -157,6 +159,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
|
|||
{
|
||||
if((timeout==0)&&(!asynch_allowed)) /* request for a asynch control pipe is not allowed */
|
||||
return -1;
|
||||
|
||||
/* set setup command */
|
||||
setup_packet.requesttype = requesttype;
|
||||
setup_packet.request = request;
|
||||
|
@ -330,8 +333,7 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
|
|||
int usb_clear_halt(struct usb_device *dev, int pipe)
|
||||
{
|
||||
int result;
|
||||
unsigned short status;
|
||||
int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
|
||||
int endp = usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
|
||||
|
||||
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||
USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, USB_CNTL_TIMEOUT * 3);
|
||||
|
@ -339,15 +341,14 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
|
|||
/* don't clear if failed */
|
||||
if (result < 0)
|
||||
return result;
|
||||
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||
USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
|
||||
&status, sizeof(status), USB_CNTL_TIMEOUT * 3);
|
||||
if (result < 0)
|
||||
return result;
|
||||
USB_PRINTF("usb_clear_halt: status 0x%x\n",status);
|
||||
if (status & 1)
|
||||
return -1; /* still halted */
|
||||
|
||||
/*
|
||||
* NOTE: we do not get status and verify reset was successful
|
||||
* as some devices are reported to lock up upon this check..
|
||||
*/
|
||||
|
||||
usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
|
||||
|
||||
/* toggle is reset on clear */
|
||||
usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
|
||||
return 0;
|
||||
|
@ -423,7 +424,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
|
|||
struct usb_interface_descriptor *if_face = NULL;
|
||||
int ret, i;
|
||||
|
||||
for (i=0; i<dev->config.bNumInterfaces; i++) {
|
||||
for (i = 0; i < dev->config.bNumInterfaces; i++) {
|
||||
if (dev->config.if_desc[i].bInterfaceNumber == interface) {
|
||||
if_face = &dev->config.if_desc[i];
|
||||
break;
|
||||
|
@ -439,8 +440,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
|
|||
interface, NULL, 0, USB_CNTL_TIMEOUT * 5)) < 0)
|
||||
return ret;
|
||||
|
||||
if_face->act_altsetting = (unsigned char)alternate;
|
||||
usb_set_maxpacket(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -511,11 +510,74 @@ int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
|
|||
*/
|
||||
int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
|
||||
{
|
||||
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||
(USB_DT_STRING << 8) + index, langid, buf, size, USB_CNTL_TIMEOUT);
|
||||
int i;
|
||||
int result;
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
/* some devices are flaky */
|
||||
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||
(USB_DT_STRING << 8) + index, langid, buf, size,
|
||||
USB_CNTL_TIMEOUT);
|
||||
|
||||
if (result > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void usb_try_string_workarounds(unsigned char *buf, int *length)
|
||||
{
|
||||
int newlength, oldlength = *length;
|
||||
|
||||
for (newlength = 2; newlength + 1 < oldlength; newlength += 2)
|
||||
if (!isprint(buf[newlength]) || buf[newlength + 1])
|
||||
break;
|
||||
|
||||
if (newlength > 2) {
|
||||
buf[0] = newlength;
|
||||
*length = newlength;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int usb_string_sub(struct usb_device *dev, unsigned int langid,
|
||||
unsigned int index, unsigned char *buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Try to read the string descriptor by asking for the maximum
|
||||
* possible number of bytes */
|
||||
rc = usb_get_string(dev, langid, index, buf, 255);
|
||||
|
||||
/* If that failed try to read the descriptor length, then
|
||||
* ask for just that many bytes */
|
||||
if (rc < 2) {
|
||||
rc = usb_get_string(dev, langid, index, buf, 2);
|
||||
if (rc == 2)
|
||||
rc = usb_get_string(dev, langid, index, buf, buf[0]);
|
||||
}
|
||||
|
||||
if (rc >= 2) {
|
||||
if (!buf[0] && !buf[1])
|
||||
usb_try_string_workarounds(buf, &rc);
|
||||
|
||||
/* There might be extra junk at the end of the descriptor */
|
||||
if (buf[0] < rc)
|
||||
rc = buf[0];
|
||||
|
||||
rc = rc - (rc & 1); /* force a multiple of two */
|
||||
}
|
||||
|
||||
if (rc < 2)
|
||||
rc = -1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* usb_string:
|
||||
* Get string index and translate it to ascii.
|
||||
|
@ -535,7 +597,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
|
|||
|
||||
/* get langid for strings if it's not yet known */
|
||||
if (!dev->have_langid) {
|
||||
err = usb_get_string(dev, 0, 0, tbuf, 4);
|
||||
err = usb_string_sub(dev, 0, 0, tbuf);
|
||||
if (err < 0) {
|
||||
USB_PRINTF("error getting string descriptor 0 (error=%x)\n",dev->status);
|
||||
return -1;
|
||||
|
@ -550,22 +612,11 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
|
|||
dev->devnum, dev->string_langid);
|
||||
}
|
||||
}
|
||||
/* Just ask for a maximum length string and then take the length
|
||||
* that was returned. */
|
||||
err = usb_get_string(dev, dev->string_langid, index, tbuf, 4);
|
||||
|
||||
err = usb_string_sub(dev, dev->string_langid, index, tbuf);
|
||||
if (err < 0)
|
||||
return err;
|
||||
u=tbuf[0];
|
||||
USB_PRINTF("Strn Len %d, index %d\n",u,index);
|
||||
|
||||
if (u > USB_BUFSIZ) {
|
||||
USB_PRINTF("usb_string: failed to get string - too long: %d\n", u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = usb_get_string(dev, dev->string_langid, index, tbuf, u);
|
||||
if (err < 0)
|
||||
return err;
|
||||
size--; /* leave room for trailing NULL char in output buffer */
|
||||
for (idx = 0, u = 2; u < err; u += 2) {
|
||||
if (idx >= size)
|
||||
|
@ -641,11 +692,66 @@ int usb_new_device(struct usb_device *dev)
|
|||
/* We still haven't set the Address yet */
|
||||
addr = dev->devnum;
|
||||
dev->devnum = 0;
|
||||
|
||||
#undef NEW_INIT_SEQ
|
||||
#ifdef NEW_INIT_SEQ
|
||||
/* this is a Windows scheme of initialization sequence, with double
|
||||
* reset of the device. Some equipment is said to work only with such
|
||||
* init sequence; this patch is based on the work by Alan Stern:
|
||||
* http://sourceforge.net/mailarchive/forum.php?thread_id=5729457&forum_id=5398
|
||||
*/
|
||||
int j;
|
||||
struct usb_device_descriptor *desc;
|
||||
int port = -1;
|
||||
struct usb_device *parent = dev->parent;
|
||||
unsigned short portstatus;
|
||||
|
||||
/* send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is
|
||||
* only 18 bytes long, this will terminate with a short packet. But if
|
||||
* the maxpacket size is 8 or 16 the device may be waiting to transmit
|
||||
* some more. */
|
||||
|
||||
desc = (struct usb_device_descriptor *)tmpbuf;
|
||||
desc->bMaxPacketSize0 = 0;
|
||||
for (j = 0; j < 3; ++j) {
|
||||
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
|
||||
if (err < 0) {
|
||||
USB_PRINTF("usb_new_device: 64 byte descr\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
|
||||
|
||||
/* find the port number we're at */
|
||||
if (parent) {
|
||||
|
||||
for (j = 0; j < parent->maxchild; j++) {
|
||||
if (parent->children[j] == dev) {
|
||||
port = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (port < 0) {
|
||||
printf("usb_new_device: cannot locate device's port..\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* reset the port for the second time */
|
||||
err = hub_port_reset(dev->parent, port, &portstatus);
|
||||
if (err < 0) {
|
||||
printf("\n Couldn't reset port %i\n", port);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* and this is the old and known way of initializing devices */
|
||||
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
|
||||
if (err < 8) {
|
||||
printf("\n USB device not responding, giving up (status=%lX)\n",dev->status);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
|
||||
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
|
||||
switch (dev->descriptor.bMaxPacketSize0) {
|
||||
|
@ -723,7 +829,7 @@ void usb_scan_devices(void)
|
|||
/* device 0 is always present (root hub, so let it analyze) */
|
||||
dev=usb_alloc_new_device();
|
||||
usb_new_device(dev);
|
||||
printf("%d USB Devices found\n",dev_index);
|
||||
printf("%d USB Device(s) found\n",dev_index);
|
||||
/* insert "driver" if possible */
|
||||
#ifdef CONFIG_USB_KEYBOARD
|
||||
drv_usb_kbd_init();
|
||||
|
@ -821,12 +927,62 @@ struct usb_hub_device *usb_hub_allocate(void)
|
|||
|
||||
#define MAX_TRIES 5
|
||||
|
||||
static int hub_port_reset(struct usb_device *dev, int port,
|
||||
unsigned short *portstat)
|
||||
{
|
||||
int tries;
|
||||
struct usb_port_status portsts;
|
||||
unsigned short portstatus, portchange;
|
||||
|
||||
|
||||
USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
|
||||
for(tries=0;tries<MAX_TRIES;tries++) {
|
||||
|
||||
usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
|
||||
wait_ms(200);
|
||||
|
||||
if (usb_get_port_status(dev, port + 1, &portsts)<0) {
|
||||
USB_HUB_PRINTF("get_port_status failed status %lX\n",dev->status);
|
||||
return -1;
|
||||
}
|
||||
portstatus = swap_16(portsts.wPortStatus);
|
||||
portchange = swap_16(portsts.wPortChange);
|
||||
USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus ,portchange,
|
||||
portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
|
||||
USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d USB_PORT_STAT_ENABLE %d\n",
|
||||
(portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
|
||||
(portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
|
||||
(portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);
|
||||
if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
|
||||
!(portstatus & USB_PORT_STAT_CONNECTION))
|
||||
return -1;
|
||||
|
||||
if (portstatus & USB_PORT_STAT_ENABLE) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
wait_ms(200);
|
||||
}
|
||||
|
||||
if (tries==MAX_TRIES) {
|
||||
USB_HUB_PRINTF("Cannot enable port %i after %i retries, disabling port.\n", port+1, MAX_TRIES);
|
||||
USB_HUB_PRINTF("Maybe the USB cable is bad?\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
|
||||
*portstat = portstatus;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void usb_hub_port_connect_change(struct usb_device *dev, int port)
|
||||
{
|
||||
struct usb_device *usb;
|
||||
struct usb_port_status portsts;
|
||||
unsigned short portstatus, portchange;
|
||||
int tries;
|
||||
|
||||
/* Check status */
|
||||
if (usb_get_port_status(dev, port + 1, &portsts)<0) {
|
||||
|
@ -853,41 +1009,11 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
|
|||
wait_ms(200);
|
||||
|
||||
/* Reset the port */
|
||||
|
||||
for(tries=0;tries<MAX_TRIES;tries++) {
|
||||
|
||||
usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
|
||||
wait_ms(200);
|
||||
|
||||
if (usb_get_port_status(dev, port + 1, &portsts)<0) {
|
||||
USB_HUB_PRINTF("get_port_status failed status %lX\n",dev->status);
|
||||
return;
|
||||
}
|
||||
portstatus = swap_16(portsts.wPortStatus);
|
||||
portchange = swap_16(portsts.wPortChange);
|
||||
USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus ,portchange,
|
||||
portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
|
||||
USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d USB_PORT_STAT_ENABLE %d\n",
|
||||
(portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
|
||||
(portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
|
||||
(portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);
|
||||
if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
|
||||
!(portstatus & USB_PORT_STAT_CONNECTION))
|
||||
return;
|
||||
|
||||
if (portstatus & USB_PORT_STAT_ENABLE)
|
||||
break;
|
||||
|
||||
wait_ms(200);
|
||||
}
|
||||
|
||||
if (tries==MAX_TRIES) {
|
||||
USB_HUB_PRINTF("Cannot enable port %i after %i retries, disabling port.\n", port+1, MAX_TRIES);
|
||||
USB_HUB_PRINTF("Maybe the USB cable is bad?\n");
|
||||
if (hub_port_reset(dev, port, &portstatus) < 0) {
|
||||
printf("cannot reset port %i!?\n", port + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
|
||||
wait_ms(200);
|
||||
|
||||
/* Allocate a new device struct for it */
|
||||
|
|
|
@ -121,7 +121,7 @@ typedef struct {
|
|||
#define UMASS_BBB_CSW_SIZE 13
|
||||
|
||||
#define USB_MAX_STOR_DEV 5
|
||||
static int usb_max_devs; /* number of highest available usb device */
|
||||
static int usb_max_devs = 0; /* number of highest available usb device */
|
||||
|
||||
static block_dev_desc_t usb_dev_desc[USB_MAX_STOR_DEV];
|
||||
|
||||
|
@ -177,7 +177,24 @@ void usb_show_progress(void)
|
|||
}
|
||||
|
||||
/*********************************************************************************
|
||||
* (re)-scan the usb and reports device info
|
||||
* show info on storage devices; 'usb start/init' must be invoked earlier
|
||||
* as we only retrieve structures populated during devices initialization
|
||||
*/
|
||||
void usb_stor_info(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (usb_max_devs > 0)
|
||||
for (i = 0; i < usb_max_devs; i++) {
|
||||
printf (" Device %d: ", i);
|
||||
dev_print(&usb_dev_desc[i]);
|
||||
}
|
||||
else
|
||||
printf("No storage devices, perhaps not 'usb start'ed..?\n");
|
||||
}
|
||||
|
||||
/*********************************************************************************
|
||||
* scan the usb and reports device info
|
||||
* to the user if mode = 1
|
||||
* returns current device or -1 if no
|
||||
*/
|
||||
|
@ -190,7 +207,7 @@ int usb_stor_scan(int mode)
|
|||
memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
|
||||
|
||||
if(mode==1) {
|
||||
printf(" scanning bus for storage devices...\n");
|
||||
printf(" scanning bus for storage devices... ");
|
||||
}
|
||||
usb_disable_asynch(1); /* asynch transfer not allowed */
|
||||
|
||||
|
@ -202,6 +219,7 @@ int usb_stor_scan(int mode)
|
|||
usb_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
|
||||
usb_dev_desc[i].block_read=usb_stor_read;
|
||||
}
|
||||
|
||||
usb_max_devs=0;
|
||||
for(i=0;i<USB_MAX_DEVICE;i++) {
|
||||
dev=usb_get_dev_index(i); /* get device */
|
||||
|
@ -211,21 +229,17 @@ int usb_stor_scan(int mode)
|
|||
}
|
||||
if(usb_storage_probe(dev,0,&usb_stor[usb_max_devs])) { /* ok, it is a storage devices */
|
||||
/* get info and fill it in */
|
||||
|
||||
if(usb_stor_get_info(dev, &usb_stor[usb_max_devs], &usb_dev_desc[usb_max_devs])) {
|
||||
if(mode==1) {
|
||||
printf (" Device %d: ", usb_max_devs);
|
||||
dev_print(&usb_dev_desc[usb_max_devs]);
|
||||
} /* if mode */
|
||||
if(usb_stor_get_info(dev, &usb_stor[usb_max_devs], &usb_dev_desc[usb_max_devs]))
|
||||
usb_max_devs++;
|
||||
} /* if get info ok */
|
||||
} /* if storage device */
|
||||
if(usb_max_devs==USB_MAX_STOR_DEV) {
|
||||
printf("max USB Storage Device reached: %d stopping\n",usb_max_devs);
|
||||
break;
|
||||
}
|
||||
} /* for */
|
||||
|
||||
usb_disable_asynch(0); /* asynch transfer allowed */
|
||||
printf("%d Storage Device(s) found\n", usb_max_devs);
|
||||
if(usb_max_devs>0)
|
||||
return 0;
|
||||
else
|
||||
|
@ -367,11 +381,13 @@ static int usb_stor_BBB_reset(struct us_data *us)
|
|||
result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
|
||||
US_BBB_RESET, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
||||
0, us->ifnum, 0, 0, USB_CNTL_TIMEOUT*5);
|
||||
|
||||
if((result < 0) && (us->pusb_dev->status & USB_ST_STALLED))
|
||||
{
|
||||
USB_STOR_PRINTF("RESET:stall\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* long wait for reset */
|
||||
wait_ms(150);
|
||||
USB_STOR_PRINTF("BBB_reset result %d: status %X reset\n",result,us->pusb_dev->status);
|
||||
|
@ -640,7 +656,9 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
|
|||
retry = 0;
|
||||
again:
|
||||
USB_STOR_PRINTF("STATUS phase\n");
|
||||
result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE, &actlen, USB_CNTL_TIMEOUT*5);
|
||||
result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
|
||||
&actlen, USB_CNTL_TIMEOUT*5);
|
||||
|
||||
/* special handling of STALL in STATUS phase */
|
||||
if((result < 0) && (retry < 1) && (us->pusb_dev->status & USB_ST_STALLED)) {
|
||||
USB_STOR_PRINTF("STATUS:stall\n");
|
||||
|
@ -797,7 +815,7 @@ do_retry:
|
|||
static int usb_inquiry(ccb *srb,struct us_data *ss)
|
||||
{
|
||||
int retry,i;
|
||||
retry=3;
|
||||
retry=5;
|
||||
do {
|
||||
memset(&srb->cmd[0],0,12);
|
||||
srb->cmd[0]=SCSI_INQUIRY;
|
||||
|
@ -838,7 +856,7 @@ static int usb_request_sense(ccb *srb,struct us_data *ss)
|
|||
|
||||
static int usb_test_unit_ready(ccb *srb,struct us_data *ss)
|
||||
{
|
||||
int retries=10;
|
||||
int retries = 10;
|
||||
|
||||
do {
|
||||
memset(&srb->cmd[0],0,12);
|
||||
|
@ -859,7 +877,7 @@ static int usb_test_unit_ready(ccb *srb,struct us_data *ss)
|
|||
static int usb_read_capacity(ccb *srb,struct us_data *ss)
|
||||
{
|
||||
int retry;
|
||||
retry=2; /* retries */
|
||||
retry = 3; /* retries */
|
||||
do {
|
||||
memset(&srb->cmd[0],0,12);
|
||||
srb->cmd[0]=SCSI_RD_CAPAC;
|
||||
|
@ -972,9 +990,6 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data
|
|||
int protocol = 0;
|
||||
int subclass = 0;
|
||||
|
||||
|
||||
memset(ss, 0, sizeof(struct us_data));
|
||||
|
||||
/* let's examine the device now */
|
||||
iface = &dev->config.if_desc[ifnum];
|
||||
|
||||
|
@ -996,6 +1011,8 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data
|
|||
return 0;
|
||||
}
|
||||
|
||||
memset(ss, 0, sizeof(struct us_data));
|
||||
|
||||
/* At this point, we know we've got a live one */
|
||||
USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n");
|
||||
|
||||
|
@ -1103,50 +1120,62 @@ int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t
|
|||
unsigned char perq,modi;
|
||||
unsigned long cap[2];
|
||||
unsigned long *capacity,*blksz;
|
||||
ccb *pccb=&usb_ccb;
|
||||
ccb *pccb = &usb_ccb;
|
||||
|
||||
/* For some mysterious reason the 256MB flash disk of Ours Technology, Inc
|
||||
* doesn't survive this reset */
|
||||
if (dev->descriptor.idVendor != 0xea0 || dev->descriptor.idProduct != 0x6828)
|
||||
/* for some reasons a couple of devices would not survive this reset */
|
||||
if (
|
||||
/* Sony USM256E */
|
||||
(dev->descriptor.idVendor == 0x054c &&
|
||||
dev->descriptor.idProduct == 0x019e)
|
||||
|
||||
||
|
||||
/* USB007 Mini-USB2 Flash Drive */
|
||||
(dev->descriptor.idVendor == 0x066f &&
|
||||
dev->descriptor.idProduct == 0x2010)
|
||||
)
|
||||
USB_STOR_PRINTF("usb_stor_get_info: skipping RESET..\n");
|
||||
else
|
||||
ss->transport_reset(ss);
|
||||
pccb->pdata=usb_stor_buf;
|
||||
|
||||
dev_desc->target=dev->devnum;
|
||||
pccb->lun=dev_desc->lun;
|
||||
pccb->pdata = usb_stor_buf;
|
||||
|
||||
dev_desc->target = dev->devnum;
|
||||
pccb->lun = dev_desc->lun;
|
||||
USB_STOR_PRINTF(" address %d\n",dev_desc->target);
|
||||
|
||||
if(usb_inquiry(pccb,ss))
|
||||
return -1;
|
||||
perq=usb_stor_buf[0];
|
||||
modi=usb_stor_buf[1];
|
||||
if((perq & 0x1f)==0x1f) {
|
||||
|
||||
perq = usb_stor_buf[0];
|
||||
modi = usb_stor_buf[1];
|
||||
if((perq & 0x1f) == 0x1f) {
|
||||
return 0; /* skip unknown devices */
|
||||
}
|
||||
if((modi&0x80)==0x80) {/* drive is removable */
|
||||
dev_desc->removable=1;
|
||||
if((modi&0x80) == 0x80) {/* drive is removable */
|
||||
dev_desc->removable = 1;
|
||||
}
|
||||
memcpy(&dev_desc->vendor[0], &usb_stor_buf[8], 8);
|
||||
memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
|
||||
memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
|
||||
dev_desc->vendor[8]=0;
|
||||
dev_desc->product[16]=0;
|
||||
dev_desc->revision[4]=0;
|
||||
dev_desc->vendor[8] = 0;
|
||||
dev_desc->product[16] = 0;
|
||||
dev_desc->revision[4] = 0;
|
||||
USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n",usb_stor_buf[2],usb_stor_buf[3]);
|
||||
if(usb_test_unit_ready(pccb,ss)) {
|
||||
printf("Device NOT ready\n Request Sense returned %02X %02X %02X\n",pccb->sense_buf[2],pccb->sense_buf[12],pccb->sense_buf[13]);
|
||||
if(dev_desc->removable==1) {
|
||||
dev_desc->type=perq;
|
||||
if(dev_desc->removable == 1) {
|
||||
dev_desc->type = perq;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
pccb->pdata=(unsigned char *)&cap[0];
|
||||
pccb->pdata = (unsigned char *)&cap[0];
|
||||
memset(pccb->pdata,0,8);
|
||||
if(usb_read_capacity(pccb,ss)!=0) {
|
||||
if(usb_read_capacity(pccb,ss) != 0) {
|
||||
printf("READ_CAP ERROR\n");
|
||||
cap[0]=2880;
|
||||
cap[1]=0x200;
|
||||
cap[0] = 2880;
|
||||
cap[1] = 0x200;
|
||||
}
|
||||
USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n",cap[0],cap[1]);
|
||||
#if 0
|
||||
|
@ -1166,13 +1195,13 @@ int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t
|
|||
(((unsigned long)(cap[1]) & (unsigned long)0xff000000UL) >> 24) ));
|
||||
#endif
|
||||
/* this assumes bigendian! */
|
||||
cap[0]+=1;
|
||||
capacity=&cap[0];
|
||||
blksz=&cap[1];
|
||||
cap[0] += 1;
|
||||
capacity = &cap[0];
|
||||
blksz = &cap[1];
|
||||
USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n",*capacity,*blksz);
|
||||
dev_desc->lba=*capacity;
|
||||
dev_desc->blksz=*blksz;
|
||||
dev_desc->type=perq;
|
||||
dev_desc->lba = *capacity;
|
||||
dev_desc->blksz = *blksz;
|
||||
dev_desc->type = perq;
|
||||
USB_STOR_PRINTF(" address %d\n",dev_desc->target);
|
||||
USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);
|
||||
|
||||
|
|
|
@ -94,6 +94,8 @@ urb_priv_t urb_priv;
|
|||
int got_rhsc;
|
||||
/* device which was disconnected */
|
||||
struct usb_device *devgone;
|
||||
/* flag guarding URB transation */
|
||||
int urb_finished = 0;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -398,6 +400,16 @@ int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* if we have an unfinished URB from previous transaction let's
|
||||
* fail and scream as quickly as possible so as not to corrupt
|
||||
* further communication */
|
||||
if (!urb_finished) {
|
||||
err("sohci_submit_job: URB NOT FINISHED");
|
||||
return -1;
|
||||
}
|
||||
/* we're about to begin a new transaction here so mark the URB unfinished */
|
||||
urb_finished = 0;
|
||||
|
||||
/* every endpoint has a ed, locate and fill it */
|
||||
if (!(ed = ep_add_ed (dev, pipe))) {
|
||||
err("sohci_submit_job: ENOMEM");
|
||||
|
@ -658,7 +670,6 @@ static void td_fill (ohci_t *ohci, unsigned int info,
|
|||
else
|
||||
td->hwBE = 0;
|
||||
td->hwNextTD = m32_swap (td_pt);
|
||||
td->hwPSW [0] = m16_swap (((__u32)data & 0x0FFF) | 0xE000);
|
||||
|
||||
/* append to queue */
|
||||
td->ed->hwTailP = td->hwNextTD;
|
||||
|
@ -793,6 +804,7 @@ static td_t * dl_reverse_done_list (ohci_t *ohci)
|
|||
td_rev = td_list;
|
||||
td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0;
|
||||
}
|
||||
|
||||
return td_list;
|
||||
}
|
||||
|
||||
|
@ -826,6 +838,17 @@ static int dl_done_list (ohci_t *ohci, td_t *td_list)
|
|||
stat = cc_to_error[cc];
|
||||
}
|
||||
|
||||
/* see if this done list makes for all TD's of current URB,
|
||||
* and mark the URB finished if so */
|
||||
if (++(lurb_priv->td_cnt) == lurb_priv->length) {
|
||||
if ((ed->state & (ED_OPER | ED_UNLINK)))
|
||||
urb_finished = 1;
|
||||
else
|
||||
dbg("dl_done_list: strange.., ED state %x, ed->state\n");
|
||||
} else
|
||||
dbg("dl_done_list: processing TD %x, len %x\n", lurb_priv->td_cnt,
|
||||
lurb_priv->length);
|
||||
|
||||
if (ed->state != ED_NEW) {
|
||||
edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
|
||||
edTailP = m32_swap (ed->hwTailP);
|
||||
|
@ -1197,6 +1220,8 @@ pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
|
|||
return stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* common code for handling submit messages - used for all but root hub */
|
||||
|
@ -1245,22 +1270,41 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
for (;;) {
|
||||
/* check whether the controller is done */
|
||||
stat = hc_interrupt();
|
||||
|
||||
if (stat < 0) {
|
||||
stat = USB_ST_CRC_ERR;
|
||||
break;
|
||||
}
|
||||
if (stat >= 0 && stat != 0xff) {
|
||||
|
||||
/* NOTE: since we are not interrupt driven in U-Boot and always
|
||||
* handle only one URB at a time, we cannot assume the
|
||||
* transaction finished on the first successful return from
|
||||
* hc_interrupt().. unless the flag for current URB is set,
|
||||
* meaning that all TD's to/from device got actually
|
||||
* transferred and processed. If the current URB is not
|
||||
* finished we need to re-iterate this loop so as
|
||||
* hc_interrupt() gets called again as there needs to be some
|
||||
* more TD's to process still */
|
||||
if ((stat >= 0) && (stat != 0xff) && (urb_finished)) {
|
||||
/* 0xff is returned for an SF-interrupt */
|
||||
break;
|
||||
}
|
||||
|
||||
if (--timeout) {
|
||||
wait_ms(1);
|
||||
if (!urb_finished)
|
||||
dbg("\%");
|
||||
|
||||
} else {
|
||||
err("CTL:TIMEOUT ");
|
||||
dbg("submit_common_msg: TO status %x\n", stat);
|
||||
stat = USB_ST_CRC_ERR;
|
||||
urb_finished = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* we got an Root Hub Status Change interrupt */
|
||||
if (got_rhsc) {
|
||||
#ifdef DEBUG
|
||||
|
@ -1282,6 +1326,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
devgone = dev;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
dev->status = stat;
|
||||
dev->act_len = transfer_len;
|
||||
|
@ -1457,16 +1502,26 @@ hc_interrupt (void)
|
|||
int ints;
|
||||
int stat = -1;
|
||||
|
||||
if ((ohci->hcca->done_head != 0) && !(m32_swap (ohci->hcca->done_head) & 0x01)) {
|
||||
if ((ohci->hcca->done_head != 0) &&
|
||||
!(m32_swap (ohci->hcca->done_head) & 0x01)) {
|
||||
|
||||
ints = OHCI_INTR_WDH;
|
||||
} else {
|
||||
ints = readl (®s->intrstatus);
|
||||
|
||||
} else if ((ints = readl (®s->intrstatus)) == ~(u32)0) {
|
||||
ohci->disabled++;
|
||||
err ("%s device removed!", ohci->slot_name);
|
||||
return -1;
|
||||
|
||||
} else if ((ints &= readl (®s->intrenable)) == 0) {
|
||||
dbg("hc_interrupt: returning..\n");
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
|
||||
|
||||
if (ints & OHCI_INTR_RHSC) {
|
||||
got_rhsc = 1;
|
||||
stat = 0xff;
|
||||
}
|
||||
|
||||
if (ints & OHCI_INTR_UE) {
|
||||
|
@ -1490,6 +1545,7 @@ hc_interrupt (void)
|
|||
|
||||
if (ints & OHCI_INTR_WDH) {
|
||||
wait_ms(1);
|
||||
|
||||
writel (OHCI_INTR_WDH, ®s->intrdisable);
|
||||
stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
|
||||
writel (OHCI_INTR_WDH, ®s->intrenable);
|
||||
|
@ -1610,6 +1666,8 @@ int usb_lowlevel_init(void)
|
|||
wait_ms(1);
|
||||
#endif
|
||||
ohci_inited = 1;
|
||||
urb_finished = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ static int cc_to_error[16] = {
|
|||
};
|
||||
|
||||
/* ED States */
|
||||
|
||||
#define ED_NEW 0x00
|
||||
#define ED_UNLINK 0x01
|
||||
#define ED_OPER 0x02
|
||||
|
@ -104,7 +103,6 @@ struct td {
|
|||
__u32 hwNextTD; /* Next TD Pointer */
|
||||
__u32 hwBE; /* Memory Buffer End Pointer */
|
||||
|
||||
__u16 hwPSW[MAXPSW];
|
||||
__u8 unused;
|
||||
__u8 index;
|
||||
struct ed *ed;
|
||||
|
|
|
@ -98,6 +98,8 @@ urb_priv_t urb_priv;
|
|||
int got_rhsc;
|
||||
/* device which was disconnected */
|
||||
struct usb_device *devgone;
|
||||
/* flag guarding URB transation */
|
||||
int urb_finished = 0;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -402,6 +404,16 @@ int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* if we have an unfinished URB from previous transaction let's
|
||||
* fail and scream as quickly as possible so as not to corrupt
|
||||
* further communication */
|
||||
if (!urb_finished) {
|
||||
err("sohci_submit_job: URB NOT FINISHED");
|
||||
return -1;
|
||||
}
|
||||
/* we're about to begin a new transaction here so mark the URB unfinished */
|
||||
urb_finished = 0;
|
||||
|
||||
/* every endpoint has a ed, locate and fill it */
|
||||
if (!(ed = ep_add_ed (dev, pipe))) {
|
||||
err("sohci_submit_job: ENOMEM");
|
||||
|
@ -664,7 +676,6 @@ static void td_fill (ohci_t *ohci, unsigned int info,
|
|||
else
|
||||
td->hwBE = 0;
|
||||
td->hwNextTD = ohci_cpu_to_le32 ((unsigned long)td_pt);
|
||||
td->hwPSW [0] = ohci_cpu_to_le16 (((__u32)data & 0x0FFF) | 0xE000);
|
||||
|
||||
/* append to queue */
|
||||
td->ed->hwTailP = td->hwNextTD;
|
||||
|
@ -673,7 +684,6 @@ static void td_fill (ohci_t *ohci, unsigned int info,
|
|||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* prepare all TDs of a transfer */
|
||||
|
||||
static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer,
|
||||
int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval)
|
||||
{
|
||||
|
@ -813,7 +823,7 @@ static int dl_done_list (ohci_t *ohci, td_t *td_list)
|
|||
td_t *td_list_next = NULL;
|
||||
ed_t *ed;
|
||||
int cc = 0;
|
||||
int stat = 0xff;
|
||||
int stat = 0;
|
||||
/* urb_t *urb; */
|
||||
urb_priv_t *lurb_priv;
|
||||
__u32 tdINFO, edHeadP, edTailP;
|
||||
|
@ -835,6 +845,7 @@ static int dl_done_list (ohci_t *ohci, td_t *td_list)
|
|||
&& (lurb_priv->state != URB_DEL)) {
|
||||
dbg("ConditionCode %#x", cc);
|
||||
stat = cc_to_error[cc];
|
||||
urb_finished = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1250,18 +1261,35 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
stat = USB_ST_CRC_ERR;
|
||||
break;
|
||||
}
|
||||
if (stat >= 0 && stat < 0xff) {
|
||||
|
||||
/* NOTE: since we are not interrupt driven in U-Boot and always
|
||||
* handle only one URB at a time, we cannot assume the
|
||||
* transaction finished on the first successful return from
|
||||
* hc_interrupt().. unless the flag for current URB is set,
|
||||
* meaning that all TD's to/from device got actually
|
||||
* transferred and processed. If the current URB is not
|
||||
* finished we need to re-iterate this loop so as
|
||||
* hc_interrupt() gets called again as there needs to be some
|
||||
* more TD's to process still */
|
||||
if ((stat >= 0) && (stat != 0xff) && (urb_finished)) {
|
||||
/* 0xff is returned for an SF-interrupt */
|
||||
break;
|
||||
}
|
||||
|
||||
if (--timeout) {
|
||||
wait_ms(1);
|
||||
if (!urb_finished)
|
||||
dbg("\%");
|
||||
|
||||
} else {
|
||||
err("CTL:TIMEOUT ");
|
||||
dbg("submit_common_msg: TO status %x\n", stat);
|
||||
stat = USB_ST_CRC_ERR;
|
||||
urb_finished = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* we got an Root Hub Status Change interrupt */
|
||||
if (got_rhsc) {
|
||||
#ifdef DEBUG
|
||||
|
@ -1283,6 +1311,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
devgone = dev;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
dev->status = stat;
|
||||
dev->act_len = transfer_len;
|
||||
|
@ -1454,17 +1483,27 @@ hc_interrupt (void)
|
|||
struct ohci_regs *regs = ohci->regs;
|
||||
int ints;
|
||||
int stat = -1;
|
||||
|
||||
if ((ohci->hcca->done_head != 0) &&
|
||||
!(ohci_cpu_to_le32(ohci->hcca->done_head) & 0x01)) {
|
||||
|
||||
if ((ohci->hcca->done_head != 0) && !(ohci_cpu_to_le32 (ohci->hcca->done_head) & 0x01)) {
|
||||
ints = OHCI_INTR_WDH;
|
||||
} else {
|
||||
ints = readl (®s->intrstatus);
|
||||
ints = OHCI_INTR_WDH;
|
||||
|
||||
} else if ((ints = readl (®s->intrstatus)) == ~(u32)0) {
|
||||
ohci->disabled++;
|
||||
err ("%s device removed!", ohci->slot_name);
|
||||
return -1;
|
||||
|
||||
} else if ((ints &= readl (®s->intrenable)) == 0) {
|
||||
dbg("hc_interrupt: returning..\n");
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
|
||||
|
||||
if (ints & OHCI_INTR_RHSC) {
|
||||
got_rhsc = 1;
|
||||
stat = 0xff;
|
||||
}
|
||||
|
||||
if (ints & OHCI_INTR_UE) {
|
||||
|
@ -1499,6 +1538,7 @@ hc_interrupt (void)
|
|||
/* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
|
||||
if (ints & OHCI_INTR_SF) {
|
||||
unsigned int frame = ohci_cpu_to_le16 (ohci->hcca->frame_no) & 1;
|
||||
wait_ms(1);
|
||||
writel (OHCI_INTR_SF, ®s->intrdisable);
|
||||
if (ohci->ed_rm_list[frame] != NULL)
|
||||
writel (OHCI_INTR_SF, ®s->intrenable);
|
||||
|
@ -1589,6 +1629,8 @@ int usb_lowlevel_init(void)
|
|||
ohci_dump (&gohci, 1);
|
||||
#endif
|
||||
ohci_inited = 1;
|
||||
urb_finished = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,6 @@ struct td {
|
|||
__u32 hwNextTD; /* Next TD Pointer */
|
||||
__u32 hwBE; /* Memory Buffer End Pointer */
|
||||
|
||||
__u16 hwPSW[MAXPSW];
|
||||
__u8 unused;
|
||||
__u8 index;
|
||||
struct ed *ed;
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
#define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
|
||||
|
||||
|
||||
/* String descriptor */
|
||||
struct usb_string_descriptor {
|
||||
unsigned char bLength;
|
||||
|
@ -191,6 +190,7 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||
#define USB_MAX_STOR_DEV 5
|
||||
block_dev_desc_t *usb_stor_get_dev(int index);
|
||||
int usb_stor_scan(int mode);
|
||||
void usb_stor_info(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -26,20 +26,6 @@
|
|||
#ifndef _USB_DEFS_H_
|
||||
#define _USB_DEFS_H_
|
||||
|
||||
|
||||
/* Everything is aribtrary */
|
||||
#define USB_ALTSETTINGALLOC 4
|
||||
#define USB_MAXALTSETTING 128 /* Hard limit */
|
||||
|
||||
#define USB_MAX_DEVICE 32
|
||||
#define USB_MAXCONFIG 8
|
||||
#define USB_MAXINTERFACES 8
|
||||
#define USB_MAXENDPOINTS 16
|
||||
#define USB_MAXCHILDREN 8 /* This is arbitrary */
|
||||
#define USB_MAX_HUB 16
|
||||
|
||||
#define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
|
||||
|
||||
/* USB constants */
|
||||
|
||||
/* Device and/or Interface Class codes */
|
||||
|
|
Loading…
Reference in a new issue