From 904d0fff2f350e94668043c0de413c4500b33809 Mon Sep 17 00:00:00 2001 From: Dobrica Pavlinusic Date: Mon, 14 May 2007 00:13:48 -0500 Subject: [PATCH] special usb hub handling, IDE disks, and retries all over the place --- drivers/usb/hcd.c | 4 +- drivers/usb/hub.c | 18 ++++++++- drivers/usb/storage/scsiglue.c | 6 +++ drivers/usb/storage/usb.h | 1 + drivers/usb/usb.c | 73 +++++++++++++++++++++++++++++++++- include/linux/usb.h | 5 +++ 6 files changed, 103 insertions(+), 4 deletions(-) diff --git a/drivers/usb/hcd.c b/drivers/usb/hcd.c index 8163ba4..e8290ce 100644 --- a/drivers/usb/hcd.c +++ b/drivers/usb/hcd.c @@ -671,7 +671,9 @@ clean_2: #else bufp = __irq_itoa(dev->irq); #endif - if (request_irq (dev->irq, hcd_irq, SA_SHIRQ, hcd->description, hcd) + //+Wilson 10/14/2003 + //if (request_irq (dev->irq, hcd_irq, SA_SHIRQ, hcd->description, hcd) + if (request_irq (dev->irq, hcd_irq, SA_INTERRUPT, hcd->description, hcd) != 0) { err ("request interrupt %s failed", bufp); retval = -EBUSY; diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c index 3a87b01..08a212d 100644 --- a/drivers/usb/hub.c +++ b/drivers/usb/hub.c @@ -41,6 +41,15 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); static pid_t khubd_pid = 0; /* PID of khubd */ static DECLARE_COMPLETION(khubd_exited); +//+Wilson12032003 +extern void led_status(int); +//int HubFlag = 0; +#define LED_OFF 0 +#define LED_GREEN 1 +#define LED_RED 2 +#define LED_HUB 3 +//Wilson12032003+ + #ifdef DEBUG static inline char *portspeed (int portstatus) { @@ -179,6 +188,12 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor dev->maxchild = hub->descriptor->bNbrPorts; info("%d port%s detected", hub->descriptor->bNbrPorts, (hub->descriptor->bNbrPorts == 1) ? "" : "s"); + //+Wilson12032003 + /* Indicates that a usb hub is being detected, so the LED_RED of the led status is invalid now */ + //led_status(LED_HUB); + dev->HubFlag = 1; + //Wilson12032003+ + le16_to_cpus(&hub->descriptor->wHubCharacteristics); if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND) @@ -827,7 +842,8 @@ static void usb_hub_events(void) hub->error = 0; } - for (i = 0; i < hub->descriptor->bNbrPorts; i++) { + //for (i = 0; i < hub->descriptor->bNbrPorts; i++) { //+Wilson04272004 + for (i = (hub->descriptor->bNbrPorts - 1); i >= 0; i--) { //+Wilson04272004, Reversed the get port sequence ret = usb_hub_port_status(dev, i, &portstatus, &portchange); if (ret < 0) { continue; diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 713f7d7..d839b95 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -95,6 +95,12 @@ static int detect(struct SHT *sht) if (us->host) { us->host->hostdata[0] = (unsigned long)us; us->host_no = us->host->host_no; + //+Wilson05112005, Indicate clearly of IDE HDD existence + if(us->ide == 0) + us->host->ide_hdd = 0; //No IDE HDD + else + us->host->ide_hdd = 1; //IDE HDD exist + //Wilson05112005+ return 1; } diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 0cf9005..2c1dcff 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -181,6 +181,7 @@ struct us_data { struct us_unusual_dev *unusual_dev; /* If unusual device */ void *extra; /* Any extra data */ extra_data_destructor extra_destructor;/* extra data destructor */ + unsigned int ide; //+Wilson05112005, ide hdd exist }; /* The list of structures and the protective lock for them */ diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index 695db60..cfca8fd 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -31,6 +31,23 @@ #include #include +//+Wilson10292003 +#undef DBG +//Wilson10292003+ + +//+Wilson12032003 +extern void led_status(int); +//extern int HubFlag; +#define LED_OFF 0 +#define LED_GREEN 1 +#define LED_RED 2 +#define LED_HUB 3 +//Wilson12032003+ + +//+Wilson12192003 +//extern int ScsiOk; +//Wilson12192003+ + #ifdef CONFIG_USB_DEBUG #define DEBUG #else @@ -812,7 +829,10 @@ int usb_find_interface_driver_for_ifnum(struct usb_device *dev, unsigned ifnum) */ static void call_policy_interface (char *verb, struct usb_device *dev, int interface) { - char *argv [3], **envp, *buf, *scratch; + //+Wilson11132003 + //char *argv [3], **envp, *buf, *scratch; + char *argv[5], **envp, *buf, *scratch; + //Wilson11132003+ int i = 0, value; if (!hotplug_path [0]) @@ -843,7 +863,23 @@ static void call_policy_interface (char *verb, struct usb_device *dev, int inter /* only one standardized param to hotplug command: type */ argv [0] = hotplug_path; argv [1] = "usb"; - argv [2] = 0; + //argv [2] = 0; //+Wilson10282003 + argv[2] = verb; //+Wilson10282003 + argv[3] = 0; //+Wilson11132003 + + //+Wilson11072003 + #if 01 + if((dev->devnum == 1) || (dev->HubFlag == 1)) //+Wilson12032003 + { + argv[3] = "host_hub"; + dev->HubFlag = 0; //+Wilson12032003 + } + else + argv[3] = 0; + + argv[4] = 0; + #endif + //Wilson11072003+ /* minimal command environment */ envp [i++] = "HOME=/"; @@ -901,6 +937,31 @@ static void call_policy_interface (char *verb, struct usb_device *dev, int inter envp [i++] = 0; /* assert: (scratch - buf) < sizeof buf */ + //+Wilson12192003 + #if 0 + do { + if(dev->HubFlag == 1) + { + printk("HubFlag = %d ",dev->HubFlag); + dev->HubFlag = 0; + break; + } + + if(dev->ScsiMount == 1 || dev->ScsiUmount == 1) + { + printk("ScsiMount = %d ScsiUmount = %d ",dev->ScsiMount, dev->ScsiUmount); + dev->ScsiMount = 0; + dev->ScsiUmount = 0; + break; + } + wait_ms(10); + retries--; + } while(retries); + printk(" retries = %d\n",retries); + #endif + //Wilson12192003+ + + /* NOTE: user mode daemons can call the agents too */ dbg ("kusbd: %s %s %d", argv [0], verb, dev->devnum); @@ -2232,6 +2293,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) int usb_new_device(struct usb_device *dev) { int err; + int retries = 3; //+Wilson02192004 /* USB v1.1 5.5.3 */ /* We read the first 8 bytes from the device descriptor to get to */ @@ -2240,7 +2302,14 @@ int usb_new_device(struct usb_device *dev) dev->epmaxpacketin [0] = 8; dev->epmaxpacketout[0] = 8; + //call_policy("failure", dev); //+Wilson11042003 + wait_ms(10); //+Wilson03172004, due to some flash drives failed to work + + do { //+Wilson 10/16/2003 err = usb_set_address(dev); + retries--; //+Wilson02192004 + } while((err<0) && retries); //+Wilson 10/16/2003 + if (err < 0) { err("USB device not accepting new address=%d (error=%d)", dev->devnum, err); diff --git a/include/linux/usb.h b/include/linux/usb.h index 52ea639..5a9fd78 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -876,6 +876,11 @@ struct usb_device { int maxchild; /* Number of ports if hub */ struct usb_device *children[USB_MAXCHILDREN]; + //+Wilson12192003 + int HubFlag; /* Device is a hub??? */ + //int ScsiMount; /* /proc/scsi/scsi is ok & Scsi device is plugged-in */ + //int ScsiUmount; /* Scsi device is unplugged */ + //Wilson12192003+ }; extern int usb_ifnum_to_ifpos(struct usb_device *dev, unsigned ifnum); -- 2.20.1