diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/usb/Config.in new/linux-2.4.21-pre4/drivers/usb/Config.in --- orig/linux-2.4.21-pre4/drivers/usb/Config.in Wed Feb 26 09:53:50 2003 +++ new/linux-2.4.21-pre4/drivers/usb/Config.in Mon Feb 9 17:07:54 2004 @@ -27,6 +27,7 @@ define_bool CONFIG_USB_UHCI_ALT n fi dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB + dep_tristate 'SL811HS support' CONFIG_USB_SL811HS $CONFIG_USB comment 'USB Device Class drivers' dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/usb/Makefile new/linux-2.4.21-pre4/drivers/usb/Makefile --- orig/linux-2.4.21-pre4/drivers/usb/Makefile Wed Feb 26 09:53:50 2003 +++ new/linux-2.4.21-pre4/drivers/usb/Makefile Mon Feb 9 17:04:58 2004 @@ -53,6 +53,7 @@ obj-$(CONFIG_USB_UHCI) += usb-uhci.o obj-$(CONFIG_USB_UHCI_ALT) += uhci.o obj-$(CONFIG_USB_OHCI) += usb-ohci.o +obj-$(CONFIG_USB_SL811HS) += hc_sl811.o ifneq ($(CONFIG_USB_EHCI_HCD),n) usbcore-objs += hcd.o diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/usb/hc_simple.c new/linux-2.4.21-pre4/drivers/usb/hc_simple.c --- orig/linux-2.4.21-pre4/drivers/usb/hc_simple.c Wed Sep 11 21:45:17 2002 +++ new/linux-2.4.21-pre4/drivers/usb/hc_simple.c Mon Feb 9 17:23:50 2004 @@ -33,6 +33,24 @@ /* URB HCD API function layer * * * */ + +#if 1 +static const char *hcs_pipetypestr(struct urb *urb) +{ + char *type; + switch (usb_pipetype (urb->pipe)) { + case PIPE_ISOCHRONOUS: type="isoc"; break; + case PIPE_BULK: type="bulk";break; + case PIPE_INTERRUPT: type="intr";break; + case PIPE_CONTROL: type="ctrl";break; + default: type="????"; break; + } + return type; +} +#endif + +static struct urb *qu_next_urb (hci_t * hci, struct urb * urb, int resub_ok); + /*************************************************************************** * Function Name : hcs_urb_queue * @@ -47,10 +65,17 @@ static inline int hcs_urb_queue (hci_t * hci, struct urb * urb) { int i; - DBGFUNC ("enter hcs_urb_queue\n"); if (usb_pipeisoc (urb->pipe)) { + struct hci_device *hci_dev = usb_to_hci (urb->dev); + epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)]; + DBGVERBOSE ("hcs_urb_queue: isoc pipe\n"); +#if 0 + if(usb_pipeisoc(urb->pipe) && sl811_dump) + printk("hcs_urb_queue: urb=%p length=%d (%s:%d)\n", + urb,urb->actual_length,__FILE__,__LINE__); +#endif for (i = 0; i < urb->number_of_packets; i++) { urb->iso_frame_desc[i].actual_length = 0; urb->iso_frame_desc[i].status = -EXDEV; @@ -58,6 +83,8 @@ /* urb->next hack : 1 .. resub, 0 .. single shot */ /* urb->interval = urb->next ? 1 : 0; */ + + ed->iso_index = 0; } urb->status = -EINPROGRESS; @@ -139,7 +166,11 @@ unsigned int pipe = urb->pipe; unsigned long flags; int ret; - +#if 1 + if(sl811_dump && usb_pipedevice(urb->pipe)==4) + printk("hci_submit_urb[%s] adr=%d urb=%p (%s:%d)\n", + hcs_pipetypestr(urb), usb_pipedevice(urb->pipe),urb,__FILE__,__LINE__); +#endif DBGFUNC ("enter hci_submit_urb, pipe = 0x%x\n", urb->pipe); if (!urb->dev || !urb->dev->bus || urb->hcpriv) return -EINVAL; @@ -177,6 +208,8 @@ } +#define USE_NEXT_URB + /*************************************************************************** * Function Name : hci_unlink_urb * @@ -219,8 +252,11 @@ if (urb-> transfer_flags & (USB_ASYNC_UNLINK | USB_TIMEOUT_KILLED)) { /* asynchron with callback */ - +#ifdef USE_NEXT_URB + qu_next_urb(hci, urb, 0); +#else list_del (&urb->urb_list); /* relink the urb to the del list */ +#endif list_add (&urb->urb_list, &hci->del_list); spin_unlock_irqrestore (&usb_urb_lock, flags); @@ -233,7 +269,11 @@ comp = urb->complete; urb->complete = NULL; +#ifdef USE_NEXT_URB + qu_next_urb(hci, urb, 0); +#else list_del (&urb->urb_list); /* relink the urb to the del list */ +#endif list_add (&urb->urb_list, &hci->del_list); spin_unlock_irqrestore (&usb_urb_lock, flags); @@ -394,21 +434,6 @@ #endif /*************************************************************************** - * Function Name : qu_pipeindex - * - * This function gets the index of the pipe. - * - * Input: pipe: the urb pipe - * - * Return: index - **************************************************************************/ -static inline int qu_pipeindex (__u32 pipe) -{ - DBGFUNC ("enter qu_pipeindex\n"); - return (usb_pipeendpoint (pipe) << 1) | (usb_pipecontrol (pipe) ? 0 : usb_pipeout (pipe)); -} - -/*************************************************************************** * Function Name : qu_seturbstate * * This function set the state of the URB. @@ -518,23 +543,32 @@ { struct hci_device *hci_dev = usb_to_hci (urb->dev); epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)]; - +#if 0 + if(usb_pipeisoc(urb->pipe) && sl811_dump) + printk("qu_queue_urb: urb=%p (%s:%d)\n",urb,__FILE__,__LINE__); +#endif DBGFUNC ("Enter qu_queue_urb\n"); /* for ISOC transfers calculate start frame index */ - if (usb_pipeisoc (urb->pipe) && urb->transfer_flags & USB_ISO_ASAP) { - urb->start_frame = ((ed->pipe_head) ? (ed->last_iso + 1) : hci_get_current_frame_number (urb-> dev) + 1) & 0xffff; + if (usb_pipeisoc (urb->pipe)){ + if(urb->transfer_flags & USB_ISO_ASAP) + urb->start_frame = ((ed->pipe_head) ? (ed->last_iso + 1) : hci_get_current_frame_number (urb-> dev) + 1) & 0xffff; + else { + printk("qu_queue_urb: urb->start_frame=%d now %d\n (%s:%d)", + urb->start_frame, hci_get_current_frame_number (urb-> dev), + __FILE__,__LINE__); + } } if (ed->pipe_head) { __list_add (&urb->urb_list, ed->urb_queue.prev, &(ed->urb_queue)); } else { - ed->pipe_head = urb; - qu_queue_active_urb (hci, urb, ed); - if (++hci->active_urbs == 1) - hc_start_int (hci); + ed->pipe_head = urb; + qu_queue_active_urb (hci, urb, ed); + if (++hci->active_urbs == 1) + hc_start_int (hci); } return 0; @@ -560,6 +594,13 @@ DBGFUNC ("enter qu_next_urb\n"); list_del (&urb->urb_list); INIT_LIST_HEAD (&urb->urb_list); +#if 0 + if(usb_pipeisoc(urb->pipe) && sl811_dump){ + printk("qu_next_urb: ed->pipe_head=%p urb=%p active_urbs=%d(%s:%d)\n", + ed->pipe_head, urb, hci->active_urbs,__FILE__,__LINE__); + printk("%s\n", list_empty(&hci->iso_list) ? "empty":"not empty"); + } +#endif if (ed->pipe_head == urb) { #ifdef HC_URB_TIMEOUT @@ -571,11 +612,11 @@ hc_stop_int (hci); if (!list_empty (&ed->urb_queue)) { - urb = list_entry (ed->urb_queue.next, struct urb, urb_list); - list_del (&urb->urb_list); - INIT_LIST_HEAD (&urb->urb_list); - ed->pipe_head = urb; - qu_queue_active_urb (hci, urb, ed); + urb = list_entry (ed->urb_queue.next, struct urb, urb_list); + list_del (&urb->urb_list); + INIT_LIST_HEAD (&urb->urb_list); + ed->pipe_head = urb; + qu_queue_active_urb (hci, urb, ed); } else { ed->pipe_head = NULL; urb = NULL; @@ -598,7 +639,7 @@ static struct urb *qu_return_urb (hci_t * hci, struct urb * urb, int resub_ok) { struct urb *next_urb; - + DBGFUNC ("enter qu_return_rub\n"); next_urb = qu_next_urb (hci, urb, resub_ok); hcs_return_urb (hci, urb, resub_ok); @@ -617,39 +658,51 @@ * list_lh = pointer to the isochronous list * frame_number = the frame number * - * Return: 0 = unsuccessful; 1 = successful + * Return: 0 = unsuccessful; 1 = successful + * Return: units_left **************************************************************************/ static int sh_scan_iso_urb_list (hci_t * hci, struct list_head *list_lh, int frame_number) { - struct list_head *lh = list_lh->next; - struct urb *urb; - - DBGFUNC ("enter sh_scan_iso_urb_list\n"); - hci->td_array->len = 0; - - while (lh != list_lh) { - urb = list_entry (lh, struct urb, urb_list); - lh = lh->next; - if (((frame_number - urb->start_frame) & 0x7ff) < - urb->number_of_packets) { - if (!sh_add_packet (hci, urb)) { - return 0; - } else { - if (((frame_number - - urb->start_frame) & 0x7ff) > 0x400) { - if (qu_urbstate (urb) > 0) - urb = qu_return_urb (hci, urb, 1); - else - urb = qu_next_urb (hci, urb, 1); - - if (lh == list_lh && urb) - lh = &urb->urb_list; - } - } - } - } - return 1; + struct list_head *lh = list_lh->next; + struct urb *urb; + int f; + + DBGFUNC ("enter sh_scan_iso_urb_list\n"); + hci->td_array->len = 0; + + while (lh != list_lh) { + urb = list_entry (lh, struct urb, urb_list); + lh = lh->next; + f = (frame_number - urb->start_frame) & 0x7fff; + if (f < 0x400) { + struct hci_device *hci_dev = usb_to_hci (urb->dev); + epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)]; + if(ed->iso_index >= urb->number_of_packets){ + qu_return_urb(hci, urb, 1); + return 0; + } + + if (!sh_add_packet (hci, urb)) { + return 0; + } else { + if (f > 0x400){ + printk("sh_scan_iso_urb_list: state=%d(%s,%d)\n", + qu_urbstate (urb),__FILE__,__LINE__); + if (qu_urbstate (urb) > 0) + urb = qu_return_urb (hci, urb, 1); + else + urb = qu_next_urb (hci, urb, 1); + + if (lh == list_lh && urb) + lh = &urb->urb_list; + } + urb->start_frame = frame_number + 1; + } + return 0; + } + } + return 1; } /*************************************************************************** @@ -661,7 +714,8 @@ * Input: hci = data structure for the host controller * list_lh = pointer to the isochronous list * - * Return: 0 = unsuccessful; 1 = successful + * Return: 0 = unsuccessful; 1 = successful + * Return: units_left, 0 = no_more_packet **************************************************************************/ static int sh_scan_urb_list (hci_t * hci, struct list_head *list_lh) { @@ -692,7 +746,6 @@ urb->interval, usb_pipeint (urb->pipe)); urb->start_frame = hci->frame_number; return 0; - } } } @@ -742,14 +795,26 @@ if (hci->td_array->len == 0 && !list_empty (&hci->ctrl_list) && units_left > 0) { units_left = sh_scan_urb_list (hci, &hci->ctrl_list); + if(sl811_dump) + printk("sh_scan_urb_list: => %d iso_list:%s (%s:%d)\n", + units_left, list_empty(&hci->iso_list) ? "empty" : "not empty" + , __FILE__,__LINE__); } +#if 1 + /* schedule the next available isochronous transfer or the next + * stage of isochronous transfer */ + + if (isSOF && hci->td_array->len == 0 && !list_empty (&hci->iso_list) && units_left > 0) { + /* units_left = sh_scan_urb_list (hci, &hci->iso_list); */ + units_left = sh_scan_iso_urb_list (hci, &hci->iso_list, hci->frame_number); + } +#endif + /* schedule the next available bulk transfer or the next * stage of the bulk transfer */ - if (hci->td_array->len == 0 && !list_empty (&hci->bulk_list) && units_left > 0) { sh_scan_urb_list (hci, &hci->bulk_list); - /* be fair to each BULK URB (move list head around) * only when the new SOF happens */ @@ -786,19 +851,38 @@ int ret; int i = 0; int iso = 0; + struct hci_device *hci_dev = usb_to_hci (urb->dev); + epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)]; DBGFUNC ("enter sh_add_packet\n"); if (maxps == 0) maxps = 8; + if(sl811_dump && address==4) + printk("sh_add_packet[%s] adr=%d urb=%p (%s:%d)\n", + hcs_pipetypestr(urb), address, urb, __FILE__,__LINE__); + /* calculate len, toggle bit and add the transaction */ switch (usb_pipetype (urb->pipe)) { case PIPE_ISOCHRONOUS: pid = out ? PID_OUT : PID_IN; iso = 1; - i = hci->frame_number - urb->start_frame; + if(sl811_dump) + printk("iso_index=%d number_of_packets=%d (%s:%d)\n", + ed->iso_index,urb->number_of_packets,__FILE__,__LINE__); + i = ed->iso_index; + if(i >= urb->number_of_packets) + return 0; data = urb->transfer_buffer + urb->iso_frame_desc[i].offset; len = urb->iso_frame_desc[i].length; +#if 1 + if(sl811_dump){ + int ra; + asm("move %0,$31":"=r" (ra)); + printk("sh_add_packet: ra=%x urb=%p i=%d len=%d number_of_packet=%d (%s:%d)\n", + ra,urb,i,len,urb->number_of_packets,__FILE__,__LINE__); + } +#endif break; case PIPE_BULK: /* BULK and BULK0 */ @@ -855,7 +939,11 @@ ret = hc_add_trans (hci, len, data, toggle, maxps, slow, endpoint, address, pid, iso, qu_urbstate (urb)); - +#if 1 + if(iso && sl811_dump){ + printk("sh_add_packet: hc_add_trans()=>%d (%s:%d)\n",ret,__FILE__,__LINE__); + } +#endif DBGVERBOSE ("transfer_pa: addr:%d ep:%d pid:%x tog:%x iso:%x sl:%x " "max:%d\n len:%d ret:%d data:%p left:%d\n", address, endpoint, pid, toggle, iso, slow, @@ -976,16 +1064,20 @@ active = 0; if ((cc & +#if 1 + (SL11H_STATMASK_ERROR | +#else (SL11H_STATMASK_ERROR | SL11H_STATMASK_TMOUT | +#endif SL11H_STATMASK_OVF | SL11H_STATMASK_STALL)) && !(cc & SL11H_STATMASK_NAK)) { if (++urb->error_count > 3) { - DBGERR ("done_list: excessive error: errcount = 0x%x, cc = 0x%x\n", + DBGERR ("done_list: excessive error: errcount = %d, cc = 0x%02x\n", urb->error_count, cc); urb_state = 0; active = 0; } else { - DBGERR ("done_list: packet err, cc = 0x%x, " + DBGERR ("done_list: packet err, cc = 0x%02x, " " urb->length = 0x%x, actual_len = 0x%x," " urb_state =0x%x\n", cc, urb->transfer_buffer_length, @@ -1006,7 +1098,7 @@ } else { if (cc & SL11H_STATMASK_NAK) { if (hci->nakCnt < 0x10000) { - hci->nakCnt++; + /* hci->nakCnt++; */ hci->last_packet_nak = 1; active = 1; *isExcessNak = 0; @@ -1029,9 +1121,17 @@ usb_pipeout (urb->pipe), toggle); } if (usb_pipeisoc (urb->pipe)) { + struct hci_device *hci_dev = usb_to_hci (urb->dev); + epd_t *ed = &hci_dev->ed[qu_pipeindex (urb->pipe)]; urb->iso_frame_desc[iso_index].actual_length = actbytes; urb->iso_frame_desc[iso_index].status = cc_to_error (cc); - active = (iso_index < urb->number_of_packets); + active = (iso_index < urb->number_of_packets-1); + ed->iso_index++; +#if 1 + if(sl811_dump) + printk("%s iso_index=%d active=%d urb_state=%d(%s:%d)\n", + __FUNCTION__,iso_index,active,urb_state,__FILE__,__LINE__); +#endif } } if (!active) { @@ -1042,7 +1142,7 @@ urb->status); } hci->td_array->len = 0; - qu_return_urb (hci, urb, 1); + qu_return_urb (hci, urb, 0); return -1; } else { /* We do not want to decrement the urb_state if exceeded nak, @@ -1070,3 +1170,7 @@ return urb_state; } + +/*** Local Variables: ***/ +/*** compile-command: "cd ../..;make" ***/ +/*** End: ***/ diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/usb/hc_simple.h new/linux-2.4.21-pre4/drivers/usb/hc_simple.h --- orig/linux-2.4.21-pre4/drivers/usb/hc_simple.h Wed Sep 11 21:45:17 2002 +++ new/linux-2.4.21-pre4/drivers/usb/hc_simple.h Mon Feb 9 17:30:21 2004 @@ -27,6 +27,7 @@ // int urb_state; struct timer_list timeout; int last_iso; /* timestamp of last queued ISOC transfer */ + int iso_index; } epd_t; @@ -229,3 +230,18 @@ } } } + +/*************************************************************************** + * Function Name : qu_pipeindex + * + * This function gets the index of the pipe. + * + * Input: pipe: the urb pipe + * + * Return: index + **************************************************************************/ +static inline int qu_pipeindex (__u32 pipe) +{ + DBGFUNC ("enter qu_pipeindex\n"); + return (usb_pipeendpoint (pipe) << 1) | (usb_pipecontrol (pipe) ? 0 : usb_pipeout (pipe)); +} diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/usb/hc_sl811.c new/linux-2.4.21-pre4/drivers/usb/hc_sl811.c --- orig/linux-2.4.21-pre4/drivers/usb/hc_sl811.c Wed Feb 26 07:03:10 2003 +++ new/linux-2.4.21-pre4/drivers/usb/hc_sl811.c Mon Feb 9 17:00:33 2004 @@ -22,6 +22,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *-------------------------------------------------------------------------*/ +#define USE_PROC +#ifdef USE_PROC +#include +#endif + + +#define EXPORT_SYMTAB #include #include @@ -38,7 +45,7 @@ #include #include -#include "../core/hcd.h" +#include "hcd.h" #undef HC_URB_TIMEOUT #undef HC_SWITCH_INT @@ -86,6 +93,7 @@ #include "hc_simple.h" static int urb_debug = 0; +static int sl811_dump = 0; #include "hc_simple.c" #include "hc_sl811_rh.c" @@ -95,9 +103,11 @@ * NOTE: values need to modify for different development boards */ -static int base_addr = 0xd3800000; -static int data_reg_addr = 0xd3810000; -static int irq = 34; +#include + +static int base_addr = 0xaa0000c0; +static int data_reg_addr = 0xaa0000c2; +static int irq = GIU_IRQ(2); /* forware declaration */ @@ -116,6 +126,8 @@ MODULE_PARM (irq, "i"); MODULE_PARM_DESC (irq, "IRQ 34 (default)"); +static int workaround_e4_miss_packet = 1; + static int hc_reset (hci_t * hci); /*************************************************************************** @@ -128,7 +140,7 @@ * * Return: data **************************************************************************/ -char SL811Read (hci_t * hci, char offset) +unsigned char SL811Read (hci_t * hci, char offset) { hcipriv_t *hp = &hci->hp; char data; @@ -570,6 +582,7 @@ int mask = SL11H_INTMASK_XFERDONE | SL11H_INTMASK_SOFINTR | SL11H_INTMASK_INSRMV | SL11H_INTMASK_USBRESET; + /* printk("hc_start_int: (%s:%d)\n",__FILE__,__LINE__); */ SL811Write (hci, IntEna, mask); #endif } @@ -702,7 +715,20 @@ SL811BufWrite (hci, SL11H_BUFADDRREG, (__u8 *) & setup_data[0], 4); - SL811Write (hci, SL11H_HOSTCTLREG, cmd); + if(workaround_e4_miss_packet){ + __u8 sofc; + sofc = SL811Read(hci, SL11H_SOFTMRREG); + if(sofc > 20) + SL811Write(hci, SL11H_HOSTCTLREG, cmd); + else if(sofc > 2) + SL811Write(hci, SL11H_HOSTCTLREG, cmd|0x20); + else { + while(sofc < 2) + sofc = SL811Read(hci, SL11H_SOFTMRREG); + SL811Write(hci, SL11H_HOSTCTLREG, cmd|0x20); + } + } + else SL811Write (hci, SL11H_HOSTCTLREG, cmd); #if 0 /* The SL811 has a hardware flaw when hub devices sends out @@ -739,16 +765,17 @@ *****************************************************************/ static void hc_interrupt (int irq, void *__hci, struct pt_regs *r) { - char ii; + unsigned char ii; hci_t *hci = __hci; int isExcessNak = 0; int urb_state = 0; - char tmpIrq = 0; + /* char tmpIrq = 0; */ /* Get value from interrupt status register */ ii = SL811Read (hci, SL11H_INTSTATREG); - + SL811Write (hci, SL11H_INTSTATREG, ii); + if (ii & SL11H_INTMASK_INSRMV) { /* Device insertion or removal detected for the USB port */ @@ -761,11 +788,10 @@ /* Clear all interrupts */ - SL811Write (hci, SL11H_INTSTATREG, 0xff); + /* SL811Write (hci, SL11H_INTSTATREG, 0xff); */ if (ii & SL11H_INTMASK_XFERDONE) { /* USB Done interrupt occurred */ - urb_state = sh_done_list (hci, &isExcessNak); #ifdef WARNING if (hci->td_array->len > 0) @@ -773,33 +799,43 @@ hci->td_array->len); #endif if (hci->td_array->len == 0 && !isExcessNak +#if 0 && !(ii & SL11H_INTMASK_SOFINTR) && (urb_state == 0)) { - if (urb_state == 0) { +#else /* test by nari */ + && !(ii & SL11H_INTMASK_SOFINTR)) { +#endif + + if (urb_state == 0) { /* All urb_state has not been finished yet! * continue with the current urb transaction */ - if (hci->last_packet_nak == 0) { - if (!usb_pipecontrol - (hci->td_array->td[0].urb->pipe)) - sh_add_packet (hci, hci->td_array-> td[0].urb); - } - } else { + if (hci->last_packet_nak == 0) { + if (!usb_pipecontrol(hci->td_array->td[0].urb->pipe) +#if 1 /* test by nari */ + && !usb_pipeisoc(hci->td_array->td[0].urb->pipe) +#endif + ) + sh_add_packet (hci, hci->td_array-> td[0].urb); + } + } else { /* The last transaction has completed: * schedule the next transaction */ - sh_schedule_trans (hci, 0); - } + sh_schedule_trans (hci, 0); + } } - SL811Write (hci, SL11H_INTSTATREG, 0xff); + /* SL811Write (hci, SL11H_INTSTATREG, 0xff); */ return; } if (ii & SL11H_INTMASK_SOFINTR) { hci->frame_number = (hci->frame_number + 1) % 2048; - if (hci->td_array->len == 0) + if (hci->td_array->len == 0){ sh_schedule_trans (hci, 1); + sofWaitCnt = 0; + } else { if (sofWaitCnt++ > 100) { /* The last transaction has not completed. @@ -808,17 +844,19 @@ * (THIS NEEDS TO BE WORK ON MORE, IT SHOULD NEVER * GET TO THIS POINT) */ - +#if 1 DBGERR ("SOF interrupt: td_array->len = 0x%x, s/b: 0\n", hci->td_array->len); urb_print (hci->td_array->td[hci->td_array->len - 1].urb, "INTERRUPT", 0); +#endif sh_done_list (hci, &isExcessNak); - SL811Write (hci, SL11H_INTSTATREG, 0xff); + /* SL811Write (hci, SL11H_INTSTATREG, 0xff); */ hci->td_array->len = 0; sofWaitCnt = 0; } } +#if 0 tmpIrq = SL811Read (hci, SL11H_INTSTATREG) & SL811Read (hci, SL11H_INTENBLREG); if (tmpIrq) { DBG ("IRQ occurred while service SOF: irq = 0x%x\n", @@ -833,13 +871,14 @@ tmpIrq); urb_state = sh_done_list (hci, &isExcessNak); } - SL811Write (hci, SL11H_INTSTATREG, 0xff); + /* SL811Write (hci, SL11H_INTSTATREG, 0xff); */ } +#endif } else { DBG ("SL811 ISR: unknown, int = 0x%x \n", ii); } - SL811Write (hci, SL11H_INTSTATREG, 0xff); + /* SL811Write (hci, SL11H_INTSTATREG, 0xff); */ return; } @@ -1195,7 +1234,9 @@ kfree (hp->tl); if (hp->hcport > 0) { +#if 0 release_region (hp->hcport, 2); +#endif hp->hcport = 0; } @@ -1213,6 +1254,8 @@ kfree (hci); } + + /***************************************************************** * * Function Name: init_irq @@ -1227,8 +1270,20 @@ *****************************************************************/ void init_irq (void) { +#if 0 /* for only Humblesoft VR4131 DIMM Board */ GPDR &= ~(1 << 13); set_GPIO_IRQ_edge (1 << 13, GPIO_RISING_EDGE); +#else + /* vr41xx_set_irq_trigger(2, TRIGGER_EDGE, SIGNAL_HOLD); */ + +#define VR4131_GIUINTTYPL (*(volatile unsigned short *)0xaf000150) +#define VR4131_GIUINTHTSELL (*(volatile unsigned short *)0xaf000158) + + u16 mask = 0x0004; /* GPIO2 */ + + VR4131_GIUINTTYPL |= mask; + VR4131_GIUINTHTSELL |= mask; +#endif } /***************************************************************** @@ -1258,22 +1313,24 @@ init_irq (); hp = &hci->hp; - +#if 0 if (!request_region (addr, 256, "SL811 USB HOST")) { DBGERR ("request address %d failed", addr); hc_release_hci (hci); return -EBUSY; } +#endif hp->hcport = addr; if (!hp->hcport) { DBGERR ("Error mapping SL811 Memory 0x%x", hp->hcport); } - +#if 0 if (!request_region (addr2, 256, "SL811 USB HOST")) { DBGERR ("request address %d failed", addr2); hc_release_hci (hci); return -EBUSY; } +#endif hp->hcport2 = addr2; if (!hp->hcport2) { DBGERR ("Error mapping SL811 Memory 0x%x", hp->hcport2); @@ -1285,12 +1342,16 @@ } usb_register_bus (hci->bus); - +#if 0 if (request_irq (irq, hc_interrupt, 0, "SL811", hci) != 0) { - DBGERR ("request interrupt %d failed", irq); +#else + if (request_irq (irq, hc_interrupt, SA_INTERRUPT, "SL811", hci) != 0) { +#endif + DBGERR ("request interrupt %d failed", irq); hc_release_hci (hci); return -EBUSY; } + hp->irq = irq; printk (KERN_INFO __FILE__ ": USB SL811 at %x, addr2 = %x, IRQ %d\n", @@ -1306,6 +1367,42 @@ return 0; } +#ifdef USE_PROC +static int sl811_read_proc(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0,s; + char *p = buf; + struct list_head *hci_l; + hci_t *hci; + + for (hci_l = hci_hcd_list.next; hci_l != &hci_hcd_list;hci_l=hci_l->next) { + hci = list_entry (hci_l, hci_t, hci_hcd_list); + s = sprintf(p,"hci=%p iso_list:%s empty\n", + hci,list_empty(&hci->iso_list)?"":"not"); + p += s, len += s; + } + *eof = 1; + return len; +} + + static int sl811_write_proc (struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int i,c; + void sl811_dump_set(int v); + + for(i=0;iread_proc = sl811_read_proc; + entry->write_proc = sl811_write_proc; + entry->data = NULL; + } + +#endif + return ret; } @@ -1345,6 +1452,12 @@ hci_t *hci; DBGFUNC ("Enter hci_hcd_cleanup\n"); + +#ifdef USE_PROC + remove_proc_entry("sl811", NULL); +#endif + + for (hci_l = hci_hcd_list.next; hci_l != &hci_hcd_list;) { hci = list_entry (hci_l, hci_t, hci_hcd_list); hci_l = hci_l->next; @@ -1352,8 +1465,47 @@ } } + +void sl811_dump_set(int v) +{ + printk(KERN_INFO "sl811_dump_set(%d)\n",v); + sl811_dump = v; +} + +void sl811_check(void) +{ +#define VR4131_GIUPIODL (*(volatile unsigned short *)0xaf000144) +#define VR4131_GIUINTSTATL (*(volatile unsigned short *)0xaf000148) +#define VR4131_GIUINTENL (*(volatile unsigned short *)0xaf00014c) +#define VR4131_GIUINTTYPL (*(volatile unsigned short *)0xaf000150) +#define VR4131_GIUINTHTSELL (*(volatile unsigned short *)0xaf000158) + +#define VR4131_SYSINT1REG (*(volatile unsigned short *)0xaf000080) +#define VR4131_GIUINTLREG (*(volatile unsigned short *)0xaf000088) +#define VR4131_MSYSINT1REG (*(volatile unsigned short *)0xaf00008c) +#define VR4131_MGIUINTLREG (*(volatile unsigned short *)0xaf000094) + + printk("sl811_check:\n"); + printk(" GIUIPIODL =%04x\n",VR4131_GIUPIODL); + printk(" GIUINTSTATL =%04x\n",VR4131_GIUINTSTATL); + printk(" GIUINTENL =%04x\n",VR4131_GIUINTENL); + printk(" SYSINT1REG =%04x\n",VR4131_SYSINT1REG); + printk(" GIUINTLREG =%04x\n",VR4131_GIUINTLREG); + printk(" MSYSINT1REG =%04x\n",VR4131_MSYSINT1REG); + printk(" MGIUINTLREG =%04x\n",VR4131_MGIUINTLREG); +} + +EXPORT_SYMBOL(sl811_dump_set); +EXPORT_SYMBOL(sl811_check); +EXPORT_SYMBOL(sl811_dump); + + module_init (hci_hcd_init); module_exit (hci_hcd_cleanup); MODULE_AUTHOR ("Pei Liu "); MODULE_DESCRIPTION ("USB SL811HS Host Controller Driver"); + +/*** Local Variables: ***/ +/*** compile-command: "cd ../..;make" ***/ +/*** End: ***/ diff -urN -X ignore orig/linux-2.4.21-pre4/drivers/usb/hc_sl811_rh.c new/linux-2.4.21-pre4/drivers/usb/hc_sl811_rh.c --- orig/linux-2.4.21-pre4/drivers/usb/hc_sl811_rh.c Wed Sep 11 21:45:17 2002 +++ new/linux-2.4.21-pre4/drivers/usb/hc_sl811_rh.c Mon Feb 9 17:03:04 2004 @@ -153,8 +153,13 @@ } len = i / 8 + 1; +#ifdef min +#undef min +#endif +#define min(x,y) ((x)<(y) ?(x):(y)) + if (ret > 0) { - memcpy (rh_data, data, min (len, min (rh_len, (int)sizeof (data)))); + memcpy (rh_data, data, min(len, min(rh_len, (int)sizeof(data)))); return len; } return 0; @@ -484,7 +489,8 @@ hci->rh.urb = NULL; urb->hcpriv = NULL; - usb_put_dev (urb->dev); + /* usb_put_dev (urb->dev); */ + usb_free_dev (urb->dev); urb->dev = NULL; if (urb->transfer_flags & USB_ASYNC_UNLINK) { urb->status = -ECONNRESET;