From 6f5794a6f78b313231256958fd73673c6aacc116 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Tue, 16 Sep 2008 14:55:43 +0200 Subject: [PATCH] Refactoring parts of the common USB OHCI code This patch refactors some large routines of the USB OHCI code by making some routines smaller and more readable which helps debugging and understanding the code. (Makes the code looks somewhat more like the Linux implementation.) Also made entire file compliant to Linux Coding Rules (checkpatch.pl compliant) Signed-off-by: Remy Bohmer Signed-off-by: Markus Klotzbuecher --- common/usb.c | 542 +++++++++++++---------- drivers/usb/usb_ohci.c | 972 ++++++++++++++++++++++------------------- drivers/usb/usb_ohci.h | 35 ++ 3 files changed, 862 insertions(+), 687 deletions(-) diff --git a/common/usb.c b/common/usb.c index 4d64ccb438..be81aaf0bd 100644 --- a/common/usb.c +++ b/common/usb.c @@ -58,9 +58,9 @@ #undef USB_DEBUG #ifdef USB_DEBUG -#define USB_PRINTF(fmt,args...) printf (fmt ,##args) +#define USB_PRINTF(fmt, args...) printf (fmt , ##args) #else -#define USB_PRINTF(fmt,args...) +#define USB_PRINTF(fmt, args...) #endif #define USB_BUFSIZ 512 @@ -88,7 +88,7 @@ void usb_hub_reset(void); void __inline__ wait_ms(unsigned long ms) { - while(ms-->0) + while (ms-- > 0) udelay(1000); } /*************************************************************************** @@ -99,22 +99,22 @@ int usb_init(void) { int result; - running=0; - dev_index=0; - asynch_allowed=1; + running = 0; + dev_index = 0; + asynch_allowed = 1; usb_hub_reset(); /* init low_level USB */ printf("USB: "); result = usb_lowlevel_init(); - /* if lowlevel init is OK, scan the bus for devices i.e. search HUBs and configure them */ - if(result==0) { + /* if lowlevel init is OK, scan the bus for devices + * i.e. search HUBs and configure them */ + if (result == 0) { printf("scanning bus for devices... "); - running=1; + running = 1; usb_scan_devices(); usb_started = 1; return 0; - } - else { + } else { printf("Error, couldn't init Lowlevel part\n"); usb_started = 0; return -1; @@ -143,7 +143,7 @@ int usb_stop(void) */ void usb_disable_asynch(int disable) { - asynch_allowed=!disable; + asynch_allowed = !disable; } @@ -156,9 +156,9 @@ void usb_disable_asynch(int disable) * submits an Interrupt Message */ int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, - void *buffer,int transfer_len, int interval) + void *buffer, int transfer_len, int interval) { - return submit_int_msg(dev,pipe,buffer,transfer_len,interval); + return submit_int_msg(dev, pipe, buffer, transfer_len, interval); } /* @@ -175,8 +175,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned short value, unsigned short index, void *data, unsigned short size, int timeout) { - if((timeout==0)&&(!asynch_allowed)) /* request for a asynch control pipe is not allowed */ + if ((timeout == 0) && (!asynch_allowed)) { + /* request for a asynch control pipe is not allowed */ return -1; + } /* set setup command */ setup_packet.requesttype = requesttype; @@ -184,24 +186,24 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, setup_packet.value = cpu_to_le16(value); setup_packet.index = cpu_to_le16(index); setup_packet.length = cpu_to_le16(size); - USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, value 0x%X index 0x%X length 0x%X\n", - request,requesttype,value,index,size); - dev->status=USB_ST_NOT_PROC; /*not yet processed */ + USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ + "value 0x%X index 0x%X length 0x%X\n", + request, requesttype, value, index, size); + dev->status = USB_ST_NOT_PROC; /*not yet processed */ - submit_control_msg(dev,pipe,data,size,&setup_packet); - if(timeout==0) { + submit_control_msg(dev, pipe, data, size, &setup_packet); + if (timeout == 0) return (int)size; - } - while(timeout--) { - if(!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) + + while (timeout--) { + if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) break; wait_ms(1); } - if(dev->status==0) + if (dev->status == 0) return dev->act_len; - else { + else return -1; - } } /*------------------------------------------------------------------- @@ -214,15 +216,15 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, { if (len < 0) return -1; - dev->status=USB_ST_NOT_PROC; /*not yet processed */ - submit_bulk_msg(dev,pipe,data,len); - while(timeout--) { - if(!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) + dev->status = USB_ST_NOT_PROC; /*not yet processed */ + submit_bulk_msg(dev, pipe, data, len); + while (timeout--) { + if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) break; wait_ms(1); } - *actual_length=dev->act_len; - if(dev->status==0) + *actual_length = dev->act_len; + if (dev->status == 0) return 0; else return -1; @@ -237,9 +239,10 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, * returns the max packet size, depending on the pipe direction and * the configurations values */ -int usb_maxpacket(struct usb_device *dev,unsigned long pipe) +int usb_maxpacket(struct usb_device *dev, unsigned long pipe) { - if((pipe & USB_DIR_IN)==0) /* direction is out -> use emaxpacket out */ + /* direction is out -> use emaxpacket out */ + if ((pipe & USB_DIR_IN) == 0) return(dev->epmaxpacketout[((pipe>>15) & 0xf)]); else return(dev->epmaxpacketin[((pipe>>15) & 0xf)]); @@ -318,8 +321,9 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno) dev->configno = cfgno; head = (struct usb_descriptor_header *) &buffer[0]; - if(head->bDescriptorType != USB_DT_CONFIG) { - printf(" ERROR: NOT USB_CONFIG_DESC %x\n", head->bDescriptorType); + if (head->bDescriptorType != USB_DT_CONFIG) { + printf(" ERROR: NOT USB_CONFIG_DESC %x\n", + head->bDescriptorType); return -1; } memcpy(&dev->config, buffer, buffer[0]); @@ -327,45 +331,52 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno) dev->config.no_of_if = 0; index = dev->config.bLength; - /* Ok the first entry must be a configuration entry, now process the others */ + /* Ok the first entry must be a configuration entry, + * now process the others */ head = (struct usb_descriptor_header *) &buffer[index]; - while(index + 1 < dev->config.wTotalLength) { - switch(head->bDescriptorType) { - case USB_DT_INTERFACE: - if(((struct usb_interface_descriptor *) &buffer[index])-> - bInterfaceNumber != curr_if_num) { - /* this is a new interface, copy new desc */ - ifno = dev->config.no_of_if; - dev->config.no_of_if++; - memcpy(&dev->config.if_desc[ifno], - &buffer[index], buffer[index]); - dev->config.if_desc[ifno].no_of_ep = 0; - dev->config.if_desc[ifno].num_altsetting = 1; - curr_if_num = dev->config.if_desc[ifno].bInterfaceNumber; - } else { - /* found alternate setting for the interface */ - dev->config.if_desc[ifno].num_altsetting++; - } - break; - case USB_DT_ENDPOINT: - epno = dev->config.if_desc[ifno].no_of_ep; - dev->config.if_desc[ifno].no_of_ep++; /* found an endpoint */ - memcpy(&dev->config.if_desc[ifno].ep_desc[epno], + while (index + 1 < dev->config.wTotalLength) { + switch (head->bDescriptorType) { + case USB_DT_INTERFACE: + if (((struct usb_interface_descriptor *) \ + &buffer[index])->bInterfaceNumber != curr_if_num) { + /* this is a new interface, copy new desc */ + ifno = dev->config.no_of_if; + dev->config.no_of_if++; + memcpy(&dev->config.if_desc[ifno], &buffer[index], buffer[index]); - le16_to_cpus(&(dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize)); - USB_PRINTF("if %d, ep %d\n", ifno, epno); - break; - default: - if(head->bLength == 0) - return 1; - USB_PRINTF("unknown Description Type : %x\n", head->bDescriptorType); - { - ch = (unsigned char *)head; - for(i = 0; i < head->bLength; i++) - USB_PRINTF("%02X ", *ch++); - USB_PRINTF("\n\n\n"); - } - break; + dev->config.if_desc[ifno].no_of_ep = 0; + dev->config.if_desc[ifno].num_altsetting = 1; + curr_if_num = + dev->config.if_desc[ifno].bInterfaceNumber; + } else { + /* found alternate setting for the interface */ + dev->config.if_desc[ifno].num_altsetting++; + } + break; + case USB_DT_ENDPOINT: + epno = dev->config.if_desc[ifno].no_of_ep; + /* found an endpoint */ + dev->config.if_desc[ifno].no_of_ep++; + memcpy(&dev->config.if_desc[ifno].ep_desc[epno], + &buffer[index], buffer[index]); + le16_to_cpus(&(dev->config.if_desc[ifno].ep_desc[epno].\ + wMaxPacketSize)); + USB_PRINTF("if %d, ep %d\n", ifno, epno); + break; + default: + if (head->bLength == 0) + return 1; + + USB_PRINTF("unknown Description Type : %x\n", + head->bDescriptorType); + + { + ch = (unsigned char *)head; + for (i = 0; i < head->bLength; i++) + USB_PRINTF("%02X ", *ch++); + USB_PRINTF("\n\n\n"); + } + break; } index += head->bLength; head = (struct usb_descriptor_header *)&buffer[index]; @@ -384,7 +395,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe) 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); + USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, + endp, NULL, 0, USB_CNTL_TIMEOUT * 3); /* don't clear if failed */ if (result < 0) @@ -406,7 +418,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe) /********************************************************************** * get_descriptor type */ -int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) +int usb_get_descriptor(struct usb_device *dev, unsigned char type, + unsigned char index, void *buf, int size) { int res; res = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), @@ -419,32 +432,36 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char /********************************************************************** * gets configuration cfgno and store it in the buffer */ -int usb_get_configuration_no(struct usb_device *dev,unsigned char *buffer,int cfgno) +int usb_get_configuration_no(struct usb_device *dev, + unsigned char *buffer, int cfgno) { int result; unsigned int tmp; struct usb_config_descriptor *config; - config=(struct usb_config_descriptor *)&buffer[0]; + config = (struct usb_config_descriptor *)&buffer[0]; result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8); if (result < 8) { if (result < 0) - printf("unable to get descriptor, error %lX\n",dev->status); + printf("unable to get descriptor, error %lX\n", + dev->status); else - printf("config descriptor too short (expected %i, got %i)\n",8,result); + printf("config descriptor too short " \ + "(expected %i, got %i)\n", 8, result); return -1; } tmp = le16_to_cpu(config->wTotalLength); if (tmp > USB_BUFSIZ) { - USB_PRINTF("usb_get_configuration_no: failed to get descriptor - too long: %d\n", - tmp); + USB_PRINTF("usb_get_configuration_no: failed to get " \ + "descriptor - too long: %d\n", tmp); return -1; } result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp); - USB_PRINTF("get_conf_no %d Result %d, wLength %d\n",cfgno,result,tmp); + USB_PRINTF("get_conf_no %d Result %d, wLength %d\n", + cfgno, result, tmp); return result; } @@ -456,11 +473,11 @@ int usb_set_address(struct usb_device *dev) { int res; - USB_PRINTF("set address %d\n",dev->devnum); - res=usb_control_msg(dev, usb_snddefctrl(dev), - USB_REQ_SET_ADDRESS, 0, - (dev->devnum),0, - NULL,0, USB_CNTL_TIMEOUT); + USB_PRINTF("set address %d\n", dev->devnum); + res = usb_control_msg(dev, usb_snddefctrl(dev), + USB_REQ_SET_ADDRESS, 0, + (dev->devnum), 0, + NULL, 0, USB_CNTL_TIMEOUT); return res; } @@ -484,16 +501,19 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) } /* * We should return now for devices with only one alternate setting. - * According to 9.4.10 of the Universal Serial Bus Specification Revision 2.0 - * such devices can return with a STALL. This results in some USB sticks - * timeouting during initialization and then being unusable in U-Boot. + * According to 9.4.10 of the Universal Serial Bus Specification + * Revision 2.0 such devices can return with a STALL. This results in + * some USB sticks timeouting during initialization and then being + * unusable in U-Boot. */ if (if_face->num_altsetting == 1) return 0; - if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate, - interface, NULL, 0, USB_CNTL_TIMEOUT * 5)) < 0) + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, + alternate, interface, NULL, 0, + USB_CNTL_TIMEOUT * 5); + if (ret < 0) return ret; return 0; @@ -505,18 +525,17 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) int usb_set_configuration(struct usb_device *dev, int configuration) { int res; - USB_PRINTF("set configuration %d\n",configuration); + USB_PRINTF("set configuration %d\n", configuration); /* set setup command */ - res=usb_control_msg(dev, usb_sndctrlpipe(dev,0), - USB_REQ_SET_CONFIGURATION, 0, - configuration,0, - NULL,0, USB_CNTL_TIMEOUT); - if(res==0) { + res = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_CONFIGURATION, 0, + configuration, 0, + NULL, 0, USB_CNTL_TIMEOUT); + if (res == 0) { dev->toggle[0] = 0; dev->toggle[1] = 0; return 0; - } - else + } else return -1; } @@ -543,11 +562,13 @@ int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id) /******************************************************************** * get report */ -int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) +int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT); + USB_REQ_GET_REPORT, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT); } /******************************************************************** @@ -564,7 +585,8 @@ int usb_get_class_descriptor(struct usb_device *dev, int ifnum, /******************************************************************** * get string index in buffer */ -int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size) +int usb_get_string(struct usb_device *dev, unsigned short langid, + unsigned char index, void *buf, int size) { int i; int result; @@ -655,17 +677,19 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) if (!dev->have_langid) { err = usb_string_sub(dev, 0, 0, tbuf); if (err < 0) { - USB_PRINTF("error getting string descriptor 0 (error=%x)\n",dev->status); + USB_PRINTF("error getting string descriptor 0 " \ + "(error=%x)\n", dev->status); return -1; } else if (tbuf[0] < 4) { USB_PRINTF("string descriptor 0 too short\n"); return -1; } else { dev->have_langid = -1; - dev->string_langid = tbuf[2] | (tbuf[3]<< 8); + dev->string_langid = tbuf[2] | (tbuf[3] << 8); /* always use the first langid listed */ - USB_PRINTF("USB device number %d default language ID 0x%x\n", - dev->devnum, dev->string_langid); + USB_PRINTF("USB device number %d default " \ + "language ID 0x%x\n", + dev->devnum, dev->string_langid); } } @@ -697,9 +721,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) /* returns a pointer to the device with the index [index]. * if the device is not assigned (dev->devnum==-1) returns NULL */ -struct usb_device * usb_get_dev_index(int index) +struct usb_device *usb_get_dev_index(int index) { - if(usb_dev[index].devnum==-1) + if (usb_dev[index].devnum == -1) return NULL; else return &usb_dev[index]; @@ -709,21 +733,22 @@ struct usb_device * usb_get_dev_index(int index) /* returns a pointer of a new device structure or NULL, if * no device struct is available */ -struct usb_device * usb_alloc_new_device(void) +struct usb_device *usb_alloc_new_device(void) { int i; - USB_PRINTF("New Device %d\n",dev_index); - if(dev_index==USB_MAX_DEVICE) { - printf("ERROR, too many USB Devices, max=%d\n",USB_MAX_DEVICE); + USB_PRINTF("New Device %d\n", dev_index); + if (dev_index == USB_MAX_DEVICE) { + printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE); return NULL; } - usb_dev[dev_index].devnum=dev_index+1; /* default Address is 0, real addresses start with 1 */ - usb_dev[dev_index].maxchild=0; - for(i=0;idescriptor, 8); if (err < 8) { - printf("\n USB device not responding, giving up (status=%lX)\n",dev->status); + printf("\n USB device not responding, " \ + "giving up (status=%lX)\n", dev->status); return 1; } #endif @@ -811,17 +837,18 @@ int usb_new_device(struct usb_device *dev) dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; switch (dev->descriptor.bMaxPacketSize0) { - case 8: dev->maxpacketsize = 0; break; - case 16: dev->maxpacketsize = 1; break; - case 32: dev->maxpacketsize = 2; break; - case 64: dev->maxpacketsize = 3; break; + case 8: dev->maxpacketsize = 0; break; + case 16: dev->maxpacketsize = 1; break; + case 32: dev->maxpacketsize = 2; break; + case 64: dev->maxpacketsize = 3; break; } dev->devnum = addr; err = usb_set_address(dev); /* set address */ if (err < 0) { - printf("\n USB device not accepting new address (error=%lX)\n", dev->status); + printf("\n USB device not accepting new address " \ + "(error=%lX)\n", dev->status); return 1; } @@ -829,12 +856,15 @@ int usb_new_device(struct usb_device *dev) tmp = sizeof(dev->descriptor); - err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, sizeof(dev->descriptor)); + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, + &dev->descriptor, sizeof(dev->descriptor)); if (err < tmp) { if (err < 0) - printf("unable to get device descriptor (error=%d)\n",err); + printf("unable to get device descriptor (error=%d)\n", + err); else - printf("USB device descriptor short read (expected %i, got %i)\n",tmp,err); + printf("USB device descriptor short read " \ + "(expected %i, got %i)\n", tmp, err); return 1; } /* correct le values */ @@ -843,30 +873,35 @@ int usb_new_device(struct usb_device *dev) le16_to_cpus(&dev->descriptor.idProduct); le16_to_cpus(&dev->descriptor.bcdDevice); /* only support for one config for now */ - usb_get_configuration_no(dev,&tmpbuf[0],0); - usb_parse_config(dev,&tmpbuf[0],0); + usb_get_configuration_no(dev, &tmpbuf[0], 0); + usb_parse_config(dev, &tmpbuf[0], 0); usb_set_maxpacket(dev); /* we set the default configuration here */ if (usb_set_configuration(dev, dev->config.bConfigurationValue)) { - printf("failed to set default configuration len %d, status %lX\n",dev->act_len,dev->status); + printf("failed to set default configuration " \ + "len %d, status %lX\n", dev->act_len, dev->status); return -1; } USB_PRINTF("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n", - dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber); + dev->descriptor.iManufacturer, dev->descriptor.iProduct, + dev->descriptor.iSerialNumber); memset(dev->mf, 0, sizeof(dev->mf)); memset(dev->prod, 0, sizeof(dev->prod)); memset(dev->serial, 0, sizeof(dev->serial)); if (dev->descriptor.iManufacturer) - usb_string(dev, dev->descriptor.iManufacturer, dev->mf, sizeof(dev->mf)); + usb_string(dev, dev->descriptor.iManufacturer, + dev->mf, sizeof(dev->mf)); if (dev->descriptor.iProduct) - usb_string(dev, dev->descriptor.iProduct, dev->prod, sizeof(dev->prod)); + usb_string(dev, dev->descriptor.iProduct, + dev->prod, sizeof(dev->prod)); if (dev->descriptor.iSerialNumber) - usb_string(dev, dev->descriptor.iSerialNumber, dev->serial, sizeof(dev->serial)); + usb_string(dev, dev->descriptor.iSerialNumber, + dev->serial, sizeof(dev->serial)); USB_PRINTF("Manufacturer %s\n", dev->mf); USB_PRINTF("Product %s\n", dev->prod); USB_PRINTF("SerialNumber %s\n", dev->serial); /* now prode if the device is a hub */ - usb_hub_probe(dev,0); + usb_hub_probe(dev, 0); return 0; } @@ -877,15 +912,15 @@ void usb_scan_devices(void) struct usb_device *dev; /* first make all devices unknown */ - for(i=0;ipusb_dev; + dev = hub->pusb_dev; /* Enable power to the ports */ USB_HUB_PRINTF("enabling power on all ports\n"); for (i = 0; i < dev->maxchild; i++) { usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER); - USB_HUB_PRINTF("port %d returns %lX\n",i+1,dev->status); + USB_HUB_PRINTF("port %d returns %lX\n", i + 1, dev->status); wait_ms(hub->desc.bPwrOn2PwrGood * 2); } } void usb_hub_reset(void) { - usb_hub_index=0; + usb_hub_index = 0; } struct usb_hub_device *usb_hub_allocate(void) { - if(usb_hub_indexstatus); + 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 = le16_to_cpu(portsts.wPortStatus); portchange = le16_to_cpu(portsts.wPortChange); - USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus ,portchange, - portstatus&(1<children[port])) { + (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) { USB_HUB_PRINTF("usb_disconnect(&hub->children[port]);\n"); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) @@ -1073,11 +1115,11 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) wait_ms(200); /* Allocate a new device struct for it */ - usb=usb_alloc_new_device(); + usb = usb_alloc_new_device(); usb->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0; dev->children[port] = usb; - usb->parent=dev; + usb->parent = dev; /* Run it through the hoops (find a driver, etc) */ if (usb_new_device(usb)) { /* Woops, disable the port */ @@ -1096,13 +1138,14 @@ int usb_hub_configure(struct usb_device *dev) struct usb_hub_device *hub; /* "allocate" Hub device */ - hub=usb_hub_allocate(); - if(hub==NULL) + hub = usb_hub_allocate(); + if (hub == NULL) return -1; - hub->pusb_dev=dev; + hub->pusb_dev = dev; /* Get the the hub descriptor */ if (usb_get_hub_descriptor(dev, buffer, 4) < 0) { - USB_HUB_PRINTF("usb_hub_configure: failed to get hub descriptor, giving up %lX\n",dev->status); + USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \ + "descriptor, giving up %lX\n", dev->status); return -1; } descriptor = (struct usb_hub_descriptor *)buffer; @@ -1110,43 +1153,48 @@ int usb_hub_configure(struct usb_device *dev) /* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */ i = descriptor->bLength; if (i > USB_BUFSIZ) { - USB_HUB_PRINTF("usb_hub_configure: failed to get hub descriptor - too long: %d\n", - descriptor->bLength); + USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \ + "descriptor - too long: %d\n", + descriptor->bLength); return -1; } if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) { - USB_HUB_PRINTF("usb_hub_configure: failed to get hub descriptor 2nd giving up %lX\n",dev->status); + USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \ + "descriptor 2nd giving up %lX\n", dev->status); return -1; } - memcpy((unsigned char *)&hub->desc,buffer,descriptor->bLength); + memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength); /* adjust 16bit values */ - hub->desc.wHubCharacteristics = le16_to_cpu(descriptor->wHubCharacteristics); + hub->desc.wHubCharacteristics = + le16_to_cpu(descriptor->wHubCharacteristics); /* set the bitmap */ - bitmap=(unsigned char *)&hub->desc.DeviceRemovable[0]; - memset(bitmap,0xff,(USB_MAXCHILDREN+1+7)/8); /* devices not removable by default */ - bitmap=(unsigned char *)&hub->desc.PortPowerCtrlMask[0]; - memset(bitmap,0xff,(USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */ - for(i=0;i<((hub->desc.bNbrPorts + 1 + 7)/8);i++) { - hub->desc.DeviceRemovable[i]=descriptor->DeviceRemovable[i]; - } - for(i=0;i<((hub->desc.bNbrPorts + 1 + 7)/8);i++) { - hub->desc.DeviceRemovable[i]=descriptor->PortPowerCtrlMask[i]; - } + bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0]; + /* devices not removable by default */ + memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); + bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0]; + memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */ + + for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++) + hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i]; + + for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++) + hub->desc.DeviceRemovable[i] = descriptor->PortPowerCtrlMask[i]; + dev->maxchild = descriptor->bNbrPorts; USB_HUB_PRINTF("%d ports detected\n", dev->maxchild); switch (hub->desc.wHubCharacteristics & HUB_CHAR_LPSM) { - case 0x00: - USB_HUB_PRINTF("ganged power switching\n"); - break; - case 0x01: - USB_HUB_PRINTF("individual port power switching\n"); - break; - case 0x02: - case 0x03: - USB_HUB_PRINTF("unknown reserved power switching mode\n"); - break; + case 0x00: + USB_HUB_PRINTF("ganged power switching\n"); + break; + case 0x01: + USB_HUB_PRINTF("individual port power switching\n"); + break; + case 0x02: + case 0x03: + USB_HUB_PRINTF("unknown reserved power switching mode\n"); + break; } if (hub->desc.wHubCharacteristics & HUB_CHAR_COMPOUND) @@ -1155,40 +1203,52 @@ int usb_hub_configure(struct usb_device *dev) USB_HUB_PRINTF("standalone hub\n"); switch (hub->desc.wHubCharacteristics & HUB_CHAR_OCPM) { - case 0x00: - USB_HUB_PRINTF("global over-current protection\n"); - break; - case 0x08: - USB_HUB_PRINTF("individual port over-current protection\n"); - break; - case 0x10: - case 0x18: - USB_HUB_PRINTF("no over-current protection\n"); - break; + case 0x00: + USB_HUB_PRINTF("global over-current protection\n"); + break; + case 0x08: + USB_HUB_PRINTF("individual port over-current protection\n"); + break; + case 0x10: + case 0x18: + USB_HUB_PRINTF("no over-current protection\n"); + break; } - USB_HUB_PRINTF("power on to power good time: %dms\n", descriptor->bPwrOn2PwrGood * 2); - USB_HUB_PRINTF("hub controller current requirement: %dmA\n", descriptor->bHubContrCurrent); + + USB_HUB_PRINTF("power on to power good time: %dms\n", + descriptor->bPwrOn2PwrGood * 2); + USB_HUB_PRINTF("hub controller current requirement: %dmA\n", + descriptor->bHubContrCurrent); + for (i = 0; i < dev->maxchild; i++) USB_HUB_PRINTF("port %d is%s removable\n", i + 1, - hub->desc.DeviceRemovable[(i + 1)/8] & (1 << ((i + 1)%8)) ? " not" : ""); + hub->desc.DeviceRemovable[(i + 1) / 8] & \ + (1 << ((i + 1) % 8)) ? " not" : ""); + if (sizeof(struct usb_hub_status) > USB_BUFSIZ) { - USB_HUB_PRINTF("usb_hub_configure: failed to get Status - too long: %d\n", - descriptor->bLength); + USB_HUB_PRINTF("usb_hub_configure: failed to get Status - " \ + "too long: %d\n", descriptor->bLength); return -1; } if (usb_get_hub_status(dev, buffer) < 0) { - USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",dev->status); + USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n", + dev->status); return -1; } + hubsts = (struct usb_hub_status *)buffer; USB_HUB_PRINTF("get_hub_status returned status %X, change %X\n", - le16_to_cpu(hubsts->wHubStatus),le16_to_cpu(hubsts->wHubChange)); + le16_to_cpu(hubsts->wHubStatus), + le16_to_cpu(hubsts->wHubChange)); USB_HUB_PRINTF("local power source is %s\n", - (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good"); + (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \ + "lost (inactive)" : "good"); USB_HUB_PRINTF("%sover-current condition exists\n", - (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? "" : "no "); + (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \ + "" : "no "); usb_hub_power_on(hub); + for (i = 0; i < dev->maxchild; i++) { struct usb_port_status portsts; unsigned short portstatus, portchange; @@ -1197,41 +1257,51 @@ int usb_hub_configure(struct usb_device *dev) USB_HUB_PRINTF("get_port_status failed\n"); continue; } + portstatus = le16_to_cpu(portsts.wPortStatus); portchange = le16_to_cpu(portsts.wPortChange); - USB_HUB_PRINTF("Port %d Status %X Change %X\n",i+1,portstatus,portchange); + USB_HUB_PRINTF("Port %d Status %X Change %X\n", + i + 1, portstatus, portchange); + if (portchange & USB_PORT_STAT_C_CONNECTION) { USB_HUB_PRINTF("port %d connection change\n", i + 1); usb_hub_port_connect_change(dev, i); } if (portchange & USB_PORT_STAT_C_ENABLE) { - USB_HUB_PRINTF("port %d enable change, status %x\n", i + 1, portstatus); - usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE); - - /* EM interference sometimes causes bad shielded USB devices to - * be shutdown by the hub, this hack enables them again. - * Works at least with mouse driver */ + USB_HUB_PRINTF("port %d enable change, status %x\n", + i + 1, portstatus); + usb_clear_port_feature(dev, i + 1, + USB_PORT_FEAT_C_ENABLE); + + /* EM interference sometimes causes bad shielded USB + * devices to be shutdown by the hub, this hack enables + * them again. Works at least with mouse driver */ if (!(portstatus & USB_PORT_STAT_ENABLE) && - (portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) { - USB_HUB_PRINTF("already running port %i disabled by hub (EMI?), re-enabling...\n", - i + 1); + (portstatus & USB_PORT_STAT_CONNECTION) && + ((dev->children[i]))) { + USB_HUB_PRINTF("already running port %i " \ + "disabled by hub (EMI?), " \ + "re-enabling...\n", i + 1); usb_hub_port_connect_change(dev, i); } } if (portstatus & USB_PORT_STAT_SUSPEND) { USB_HUB_PRINTF("port %d suspend change\n", i + 1); - usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_SUSPEND); + usb_clear_port_feature(dev, i + 1, + USB_PORT_FEAT_SUSPEND); } if (portchange & USB_PORT_STAT_C_OVERCURRENT) { USB_HUB_PRINTF("port %d over-current change\n", i + 1); - usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_OVER_CURRENT); + usb_clear_port_feature(dev, i + 1, + USB_PORT_FEAT_C_OVER_CURRENT); usb_hub_power_on(hub); } if (portchange & USB_PORT_STAT_C_RESET) { USB_HUB_PRINTF("port %d reset change\n", i + 1); - usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET); + usb_clear_port_feature(dev, i + 1, + USB_PORT_FEAT_C_RESET); } } /* end for i all ports */ @@ -1265,7 +1335,7 @@ int usb_hub_probe(struct usb_device *dev, int ifnum) return 0; /* We found a hub */ USB_HUB_PRINTF("USB hub found\n"); - ret=usb_hub_configure(dev); + ret = usb_hub_configure(dev); return ret; } diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c index da11ecbc0f..76c6390b15 100644 --- a/drivers/usb/usb_ohci.c +++ b/drivers/usb/usb_ohci.c @@ -97,7 +97,8 @@ # define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a)) #endif /* CFG_OHCI_SWAP_REG_ACCESS */ -#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +#define min_t(type, x, y) \ + ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) #ifdef CONFIG_PCI_OHCI static struct pci_device_id ohci_pci_ids[] = { @@ -120,13 +121,13 @@ static struct pci_device_id ehci_pci_ids[] = { #ifdef DEBUG #define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg) #else -#define dbg(format, arg...) do {} while(0) +#define dbg(format, arg...) do {} while (0) #endif /* DEBUG */ #define err(format, arg...) printf("ERROR: " format "\n", ## arg) #ifdef SHOW_INFO #define info(format, arg...) printf("INFO: " format "\n", ## arg) #else -#define info(format, arg...) do {} while(0) +#define info(format, arg...) do {} while (0) #endif #ifdef CFG_OHCI_BE_CONTROLLER @@ -145,25 +146,24 @@ struct ohci_hcca ghcca[1]; struct ohci_hcca *phcca; /* this allocates EDs for all possible endpoints */ struct ohci_device ohci_dev; -/* RHSC flag */ -int got_rhsc; /* device which was disconnected */ struct usb_device *devgone; -static inline u32 roothub_a (struct ohci *hc) - { return readl (&hc->regs->roothub.a); } -static inline u32 roothub_b (struct ohci *hc) - { return readl (&hc->regs->roothub.b); } -static inline u32 roothub_status (struct ohci *hc) - { return readl (&hc->regs->roothub.status); } -static inline u32 roothub_portstatus (struct ohci *hc, int i) - { return readl (&hc->regs->roothub.portstatus[i]); } +static inline u32 roothub_a(struct ohci *hc) + { return readl(&hc->regs->roothub.a); } +static inline u32 roothub_b(struct ohci *hc) + { return readl(&hc->regs->roothub.b); } +static inline u32 roothub_status(struct ohci *hc) + { return readl(&hc->regs->roothub.status); } +static inline u32 roothub_portstatus(struct ohci *hc, int i) + { return readl(&hc->regs->roothub.portstatus[i]); } /* forward declaration */ -static int hc_interrupt (void); -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); +static int hc_interrupt(void); +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); /*-------------------------------------------------------------------------* * URB support functions @@ -171,11 +171,11 @@ td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer, /* free HCD-private data associated with this URB */ -static void urb_free_priv (urb_priv_t * urb) +static void urb_free_priv(urb_priv_t *urb) { int i; int last; - struct td * td; + struct td *td; last = urb->length - 1; if (last >= 0) { @@ -193,72 +193,74 @@ static void urb_free_priv (urb_priv_t * urb) /*-------------------------------------------------------------------------*/ #ifdef DEBUG -static int sohci_get_current_frame_number (struct usb_device * dev); +static int sohci_get_current_frame_number(struct usb_device *dev); /* debug| print the main components of an URB * small: 0) header + data packets 1) just header */ -static void pkt_print (urb_priv_t *purb, struct usb_device * dev, - unsigned long pipe, void * buffer, - int transfer_len, struct devrequest * setup, char * str, int small) +static void pkt_print(urb_priv_t *purb, struct usb_device *dev, + unsigned long pipe, void *buffer, int transfer_len, + struct devrequest *setup, char *str, int small) { - dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx", + dbg("%s URB:[%4x] dev:%2lu,ep:%2lu-%c,type:%s,len:%d/%d stat:%#lx", str, - sohci_get_current_frame_number (dev), - usb_pipedevice (pipe), - usb_pipeendpoint (pipe), - usb_pipeout (pipe)? 'O': 'I', - usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): - (usb_pipecontrol (pipe)? "CTRL": "BULK"), + sohci_get_current_frame_number(dev), + usb_pipedevice(pipe), + usb_pipeendpoint(pipe), + usb_pipeout(pipe)? 'O': 'I', + usb_pipetype(pipe) < 2 ? \ + (usb_pipeint(pipe)? "INTR": "ISOC"): \ + (usb_pipecontrol(pipe)? "CTRL": "BULK"), (purb ? purb->actual_length : 0), transfer_len, dev->status); #ifdef OHCI_VERBOSE_DEBUG if (!small) { int i, len; - if (usb_pipecontrol (pipe)) { - printf (__FILE__ ": cmd(8):"); + if (usb_pipecontrol(pipe)) { + printf(__FILE__ ": cmd(8):"); for (i = 0; i < 8 ; i++) - printf (" %02x", ((__u8 *) setup) [i]); - printf ("\n"); + printf(" %02x", ((__u8 *) setup) [i]); + printf("\n"); } if (transfer_len > 0 && buffer) { - printf (__FILE__ ": data(%d/%d):", + printf(__FILE__ ": data(%d/%d):", (purb ? purb->actual_length : 0), transfer_len); - len = usb_pipeout (pipe)? - transfer_len: + len = usb_pipeout(pipe)? transfer_len: (purb ? purb->actual_length : 0); for (i = 0; i < 16 && i < len; i++) - printf (" %02x", ((__u8 *) buffer) [i]); - printf ("%s\n", i < len? "...": ""); + printf(" %02x", ((__u8 *) buffer) [i]); + printf("%s\n", i < len? "...": ""); } } #endif } -/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ -void ep_print_int_eds (ohci_t *ohci, char * str) { +/* just for debugging; prints non-empty branches of the int ed tree + * inclusive iso eds */ +void ep_print_int_eds(ohci_t *ohci, char *str) +{ int i, j; - __u32 * ed_p; - for (i= 0; i < 32; i++) { + __u32 *ed_p; + for (i = 0; i < 32; i++) { j = 5; ed_p = &(ohci->hcca->int_table [i]); if (*ed_p == 0) continue; - printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i); + printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i); while (*ed_p != 0 && j--) { ed_t *ed = (ed_t *)m32_swap(ed_p); - printf (" ed: %4x;", ed->hwINFO); + printf(" ed: %4x;", ed->hwINFO); ed_p = &ed->hwNextED; } - printf ("\n"); + printf("\n"); } } -static void ohci_dump_intr_mask (char *label, __u32 mask) +static void ohci_dump_intr_mask(char *label, __u32 mask) { - dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", + dbg("%s: 0x%08x%s%s%s%s%s%s%s%s%s", label, mask, (mask & OHCI_INTR_MIE) ? " MIE" : "", @@ -273,46 +275,46 @@ static void ohci_dump_intr_mask (char *label, __u32 mask) ); } -static void maybe_print_eds (char *label, __u32 value) +static void maybe_print_eds(char *label, __u32 value) { ed_t *edp = (ed_t *)value; if (value) { - dbg ("%s %08x", label, value); - dbg ("%08x", edp->hwINFO); - dbg ("%08x", edp->hwTailP); - dbg ("%08x", edp->hwHeadP); - dbg ("%08x", edp->hwNextED); + dbg("%s %08x", label, value); + dbg("%08x", edp->hwINFO); + dbg("%08x", edp->hwTailP); + dbg("%08x", edp->hwHeadP); + dbg("%08x", edp->hwNextED); } } -static char * hcfs2string (int state) +static char *hcfs2string(int state) { switch (state) { - case OHCI_USB_RESET: return "reset"; - case OHCI_USB_RESUME: return "resume"; - case OHCI_USB_OPER: return "operational"; - case OHCI_USB_SUSPEND: return "suspend"; + case OHCI_USB_RESET: return "reset"; + case OHCI_USB_RESUME: return "resume"; + case OHCI_USB_OPER: return "operational"; + case OHCI_USB_SUSPEND: return "suspend"; } return "?"; } /* dump control and status registers */ -static void ohci_dump_status (ohci_t *controller) +static void ohci_dump_status(ohci_t *controller) { struct ohci_regs *regs = controller->regs; __u32 temp; - temp = readl (®s->revision) & 0xff; + temp = readl(®s->revision) & 0xff; if (temp != 0x10) - dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); + dbg("spec %d.%d", (temp >> 4), (temp & 0x0f)); - temp = readl (®s->control); - dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, + temp = readl(®s->control); + dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, (temp & OHCI_CTRL_RWE) ? " RWE" : "", (temp & OHCI_CTRL_RWC) ? " RWC" : "", (temp & OHCI_CTRL_IR) ? " IR" : "", - hcfs2string (temp & OHCI_CTRL_HCFS), + hcfs2string(temp & OHCI_CTRL_HCFS), (temp & OHCI_CTRL_BLE) ? " BLE" : "", (temp & OHCI_CTRL_CLE) ? " CLE" : "", (temp & OHCI_CTRL_IE) ? " IE" : "", @@ -320,8 +322,8 @@ static void ohci_dump_status (ohci_t *controller) temp & OHCI_CTRL_CBSR ); - temp = readl (®s->cmdstatus); - dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, + temp = readl(®s->cmdstatus); + dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, (temp & OHCI_SOC) >> 16, (temp & OHCI_OCR) ? " OCR" : "", (temp & OHCI_BLF) ? " BLF" : "", @@ -329,31 +331,31 @@ static void ohci_dump_status (ohci_t *controller) (temp & OHCI_HCR) ? " HCR" : "" ); - ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); - ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); + ohci_dump_intr_mask("intrstatus", readl(®s->intrstatus)); + ohci_dump_intr_mask("intrenable", readl(®s->intrenable)); - maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); + maybe_print_eds("ed_periodcurrent", readl(®s->ed_periodcurrent)); - maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); - maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); + maybe_print_eds("ed_controlhead", readl(®s->ed_controlhead)); + maybe_print_eds("ed_controlcurrent", readl(®s->ed_controlcurrent)); - maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); - maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); + maybe_print_eds("ed_bulkhead", readl(®s->ed_bulkhead)); + maybe_print_eds("ed_bulkcurrent", readl(®s->ed_bulkcurrent)); - maybe_print_eds ("donehead", readl (®s->donehead)); + maybe_print_eds("donehead", readl(®s->donehead)); } -static void ohci_dump_roothub (ohci_t *controller, int verbose) +static void ohci_dump_roothub(ohci_t *controller, int verbose) { __u32 temp, ndp, i; - temp = roothub_a (controller); + temp = roothub_a(controller); ndp = (temp & RH_A_NDP); #ifdef CONFIG_AT91C_PQFP_UHPBUG ndp = (ndp == 2) ? 1:0; #endif if (verbose) { - dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, + dbg("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, ((temp & RH_A_POTPGT) >> 24) & 0xff, (temp & RH_A_NOCP) ? " NOCP" : "", (temp & RH_A_OCPM) ? " OCPM" : "", @@ -362,14 +364,14 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose) (temp & RH_A_PSM) ? " PSM" : "", ndp ); - temp = roothub_b (controller); - dbg ("roothub.b: %08x PPCM=%04x DR=%04x", + temp = roothub_b(controller); + dbg("roothub.b: %08x PPCM=%04x DR=%04x", temp, (temp & RH_B_PPCM) >> 16, (temp & RH_B_DR) ); - temp = roothub_status (controller); - dbg ("roothub.status: %08x%s%s%s%s%s%s", + temp = roothub_status(controller); + dbg("roothub.status: %08x%s%s%s%s%s%s", temp, (temp & RH_HS_CRWE) ? " CRWE" : "", (temp & RH_HS_OCIC) ? " OCIC" : "", @@ -381,8 +383,8 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose) } for (i = 0; i < ndp; i++) { - temp = roothub_portstatus (controller, i); - dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", + temp = roothub_portstatus(controller, i); + dbg("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", i, temp, (temp & RH_PS_PRSC) ? " PRSC" : "", @@ -403,16 +405,16 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose) } } -static void ohci_dump (ohci_t *controller, int verbose) +static void ohci_dump(ohci_t *controller, int verbose) { - dbg ("OHCI controller usb-%s state", controller->slot_name); + dbg("OHCI controller usb-%s state", controller->slot_name); /* dumps some of the state we know about */ - ohci_dump_status (controller); + ohci_dump_status(controller); if (verbose) - ep_print_int_eds (controller, "hcca"); - dbg ("hcca frame #%04x", controller->hcca->frame_no); - ohci_dump_roothub (controller, 1); + ep_print_int_eds(controller, "hcca"); + dbg("hcca frame #%04x", controller->hcca->frame_no); + ohci_dump_roothub(controller, 1); } #endif /* DEBUG */ @@ -425,7 +427,7 @@ static void ohci_dump (ohci_t *controller, int verbose) int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup) { ohci_t *ohci; - ed_t * ed; + ed_t *ed; urb_priv_t *purb_priv = urb; int i, size = 0; struct usb_device *dev = urb->dev; @@ -443,27 +445,29 @@ int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup) return -1; } - /* we're about to begin a new transaction here so mark the URB unfinished */ + /* 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, interval, 1))) { + ed = ep_add_ed(dev, pipe, interval, 1); + if (!ed) { err("sohci_submit_job: ENOMEM"); return -1; } /* for the private part of the URB we need the number of TDs (size) */ - switch (usb_pipetype (pipe)) { - case PIPE_BULK: /* one TD for every 4096 Byte */ - size = (transfer_len - 1) / 4096 + 1; - break; - case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ - size = (transfer_len == 0)? 2: - (transfer_len - 1) / 4096 + 3; - break; - case PIPE_INTERRUPT: /* 1 TD */ - size = 1; - break; + switch (usb_pipetype(pipe)) { + case PIPE_BULK: /* one TD for every 4096 Byte */ + size = (transfer_len - 1) / 4096 + 1; + break; + case PIPE_CONTROL:/* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ + size = (transfer_len == 0)? 2: + (transfer_len - 1) / 4096 + 3; + break; + case PIPE_INTERRUPT: /* 1 TD */ + size = 1; + break; } ed->purb = urb; @@ -482,27 +486,28 @@ int sohci_submit_job(urb_priv_t *urb, struct devrequest *setup) /* allocate the TDs */ /* note that td[0] was allocated in ep_add_ed */ for (i = 0; i < size; i++) { - purb_priv->td[i] = td_alloc (dev); + purb_priv->td[i] = td_alloc(dev); if (!purb_priv->td[i]) { purb_priv->length = i; - urb_free_priv (purb_priv); + urb_free_priv(purb_priv); err("sohci_submit_job: ENOMEM"); return -1; } } if (ed->state == ED_NEW || (ed->state & ED_DEL)) { - urb_free_priv (purb_priv); + urb_free_priv(purb_priv); err("sohci_submit_job: EINVAL"); return -1; } /* link the ed into a chain if is not already */ if (ed->state != ED_OPER) - ep_link (ohci, ed); + ep_link(ohci, ed); /* fill the TDs and link it to the ed */ - td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval); + td_submit_job(dev, pipe, buffer, transfer_len, + setup, purb_priv, interval); return 0; } @@ -511,19 +516,19 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb) { struct ohci_regs *regs = hc->regs; - switch (usb_pipetype (urb->pipe)) { + switch (usb_pipetype(urb->pipe)) { case PIPE_INTERRUPT: /* implicitly requeued */ if (urb->dev->irq_handle && (urb->dev->irq_act_len = urb->actual_length)) { - writel (OHCI_INTR_WDH, ®s->intrenable); - readl (®s->intrenable); /* PCI posting flush */ + writel(OHCI_INTR_WDH, ®s->intrenable); + readl(®s->intrenable); /* PCI posting flush */ urb->dev->irq_handle(urb->dev); - writel (OHCI_INTR_WDH, ®s->intrdisable); - readl (®s->intrdisable); /* PCI posting flush */ + writel(OHCI_INTR_WDH, ®s->intrdisable); + readl(®s->intrdisable); /* PCI posting flush */ } urb->actual_length = 0; - td_submit_job ( + td_submit_job( urb->dev, urb->pipe, urb->transfer_buffer, @@ -546,11 +551,11 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb) #ifdef DEBUG /* tell us the current USB frame number */ -static int sohci_get_current_frame_number (struct usb_device *usb_dev) +static int sohci_get_current_frame_number(struct usb_device *usb_dev) { ohci_t *ohci = &gohci; - return m16_swap (ohci->hcca->frame_no); + return m16_swap(ohci->hcca->frame_no); } #endif @@ -563,7 +568,7 @@ static int sohci_get_current_frame_number (struct usb_device *usb_dev) * returns the branch and * sets the interval to interval = 2^integer (ld (interval)) */ -static int ep_int_ballance (ohci_t * ohci, int interval, int load) +static int ep_int_ballance(ohci_t *ohci, int interval, int load) { int i, branch = 0; @@ -585,20 +590,19 @@ static int ep_int_ballance (ohci_t * ohci, int interval, int load) /* 2^int( ld (inter)) */ -static int ep_2_n_interval (int inter) +static int ep_2_n_interval(int inter) { int i; - for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++); + for (i = 0; ((inter >> i) > 1) && (i < 5); i++); return 1 << i; } /*-------------------------------------------------------------------------*/ /* the int tree is a binary tree - * in order to process it sequentially the indexes of the branches have to be mapped - * the mapping reverses the bits of a word of num_bits length */ - -static int ep_rev (int num_bits, int word) + * in order to process it sequentially the indexes of the branches have to + * be mapped the mapping reverses the bits of a word of num_bits length */ +static int ep_rev(int num_bits, int word) { int i, wout = 0; @@ -613,7 +617,7 @@ static int ep_rev (int num_bits, int word) /* link an ed into one of the HC chains */ -static int ep_link (ohci_t *ohci, ed_t *edi) +static int ep_link(ohci_t *ohci, ed_t *edi) { volatile ed_t *ed = edi; int int_branch; @@ -621,7 +625,7 @@ static int ep_link (ohci_t *ohci, ed_t *edi) int inter; int interval; int load; - __u32 * ed_p; + __u32 *ed_p; ed->state = ED_OPER; ed->int_interval = 0; @@ -629,49 +633,54 @@ static int ep_link (ohci_t *ohci, ed_t *edi) switch (ed->type) { case PIPE_CONTROL: ed->hwNextED = 0; - if (ohci->ed_controltail == NULL) { - writel (ed, &ohci->regs->ed_controlhead); - } else { - ohci->ed_controltail->hwNextED = m32_swap ((unsigned long)ed); - } + if (ohci->ed_controltail == NULL) + writel(ed, &ohci->regs->ed_controlhead); + else + ohci->ed_controltail->hwNextED = + m32_swap((unsigned long)ed); + ed->ed_prev = ohci->ed_controltail; if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && !ohci->ed_rm_list[1] && !ohci->sleeping) { ohci->hc_control |= OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); + writel(ohci->hc_control, &ohci->regs->control); } ohci->ed_controltail = edi; break; case PIPE_BULK: ed->hwNextED = 0; - if (ohci->ed_bulktail == NULL) { - writel (ed, &ohci->regs->ed_bulkhead); - } else { - ohci->ed_bulktail->hwNextED = m32_swap ((unsigned long)ed); - } + if (ohci->ed_bulktail == NULL) + writel(ed, &ohci->regs->ed_bulkhead); + else + ohci->ed_bulktail->hwNextED = + m32_swap((unsigned long)ed); + ed->ed_prev = ohci->ed_bulktail; if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && !ohci->ed_rm_list[1] && !ohci->sleeping) { ohci->hc_control |= OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); + writel(ohci->hc_control, &ohci->regs->control); } ohci->ed_bulktail = edi; break; case PIPE_INTERRUPT: load = ed->int_load; - interval = ep_2_n_interval (ed->int_period); + interval = ep_2_n_interval(ed->int_period); ed->int_interval = interval; - int_branch = ep_int_ballance (ohci, interval, load); + int_branch = ep_int_ballance(ohci, interval, load); ed->int_branch = int_branch; - for (i = 0; i < ep_rev (6, interval); i += inter) { + for (i = 0; i < ep_rev(6, interval); i += inter) { inter = 1; - for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]); - (*ed_p != 0) && (((ed_t *)ed_p)->int_interval >= interval); + for (ed_p = &(ohci->hcca->int_table[\ + ep_rev(5, i) + int_branch]); + (*ed_p != 0) && + (((ed_t *)ed_p)->int_interval >= interval); ed_p = &(((ed_t *)ed_p)->hwNextED)) - inter = ep_rev (6, ((ed_t *)ed_p)->int_interval); + inter = ep_rev(6, + ((ed_t *)ed_p)->int_interval); ed->hwNextED = *ed_p; *ed_p = m32_swap((unsigned long)ed); } @@ -683,19 +692,21 @@ static int ep_link (ohci_t *ohci, ed_t *edi) /*-------------------------------------------------------------------------*/ /* scan the periodic table to find and unlink this ED */ -static void periodic_unlink ( struct ohci *ohci, volatile struct ed *ed, - unsigned index, unsigned period) +static void periodic_unlink(struct ohci *ohci, volatile struct ed *ed, + unsigned index, unsigned period) { for (; index < NUM_INTS; index += period) { __u32 *ed_p = &ohci->hcca->int_table [index]; /* ED might have been unlinked through another path */ while (*ed_p != 0) { - if (((struct ed *)m32_swap ((unsigned long)ed_p)) == ed) { + if (((struct ed *) + m32_swap((unsigned long)ed_p)) == ed) { *ed_p = ed->hwNextED; break; } - ed_p = & (((struct ed *)m32_swap ((unsigned long)ed_p))->hwNextED); + ed_p = &(((struct ed *) + m32_swap((unsigned long)ed_p))->hwNextED); } } } @@ -705,28 +716,30 @@ static void periodic_unlink ( struct ohci *ohci, volatile struct ed *ed, * the link from the ed still points to another operational ed or 0 * so the HC can eventually finish the processing of the unlinked ed */ -static int ep_unlink (ohci_t *ohci, ed_t *edi) +static int ep_unlink(ohci_t *ohci, ed_t *edi) { volatile ed_t *ed = edi; int i; - ed->hwINFO |= m32_swap (OHCI_ED_SKIP); + ed->hwINFO |= m32_swap(OHCI_ED_SKIP); switch (ed->type) { case PIPE_CONTROL: if (ed->ed_prev == NULL) { if (!ed->hwNextED) { ohci->hc_control &= ~OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); + writel(ohci->hc_control, &ohci->regs->control); } - writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead); + writel(m32_swap(*((__u32 *)&ed->hwNextED)), + &ohci->regs->ed_controlhead); } else { ed->ed_prev->hwNextED = ed->hwNextED; } if (ohci->ed_controltail == ed) { ohci->ed_controltail = ed->ed_prev; } else { - ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; + ((ed_t *)m32_swap( + *((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; } break; @@ -734,21 +747,23 @@ static int ep_unlink (ohci_t *ohci, ed_t *edi) if (ed->ed_prev == NULL) { if (!ed->hwNextED) { ohci->hc_control &= ~OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); + writel(ohci->hc_control, &ohci->regs->control); } - writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead); + writel(m32_swap(*((__u32 *)&ed->hwNextED)), + &ohci->regs->ed_bulkhead); } else { ed->ed_prev->hwNextED = ed->hwNextED; } if (ohci->ed_bulktail == ed) { ohci->ed_bulktail = ed->ed_prev; } else { - ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; + ((ed_t *)m32_swap( + *((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; } break; case PIPE_INTERRUPT: - periodic_unlink (ohci, ed, 0, 1); + periodic_unlink(ohci, ed, 0, 1); for (i = ed->int_branch; i < 32; i += ed->int_interval) ohci->ohci_int_load[i] -= ed->int_load; break; @@ -767,15 +782,15 @@ static int ep_unlink (ohci_t *ohci, ed_t *edi) * info fields are setted anyway even though most of them should not * change */ -static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe, - int interval, int load) +static ed_t *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe, + int interval, int load) { td_t *td; ed_t *ed_ret; volatile ed_t *ed; - ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) | - (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]; + ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint(pipe) << 1) | + (usb_pipecontrol(pipe)? 0: usb_pipeout(pipe))]; if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { err("ep_add_ed: pending delete"); @@ -784,22 +799,22 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe, } if (ed->state == ED_NEW) { - ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */ /* dummy td; end of td list for ed */ - td = td_alloc (usb_dev); - ed->hwTailP = m32_swap ((unsigned long)td); + td = td_alloc(usb_dev); + ed->hwTailP = m32_swap((unsigned long)td); ed->hwHeadP = ed->hwTailP; ed->state = ED_UNLINK; - ed->type = usb_pipetype (pipe); + ed->type = usb_pipetype(pipe); ohci_dev.ed_cnt++; } - ed->hwINFO = m32_swap (usb_pipedevice (pipe) - | usb_pipeendpoint (pipe) << 7 - | (usb_pipeisoc (pipe)? 0x8000: 0) - | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) - | usb_pipeslow (pipe) << 13 - | usb_maxpacket (usb_dev, pipe) << 16); + ed->hwINFO = m32_swap(usb_pipedevice(pipe) + | usb_pipeendpoint(pipe) << 7 + | (usb_pipeisoc(pipe)? 0x8000: 0) + | (usb_pipecontrol(pipe)? 0: \ + (usb_pipeout(pipe)? 0x800: 0x1000)) + | usb_pipeslow(pipe) << 13 + | usb_maxpacket(usb_dev, pipe) << 16); if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) { ed->int_period = interval; @@ -815,7 +830,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe, /* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ -static void td_fill (ohci_t *ohci, unsigned int info, +static void td_fill(ohci_t *ohci, unsigned int info, void *data, int len, struct usb_device *dev, int index, urb_priv_t *urb_priv) { @@ -833,29 +848,32 @@ static void td_fill (ohci_t *ohci, unsigned int info, td_pt->hwNextTD = 0; /* fill the old dummy TD */ - td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf); + td = urb_priv->td [index] = + (td_t *)(m32_swap(urb_priv->ed->hwTailP) & ~0xf); td->ed = urb_priv->ed; td->next_dl_td = NULL; td->index = index; td->data = (__u32)data; #ifdef OHCI_FILL_TRACE - if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe)) { + if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && + usb_pipeout(urb_priv->pipe)) { for (i = 0; i < len; i++) - printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]); + printf("td->data[%d] %#2x ", i, ((unsigned char *)td->data)[i]); printf("\n"); } #endif if (!len) data = 0; - td->hwINFO = m32_swap (info); - td->hwCBP = m32_swap ((unsigned long)data); + td->hwINFO = m32_swap(info); + td->hwCBP = m32_swap((unsigned long)data); if (data) - td->hwBE = m32_swap ((unsigned long)(data + len - 1)); + td->hwBE = m32_swap((unsigned long)(data + len - 1)); else td->hwBE = 0; - td->hwNextTD = m32_swap ((unsigned long)td_pt); + + td->hwNextTD = m32_swap((unsigned long)td_pt); /* append to queue */ td->ed->hwTailP = td->hwNextTD; @@ -865,8 +883,10 @@ 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) +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) { ohci_t *ohci = &gohci; int data_len = transfer_len; @@ -875,12 +895,14 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf __u32 info = 0; unsigned int toggle = 0; - /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ - if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { + /* OHCI handles the DATA-toggles itself, we just use the USB-toggle + * bits for reseting */ + if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { toggle = TD_T_TOGGLE; } else { toggle = TD_T_DATA0; - usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1); + usb_settoggle(dev, usb_pipeendpoint(pipe), + usb_pipeout(pipe), 1); } urb->td_cnt = 0; if (data_len) @@ -888,44 +910,58 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf else data = 0; - switch (usb_pipetype (pipe)) { + switch (usb_pipetype(pipe)) { case PIPE_BULK: - info = usb_pipeout (pipe)? + info = usb_pipeout(pipe)? TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; - while(data_len > 4096) { - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb); + while (data_len > 4096) { + td_fill(ohci, info | (cnt? TD_T_TOGGLE:toggle), + data, 4096, dev, cnt, urb); data += 4096; data_len -= 4096; cnt++; } - info = usb_pipeout (pipe)? + info = usb_pipeout(pipe)? TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb); + td_fill(ohci, info | (cnt? TD_T_TOGGLE:toggle), data, + data_len, dev, cnt, urb); cnt++; - if (!ohci->sleeping) - writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ + if (!ohci->sleeping) { + /* start bulk list */ + writel(OHCI_BLF, &ohci->regs->cmdstatus); + } break; case PIPE_CONTROL: + /* Setup phase */ info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (ohci, info, setup, 8, dev, cnt++, urb); + td_fill(ohci, info, setup, 8, dev, cnt++, urb); + + /* Optional Data phase */ if (data_len > 0) { - info = usb_pipeout (pipe)? - TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; + info = usb_pipeout(pipe)? + TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : + TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; /* NOTE: mishandles transfers >8K, some >4K */ - td_fill (ohci, info, data, data_len, dev, cnt++, urb); + td_fill(ohci, info, data, data_len, dev, cnt++, urb); + } + + /* Status phase */ + info = usb_pipeout(pipe)? + TD_CC | TD_DP_IN | TD_T_DATA1: + TD_CC | TD_DP_OUT | TD_T_DATA1; + td_fill(ohci, info, data, 0, dev, cnt++, urb); + + if (!ohci->sleeping) { + /* start Control list */ + writel(OHCI_CLF, &ohci->regs->cmdstatus); } - info = usb_pipeout (pipe)? - TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (ohci, info, data, 0, dev, cnt++, urb); - if (!ohci->sleeping) - writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ break; case PIPE_INTERRUPT: - info = usb_pipeout (urb->pipe)? + info = usb_pipeout(urb->pipe)? TD_CC | TD_DP_OUT | toggle: TD_CC | TD_R | TD_DP_IN | toggle; - td_fill (ohci, info, data, data_len, dev, cnt++, urb); + td_fill(ohci, info, data, data_len, dev, cnt++, urb); break; } if (urb->length != cnt) @@ -938,16 +974,16 @@ static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buf /* calculate the transfer length and update the urb */ -static void dl_transfer_length(td_t * td) +static void dl_transfer_length(td_t *td) { __u32 tdINFO, tdBE, tdCBP; urb_priv_t *lurb_priv = td->ed->purb; - tdINFO = m32_swap (td->hwINFO); - tdBE = m32_swap (td->hwBE); - tdCBP = m32_swap (td->hwCBP); + tdINFO = m32_swap(td->hwINFO); + tdBE = m32_swap(td->hwBE); + tdCBP = m32_swap(td->hwCBP); - if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL && + if (!(usb_pipetype(lurb_priv->pipe) == PIPE_CONTROL && ((td->index == 0) || (td->index == lurb_priv->length - 1)))) { if (tdBE != 0) { if (td->hwCBP == 0) @@ -959,105 +995,128 @@ static void dl_transfer_length(td_t * td) } /*-------------------------------------------------------------------------*/ +static void check_status(td_t *td_list) +{ + urb_priv_t *lurb_priv = td_list->ed->purb; + int urb_len = lurb_priv->length; + __u32 *phwHeadP = &td_list->ed->hwHeadP; + int cc; + + cc = TD_CC_GET(m32_swap(td_list->hwINFO)); + if (cc) { + err(" USB-error: %s (%x)", cc_to_string[cc], cc); + + if (*phwHeadP & m32_swap(0x1)) { + if (lurb_priv && + ((td_list->index + 1) < urb_len)) { + *phwHeadP = + (lurb_priv->td[urb_len - 1]->hwNextTD &\ + m32_swap(0xfffffff0)) | + (*phwHeadP & m32_swap(0x2)); + + lurb_priv->td_cnt += urb_len - + td_list->index - 1; + } else + *phwHeadP &= m32_swap(0xfffffff2); + } +#ifdef CONFIG_MPC5200 + td_list->hwNextTD = 0; +#endif + } +} /* replies to the request have to be on a FIFO basis so * we reverse the reversed done-list */ - -static td_t * dl_reverse_done_list (ohci_t *ohci) +static td_t *dl_reverse_done_list(ohci_t *ohci) { __u32 td_list_hc; td_t *td_rev = NULL; td_t *td_list = NULL; - urb_priv_t *lurb_priv = NULL; - td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0; + td_list_hc = m32_swap(ohci->hcca->done_head) & 0xfffffff0; ohci->hcca->done_head = 0; while (td_list_hc) { td_list = (td_t *)td_list_hc; - - if (TD_CC_GET (m32_swap (td_list->hwINFO))) { - lurb_priv = td_list->ed->purb; - dbg(" USB-error/status: %x : %p", - TD_CC_GET (m32_swap (td_list->hwINFO)), td_list); - if (td_list->ed->hwHeadP & m32_swap (0x1)) { - if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) { - td_list->ed->hwHeadP = - (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) | - (td_list->ed->hwHeadP & m32_swap (0x2)); - lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1; - } else - td_list->ed->hwHeadP &= m32_swap (0xfffffff2); - } -#ifdef CONFIG_MPC5200 - td_list->hwNextTD = 0; -#endif - } - + check_status(td_list); td_list->next_dl_td = td_rev; td_rev = td_list; - td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0; + td_list_hc = m32_swap(td_list->hwNextTD) & 0xfffffff0; } return td_list; } +/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/ -/* td done list */ -static int dl_done_list (ohci_t *ohci, td_t *td_list) +static void finish_urb(ohci_t *ohci, urb_priv_t *urb, int status) +{ + if ((status & (ED_OPER | ED_UNLINK)) && (urb->state != URB_DEL)) + urb->finished = sohci_return_job(ohci, urb); + else + dbg("finish_urb: strange.., ED state %x, \n", status); +} + +/* + * Used to take back a TD from the host controller. This would normally be + * called from within dl_done_list, however it may be called directly if the + * HC no longer sees the TD and it has not appeared on the donelist (after + * two frames). This bug has been observed on ZF Micro systems. + */ +static int takeback_td(ohci_t *ohci, td_t *td_list) { - td_t *td_list_next = NULL; ed_t *ed; - int cc = 0; + int cc; int stat = 0; /* urb_t *urb; */ urb_priv_t *lurb_priv; __u32 tdINFO, edHeadP, edTailP; - while (td_list) { - td_list_next = td_list->next_dl_td; + tdINFO = m32_swap(td_list->hwINFO); - tdINFO = m32_swap (td_list->hwINFO); + ed = td_list->ed; + lurb_priv = ed->purb; - ed = td_list->ed; - lurb_priv = ed->purb; + dl_transfer_length(td_list); - dl_transfer_length(td_list); + lurb_priv->td_cnt++; - /* error code of transfer */ - cc = TD_CC_GET (tdINFO); - if (cc != 0) { - dbg("ConditionCode %#x", cc); - stat = cc_to_error[cc]; - } + /* error code of transfer */ + cc = TD_CC_GET(tdINFO); + if (cc) { + err("USB-error: %s (%x)", cc_to_string[cc], cc); + 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 1 - if ((ed->state & (ED_OPER | ED_UNLINK)) && - (lurb_priv->state != URB_DEL)) -#else - if ((ed->state & (ED_OPER | ED_UNLINK))) -#endif - lurb_priv->finished = sohci_return_job(ohci, - lurb_priv); - 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 && - (usb_pipetype (lurb_priv->pipe) != PIPE_INTERRUPT)) { - edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0; - edTailP = m32_swap (ed->hwTailP); - - /* unlink eds if they are not busy */ - if ((edHeadP == edTailP) && (ed->state == ED_OPER)) - ep_unlink (ohci, ed); - } + /* 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) + finish_urb(ohci, lurb_priv, ed->state); + + dbg("dl_done_list: processing TD %x, len %x\n", + lurb_priv->td_cnt, lurb_priv->length); + + if (ed->state != ED_NEW && + (usb_pipetype(lurb_priv->pipe) != PIPE_INTERRUPT)) { + edHeadP = m32_swap(ed->hwHeadP) & 0xfffffff0; + edTailP = m32_swap(ed->hwTailP); + + /* unlink eds if they are not busy */ + if ((edHeadP == edTailP) && (ed->state == ED_OPER)) + ep_unlink(ohci, ed); + } + return stat; +} - td_list = td_list_next; +static int dl_done_list(ohci_t *ohci) +{ + int stat = 0; + td_t *td_list = dl_reverse_done_list(ohci); + + while (td_list) { + td_t *td_next = td_list->next_dl_td; + stat = takeback_td(ohci, td_list); + td_list = td_next; } return stat; } @@ -1100,7 +1159,7 @@ static __u8 root_hub_config_des[] = 0x01, /* __u8 bConfigurationValue; */ 0x00, /* __u8 iConfiguration; */ 0x40, /* __u8 bmAttributes; - Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ + Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ 0x00, /* __u8 MaxPower; */ /* interface */ @@ -1170,14 +1229,17 @@ static unsigned char root_hub_str_index1[] = #define OK(x) len = (x); break #ifdef DEBUG -#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);} -#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);} +#define WR_RH_STAT(x) {info("WR:status %#8x", (x)); writel((x), \ + &gohci.regs->roothub.status); } +#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, \ + (x)); writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); } #else #define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status) -#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1]) +#define WR_RH_PORTSTAT(x) writel((x), \ + &gohci.regs->roothub.portstatus[wIndex-1]) #endif #define RD_RH_STAT roothub_status(&gohci) -#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1) +#define RD_RH_PORTSTAT roothub_portstatus(&gohci, wIndex-1) /* request to virtual root hub */ @@ -1187,13 +1249,13 @@ int rh_check_port_status(ohci_t *controller) int res; res = -1; - temp = roothub_a (controller); + temp = roothub_a(controller); ndp = (temp & RH_A_NDP); #ifdef CONFIG_AT91C_PQFP_UHPBUG ndp = (ndp == 2) ? 1:0; #endif for (i = 0; i < ndp; i++) { - temp = roothub_portstatus (controller, i); + temp = roothub_portstatus(controller, i); /* check for a device disconnect */ if (((temp & (RH_PS_PESC | RH_PS_CSC)) == (RH_PS_PESC | RH_PS_CSC)) && @@ -1208,7 +1270,7 @@ int rh_check_port_status(ohci_t *controller) static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, struct devrequest *cmd) { - void * data = buffer; + void *data = buffer; int leni = transfer_len; int len = 0; int stat = 0; @@ -1220,7 +1282,8 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, __u16 wLength; #ifdef DEBUG -pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe)); +pkt_print(NULL, dev, pipe, buffer, transfer_len, + cmd, "SUB(rh)", usb_pipein(pipe)); #else wait_ms(1); #endif @@ -1230,9 +1293,9 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe } bmRType_bReq = cmd->requesttype | (cmd->request << 8); - wValue = le16_to_cpu (cmd->value); - wIndex = le16_to_cpu (cmd->index); - wLength = le16_to_cpu (cmd->length); + wValue = le16_to_cpu(cmd->value); + wIndex = le16_to_cpu(cmd->index); + wLength = le16_to_cpu(cmd->length); info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x", dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength); @@ -1247,118 +1310,118 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe */ case RH_GET_STATUS: - *(__u16 *) data_buf = cpu_to_le16 (1); OK (2); + *(__u16 *) data_buf = cpu_to_le16(1); + OK(2); case RH_GET_STATUS | RH_INTERFACE: - *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); + *(__u16 *) data_buf = cpu_to_le16(0); + OK(2); case RH_GET_STATUS | RH_ENDPOINT: - *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); + *(__u16 *) data_buf = cpu_to_le16(0); + OK(2); case RH_GET_STATUS | RH_CLASS: - *(__u32 *) data_buf = cpu_to_le32 ( + *(__u32 *) data_buf = cpu_to_le32( RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); - OK (4); + OK(4); case RH_GET_STATUS | RH_OTHER | RH_CLASS: - *(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4); + *(__u32 *) data_buf = cpu_to_le32(RD_RH_PORTSTAT); + OK(4); case RH_CLEAR_FEATURE | RH_ENDPOINT: switch (wValue) { - case (RH_ENDPOINT_STALL): OK (0); + case (RH_ENDPOINT_STALL): + OK(0); } break; case RH_CLEAR_FEATURE | RH_CLASS: switch (wValue) { - case RH_C_HUB_LOCAL_POWER: - OK(0); - case (RH_C_HUB_OVER_CURRENT): - WR_RH_STAT(RH_HS_OCIC); OK (0); + case RH_C_HUB_LOCAL_POWER: + OK(0); + case (RH_C_HUB_OVER_CURRENT): + WR_RH_STAT(RH_HS_OCIC); + OK(0); } break; case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: switch (wValue) { - case (RH_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_POCI); OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); - case (RH_C_PORT_CONNECTION): - WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); - case (RH_C_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_PESC); OK (0); - case (RH_C_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); - case (RH_C_PORT_OVER_CURRENT): - WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); - case (RH_C_PORT_RESET): - WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); + case (RH_PORT_ENABLE): WR_RH_PORTSTAT(RH_PS_CCS); OK(0); + case (RH_PORT_SUSPEND): WR_RH_PORTSTAT(RH_PS_POCI); OK(0); + case (RH_PORT_POWER): WR_RH_PORTSTAT(RH_PS_LSDA); OK(0); + case (RH_C_PORT_CONNECTION): WR_RH_PORTSTAT(RH_PS_CSC); OK(0); + case (RH_C_PORT_ENABLE): WR_RH_PORTSTAT(RH_PS_PESC); OK(0); + case (RH_C_PORT_SUSPEND): WR_RH_PORTSTAT(RH_PS_PSSC); OK(0); + case (RH_C_PORT_OVER_CURRENT):WR_RH_PORTSTAT(RH_PS_OCIC); OK(0); + case (RH_C_PORT_RESET): WR_RH_PORTSTAT(RH_PS_PRSC); OK(0); } break; case RH_SET_FEATURE | RH_OTHER | RH_CLASS: switch (wValue) { - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); - case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT (RH_PS_PRS); - OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_PPS ); - wait_ms(100); - OK (0); - case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT (RH_PS_PES ); - OK (0); + case (RH_PORT_SUSPEND): + WR_RH_PORTSTAT(RH_PS_PSS); OK(0); + case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ + if (RD_RH_PORTSTAT & RH_PS_CCS) + WR_RH_PORTSTAT(RH_PS_PRS); + OK(0); + case (RH_PORT_POWER): + WR_RH_PORTSTAT(RH_PS_PPS); + wait_ms(100); + OK(0); + case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ + if (RD_RH_PORTSTAT & RH_PS_CCS) + WR_RH_PORTSTAT(RH_PS_PES); + OK(0); } break; - case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0); + case RH_SET_ADDRESS: + gohci.rh.devnum = wValue; + OK(0); case RH_GET_DESCRIPTOR: switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ + case (0x01): /* device descriptor */ + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_dev_des), + wLength)); + data_buf = root_hub_dev_des; OK(len); + case (0x02): /* configuration descriptor */ + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_config_des), + wLength)); + data_buf = root_hub_config_des; OK(len); + case (0x03): /* string descriptors */ + if (wValue == 0x0300) { len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_dev_des), - wLength)); - data_buf = root_hub_dev_des; OK(len); - case (0x02): /* configuration descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_config_des), - wLength)); - data_buf = root_hub_config_des; OK(len); - case (0x03): /* string descriptors */ - if(wValue==0x0300) { - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_str_index0), - wLength)); - data_buf = root_hub_str_index0; - OK(len); - } - if(wValue==0x0301) { - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_str_index1), - wLength)); - data_buf = root_hub_str_index1; - OK(len); + leni, + min_t(unsigned int, + sizeof(root_hub_str_index0), + wLength)); + data_buf = root_hub_str_index0; + OK(len); } - default: - stat = USB_ST_STALLED; + if (wValue == 0x0301) { + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_str_index1), + wLength)); + data_buf = root_hub_str_index1; + OK(len); + } + default: + stat = USB_ST_STALLED; } break; case RH_GET_DESCRIPTOR | RH_CLASS: { - __u32 temp = roothub_a (&gohci); + __u32 temp = roothub_a(&gohci); data_buf [0] = 9; /* min length; */ data_buf [1] = 0x29; @@ -1371,13 +1434,13 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe data_buf [3] |= 0x1; if (temp & RH_A_NOCP) /* no overcurrent reporting? */ data_buf [3] |= 0x10; - else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */ + else if (temp & RH_A_OCPM)/* per-port overcurrent reporting? */ data_buf [3] |= 0x8; /* corresponds to data_buf[4-7] */ datab [1] = 0; data_buf [5] = (temp & RH_A_POTPGT) >> 24; - temp = roothub_b (&gohci); + temp = roothub_b(&gohci); data_buf [7] = temp & RH_B_DR; if (data_buf [2] < 7) { data_buf [8] = 0xff; @@ -1389,32 +1452,33 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe len = min_t(unsigned int, leni, min_t(unsigned int, data_buf [0], wLength)); - OK (len); + OK(len); } - case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1); + case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK(1); - case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0); + case RH_SET_CONFIGURATION: WR_RH_STAT(0x10000); OK(0); default: - dbg ("unsupported root hub command"); + dbg("unsupported root hub command"); stat = USB_ST_STALLED; } #ifdef DEBUG - ohci_dump_roothub (&gohci, 1); + ohci_dump_roothub(&gohci, 1); #else wait_ms(1); #endif len = min_t(int, len, leni); if (data != data_buf) - memcpy (data, data_buf, len); + memcpy(data, data_buf, len); dev->act_len = len; dev->status = stat; #ifdef DEBUG - pkt_print(NULL, dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/); + pkt_print(NULL, dev, pipe, buffer, + transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/); #else wait_ms(1); #endif @@ -1451,7 +1515,8 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, #ifdef DEBUG urb->actual_length = 0; - pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); + pkt_print(urb, dev, pipe, buffer, transfer_len, + setup, "SUB", usb_pipein(pipe)); #else wait_ms(1); #endif @@ -1473,7 +1538,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, /* allow more time for a BULK device to react - some are slow */ #define BULK_TO 5000 /* timeout in milliseconds */ - if (usb_pipetype (pipe) == PIPE_BULK) + if (usb_pipetype(pipe) == PIPE_BULK) timeout = BULK_TO; else timeout = 100; @@ -1504,7 +1569,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, if (--timeout) { wait_ms(1); if (!urb->finished) - dbg("\%"); + dbg("*"); } else { err("CTL:TIMEOUT "); @@ -1519,14 +1584,15 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, dev->act_len = transfer_len; #ifdef DEBUG - pkt_print(urb, dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe)); + pkt_print(urb, dev, pipe, buffer, transfer_len, + setup, "RET(ctlr)", usb_pipein(pipe)); #else wait_ms(1); #endif /* free TDs in urb_priv */ - if (usb_pipetype (pipe) != PIPE_INTERRUPT) - urb_free_priv (urb); + if (usb_pipetype(pipe) != PIPE_INTERRUPT) + urb_free_priv(urb); return 0; } @@ -1545,7 +1611,8 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, info("submit_control_msg"); #ifdef DEBUG - pkt_print(NULL, dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); + pkt_print(NULL, dev, pipe, buffer, transfer_len, + setup, "SUB", usb_pipein(pipe)); #else wait_ms(1); #endif @@ -1578,7 +1645,7 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, /* reset the HC and BUS */ -static int hc_reset (ohci_t *ohci) +static int hc_reset(ohci_t *ohci) { #ifdef CONFIG_PCI_EHCI_DEVNO pci_dev_t pdev; @@ -1599,7 +1666,7 @@ static int hc_reset (ohci_t *ohci) int timeout = 1000; pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base); - writel (readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET, + writel(readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET, base + EHCI_USBCMD_OFF); while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET) { @@ -1612,11 +1679,12 @@ static int hc_reset (ohci_t *ohci) } else printf("No EHCI func at %d index!\n", CONFIG_PCI_EHCI_DEVNO); #endif - if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ - writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ + if (readl(&ohci->regs->control) & OHCI_CTRL_IR) { + /* SMM owns the HC */ + writel(OHCI_OCR, &ohci->regs->cmdstatus);/* request ownership */ info("USB HC TakeOver from SMM"); - while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { - wait_ms (10); + while (readl(&ohci->regs->control) & OHCI_CTRL_IR) { + wait_ms(10); if (--smm_timeout == 0) { err("USB HC TakeOver failed!"); return -1; @@ -1625,7 +1693,7 @@ static int hc_reset (ohci_t *ohci) } /* Disable HC interrupts */ - writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); + writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n", ohci->slot_name, @@ -1633,16 +1701,16 @@ static int hc_reset (ohci_t *ohci) /* Reset USB (needed by some controllers) */ ohci->hc_control = 0; - writel (ohci->hc_control, &ohci->regs->control); + writel(ohci->hc_control, &ohci->regs->control); /* HC Reset requires max 10 us delay */ - writel (OHCI_HCR, &ohci->regs->cmdstatus); - while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { + writel(OHCI_HCR, &ohci->regs->cmdstatus); + while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { if (--timeout == 0) { err("USB HC reset timed out!"); return -1; } - udelay (1); + udelay(1); } return 0; } @@ -1653,7 +1721,7 @@ static int hc_reset (ohci_t *ohci) * enable interrupts * connect the virtual root hub */ -static int hc_start (ohci_t * ohci) +static int hc_start(ohci_t *ohci) { __u32 mask; unsigned int fminterval; @@ -1663,44 +1731,44 @@ static int hc_start (ohci_t * ohci) /* Tell the controller where the control and bulk lists are * The lists are empty now. */ - writel (0, &ohci->regs->ed_controlhead); - writel (0, &ohci->regs->ed_bulkhead); + writel(0, &ohci->regs->ed_controlhead); + writel(0, &ohci->regs->ed_bulkhead); - writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ + writel((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ fminterval = 0x2edf; - writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); + writel((fminterval * 9) / 10, &ohci->regs->periodicstart); fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel (fminterval, &ohci->regs->fminterval); - writel (0x628, &ohci->regs->lsthresh); + writel(fminterval, &ohci->regs->fminterval); + writel(0x628, &ohci->regs->lsthresh); /* start controller operations */ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; ohci->disabled = 0; - writel (ohci->hc_control, &ohci->regs->control); + writel(ohci->hc_control, &ohci->regs->control); /* disable all interrupts */ mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | OHCI_INTR_OC | OHCI_INTR_MIE); - writel (mask, &ohci->regs->intrdisable); + writel(mask, &ohci->regs->intrdisable); /* clear all interrupts */ mask &= ~OHCI_INTR_MIE; - writel (mask, &ohci->regs->intrstatus); + writel(mask, &ohci->regs->intrstatus); /* Choose the interrupts we care about now - but w/o MIE */ mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; - writel (mask, &ohci->regs->intrenable); + writel(mask, &ohci->regs->intrenable); #ifdef OHCI_USE_NPS /* required for AMD-756 and some Mac platforms */ - writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, + writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM, &ohci->regs->roothub.a); - writel (RH_HS_LPSC, &ohci->regs->roothub.status); + writel(RH_HS_LPSC, &ohci->regs->roothub.status); #endif /* OHCI_USE_NPS */ -#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);}) +#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); }) /* POTPGT delay is bits 24-31, in 2 ms units. */ - mdelay ((roothub_a (ohci) >> 23) & 0x1fe); + mdelay((roothub_a(ohci) >> 23) & 0x1fe); /* connect the virtual root hub */ ohci->rh.devnum = 0; @@ -1718,7 +1786,7 @@ void usb_event_poll(void) /* an interrupt happens */ -static int hc_interrupt (void) +static int hc_interrupt(void) { ohci_t *ohci = &gohci; struct ohci_regs *regs = ohci->regs; @@ -1726,69 +1794,74 @@ static int hc_interrupt (void) int stat = -1; if ((ohci->hcca->done_head != 0) && - !(m32_swap (ohci->hcca->done_head) & 0x01)) { + !(m32_swap(ohci->hcca->done_head) & 0x01)) { 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; + } else { + ints = readl(®s->intrstatus); + if (ints == ~(u32)0) { + ohci->disabled++; + err("%s device removed!", ohci->slot_name); + return -1; + } else { + ints &= readl(®s->intrenable); + if (ints == 0) { + dbg("hc_interrupt: returning..\n"); + return 0xff; + } + } } - /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */ + /* dbg("Interrupt: %x frame: %x", ints, + le16_to_cpu(ohci->hcca->frame_no)); */ - if (ints & OHCI_INTR_RHSC) { - got_rhsc = 1; + if (ints & OHCI_INTR_RHSC) stat = 0xff; - } if (ints & OHCI_INTR_UE) { ohci->disabled++; - err ("OHCI Unrecoverable Error, controller usb-%s disabled", + err("OHCI Unrecoverable Error, controller usb-%s disabled", ohci->slot_name); /* e.g. due to PCI Master/Target Abort */ #ifdef DEBUG - ohci_dump (ohci, 1); + ohci_dump(ohci, 1); #else - wait_ms(1); + wait_ms(1); #endif /* FIXME: be optimistic, hope that bug won't repeat often. */ /* Make some non-interrupt context restart the controller. */ /* Count and limit the retries though; either hardware or */ /* software errors can go forever... */ - hc_reset (ohci); + hc_reset(ohci); return -1; } if (ints & OHCI_INTR_WDH) { wait_ms(1); - writel (OHCI_INTR_WDH, ®s->intrdisable); - (void)readl (®s->intrdisable); /* flush */ - stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci)); - writel (OHCI_INTR_WDH, ®s->intrenable); - (void)readl (®s->intrdisable); /* flush */ + writel(OHCI_INTR_WDH, ®s->intrdisable); + (void)readl(®s->intrdisable); /* flush */ + stat = dl_done_list(&gohci); + writel(OHCI_INTR_WDH, ®s->intrenable); + (void)readl(®s->intrdisable); /* flush */ } if (ints & OHCI_INTR_SO) { dbg("USB Schedule overrun\n"); - writel (OHCI_INTR_SO, ®s->intrenable); + writel(OHCI_INTR_SO, ®s->intrenable); stat = -1; } /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */ if (ints & OHCI_INTR_SF) { - unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1; + unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1; wait_ms(1); - writel (OHCI_INTR_SF, ®s->intrdisable); + writel(OHCI_INTR_SF, ®s->intrdisable); if (ohci->ed_rm_list[frame] != NULL) - writel (OHCI_INTR_SF, ®s->intrenable); + writel(OHCI_INTR_SF, ®s->intrenable); stat = 0xff; } - writel (ints, ®s->intrstatus); + writel(ints, ®s->intrstatus); return stat; } @@ -1798,12 +1871,12 @@ static int hc_interrupt (void) /* De-allocate all resources.. */ -static void hc_release_ohci (ohci_t *ohci) +static void hc_release_ohci(ohci_t *ohci) { - dbg ("USB HC release ohci usb-%s", ohci->slot_name); + dbg("USB HC release ohci usb-%s", ohci->slot_name); if (!ohci->disabled) - hc_reset (ohci); + hc_reset(ohci); } /*-------------------------------------------------------------------------*/ @@ -1821,16 +1894,16 @@ int usb_lowlevel_init(void) #ifdef CFG_USB_OHCI_CPU_INIT /* cpu dependant init */ - if(usb_cpu_init()) + if (usb_cpu_init()) return -1; #endif #ifdef CFG_USB_OHCI_BOARD_INIT /* board dependant init */ - if(usb_board_init()) + if (usb_board_init()) return -1; #endif - memset (&gohci, 0, sizeof (ohci_t)); + memset(&gohci, 0, sizeof(ohci_t)); /* align the storage */ if ((__u32)&ghcca[0] & 0xff) { @@ -1851,7 +1924,7 @@ int usb_lowlevel_init(void) } ptd = gtd; gohci.hcca = phcca; - memset (phcca, 0, sizeof (struct ohci_hcca)); + memset(phcca, 0, sizeof(struct ohci_hcca)); gohci.disabled = 1; gohci.sleeping = 0; @@ -1879,9 +1952,9 @@ int usb_lowlevel_init(void) gohci.flags = 0; gohci.slot_name = CFG_USB_OHCI_SLOT_NAME; - if (hc_reset (&gohci) < 0) { - hc_release_ohci (&gohci); - err ("can't reset usb-%s", gohci.slot_name); + if (hc_reset(&gohci) < 0) { + hc_release_ohci(&gohci); + err("can't reset usb-%s", gohci.slot_name); #ifdef CFG_USB_OHCI_BOARD_INIT /* board dependant cleanup */ usb_board_init_fail(); @@ -1894,12 +1967,9 @@ int usb_lowlevel_init(void) return -1; } - /* FIXME this is a second HC reset; why?? */ - /* writel(gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control); - wait_ms(10); */ - if (hc_start (&gohci) < 0) { - err ("can't start usb-%s", gohci.slot_name); - hc_release_ohci (&gohci); + if (hc_start(&gohci) < 0) { + err("can't start usb-%s", gohci.slot_name); + hc_release_ohci(&gohci); /* Initialization failed */ #ifdef CFG_USB_OHCI_BOARD_INIT /* board dependant cleanup */ @@ -1914,7 +1984,7 @@ int usb_lowlevel_init(void) } #ifdef DEBUG - ohci_dump (&gohci, 1); + ohci_dump(&gohci, 1); #else wait_ms(1); #endif @@ -1930,17 +2000,17 @@ int usb_lowlevel_stop(void) return 0; /* TODO release any interrupts, etc. */ /* call hc_release_ohci() here ? */ - hc_reset (&gohci); + hc_reset(&gohci); #ifdef CFG_USB_OHCI_BOARD_INIT /* board dependant cleanup */ - if(usb_board_stop()) + if (usb_board_stop()) return -1; #endif #ifdef CFG_USB_OHCI_CPU_INIT /* cpu dependant cleanup */ - if(usb_cpu_stop()) + if (usb_cpu_stop()) return -1; #endif /* This driver is no longer initialised. It needs a new low-level diff --git a/drivers/usb/usb_ohci.h b/drivers/usb/usb_ohci.h index 7a04bf5e8a..50aaafd5fe 100644 --- a/drivers/usb/usb_ohci.h +++ b/drivers/usb/usb_ohci.h @@ -38,6 +38,41 @@ static int cc_to_error[16] = { /* Not Access */ -1 }; +static const char *cc_to_string[16] = { + "No Error", + "CRC: Last data packet from endpoint contained a CRC error.", + "BITSTUFFING: Last data packet from endpoint contained a bit " \ + "stuffing violation", + "DATATOGGLEMISMATCH: Last packet from endpoint had data toggle PID\n" \ + "that did not match the expected value.", + "STALL: TD was moved to the Done Queue because the endpoint returned" \ + " a STALL PID", + "DEVICENOTRESPONDING: Device did not respond to token (IN) or did\n" \ + "not provide a handshake (OUT)", + "PIDCHECKFAILURE: Check bits on PID from endpoint failed on data PID\n"\ + "(IN) or handshake (OUT)", + "UNEXPECTEDPID: Receive PID was not valid when encountered or PID\n" \ + "value is not defined.", + "DATAOVERRUN: The amount of data returned by the endpoint exceeded\n" \ + "either the size of the maximum data packet allowed\n" \ + "from the endpoint (found in MaximumPacketSize field\n" \ + "of ED) or the remaining buffer size.", + "DATAUNDERRUN: The endpoint returned less than MaximumPacketSize\n" \ + "and that amount was not sufficient to fill the\n" \ + "specified buffer", + "reserved1", + "reserved2", + "BUFFEROVERRUN: During an IN, HC received data from endpoint faster\n" \ + "than it could be written to system memory", + "BUFFERUNDERRUN: During an OUT, HC could not retrieve data from\n" \ + "system memory fast enough to keep up with data USB " \ + "data rate.", + "NOT ACCESSED: This code is set by software before the TD is placed" \ + "on a list to be processed by the HC.(1)", + "NOT ACCESSED: This code is set by software before the TD is placed" \ + "on a list to be processed by the HC.(2)", +}; + /* ED States */ #define ED_NEW 0x00 -- 2.25.1