LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 696|回复: 3

请问像这种纯文本的补丁应该怎么打啊?

[复制链接]
发表于 2005-1-10 10:31:56 | 显示全部楼层 |阅读模式
我在网上找到了一个补丁,但是全文本的,不知道该怎么打上。

  1. ChangeSet 1.1074.1.15, 2003/07/09 22:17:36-07:00, yinah@couragetech.com.cn

  2. [PATCH] USB: patch for sl811 usb host controller driver

  3. Ok, I have get rid of the typedefs and make it build on 2.4.21.

  4. I'm not try to merge this with the existing sl811 driver, I modifed most
  5. of it for support isochronous transfer mode, especially the structrue
  6. and the urb schedule part, so it's almost a new one.  Some one need this
  7. feature can use this one, others can still use the existing.  So may be
  8. it makes sense to have two different drivers.  Note: I wrote it on
  9. 2.4.18,  at our board which use SA1110, and I test it with usb mouse,
  10. usb moving disk and a web camera which use ov511 chipset.


  11. drivers/usb/host/Config.in |    1
  12. drivers/usb/host/Makefile  |    1
  13. drivers/usb/host/sl811.c   | 2749 +++++++++++++++++++++++++++++++++++++++++++++
  14. drivers/usb/host/sl811.h   |  177 ++
  15. 4 files changed, 2928 insertions(+)


  16. diff -Nru a/drivers/usb/host/Config.in b/drivers/usb/host/Config.in
  17. --- a/drivers/usb/host/Config.in        Mon Jul 14 10:04:12 2003
  18. +++ b/drivers/usb/host/Config.in        Mon Jul 14 10:04:12 2003
  19. @@ -12,4 +12,5 @@
  20.     define_bool CONFIG_USB_UHCI_ALT n
  21. fi
  22. dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
  23. +dep_tristate '  SL811HS Alternate (support isochornous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB

  24. diff -Nru a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
  25. --- a/drivers/usb/host/Makefile        Mon Jul 14 10:04:12 2003
  26. +++ b/drivers/usb/host/Makefile        Mon Jul 14 10:04:12 2003
  27. @@ -9,6 +9,7 @@
  28. obj-$(CONFIG_USB_UHCI_ALT)                        += uhci.o
  29. obj-$(CONFIG_USB_UHCI)                                += usb-uhci.o
  30. obj-$(CONFIG_USB_OHCI)                                += usb-ohci.o
  31. +obj-$(CONFIG_USB_SL811HS_ALT)                          += sl811.o

  32. # Extract lists of the multi-part drivers.
  33. # The 'int-*' lists are the intermediate files used to build the multi's.
  34. diff -Nru a/drivers/usb/host/sl811.c b/drivers/usb/host/sl811.c
  35. --- /dev/null        Wed Dec 31 16:00:00 1969
  36. +++ b/drivers/usb/host/sl811.c        Mon Jul 14 10:04:12 2003
  37. @@ -0,0 +1,2749 @@
  38. +/*
  39. + * SL811 Host Controller Interface driver for USB.
  40. + *
  41. + * Copyright (c) 2003/06, Courage Co., Ltd.
  42. + *
  43. + * Based on:
  44. + *        1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
  45. + *           Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
  46. + *           Adam Richter, Gregory P. Smith;
  47. +          2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
  48. + *
  49. + * It's now support isochronous mode and more effective than hc_sl811.o
  50. + *
  51. + * To do:
  52. + *        1.Modify the timeout part, it's some messy
  53. + *        2.Use usb-a and usb-b set in Ping-Pong mode
  54. +        
  55. + * This program is free software; you can redistribute it and/or modify
  56. + * it under the terms of the GNU General Public License as published by
  57. + * the Free Software Foundation; either version 2 of the License, or
  58. + * (at your option) any later version.
  59. + *
  60. + */
  61. +
  62. +#include <linux/config.h>
  63. +#include <linux/module.h>
  64. +#include <linux/kernel.h>
  65. +#include <linux/delay.h>
  66. +#include <linux/sched.h>
  67. +#include <linux/slab.h>
  68. +#include <linux/errno.h>
  69. +#include <linux/init.h>
  70. +#include <linux/smp_lock.h>
  71. +#include <linux/list.h>
  72. +#include <linux/ioport.h>
  73. +#include <asm/io.h>
  74. +#include <asm/arch/irq.h>
  75. +#include <linux/usb.h>
  76. +
  77. +#include "hcd.h"
  78. +#include "hub.h"
  79. +#include "sl811.h"
  80. +
  81. +#define DRIVER_VERSION "v0.28"
  82. +#define DRIVER_AUTHOR "Yin Aihua <yinah@couragetech.com.cn>"
  83. +#define DRIVER_DESC "Sl811 USB Host Controller Driver"
  84. +
  85. +static int sl811_addr_io = 0xf100000e;
  86. +static int sl811_data_io = 0xf100000f;
  87. +static int sl811_irq = 44;
  88. +
  89. +static LIST_HEAD(sl811_hcd_list);
  90. +
  91. +/*
  92. + * 0, normal prompt and information
  93. + * 1, error should not occur in normal
  94. + * 2, error maybe occur in normal
  95. + * 3, useful and detail debug information
  96. + * 4, function level enter and level inforamtion
  97. + * 5, endless information will output because of timer function or interrupt
  98. + */
  99. +static int debug = 0;
  100. +
  101. +MODULE_PARM(sl811_addr_io,"i");
  102. +MODULE_PARM_DESC(sl811_addr_io,"sl811 address io port 0xf100000e");
  103. +MODULE_PARM(sl811_data_io,"i");
  104. +MODULE_PARM_DESC(sl811_data_io,"sl811 data io port 0xf100000f");
  105. +MODULE_PARM(sl811_irq,"i");
  106. +MODULE_PARM_DESC(sl811_irq,"sl811 irq 44(default)");
  107. +MODULE_PARM(debug,"i");
  108. +MODULE_PARM_DESC(debug,"debug level");
  109. +
  110. +static void sl811_rh_int_timer_do(unsigned long ptr);
  111. +static void sl811_transfer_done(struct sl811_hc *hc, int sof);
  112. +
  113. +/*
  114. + * Read        a byte of data from the        SL811H/SL11H
  115. + */
  116. +static __u8 sl811_read(struct sl811_hc *hc,        __u8 offset)
  117. +{
  118. +        __u8 data;
  119. +
  120. +        writeb(offset, hc->addr_io);
  121. +        wmb();
  122. +        data = readb(hc->data_io);
  123. +        rmb();
  124. +
  125. +        return data;
  126. +}
  127. +
  128. +/*
  129. + * Write a byte        of data        to the SL811H/SL11H
  130. + */
  131. +static void sl811_write(struct sl811_hc *hc, __u8 offset, __u8 data)
  132. +{
  133. +        writeb(offset, hc->addr_io);
  134. +        writeb(data, hc->data_io);
  135. +        wmb();
  136. +}
  137. +
  138. +/*
  139. + * Read        consecutive bytes of data from the SL811H/SL11H        buffer
  140. + */
  141. +static void sl811_read_buf(struct sl811_hc *hc, __u8 offset, __u8 *buf, __u8 size)
  142. +{
  143. +        writeb(offset, hc->addr_io);
  144. +        wmb();
  145. +        while (size--) {
  146. +                *buf++ = readb(hc->data_io);
  147. +                rmb();
  148. +        }
  149. +}
  150. +
  151. +/*
  152. + * Write consecutive bytes of data to the SL811H/SL11H buffer
  153. + */
  154. +static void sl811_write_buf(struct sl811_hc *hc, __u8 offset, __u8 *buf, __u8 size)
  155. +{
  156. +        writeb(offset, hc->addr_io);
  157. +        wmb();
  158. +        while (size--) {
  159. +                writeb(*buf, hc->data_io);
  160. +                wmb();
  161. +                buf++;
  162. +        }
  163. +}
  164. +
  165. +/*
  166. + * This        routine        test the Read/Write functionality of SL811HS registers
  167. + */
  168. +static int sl811_reg_test(struct sl811_hc *hc)
  169. +{
  170. +        int i, data, result = 0;
  171. +        __u8 buf[256];
  172. +
  173. +        for (i = 0x10; i < 256;        i++) {
  174. +                /* save        the original buffer */
  175. +                buf[i] = sl811_read(hc,        i);
  176. +
  177. +                /* Write the new data to the buffer */
  178. +                sl811_write(hc,        i, i);
  179. +        }
  180. +
  181. +        /* compare the written data */
  182. +        for (i = 0x10; i < 256;        i++) {
  183. +                data = sl811_read(hc, i);
  184. +                if (data != i) {
  185. +                        PDEBUG(1, "Pattern test failed!! value = 0x%x, s/b 0x%x", data, i);
  186. +                        result = -1;
  187. +                }
  188. +        }
  189. +
  190. +        /* restore the data */
  191. +        for (i = 0x10; i < 256;        i++)
  192. +                sl811_write(hc,        i, buf[i]);
  193. +
  194. +        return result;
  195. +}
  196. +
  197. +/*
  198. + * Display all SL811HS register        values
  199. + */
  200. +static void sl811_reg_show(struct sl811_hc *hc)
  201. +{
  202. +        int i;
  203. +
  204. +        for (i = 0; i <        256; i++)
  205. +                PDEBUG(4, "offset %d: 0x%x", i, sl811_read(hc, i));
  206. +}
  207. +
  208. +/*
  209. + * This        function enables SL811HS interrupts
  210. + */
  211. +static void sl811_enable_interrupt(struct sl811_hc *hc)
  212. +{
  213. +        PDEBUG(4, "enter");
  214. +        sl811_write(hc, SL811_INTR, SL811_INTR_DONE_A | SL811_INTR_SOF | SL811_INTR_INSRMV);
  215. +}
  216. +
  217. +/*
  218. + * This        function disables SL811HS interrupts
  219. + */
  220. +static void sl811_disable_interrupt(struct sl811_hc *hc)
  221. +{
  222. +        PDEBUG(4, "enter");
  223. +        // Disable all other interrupt except for insert/remove.
  224. +        sl811_write(hc,        SL811_INTR, SL811_INTR_INSRMV);
  225. +}
  226. +
  227. +/*
  228. + * SL811 Virtual Root Hub
  229. + */
  230. +
  231. +/* Device descriptor */
  232. +static __u8 sl811_rh_dev_des[] =
  233. +{
  234. +        0x12,       /*  __u8  bLength; */
  235. +        0x01,       /*  __u8  bDescriptorType; Device */
  236. +        0x10,            /*  __u16 bcdUSB; v1.1 */
  237. +        0x01,
  238. +        0x09,            /*  __u8  bDeviceClass; HUB_CLASSCODE */
  239. +        0x00,            /*  __u8  bDeviceSubClass; */
  240. +        0x00,       /*  __u8  bDeviceProtocol; */
  241. +        0x08,       /*  __u8  bMaxPacketSize0; 8 Bytes */
  242. +        0x00,       /*  __u16 idVendor; */
  243. +        0x00,
  244. +        0x00,       /*  __u16 idProduct; */
  245. +         0x00,
  246. +        0x00,       /*  __u16 bcdDevice; */
  247. +         0x00,
  248. +        0x00,       /*  __u8  iManufacturer; */
  249. +        0x02,       /*  __u8  iProduct; */
  250. +        0x01,       /*  __u8  iSerialNumber; */
  251. +        0x01        /*  __u8  bNumConfigurations; */
  252. +};
  253. +
  254. +/* Configuration descriptor */
  255. +static __u8 sl811_rh_config_des[] =
  256. +{
  257. +        0x09,       /*  __u8  bLength; */
  258. +        0x02,       /*  __u8  bDescriptorType; Configuration */
  259. +        0x19,       /*  __u16 wTotalLength; */
  260. +        0x00,
  261. +        0x01,       /*  __u8  bNumInterfaces; */
  262. +        0x01,       /*  __u8  bConfigurationValue; */
  263. +        0x00,       /*  __u8  iConfiguration; */
  264. +        0x40,       /*  __u8  bmAttributes;
  265. +                    Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup,
  266. +                    4..0: resvd */
  267. +        0x00,       /*  __u8  MaxPower; */
  268. +
  269. +        /* interface */
  270. +        0x09,       /*  __u8  if_bLength; */
  271. +        0x04,       /*  __u8  if_bDescriptorType; Interface */
  272. +        0x00,       /*  __u8  if_bInterfaceNumber; */
  273. +        0x00,       /*  __u8  if_bAlternateSetting; */
  274. +        0x01,       /*  __u8  if_bNumEndpoints; */
  275. +        0x09,       /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
  276. +        0x00,       /*  __u8  if_bInterfaceSubClass; */
  277. +        0x00,       /*  __u8  if_bInterfaceProtocol; */
  278. +        0x00,       /*  __u8  if_iInterface; */
  279. +
  280. +        /* endpoint */
  281. +        0x07,       /*  __u8  ep_bLength; */
  282. +        0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
  283. +        0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
  284. +         0x03,       /*  __u8  ep_bmAttributes; Interrupt */
  285. +         0x08,       /*  __u16 ep_wMaxPacketSize; */
  286. +         0x00,
  287. +        0xff        /*  __u8  ep_bInterval; 255 ms */
  288. +};
  289. +
  290. +/* root hub class descriptor*/
  291. +static __u8 sl811_rh_hub_des[] =
  292. +{
  293. +        0x09,                        /*  __u8  bLength; */
  294. +        0x29,                        /*  __u8  bDescriptorType; Hub-descriptor */
  295. +        0x01,                        /*  __u8  bNbrPorts; */
  296. +        0x00,                        /* __u16  wHubCharacteristics; */
  297. +        0x00,
  298. +        0x50,                        /*  __u8  bPwrOn2pwrGood; 2ms */
  299. +        0x00,                        /*  __u8  bHubContrCurrent; 0 mA */
  300. +        0xfc,                        /*  __u8  DeviceRemovable; *** 7 Ports max *** */
  301. +        0xff                        /*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
  302. +};
  303. +
  304. +/*
  305. + * This function examine the port change in the virtual root hub. HUB INTERRUPT ENDPOINT.
  306. + */
  307. +static int sl811_rh_send_irq(struct sl811_hc *hc, __u8 *rh_change, int rh_len)
  308. +{
  309. +        __u8 data = 0;
  310. +               
  311. +        PDEBUG(5, "enter");
  312. +
  313. +        /*
  314. +         * Right now, It is assume the power is good and no changes and only one port.
  315. +         */
  316. +        if (hc->rh_status.wPortChange & (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) {  
  317. +                data = 1<<1;
  318. +                *(__u8 *)rh_change = data;
  319. +                return 1;
  320. +        } else
  321. +                return 0;
  322. +}
  323. +
  324. +/*
  325. + * This function creates a timer that act as interrupt pipe in the virtual hub.
  326. + *
  327. + * Note:  The virtual root hub's interrupt pipe are polled by the timer
  328. + *        every "interval" ms
  329. + */
  330. +static void sl811_rh_init_int_timer(struct urb * urb)
  331. +{
  332. +         struct sl811_hc *hc = urb->dev->bus->hcpriv;
  333. +         hc->rh.interval = urb->interval;
  334. +
  335. +         init_timer(&hc->rh.rh_int_timer);
  336. +         hc->rh.rh_int_timer.function = sl811_rh_int_timer_do;
  337. +         hc->rh.rh_int_timer.data = (unsigned long)urb;
  338. +         hc->rh.rh_int_timer.expires = jiffies +
  339. +                (HZ * (urb->interval < 30? 30: urb->interval)) / 1000;
  340. +         add_timer (&hc->rh.rh_int_timer);
  341. +}
  342. +
  343. +/*
  344. + * This function is called when the timer expires.  It gets the the port
  345. + * change data and pass along to the upper protocol.
  346. + */
  347. +static void sl811_rh_int_timer_do(unsigned long ptr)
  348. +{
  349. +        int len;
  350. +        struct urb *urb = (struct urb *)ptr;
  351. +        struct sl811_hc *hc = urb->dev->bus->hcpriv;
  352. +        PDEBUG (5, "enter");
  353. +
  354. +        if(hc->rh.send) {
  355. +                len = sl811_rh_send_irq(hc, urb->transfer_buffer,
  356. +                        urb->transfer_buffer_length);
  357. +                if (len > 0) {
  358. +                        urb->actual_length = len;
  359. +                        if (urb->complete)
  360. +                                urb->complete(urb);
  361. +                }
  362. +        }
  363. +
  364. +#ifdef SL811_TIMEOUT
  365. +       
  366. +{
  367. +        struct list_head *head, *tmp;
  368. +        struct sl811_urb_priv *urbp;
  369. +        struct urb *u;
  370. +        int i;
  371. +        static int timeout_count = 0;
  372. +
  373. +// check time out every second
  374. +        if (++timeout_count > 4) {
  375. +                int max_scan = hc->active_urbs;
  376. +                timeout_count = 0;
  377. +                for (i = 0; i < 6; ++i) {
  378. +                        head = &hc->urb_list[i];
  379. +                        tmp = head->next;
  380. +                        while (tmp != head && max_scan--) {
  381. +                                u = list_entry(tmp, struct urb, urb_list);
  382. +                                urbp = (struct sl811_urb_priv *)u->hcpriv;
  383. +                                tmp = tmp->next;
  384. +                                // Check if the URB timed out
  385. +                                if (u->timeout && time_after_eq(jiffies, urbp->inserttime + u->timeout)) {
  386. +                                        PDEBUG(3, "urb = %p time out, we kill it", urb);
  387. +                                        u->transfer_flags |= USB_TIMEOUT_KILLED;
  388. +                                }
  389. +                        }
  390. +                }
  391. +        }
  392. +}
  393. +
  394. +#endif
  395. +        // re-activate the timer
  396. +        sl811_rh_init_int_timer(urb);
  397. +}
  398. +
  399. +/* helper macro */
  400. +#define OK(x)        len = (x); break
  401. +
  402. +/*
  403. + * This function handles all USB request to the the virtual root hub
  404. + */
  405. +static int sl811_rh_submit_urb(struct urb *urb)
  406. +{
  407. +        struct usb_device *usb_dev = urb->dev;
  408. +        struct sl811_hc *hc = usb_dev->bus->hcpriv;
  409. +        struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *)urb->setup_packet;
  410. +        void *data = urb->transfer_buffer;
  411. +        int buf_len = urb->transfer_buffer_length;
  412. +        unsigned int pipe = urb->pipe;
  413. +        __u8 data_buf[16];
  414. +        __u8 *bufp = data_buf;
  415. +        int len = 0;
  416. +        int status = 0;
  417. +       
  418. +        __u16 bmRType_bReq;
  419. +        __u16 wValue;
  420. +        __u16 wIndex;
  421. +        __u16 wLength;
  422. +
  423. +        if (usb_pipeint(pipe)) {
  424. +                hc->rh.urb =  urb;
  425. +                hc->rh.send = 1;
  426. +                hc->rh.interval = urb->interval;
  427. +                sl811_rh_init_int_timer(urb);
  428. +                urb->status = 0;
  429. +
  430. +                return 0;
  431. +        }
  432. +
  433. +        bmRType_bReq  = cmd->bRequestType | (cmd->bRequest << 8);
  434. +        wValue        = le16_to_cpu (cmd->wValue);
  435. +        wIndex        = le16_to_cpu (cmd->wIndex);
  436. +        wLength       = le16_to_cpu (cmd->wLength);
  437. +
  438. +        PDEBUG(5, "submit rh urb, req = %d(%x) len=%d", bmRType_bReq, bmRType_bReq, wLength);
  439. +
  440. +        /* Request Destination:
  441. +                   without flags: Device,
  442. +                   USB_RECIP_INTERFACE: interface,
  443. +                   USB_RECIP_ENDPOINT: endpoint,
  444. +                   USB_TYPE_CLASS means HUB here,
  445. +                   USB_RECIP_OTHER | USB_TYPE_CLASS  almost ever means HUB_PORT here
  446. +        */
  447. +        switch (bmRType_bReq) {
  448. +        case RH_GET_STATUS:
  449. +                *(__u16 *)bufp = cpu_to_le16(1);
  450. +                OK(2);
  451. +
  452. +        case RH_GET_STATUS | USB_RECIP_INTERFACE:
  453. +                *(__u16 *)bufp = cpu_to_le16(0);
  454. +                OK(2);
  455. +
  456. +        case RH_GET_STATUS | USB_RECIP_ENDPOINT:
  457. +                *(__u16 *)bufp = cpu_to_le16(0);
  458. +                OK(2);
  459. +
  460. +        case RH_GET_STATUS | USB_TYPE_CLASS:
  461. +                *(__u32 *)bufp = cpu_to_le32(0);
  462. +                OK(4);
  463. +
  464. +        case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS:
  465. +                *(__u32 *)bufp = cpu_to_le32(hc->rh_status.wPortChange<<16 | hc->rh_status.wPortStatus);
  466. +                OK(4);
  467. +
  468. +        case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT:
  469. +                switch (wValue)        {
  470. +                case 1:
  471. +                        OK(0);
  472. +                }
  473. +                break;
  474. +
  475. +        case RH_CLEAR_FEATURE | USB_TYPE_CLASS:
  476. +                switch (wValue) {
  477. +                case C_HUB_LOCAL_POWER:
  478. +                        OK(0);
  479. +
  480. +                case C_HUB_OVER_CURRENT:
  481. +                        OK(0);
  482. +                }
  483. +                break;
  484. +
  485. +        case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
  486. +                switch (wValue) {
  487. +                case USB_PORT_FEAT_ENABLE:
  488. +                        hc->rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE;
  489. +                        OK(0);
  490. +
  491. +                case USB_PORT_FEAT_SUSPEND:
  492. +                        hc->rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND;
  493. +                        OK(0);
  494. +
  495. +                case USB_PORT_FEAT_POWER:
  496. +                        hc->rh_status.wPortStatus &= ~USB_PORT_STAT_POWER;
  497. +                        OK(0);
  498. +
  499. +                case USB_PORT_FEAT_C_CONNECTION:
  500. +                        hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
  501. +                        OK(0);
  502. +
  503. +                case USB_PORT_FEAT_C_ENABLE:
  504. +                        hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE;
  505. +                        OK(0);
  506. +
  507. +                case USB_PORT_FEAT_C_SUSPEND:
  508. +                        hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;
  509. +                        OK(0);
  510. +
  511. +                case USB_PORT_FEAT_C_OVER_CURRENT:
  512. +                        hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT;
  513. +                        OK(0);
  514. +
  515. +                case USB_PORT_FEAT_C_RESET:
  516. +                        hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET;
  517. +                        OK(0);
  518. +                }
  519. +                break;
  520. +
  521. +        case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
  522. +                switch (wValue) {
  523. +                case USB_PORT_FEAT_SUSPEND:
  524. +                        hc->rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND;
  525. +                        OK(0);
  526. +
  527. +                case USB_PORT_FEAT_RESET:
  528. +                        hc->rh_status.wPortStatus |= USB_PORT_STAT_RESET;
  529. +                        hc->rh_status.wPortChange = 0;
  530. +                        hc->rh_status.wPortChange |= USB_PORT_STAT_C_RESET;
  531. +                        hc->rh_status.wPortStatus &= ~USB_PORT_STAT_RESET;
  532. +                        hc->rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
  533. +                        OK(0);
  534. +
  535. +                case USB_PORT_FEAT_POWER:
  536. +                        hc->rh_status.wPortStatus |= USB_PORT_STAT_POWER;
  537. +                        OK(0);
  538. +
  539. +                case USB_PORT_FEAT_ENABLE:
  540. +                        hc->rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
  541. +                        OK(0);
  542. +                }
  543. +                break;
  544. +
  545. +        case RH_SET_ADDRESS:
  546. +                hc->rh.devnum = wValue;
  547. +                OK(0);
  548. +
  549. +        case RH_GET_DESCRIPTOR:
  550. +                switch ((wValue & 0xff00) >> 8) {
  551. +                case USB_DT_DEVICE:
  552. +                        len = sizeof(sl811_rh_dev_des);
  553. +                        bufp = sl811_rh_dev_des;
  554. +                        OK(len);
  555. +
  556. +                case USB_DT_CONFIG:
  557. +                        len = sizeof(sl811_rh_config_des);
  558. +                        bufp = sl811_rh_config_des;
  559. +                        OK(len);
  560. +
  561. +                case USB_DT_STRING:
  562. +                        len = usb_root_hub_string(wValue & 0xff, (int)(long)0,        "SL811HS", data, wLength);
  563. +                        if (len > 0) {
  564. +                                bufp = data;
  565. +                                OK(len);
  566. +                        }
  567. +               
  568. +                default:
  569. +                        status = -EPIPE;
  570. +                }
  571. +                break;
  572. +
  573. +        case RH_GET_DESCRIPTOR | USB_TYPE_CLASS:
  574. +                len = sizeof(sl811_rh_hub_des);
  575. +                bufp = sl811_rh_hub_des;
  576. +                OK(len);
  577. +
  578. +        case RH_GET_CONFIGURATION:
  579. +                bufp[0] = 0x01;
  580. +                OK(1);
  581. +
  582. +        case RH_SET_CONFIGURATION:
  583. +                OK(0);
  584. +
  585. +        default:
  586. +                PDEBUG(1, "unsupported root hub command");
  587. +                status = -EPIPE;
  588. +        }
  589. +
  590. +        len = min(len, buf_len);
  591. +        if (data != bufp)
  592. +                memcpy(data, bufp, len);
  593. +        urb->actual_length = len;
  594. +        urb->status = status;
  595. +
  596. +        PDEBUG(5, "len = %d, status = %d", len, status);
  597. +       
  598. +        urb->hcpriv = NULL;
  599. +        urb->dev = NULL;
  600. +        if (urb->complete)
  601. +                urb->complete(urb);
  602. +
  603. +        return 0;
  604. +}
  605. +
  606. +/*
  607. + * This function unlinks the URB
  608. + */
  609. +static int sl811_rh_unlink_urb(struct urb *urb)
  610. +{
  611. +        struct sl811_hc *hc = urb->dev->bus->hcpriv;
  612. +
  613. +        PDEBUG(5, "enter");
  614. +       
  615. +        if (hc->rh.urb == urb) {
  616. +                hc->rh.send = 0;
  617. +                del_timer(&hc->rh.rh_int_timer);
  618. +                hc->rh.urb = NULL;
  619. +                urb->hcpriv = NULL;
  620. +                usb_dec_dev_use(urb->dev);
  621. +                urb->dev = NULL;
  622. +                if (urb->transfer_flags & USB_ASYNC_UNLINK) {
  623. +                        urb->status = -ECONNRESET;
  624. +                        if (urb->complete)
  625. +                                urb->complete(urb);
  626. +                } else
  627. +                        urb->status = -ENOENT;
  628. +        }
  629. +
  630. +        return 0;
  631. +}
  632. +
  633. +/*
  634. + * This function connect the virtual root hub to the USB stack
  635. + */
  636. +static int sl811_connect_rh(struct sl811_hc * hc)
  637. +{
  638. +        struct usb_device *usb_dev;
  639. +
  640. +        hc->rh.devnum = 0;
  641. +        usb_dev = usb_alloc_dev(NULL, hc->bus);
  642. +        if (!usb_dev)
  643. +                return -ENOMEM;
  644. +
  645. +        hc->bus->root_hub = usb_dev;
  646. +        usb_connect(usb_dev);
  647. +
  648. +        if (usb_new_device(usb_dev)) {
  649. +                usb_free_dev(usb_dev);
  650. +                return -ENODEV;
  651. +        }
  652. +       
  653. +        PDEBUG(5, "leave success");
  654. +       
  655. +        return 0;
  656. +}
  657. +
  658. +/*
  659. + * This function allocates private data space for the usb device
  660. + */
  661. +static int sl811_alloc_dev_priv(struct usb_device *usb_dev)
  662. +{
  663. +        return 0;
  664. +}
  665. +
  666. +/*
  667. + * This function de-allocates private data space for the usb devic
  668. + */
  669. +static int sl811_free_dev_priv (struct usb_device *usb_dev)
  670. +{
  671. +        return 0;
  672. +}
  673. +
  674. +/*
  675. + * This function allocates private data space for the urb
  676. + */
  677. +static struct sl811_urb_priv* sl811_alloc_urb_priv(struct urb *urb)
  678. +{
  679. +        struct sl811_urb_priv *urbp;
  680. +       
  681. +        urbp = kmalloc(sizeof(*urbp), GFP_KERNEL);
  682. +        if (!urbp)
  683. +                return NULL;
  684. +       
  685. +        memset(urbp, 0, sizeof(*urbp));
  686. +       
  687. +        INIT_LIST_HEAD(&urbp->td_list);
  688. +       
  689. +        urbp->urb = urb;
  690. +        urb->hcpriv = urbp;
  691. +       
  692. +        return urbp;
  693. +}
  694. +
  695. +/*
  696. + * This function free private data space for the urb
  697. + */
  698. +static void sl811_free_urb_priv(struct urb *urb)
  699. +{
  700. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  701. +        struct sl811_td *td;
  702. +        struct list_head *head, *tmp;
  703. +       
  704. +        if (!urbp)
  705. +                return ;
  706. +       
  707. +        head = &urbp->td_list;
  708. +        tmp = head->next;
  709. +       
  710. +        while (tmp != head) {
  711. +                td = list_entry(tmp, struct sl811_td, td_list);
  712. +                tmp = tmp->next;
  713. +                kfree(td);
  714. +        }
  715. +       
  716. +        kfree(urbp);
  717. +        urb->hcpriv = NULL;
  718. +       
  719. +        return ;
  720. +}
  721. +
  722. +/*
  723. + * This        function calculate the bus time need by this td.
  724. + * Fix me! Can this use usb_calc_bus_time()?
  725. + */
  726. +static void sl811_calc_td_time(struct sl811_td *td)
  727. +{
  728. +#if 1
  729. +        int time;
  730. +        int len = td->len;
  731. +        struct sl811_hc *hc = td->urb->dev->bus->hcpriv;
  732. +
  733. +        if (hc->rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED)
  734. +                time = 8*8*len + 1024;
  735. +        else {
  736. +                if (td->ctrl & SL811_USB_CTRL_PREAMBLE)
  737. +                        time = 8*8*len + 2048;
  738. +                else
  739. +                        time = 8*len + 256;
  740. +        }
  741. +
  742. +        time += 2*10 * len;
  743. +
  744. +        td->bustime = time;
  745. +       
  746. +#else
  747. +
  748. +        unsigned long tmp;
  749. +        int time;
  750. +        int low_speed = usb_pipeslow(td->urb->pipe);
  751. +        int input_dir = usb_pipein(td->urb->pipe);
  752. +        int bytecount = td->len;
  753. +        int isoc = usb_pipeisoc(td->urb->pipe);
  754. +
  755. +        if (low_speed) {        /* no isoc. here */
  756. +                if (input_dir) {
  757. +                        tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L;
  758. +                        time =  (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
  759. +                } else {
  760. +                        tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L;
  761. +                        time =  (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
  762. +                }
  763. +        } else if (!isoc){        /* for full-speed: */
  764. +                tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
  765. +                time = (9107L + BW_HOST_DELAY + tmp);
  766. +        } else {                /* for isoc: */
  767. +                tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
  768. +                time =  (((input_dir) ? 7268L : 6265L) + BW_HOST_DELAY + tmp);
  769. +        }
  770. +       
  771. +        td->bustime = time / 84;
  772. +
  773. +#endif                 
  774. +}
  775. +
  776. +/*
  777. + * This        function calculate the remainder bus time in current frame.
  778. + */
  779. +static inline int sl811_calc_bus_remainder(struct sl811_hc *hc)
  780. +{
  781. +        return (sl811_read(hc, SL811_SOFCNTDIV) * 64);
  782. +}
  783. +
  784. +/*
  785. + * This function allocates td for the urb
  786. + */
  787. +static struct sl811_td* sl811_alloc_td(struct urb *urb)
  788. +{
  789. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  790. +        struct sl811_td *td;
  791. +       
  792. +        td = kmalloc(sizeof (*td), GFP_KERNEL);
  793. +        if (!td)
  794. +                return NULL;
  795. +       
  796. +        memset(td, 0, sizeof(*td));
  797. +       
  798. +        INIT_LIST_HEAD(&td->td_list);
  799. +       
  800. +        td->urb = urb;
  801. +        list_add_tail(&td->td_list, &urbp->td_list);
  802. +       
  803. +        return td;
  804. +}
  805. +
  806. +/*
  807. + * Fill the td.
  808. + */
  809. +static inline void sl811_fill_td(struct sl811_td *td, __u8 ctrl, __u8 addr, __u8 len, __u8 pidep, __u8 dev, __u8 *buf)
  810. +{
  811. +        td->ctrl = ctrl;
  812. +        td->addr = addr;
  813. +        td->len = len;
  814. +        td->pidep = pidep;
  815. +        td->dev = dev;
  816. +        td->buf = buf;
  817. +        td->left = len;
  818. +        td->errcnt = 3;
  819. +}
  820. +
  821. +/*
  822. + * Fill the td.
  823. + */
  824. +static inline void sl811_reset_td(struct sl811_td *td)
  825. +{
  826. +        td->status = 0;
  827. +        td->left = td->len;
  828. +        td->done = 0;
  829. +        td->errcnt = 3;
  830. +        td->nakcnt = 0;
  831. +        td->td_status = 0;
  832. +}
  833. +
  834. +static void sl811_print_td(int level, struct sl811_td *td)
  835. +{
  836. +         PDEBUG(level, "td = %p, ctrl = %x, addr = %x, len = %x, pidep = %x\n
  837. +                dev = %x, status = %x, left = %x, errcnt = %x, done = %x\n
  838. +                buf = %p, bustime = %d, td_status = %d\n",
  839. +                td, td->ctrl, td->addr, td->len, td->pidep,
  840. +                td->dev, td->status, td->left, td->errcnt, td->done,
  841. +                td->buf, td->bustime, td->td_status);
  842. +}
  843. +
  844. +/*
  845. + * Isochronous transfers
  846. + */
  847. +static int sl811_submit_isochronous(struct urb *urb)
  848. +{
  849. +        __u8 dev = usb_pipedevice(urb->pipe);
  850. +        __u8 pidep = PIDEP(usb_packetid(urb->pipe), usb_pipeendpoint(urb->pipe));
  851. +        __u8 ctrl = 0;
  852. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  853. +        struct sl811_td *td = NULL;
  854. +        int i;
  855. +       
  856. +        PDEBUG(4, "enter, urb = %p, urbp = %p", urb, urbp);
  857. +       
  858. +        /* Can't have low speed bulk transfers */
  859. +        if (usb_pipeslow(urb->pipe)) {
  860. +                PDEBUG(1, "error, urb = %p, low speed device", urb);
  861. +                return -EINVAL;
  862. +        }
  863. +       
  864. +        if (usb_pipeout(urb->pipe))
  865. +                ctrl |= SL811_USB_CTRL_DIR_OUT;
  866. +               
  867. +        ctrl |= SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE | SL811_USB_CTRL_ISO;
  868. +       
  869. +        for (i = 0; i < urb->number_of_packets; i++) {
  870. +                urb->iso_frame_desc[i].actual_length = 0;
  871. +                urb->iso_frame_desc[i].status = -EXDEV;
  872. +                       
  873. +                td = sl811_alloc_td(urb);
  874. +                if (!td)
  875. +                        return -ENOMEM;
  876. +
  877. +                sl811_fill_td(td, ctrl, SL811_DATA_START,
  878. +                        urb->iso_frame_desc[i].length,
  879. +                        pidep, dev,
  880. +                        urb->transfer_buffer + urb->iso_frame_desc[i].offset);
  881. +                sl811_calc_td_time(td);
  882. +                if (urbp->cur_td == NULL)
  883. +                        urbp->cur_td = urbp->first_td = td;       
  884. +        }
  885. +       
  886. +        urbp->last_td = td;       
  887. +       
  888. +        PDEBUG(4, "leave success");
  889. +
  890. +/*       
  891. +// for debug
  892. +        {
  893. +                struct list_head *head, *tmp;
  894. +                struct sl811_td *td;
  895. +                int i = 0;
  896. +                head = &urbp->td_list;
  897. +                tmp = head->next;
  898. +       
  899. +                if (list_empty(&urbp->td_list)) {
  900. +                        PDEBUG(1, "bug!!! td list is empty!");
  901. +                        return -ENODEV;
  902. +                }
  903. +               
  904. +                while (tmp != head) {
  905. +                        ++i;
  906. +                        td = list_entry(tmp, struct sl811_td, td_list);
  907. +                        PDEBUG(2, "td = %p, i = %d", td, i);
  908. +                        tmp = tmp->next;
  909. +                }
  910. +        }
  911. +*/       
  912. +        return 0;
  913. +}
  914. +
  915. +/*
  916. + * Reset isochronous transfers
  917. + */
  918. +static void sl811_reset_isochronous(struct urb *urb)
  919. +{
  920. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  921. +        struct sl811_td *td = NULL;
  922. +        struct list_head *head, *tmp;
  923. +        int i;
  924. +
  925. +        PDEBUG(4, "enter, urb = %p", urb);
  926. +       
  927. +        for (i = 0; i < urb->number_of_packets; i++) {
  928. +                urb->iso_frame_desc[i].actual_length = 0;
  929. +                urb->iso_frame_desc[i].status = -EXDEV;
  930. +        }
  931. +
  932. +        head = &urbp->td_list;
  933. +        tmp = head->next;
  934. +        while (tmp != head) {
  935. +                td = list_entry(tmp, struct sl811_td, td_list);
  936. +                tmp = tmp->next;
  937. +                sl811_reset_td(td);
  938. +        }
  939. +       
  940. +        urbp->cur_td = urbp->first_td;
  941. +       
  942. +        urb->status = -EINPROGRESS;
  943. +        urb->actual_length = 0;
  944. +        urb->error_count = 0;
  945. +}
  946. +
  947. +/*
  948. + * Result the iso urb.
  949. + */
  950. +static void sl811_result_isochronous(struct urb *urb)
  951. +{
  952. +        struct list_head *tmp, *head;
  953. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  954. +        int status = 0;
  955. +        struct sl811_td *td;
  956. +        int i;
  957. +
  958. +        PDEBUG(4, "enter, urb = %p", urb);
  959. +               
  960. +        urb->actual_length = 0;
  961. +
  962. +        i = 0;
  963. +        head = &urbp->td_list;
  964. +        tmp = head->next;
  965. +        while (tmp != head) {
  966. +                td = list_entry(tmp, struct sl811_td, td_list);
  967. +                tmp = tmp->next;
  968. +               
  969. +                if (!td->done) {
  970. +                        if (urbp->unlink)
  971. +                                urb->status = -ENOENT;
  972. +                        else {
  973. +                                PDEBUG(1, "we should not get here!");
  974. +                                urb->status = -EXDEV;
  975. +                        }
  976. +                        return ;       
  977. +                }
  978. +                if (td->td_status) {
  979. +                        status = td->td_status;
  980. +                        urb->error_count++;
  981. +                        PDEBUG(1, "error: td = %p, td status = %d", td, td->td_status);
  982. +                }
  983. +
  984. +                urb->iso_frame_desc[i].actual_length = td->len - td->left;
  985. +                urb->actual_length += td->len - td->left;
  986. +                urb->iso_frame_desc[i].status = td->td_status;
  987. +                ++i;
  988. +                if (td->left)
  989. +                        PDEBUG(3, "short packet, td = %p, len = %d, left = %d", td, td->len, td->left);
  990. +        }
  991. +
  992. +        urb->status = status;
  993. +/*
  994. +// for debug
  995. +        PDEBUG(2, "iso urb complete, len = %d, status =%d ", urb->actual_length, urb->status);               
  996. +*/
  997. +        PDEBUG(4, "leave success");
  998. +}
  999. +
  1000. +/*
  1001. + * Interrupt transfers
  1002. + */
  1003. +static int sl811_submit_interrupt(struct urb *urb)
  1004. +{
  1005. +        int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
  1006. +        int len = urb->transfer_buffer_length;
  1007. +        __u8 *data = urb->transfer_buffer;
  1008. +        __u8 dev = usb_pipedevice(urb->pipe);
  1009. +        __u8 pidep = PIDEP(usb_packetid(urb->pipe), usb_pipeendpoint(urb->pipe));
  1010. +        __u8 ctrl = 0;
  1011. +        struct sl811_hc *hc = urb->dev->bus->hcpriv;
  1012. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1013. +        struct sl811_td *td = NULL;
  1014. +       
  1015. +        PDEBUG(4, "enter, urb = %p", urb);
  1016. +       
  1017. +        if (len > maxsze) {
  1018. +                PDEBUG(1, "length is big than max packet size, len = %d, max packet = %d", len, maxsze);
  1019. +                return -EINVAL;
  1020. +        }
  1021. +        if (usb_pipeslow(urb->pipe) && !(hc->rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED))
  1022. +                ctrl |= SL811_USB_CTRL_PREAMBLE;
  1023. +       
  1024. +        ctrl |= SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
  1025. +        if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
  1026. +                ctrl |= SL811_USB_CTRL_TOGGLE_1;
  1027. +        usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));       
  1028. +        td = sl811_alloc_td(urb);
  1029. +        if (!td)
  1030. +                return -ENOMEM;
  1031. +               
  1032. +        sl811_fill_td(td, ctrl, SL811_DATA_START, len, pidep, dev, data);
  1033. +        sl811_calc_td_time(td);
  1034. +        urbp->cur_td = urbp->first_td = urbp->last_td = td;
  1035. +        urbp->interval = 0;
  1036. +       
  1037. +        PDEBUG(4, "leave success");
  1038. +       
  1039. +        return 0;
  1040. +}
  1041. +
  1042. +/*
  1043. + * Reset interrupt transfers
  1044. + */
  1045. +static void sl811_reset_interrupt(struct urb *urb)
  1046. +{
  1047. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1048. +        struct sl811_td *td = urbp->cur_td;
  1049. +       
  1050. +        PDEBUG(4, "enter, interval = %d", urb->interval);
  1051. +       
  1052. +        td->ctrl &= ~SL811_USB_CTRL_TOGGLE_1;
  1053. +        if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
  1054. +                td->ctrl |= SL811_USB_CTRL_TOGGLE_1;
  1055. +        usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));       
  1056. +       
  1057. +        sl811_reset_td(td);
  1058. +
  1059. +        urbp->interval = urb->interval;
  1060. +       
  1061. +        urb->status = -EINPROGRESS;
  1062. +        urb->actual_length = 0;
  1063. +}
  1064. +
  1065. +/*
  1066. + * Result the interrupt urb.
  1067. + */
  1068. +static void sl811_result_interrupt(struct urb *urb)
  1069. +{
  1070. +        struct list_head *tmp;
  1071. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1072. +        struct sl811_td *td;
  1073. +        int toggle;
  1074. +       
  1075. +        PDEBUG(4, "enter, urb = %p", urb);
  1076. +       
  1077. +        urb->actual_length = 0;
  1078. +
  1079. +        tmp = &urbp->td_list;
  1080. +        tmp = tmp->next;
  1081. +        td = list_entry(tmp, struct sl811_td, td_list);
  1082. +
  1083. +        // success.
  1084. +        if (td->done && td->td_status == 0) {
  1085. +                urb->actual_length += td->len - td->left;
  1086. +                urb->status = 0;
  1087. +                return ;
  1088. +        }
  1089. +        // tranfer is done but fail, reset the toggle.
  1090. +        else if (td->done && td->td_status) {
  1091. +                urb->status = td->td_status;
  1092. +reset_toggle:
  1093. +                toggle = (td->ctrl & SL811_USB_CTRL_TOGGLE_1) ? 1 : 0;
  1094. +                usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), toggle);
  1095. +                PDEBUG(3, "error: td = %p, td status = %d", td, td->td_status);
  1096. +                return ;
  1097. +        }
  1098. +        // unlink, and not do transfer yet
  1099. +        else if (td->done == 0 && urbp->unlink && td->td_status == 0) {
  1100. +                urb->status = -ENOENT;
  1101. +                PDEBUG(3, "unlink and not transfer!");
  1102. +                return ;
  1103. +        }
  1104. +        // unlink, and transfer not complete yet.
  1105. +        else if (td->done == 0 && urbp->unlink && td->td_status) {
  1106. +                urb->status = -ENOENT;
  1107. +                PDEBUG(3, "unlink and not complete!");
  1108. +                goto reset_toggle;
  1109. +        }
  1110. +        // must be bug!!!
  1111. +        else {// (td->done == 0 && urbp->unlink == 0)
  1112. +                PDEBUG(1, "we should not get here!");
  1113. +                urb->status = -EPIPE;
  1114. +                return ;
  1115. +        }
  1116. +}
  1117. +
  1118. +/*
  1119. + * Control transfers
  1120. + */
  1121. +static int sl811_submit_control(struct urb *urb)
  1122. +{
  1123. +        int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
  1124. +        int len = urb->transfer_buffer_length;
  1125. +        __u8 *data = urb->transfer_buffer;
  1126. +        __u8 dev = usb_pipedevice(urb->pipe);
  1127. +        __u8 pidep = 0;
  1128. +        __u8 ctrl = 0;
  1129. +        struct sl811_hc *hc = urb->dev->bus->hcpriv;
  1130. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1131. +        struct sl811_td *td = NULL;
  1132. +       
  1133. +        PDEBUG(4, "enter, urb = %p", urb);
  1134. +       
  1135. +        if (usb_pipeslow(urb->pipe) && !(hc->rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED))
  1136. +                ctrl |= SL811_USB_CTRL_PREAMBLE;
  1137. +       
  1138. +        /* Build SETUP TD */
  1139. +        pidep = PIDEP(USB_PID_SETUP, usb_pipeendpoint(urb->pipe));
  1140. +        ctrl |= SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE | SL811_USB_CTRL_DIR_OUT;
  1141. +        td = sl811_alloc_td(urb);
  1142. +        if (!td)
  1143. +                return -ENOMEM;
  1144. +               
  1145. +        sl811_fill_td(td, ctrl, SL811_DATA_START, 8, pidep, dev, urb->setup_packet);
  1146. +        sl811_calc_td_time(td);
  1147. +       
  1148. +        urbp->cur_td = urbp->first_td = td;
  1149. +       
  1150. +        /*
  1151. +         * If direction is "send", change the frame from SETUP (0x2D)
  1152. +         * to OUT (0xE1). Else change it from SETUP to IN (0x69).
  1153. +         */
  1154. +        pidep = PIDEP(usb_packetid(urb->pipe), usb_pipeendpoint(urb->pipe));
  1155. +        if (usb_pipeout(urb->pipe))
  1156. +                ctrl |= SL811_USB_CTRL_DIR_OUT;
  1157. +        else
  1158. +                ctrl &= ~SL811_USB_CTRL_DIR_OUT;
  1159. +
  1160. +        /* Build the DATA TD's */
  1161. +        while (len > 0) {
  1162. +                int pktsze = len;
  1163. +
  1164. +                if (pktsze > maxsze)
  1165. +                        pktsze = maxsze;
  1166. +
  1167. +                /* Alternate Data0/1 (start with Data1) */
  1168. +                ctrl ^= SL811_USB_CTRL_TOGGLE_1;
  1169. +       
  1170. +                td = sl811_alloc_td(urb);
  1171. +                if (!td)
  1172. +                        return -ENOMEM;
  1173. +
  1174. +                sl811_fill_td(td, ctrl, SL811_DATA_START, pktsze, pidep, dev, data);       
  1175. +                sl811_calc_td_time(td);
  1176. +               
  1177. +                data += pktsze;
  1178. +                len -= pktsze;
  1179. +        }
  1180. +
  1181. +        /* Build the final TD for control status */
  1182. +        td = sl811_alloc_td(urb);
  1183. +        if (!td)
  1184. +                return -ENOMEM;
  1185. +
  1186. +        /* It's IN if the pipe is an output pipe or we're not expecting data back */
  1187. +        if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) {
  1188. +                pidep = PIDEP(USB_PID_IN, usb_pipeendpoint(urb->pipe));
  1189. +                ctrl &= ~SL811_USB_CTRL_DIR_OUT;       
  1190. +        } else {
  1191. +                pidep = PIDEP(USB_PID_OUT, usb_pipeendpoint(urb->pipe));
  1192. +                ctrl |= SL811_USB_CTRL_DIR_OUT;
  1193. +        }
  1194. +               
  1195. +        /* End in Data1 */
  1196. +        ctrl |= SL811_USB_CTRL_TOGGLE_1;
  1197. +
  1198. +        sl811_fill_td(td, ctrl, SL811_DATA_START, 0, pidep, dev, 0);
  1199. +        sl811_calc_td_time(td);
  1200. +        urbp->last_td = td;
  1201. +/*       
  1202. +// for debug
  1203. +        {
  1204. +                struct list_head *head, *tmp;
  1205. +                struct sl811_td *td;
  1206. +                int i = 0;
  1207. +                head = &urbp->td_list;
  1208. +                tmp = head->next;
  1209. +       
  1210. +                if (list_empty(&urbp->td_list)) {
  1211. +                        PDEBUG(1, "bug!!! td list is empty!");
  1212. +                        return -ENODEV;
  1213. +                }
  1214. +               
  1215. +                while (tmp != head) {
  1216. +                        ++i;
  1217. +                        td = list_entry(tmp, struct sl811_td, td_list);
  1218. +                        PDEBUG(3, "td = %p, i = %d", td, i);
  1219. +                        tmp = tmp->next;
  1220. +                }
  1221. +        }
  1222. +*/       
  1223. +        PDEBUG(4, "leave success");
  1224. +       
  1225. +        return 0;
  1226. +}
  1227. +
  1228. +/*
  1229. + * Result the control urb.
  1230. + */
  1231. +static void sl811_result_control(struct urb *urb)
  1232. +{
  1233. +        struct list_head *tmp, *head;
  1234. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1235. +        struct sl811_td *td;
  1236. +
  1237. +        PDEBUG(4, "enter, urb = %p", urb);
  1238. +       
  1239. +        if (list_empty(&urbp->td_list)) {
  1240. +                PDEBUG(1, "td list is empty");
  1241. +                return ;
  1242. +        }
  1243. +
  1244. +        head = &urbp->td_list;
  1245. +
  1246. +        tmp = head->next;
  1247. +        td = list_entry(tmp, struct sl811_td, td_list);
  1248. +
  1249. +        /* The first TD is the SETUP phase, check the status, but skip the count */
  1250. +        if (!td->done) {
  1251. +                PDEBUG(3, "setup phase error, td = %p, done = %d", td, td->done);
  1252. +                goto err_done;
  1253. +        }
  1254. +        if (td->td_status)  {
  1255. +                PDEBUG(3, "setup phase error, td = %p, td status = %d", td, td->td_status);
  1256. +                goto err_status;
  1257. +        }
  1258. +
  1259. +        urb->actual_length = 0;
  1260. +
  1261. +        /* The rest of the TD's (but the last) are data */
  1262. +        tmp = tmp->next;
  1263. +        while (tmp != head && tmp->next != head) {
  1264. +                td = list_entry(tmp, struct sl811_td, td_list);
  1265. +                tmp = tmp->next;
  1266. +                if (!td->done) {
  1267. +                        PDEBUG(3, "data phase error, td = %p, done = %d", td, td->done);
  1268. +                        goto err_done;
  1269. +                }
  1270. +                if (td->td_status)  {
  1271. +                        PDEBUG(3, "data phase error, td = %p, td status = %d", td, td->td_status);
  1272. +                        goto err_status;
  1273. +                }
  1274. +
  1275. +                urb->actual_length += td->len - td->left;
  1276. +                // short packet.
  1277. +                if (td->left) {
  1278. +                        PDEBUG(3, "data phase short packet, td = %p, count = %d", td, td->len - td->left);
  1279. +                        break;
  1280. +                }
  1281. +        }
  1282. +
  1283. +        /* The last td is status phase */
  1284. +        td = urbp->last_td;
  1285. +        if (!td->done) {
  1286. +                PDEBUG(3, "status phase error, td = %p, done = %d", td, td->done);
  1287. +                goto err_done;
  1288. +        }
  1289. +        if (td->td_status)  {
  1290. +                PDEBUG(3, "status phase error, td = %p, td status = %d", td, td->td_status);
  1291. +                goto err_status;
  1292. +        }
  1293. +       
  1294. +        PDEBUG(4, "leave success");
  1295. +       
  1296. +        urb->status = 0;
  1297. +        return ;
  1298. +
  1299. +err_done:
  1300. +        if (urbp->unlink)
  1301. +                urb->status = -ENOENT;
  1302. +        else {
  1303. +                PDEBUG(1, "we should not get here! td = %p", td);
  1304. +                urb->status = -EPIPE;
  1305. +        }
  1306. +        return ;       
  1307. +
  1308. +err_status:
  1309. +        urb->status = td->td_status;               
  1310. +        return ;
  1311. +}
  1312. +
  1313. +/*
  1314. + * Bulk transfers
  1315. + */
  1316. +static int sl811_submit_bulk(struct urb *urb)
  1317. +{
  1318. +        int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
  1319. +        int len = urb->transfer_buffer_length;
  1320. +        __u8 *data = urb->transfer_buffer;
  1321. +        __u8 dev = usb_pipedevice(urb->pipe);
  1322. +        __u8 pidep = PIDEP(usb_packetid(urb->pipe), usb_pipeendpoint(urb->pipe));
  1323. +        __u8 ctrl = 0;
  1324. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1325. +        struct sl811_td *td = NULL;
  1326. +
  1327. +        PDEBUG(4, "enter, urb = %p", urb);
  1328. +               
  1329. +        if (len < 0) {
  1330. +                PDEBUG(1, "error, urb = %p, len = %d", urb, len);
  1331. +                return -EINVAL;
  1332. +        }
  1333. +
  1334. +        /* Can't have low speed bulk transfers */
  1335. +        if (usb_pipeslow(urb->pipe)) {
  1336. +                PDEBUG(1, "error, urb = %p, low speed device", urb);
  1337. +                return -EINVAL;
  1338. +        }
  1339. +
  1340. +        if (usb_pipeout(urb->pipe))
  1341. +                ctrl |= SL811_USB_CTRL_DIR_OUT;
  1342. +               
  1343. +        ctrl |= SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
  1344. +                       
  1345. +        /* Build the DATA TD's */
  1346. +        do {        /* Allow zero length packets */
  1347. +                int pktsze = len;
  1348. +
  1349. +                if (pktsze > maxsze)
  1350. +                        pktsze = maxsze;
  1351. +
  1352. +                td = sl811_alloc_td(urb);
  1353. +                if (!td)
  1354. +                        return -ENOMEM;
  1355. +
  1356. +                /* Alternate Data0/1 (start with Data1) */
  1357. +                ctrl &= ~SL811_USB_CTRL_TOGGLE_1;
  1358. +                if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
  1359. +                        ctrl |= SL811_USB_CTRL_TOGGLE_1;
  1360. +                usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));               
  1361. +               
  1362. +                sl811_fill_td(td, ctrl, SL811_DATA_START, pktsze, pidep, dev, data);
  1363. +                sl811_calc_td_time(td);
  1364. +               
  1365. +                if (urbp->cur_td == NULL)
  1366. +                        urbp->cur_td = urbp->first_td = td;
  1367. +                       
  1368. +                data += pktsze;
  1369. +                len -= maxsze;
  1370. +        } while (len > 0);
  1371. +
  1372. +        /*
  1373. +         * USB_ZERO_PACKET means adding a 0-length packet, if
  1374. +         * direction is OUT and the transfer_length was an
  1375. +         * exact multiple of maxsze, hence
  1376. +         * (len = transfer_length - N * maxsze) == 0
  1377. +         * however, if transfer_length == 0, the zero packet
  1378. +         * was already prepared above.
  1379. +         */
  1380. +        if (usb_pipeout(urb->pipe) && (urb->transfer_flags & USB_ZERO_PACKET) &&
  1381. +           !len && urb->transfer_buffer_length) {
  1382. +               
  1383. +                td = sl811_alloc_td(urb);
  1384. +                if (!td)
  1385. +                        return -ENOMEM;
  1386. +
  1387. +                /* Alternate Data0/1 (start with Data1) */
  1388. +                ctrl &= ~SL811_USB_CTRL_TOGGLE_1;
  1389. +                if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
  1390. +                        ctrl |= SL811_USB_CTRL_TOGGLE_1;
  1391. +                usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
  1392. +                       
  1393. +                sl811_fill_td(td, ctrl, SL811_DATA_START, 0, pidep, dev, 0);
  1394. +                sl811_calc_td_time(td);
  1395. +        }
  1396. +       
  1397. +        urbp->last_td = td;
  1398. +       
  1399. +        PDEBUG(4, "leave success");
  1400. +       
  1401. +        return 0;
  1402. +}
  1403. +
  1404. +/*
  1405. + * Reset bulk transfers
  1406. + */
  1407. +static int sl811_reset_bulk(struct urb *urb)
  1408. +{
  1409. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1410. +        struct sl811_td *td;
  1411. +        struct list_head *head, *tmp;
  1412. +
  1413. +        PDEBUG(4, "enter, urb = %p", urb);
  1414. +       
  1415. +       
  1416. +        head = &urbp->td_list;       
  1417. +        tmp = head->next;
  1418. +       
  1419. +        while (tmp != head) {
  1420. +                td = list_entry(tmp, struct sl811_td, td_list);
  1421. +
  1422. +                /* Alternate Data0/1 (start with Data1) */
  1423. +                td->ctrl &= ~SL811_USB_CTRL_TOGGLE_1;
  1424. +                if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
  1425. +                        td->ctrl |= SL811_USB_CTRL_TOGGLE_1;
  1426. +                usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
  1427. +               
  1428. +                sl811_reset_td(td);
  1429. +        }
  1430. +
  1431. +        urb->status = -EINPROGRESS;
  1432. +        urb->actual_length = 0;
  1433. +        urbp->cur_td = urbp->first_td;
  1434. +
  1435. +        PDEBUG(4, "leave success");
  1436. +       
  1437. +        return 0;
  1438. +}
  1439. +
  1440. +/*
  1441. + * Result the bulk urb.
  1442. + */
  1443. +static void sl811_result_bulk(struct urb *urb)
  1444. +{
  1445. +        struct list_head *tmp, *head;
  1446. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1447. +        struct sl811_td *td = NULL;
  1448. +        int toggle;
  1449. +
  1450. +        PDEBUG(4, "enter, urb = %p", urb);
  1451. +       
  1452. +        urb->actual_length = 0;
  1453. +
  1454. +        head = &urbp->td_list;
  1455. +        tmp = head->next;
  1456. +        while (tmp != head) {
  1457. +                td = list_entry(tmp, struct sl811_td, td_list);
  1458. +                tmp = tmp->next;
  1459. +
  1460. +                // success.
  1461. +                if (td->done && td->td_status == 0) {
  1462. +                        urb->actual_length += td->len - td->left;
  1463. +                       
  1464. +                        // short packet
  1465. +                        if (td->left) {
  1466. +                                urb->status = 0;
  1467. +                                PDEBUG(3, "short packet, td = %p, count = %d", td, td->len - td->left);
  1468. +                                goto reset_toggle;
  1469. +                        }
  1470. +                }
  1471. +                // tranfer is done but fail, reset the toggle.
  1472. +                else if (td->done && td->td_status) {
  1473. +                        urb->status = td->td_status;
  1474. +                        PDEBUG(3, "error: td = %p, td status = %d", td, td->td_status);
  1475. +                        goto reset_toggle;
  1476. +                }
  1477. +                // unlink, and not do transfer yet
  1478. +                else if (td->done == 0 && urbp->unlink && td->td_status == 0) {
  1479. +                        urb->status = -ENOENT;
  1480. +                        PDEBUG(3, "unlink and not transfer!");
  1481. +                        return ;
  1482. +                }
  1483. +                // unlink, and transfer not complete yet.
  1484. +                else if (td->done == 0 && urbp->unlink && td->td_status) {
  1485. +                        PDEBUG(3, "unlink and not complete!");
  1486. +                        urb->status = -ENOENT;
  1487. +                        goto reset_toggle;
  1488. +                }
  1489. +                // must be bug!!!
  1490. +                else {// (td->done == 0 && urbp->unlink == 0)
  1491. +                        urb->status = -EPIPE;
  1492. +                        PDEBUG(1, "we should not get here!");
  1493. +                        return ;
  1494. +                }
  1495. +        }
  1496. +       
  1497. +        PDEBUG(4, "leave success");               
  1498. +        urb->status = 0;
  1499. +        return ;
  1500. +
  1501. +reset_toggle:
  1502. +        toggle = (td->ctrl & SL811_USB_CTRL_TOGGLE_1) ? 1 : 0;
  1503. +        usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), toggle);
  1504. +}
  1505. +
  1506. +/*
  1507. + * Find the first urb have the same dev and endpoint.
  1508. + */
  1509. +static inline int sl811_find_same_urb(struct list_head *head, struct urb *urb)
  1510. +{
  1511. +        struct list_head *tmp;
  1512. +        struct urb *u;
  1513. +       
  1514. +        if (!head || !urb)
  1515. +                return 0;
  1516. +               
  1517. +        tmp = head->next;
  1518. +       
  1519. +        while (tmp != head) {
  1520. +                u = list_entry(tmp, struct urb, urb_list);
  1521. +                if (u == urb)
  1522. +                        return 1;
  1523. +                tmp = tmp->next;       
  1524. +        }
  1525. +       
  1526. +        return 0;
  1527. +}
  1528. +
  1529. +/*
  1530. + * Find the first urb have the same dev and endpoint.
  1531. + */
  1532. +static inline struct urb* sl811_find_same_devep(struct list_head *head, struct urb *urb)
  1533. +{
  1534. +        struct list_head *tmp;
  1535. +        struct urb *u;
  1536. +       
  1537. +        if (!head || !urb)
  1538. +                return NULL;
  1539. +               
  1540. +        tmp = head->next;
  1541. +       
  1542. +        while (tmp != head) {
  1543. +                u = list_entry(tmp, struct urb, urb_list);
  1544. +                if ((usb_pipe_endpdev(u->pipe)) == (usb_pipe_endpdev(urb->pipe)))
  1545. +                        return u;
  1546. +                tmp = tmp->next;       
  1547. +        }
  1548. +       
  1549. +        return NULL;
  1550. +}
  1551. +
  1552. +/*
  1553. + * This function is called by the USB core API when an URB is available to
  1554. + * process.
  1555. + */
  1556. +static int sl811_submit_urb(struct urb *urb)
  1557. +{
  1558. +        struct sl811_hc *hc = urb->dev->bus->hcpriv;
  1559. +        unsigned int pipe = urb->pipe;
  1560. +        struct list_head *head = NULL;
  1561. +        unsigned long flags;
  1562. +        int bustime;
  1563. +        int ret = 0;
  1564. +       
  1565. +        if (!urb) {
  1566. +                PDEBUG(1, "urb is null");
  1567. +                return -EINVAL;
  1568. +        }
  1569. +       
  1570. +        if (urb->hcpriv) {
  1571. +                PDEBUG(1, "urbp is not null, urb = %p, urbp = %p", urb, urb->hcpriv);
  1572. +                return -EINVAL;
  1573. +        }
  1574. +       
  1575. +        if (!urb->dev || !urb->dev->bus || !hc)  {
  1576. +                PDEBUG(1, "dev or bus or hc is null");
  1577. +                return -ENODEV;
  1578. +        }
  1579. +       
  1580. +        if (usb_endpoint_halted(urb->dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
  1581. +                PDEBUG(2, "sl811_submit_urb: endpoint_halted");
  1582. +                return -EPIPE;
  1583. +        }
  1584. +       
  1585. +        if (usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)) > SL811_DATA_LIMIT) {
  1586. +                printk(KERN_ERR "Packet size is big for SL811, should < %d!\n", SL811_DATA_LIMIT);
  1587. +                return -EINVAL;
  1588. +        }
  1589. +       
  1590. +        /* a request to the virtual root hub */
  1591. +        if (usb_pipedevice(pipe) == hc->rh.devnum)
  1592. +                return sl811_rh_submit_urb(urb);
  1593. +       
  1594. +        spin_lock_irqsave(&hc->hc_lock, flags);
  1595. +        spin_lock(&urb->lock);
  1596. +       
  1597. +        switch (usb_pipetype(urb->pipe)) {
  1598. +        case PIPE_ISOCHRONOUS:
  1599. +                head = &hc->iso_list;
  1600. +                break;
  1601. +        case PIPE_INTERRUPT:
  1602. +                head = &hc->intr_list;
  1603. +                break;
  1604. +        case PIPE_CONTROL:
  1605. +                head = &hc->ctrl_list;
  1606. +                break;
  1607. +        case PIPE_BULK:
  1608. +                head = &hc->bulk_list;
  1609. +                break;
  1610. +        }
  1611. +               
  1612. +        if (sl811_find_same_devep(head, urb)) {
  1613. +                list_add(&urb->urb_list, &hc->wait_list);
  1614. +                PDEBUG(4, "add to wait list");
  1615. +                goto out_unlock;
  1616. +        }
  1617. +       
  1618. +        if (!sl811_alloc_urb_priv(urb)) {
  1619. +                ret = -ENOMEM;
  1620. +                goto out_unlock;
  1621. +        }
  1622. +       
  1623. +        switch (usb_pipetype(urb->pipe)) {
  1624. +        case PIPE_ISOCHRONOUS:
  1625. +                if (urb->number_of_packets <= 0) {
  1626. +                        ret = -EINVAL;
  1627. +                        break;
  1628. +                }
  1629. +                bustime = usb_check_bandwidth(urb->dev, urb);
  1630. +                if (bustime < 0) {
  1631. +                        ret = bustime;
  1632. +                        break;
  1633. +                }
  1634. +                if (!(ret = sl811_submit_isochronous(urb)))
  1635. +                        usb_claim_bandwidth(urb->dev, urb, bustime, 1);
  1636. +                break;
  1637. +        case PIPE_INTERRUPT:
  1638. +                bustime = usb_check_bandwidth(urb->dev, urb);
  1639. +                if (bustime < 0)
  1640. +                        ret = bustime;
  1641. +                else if (!(ret = sl811_submit_interrupt(urb)))
  1642. +                        usb_claim_bandwidth(urb->dev, urb, bustime, 0);
  1643. +                break;
  1644. +        case PIPE_CONTROL:
  1645. +                ret = sl811_submit_control(urb);
  1646. +                break;
  1647. +        case PIPE_BULK:
  1648. +                ret = sl811_submit_bulk(urb);
  1649. +                break;
  1650. +        }
  1651. +       
  1652. +        if (!ret) {
  1653. +                ((struct sl811_urb_priv *)urb->hcpriv)->inserttime = jiffies;
  1654. +                list_add(&urb->urb_list, head);
  1655. +                PDEBUG(4, "add to type list");
  1656. +                urb->status = -EINPROGRESS;
  1657. +                if (++hc->active_urbs == 1)
  1658. +                        sl811_enable_interrupt(hc);
  1659. +                goto out_unlock;       
  1660. +        } else {
  1661. +                PDEBUG(2, "submit urb fail! error = %d", ret);
  1662. +                sl811_free_urb_priv(urb);
  1663. +        }
  1664. +       
  1665. +out_unlock:       
  1666. +        spin_unlock(&urb->lock);
  1667. +        spin_unlock_irqrestore(&hc->hc_lock, flags);
  1668. +
  1669. +        return ret;
  1670. +}
  1671. +
  1672. +/*
  1673. + * Submit the urb the wait list.
  1674. + */
  1675. +static int sl811_submit_urb_with_lock(struct urb *urb)
  1676. +{
  1677. +        struct sl811_hc *hc = urb->dev->bus->hcpriv;
  1678. +        struct list_head *head = NULL;
  1679. +        int bustime;
  1680. +        int ret = 0;
  1681. +       
  1682. +        spin_lock(&urb->lock);
  1683. +       
  1684. +        switch (usb_pipetype(urb->pipe)) {
  1685. +        case PIPE_ISOCHRONOUS:
  1686. +                head = &hc->iso_list;
  1687. +                break;
  1688. +        case PIPE_INTERRUPT:
  1689. +                head = &hc->intr_list;
  1690. +                break;
  1691. +        case PIPE_CONTROL:
  1692. +                head = &hc->ctrl_list;
  1693. +                break;
  1694. +        case PIPE_BULK:
  1695. +                head = &hc->bulk_list;
  1696. +                break;
  1697. +        }
  1698. +               
  1699. +        if (!sl811_alloc_urb_priv(urb)) {
  1700. +                ret = -ENOMEM;
  1701. +                goto out_unlock;
  1702. +        }
  1703. +       
  1704. +        switch (usb_pipetype(urb->pipe)) {
  1705. +        case PIPE_ISOCHRONOUS:
  1706. +                if (urb->number_of_packets <= 0) {
  1707. +                        ret = -EINVAL;
  1708. +                        break;
  1709. +                }
  1710. +                bustime = usb_check_bandwidth(urb->dev, urb);
  1711. +                if (bustime < 0) {
  1712. +                        ret = bustime;
  1713. +                        break;
  1714. +                }
  1715. +                if (!(ret = sl811_submit_isochronous(urb)))
  1716. +                        usb_claim_bandwidth(urb->dev, urb, bustime, 1);
  1717. +                break;
  1718. +        case PIPE_INTERRUPT:
  1719. +                bustime = usb_check_bandwidth(urb->dev, urb);
  1720. +                if (bustime < 0)
  1721. +                        ret = bustime;
  1722. +                else if (!(ret = sl811_submit_interrupt(urb)))
  1723. +                        usb_claim_bandwidth(urb->dev, urb, bustime, 0);
  1724. +                break;
  1725. +        case PIPE_CONTROL:
  1726. +                ret = sl811_submit_control(urb);
  1727. +                break;
  1728. +        case PIPE_BULK:
  1729. +                ret = sl811_submit_bulk(urb);
  1730. +                break;
  1731. +        }
  1732. +       
  1733. +        if (ret == 0) {
  1734. +                ((struct sl811_urb_priv *)urb->hcpriv)->inserttime = jiffies;
  1735. +                list_add(&urb->urb_list, head);
  1736. +                PDEBUG(4, "add to type list");
  1737. +                urb->status = -EINPROGRESS;
  1738. +                if (++hc->active_urbs == 1)
  1739. +                        sl811_enable_interrupt(hc);
  1740. +                goto out_unlock;       
  1741. +        } else {
  1742. +                PDEBUG(2, "submit urb fail! error = %d", ret);
  1743. +                sl811_free_urb_priv(urb);
  1744. +        }
  1745. +       
  1746. +out_unlock:       
  1747. +        spin_unlock(&urb->lock);
  1748. +
  1749. +        return ret;
  1750. +}
  1751. +
  1752. +/*
  1753. + * Reset the urb
  1754. + */
  1755. +static void sl811_reset_urb(struct urb *urb)
  1756. +{
  1757. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1758. +
  1759. +        switch (usb_pipetype(urb->pipe)) {
  1760. +        case PIPE_ISOCHRONOUS:
  1761. +                sl811_reset_isochronous(urb);
  1762. +                break;
  1763. +        case PIPE_INTERRUPT:
  1764. +                sl811_reset_interrupt(urb);
  1765. +                break;
  1766. +        case PIPE_CONTROL:
  1767. +                return;
  1768. +        case PIPE_BULK:
  1769. +                sl811_reset_bulk(urb);
  1770. +                break;
  1771. +        }
  1772. +        urbp->inserttime = jiffies;
  1773. +}
  1774. +
  1775. +/*
  1776. + * Return the result of a transfer
  1777. + */
  1778. +static void sl811_result_urb(struct urb *urb)
  1779. +{
  1780. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  1781. +        struct sl811_hc *hc = urb->dev->bus->hcpriv;
  1782. +        struct list_head *head = NULL;
  1783. +        struct urb *u = NULL;
  1784. +        int reset = 0;
  1785. +        int ring = 0;
  1786. +
  1787. +        if (urb->status != -EINPROGRESS) {
  1788. +                PDEBUG(1, "urb status is not EINPROGRESS!");
  1789. +                return ;
  1790. +        }
  1791. +       
  1792. +        spin_lock(&urb->lock);
  1793. +       
  1794. +        switch (usb_pipetype(urb->pipe)) {
  1795. +        case PIPE_ISOCHRONOUS:
  1796. +                head = &hc->iso_list;
  1797. +                sl811_result_isochronous(urb);
  1798. +               
  1799. +                // if the urb is not unlink and is in a urb "ring", we reset it
  1800. +                if (!urbp->unlink && urb->next)
  1801. +                        ring = 1;
  1802. +                break;
  1803. +        case PIPE_INTERRUPT:
  1804. +                head = &hc->intr_list;
  1805. +                sl811_result_interrupt(urb);
  1806. +               
  1807. +                // if the urb is not unlink and not "once" query, we reset.
  1808. +                if (!urbp->unlink && urb->interval)
  1809. +                        reset = 1;
  1810. +                break;
  1811. +        case PIPE_CONTROL:
  1812. +                head = &hc->ctrl_list;
  1813. +                sl811_result_control(urb);
  1814. +                break;
  1815. +        case PIPE_BULK:
  1816. +                head = &hc->bulk_list;
  1817. +                sl811_result_bulk(urb);
  1818. +               
  1819. +                // if the urb is not unlink and is in a urb "ring", we reset it
  1820. +                if (!urbp->unlink && urb->next)
  1821. +                        ring = 1;
  1822. +                break;
  1823. +        }
  1824. +       
  1825. +        PDEBUG(4, "result urb status = %d", urb->status);
  1826. +       
  1827. +        if (ring && urb->next == urb)
  1828. +                reset = 1;
  1829. +       
  1830. +        if (!reset) {
  1831. +                switch (usb_pipetype(urb->pipe)) {
  1832. +                case PIPE_ISOCHRONOUS:
  1833. +                        usb_release_bandwidth(urb->dev, urb, 1);
  1834. +                        break;
  1835. +                case PIPE_INTERRUPT:
  1836. +                        usb_release_bandwidth(urb->dev, urb, 0);
  1837. +                        break;
  1838. +                }
  1839. +                sl811_free_urb_priv(urb);
  1840. +        }
  1841. +       
  1842. +        spin_unlock(&urb->lock);
  1843. +       
  1844. +        if (urb->complete)
  1845. +                urb->complete(urb);
  1846. +       
  1847. +        if (reset) {
  1848. +                spin_lock(&urb->lock);
  1849. +                sl811_reset_urb(urb);
  1850. +                if (usb_pipeint(urb->pipe))
  1851. +                        list_add(&urb->urb_list, &hc->idle_intr_list);
  1852. +                else
  1853. +                        list_add(&urb->urb_list, head);
  1854. +                spin_unlock(&urb->lock);
  1855. +        } else {
  1856. +                if (--hc->active_urbs <= 0) {
  1857. +                        hc->active_urbs = 0;
  1858. +                        sl811_disable_interrupt(hc);
  1859. +                }
  1860. +               
  1861. +                if (ring)
  1862. +                        u = urb->next;
  1863. +                else
  1864. +                        u = sl811_find_same_devep(&hc->wait_list, urb);
  1865. +                       
  1866. +                if (u) {
  1867. +                        if (!list_empty(&u->urb_list))
  1868. +                                list_del(&u->urb_list);
  1869. +                        if (sl811_submit_urb_with_lock(u))
  1870. +                                list_add(&u->urb_list, &hc->wait_list);
  1871. +                }
  1872. +        }
  1873. +}
  1874. +
  1875. +
  1876. +#ifdef SL811_TIMEOUT
  1877. +
  1878. +/*
  1879. + * Unlink the urb from the urb list
  1880. + */
  1881. +static int sl811_unlink_urb(struct urb *urb)
  1882. +{
  1883. +        unsigned long flags;
  1884. +        struct sl811_hc *hc;
  1885. +        struct sl811_urb_priv *urbp;
  1886. +        int call = 0;
  1887. +        int schedule = 0;
  1888. +        int count = 0;
  1889. +       
  1890. +        if (!urb) {
  1891. +                PDEBUG(1, "urb is null");
  1892. +                return -EINVAL;
  1893. +        }
  1894. +       
  1895. +        if (!urb->dev || !urb->dev->bus) {
  1896. +                PDEBUG(1, "dev or bus is null");
  1897. +                return -ENODEV;
  1898. +        }
  1899. +       
  1900. +        hc = urb->dev->bus->hcpriv;
  1901. +        urbp = urb->hcpriv;
  1902. +       
  1903. +        /* a request to the virtual root hub */
  1904. +        if (usb_pipedevice(urb->pipe) == hc->rh.devnum)
  1905. +                return sl811_rh_unlink_urb(urb);
  1906. +       
  1907. +        spin_lock_irqsave(&hc->hc_lock, flags);
  1908. +        spin_lock(&urb->lock);
  1909. +
  1910. +        // in wait list
  1911. +        if (sl811_find_same_urb(&hc->wait_list, urb)) {       
  1912. +                PDEBUG(4, "unlink urb in wait list");
  1913. +                list_del_init(&urb->urb_list);
  1914. +                urb->status = -ENOENT;
  1915. +                call = 1;
  1916. +                goto out;
  1917. +        }
  1918. +       
  1919. +        // in intr idle list.
  1920. +        if (sl811_find_same_urb(&hc->idle_intr_list, urb)) {       
  1921. +                PDEBUG(4, "unlink urb in idle intr list");
  1922. +                list_del_init(&urb->urb_list);
  1923. +                urb->status = -ENOENT;
  1924. +                sl811_free_urb_priv(urb);
  1925. +                usb_release_bandwidth(urb->dev, urb, 0);
  1926. +                if (--hc->active_urbs <= 0) {
  1927. +                        hc->active_urbs = 0;
  1928. +                        sl811_disable_interrupt(hc);
  1929. +                }
  1930. +                call = 1;
  1931. +                goto out;
  1932. +        }
  1933. +
  1934. +        if (urb->status == -EINPROGRESS) {  
  1935. +                PDEBUG(3, "urb is still in progress");
  1936. +                urbp->unlink = 1;
  1937. +
  1938. +re_unlink:
  1939. +                // Is it in progress?
  1940. +                urbp = urb->hcpriv;
  1941. +                if (urbp && hc->cur_td == urbp->cur_td) {
  1942. +                        ++count;
  1943. +                        if (sl811_read(hc, 0) & SL811_USB_CTRL_ARM) {
  1944. +                                PDEBUG(3, "unlink: cur td is still in progress! count = %d", count);
  1945. +re_schedule:                               
  1946. +                                schedule = 1;
  1947. +                                spin_unlock(&urb->lock);
  1948. +                                spin_unlock_irqrestore(&hc->hc_lock, flags);
  1949. +                                schedule_timeout(HZ/50);
  1950. +                                spin_lock_irqsave(&hc->hc_lock, flags);
  1951. +                                spin_lock(&urb->lock);
  1952. +                        } else {
  1953. +                                PDEBUG(3, "unlink: lost of interrupt? do parse! count = %d", count);
  1954. +                                spin_unlock(&urb->lock);
  1955. +                                sl811_transfer_done(hc, 0);
  1956. +                                spin_lock(&urb->lock);
  1957. +                        }
  1958. +                        goto re_unlink;
  1959. +                }
  1960. +               
  1961. +                if (list_empty(&urb->urb_list)) {
  1962. +                        PDEBUG(3, "unlink: list empty!");
  1963. +                        goto out;
  1964. +                }
  1965. +                       
  1966. +                if (urb->transfer_flags & USB_TIMEOUT_KILLED) {
  1967. +                        PDEBUG(3, "unlink: time out killed");
  1968. +                        // it is timeout killed by us
  1969. +                        goto result;
  1970. +                } else if (urb->transfer_flags & USB_ASYNC_UNLINK) {
  1971. +                        // we do nothing, just let it be processing later
  1972. +                        PDEBUG(3, "unlink async, do nothing");
  1973. +                        goto out;
  1974. +                } else {
  1975. +                        // synchron without callback
  1976. +                        PDEBUG(3, "unlink synchron, we wait the urb complete or timeout");
  1977. +                        if (schedule == 0) {
  1978. +                                PDEBUG(3, "goto re_schedule");
  1979. +                                goto re_schedule;
  1980. +                        } else {
  1981. +                                PDEBUG(3, "already scheduled");
  1982. +                                goto result;
  1983. +                        }
  1984. +                }
  1985. +        } else if (!list_empty(&urb->urb_list)) {
  1986. +                PDEBUG(1, "urb = %p, status = %d is in a list, why?", urb, urb->status);
  1987. +                //list_del_init(&urb->urb_list);
  1988. +                //call = 1;
  1989. +        }
  1990. +
  1991. +out:
  1992. +        spin_unlock(&urb->lock);
  1993. +        spin_unlock_irqrestore(&hc->hc_lock, flags);
  1994. +       
  1995. +        if (call && urb->complete)
  1996. +                urb->complete(urb);
  1997. +       
  1998. +        return 0;
  1999. +       
  2000. +result:
  2001. +        spin_unlock(&urb->lock);
  2002. +       
  2003. +        list_del_init(&urb->urb_list);
  2004. +        sl811_result_urb(urb);       
  2005. +       
  2006. +        spin_unlock_irqrestore(&hc->hc_lock, flags);
  2007. +       
  2008. +        return 0;
  2009. +}
  2010. +
  2011. +#else
  2012. +
  2013. +/*
  2014. + * Unlink the urb from the urb list
  2015. + */
  2016. +static int sl811_unlink_urb(struct urb *urb)
  2017. +{
  2018. +        unsigned long flags;
  2019. +        struct sl811_hc *hc;
  2020. +        struct sl811_urb_priv *urbp;
  2021. +        int call = 0;
  2022. +       
  2023. +        if (!urb) {
  2024. +                PDEBUG(1, "urb is null");
  2025. +                return -EINVAL;
  2026. +        }
  2027. +       
  2028. +        if (!urb->dev || !urb->dev->bus) {
  2029. +                PDEBUG(1, "dev or bus is null");
  2030. +                return -ENODEV;
  2031. +        }
  2032. +       
  2033. +        hc = urb->dev->bus->hcpriv;
  2034. +        urbp = urb->hcpriv;
  2035. +       
  2036. +        /* a request to the virtual root hub */
  2037. +        if (usb_pipedevice(urb->pipe) == hc->rh.devnum)
  2038. +                return sl811_rh_unlink_urb(urb);
  2039. +       
  2040. +        spin_lock_irqsave(&hc->hc_lock, flags);
  2041. +        spin_lock(&urb->lock);
  2042. +
  2043. +        // in wait list
  2044. +        if (sl811_find_same_urb(&hc->wait_list, urb)) {       
  2045. +                PDEBUG(2, "unlink urb in wait list");
  2046. +                list_del_init(&urb->urb_list);
  2047. +                urb->status = -ENOENT;
  2048. +                call = 1;
  2049. +                goto out;
  2050. +        }
  2051. +       
  2052. +        if (urb->status == -EINPROGRESS) {  
  2053. +                PDEBUG(2, "urb is still in progress");
  2054. +                urbp->unlink = 1;
  2055. +
  2056. +                // Is it in progress?
  2057. +                urbp = urb->hcpriv;
  2058. +                if (urbp && hc->cur_td == urbp->cur_td) {
  2059. +                        // simple, let it out
  2060. +                        PDEBUG(2, "unlink: cur td is still in progress!");
  2061. +                        hc->cur_td = NULL;
  2062. +                }
  2063. +               
  2064. +                goto result;
  2065. +        } else if (!list_empty(&urb->urb_list)) {
  2066. +                PDEBUG(1, "urb = %p, status = %d is in a list, why?", urb, urb->status);
  2067. +                list_del_init(&urb->urb_list);
  2068. +                if (urbp)
  2069. +                        goto result;
  2070. +                else
  2071. +                        call = 1;
  2072. +        }
  2073. +
  2074. +out:
  2075. +        spin_unlock(&urb->lock);
  2076. +        spin_unlock_irqrestore(&hc->hc_lock, flags);
  2077. +       
  2078. +        if (call && urb->complete)
  2079. +                urb->complete(urb);
  2080. +                       
  2081. +        return 0;
  2082. +       
  2083. +result:
  2084. +        spin_unlock(&urb->lock);
  2085. +       
  2086. +        list_del_init(&urb->urb_list);
  2087. +        sl811_result_urb(urb);       
  2088. +       
  2089. +        spin_unlock_irqrestore(&hc->hc_lock, flags);
  2090. +       
  2091. +        return 0;
  2092. +}
  2093. +
  2094. +#endif
  2095. +
  2096. +static int sl811_get_current_frame_number(struct usb_device *usb_dev)
  2097. +{
  2098. +        return ((struct sl811_hc *)(usb_dev->bus->hcpriv))->frame_number;
  2099. +}
  2100. +
  2101. +static struct usb_operations sl811_device_operations =
  2102. +{
  2103. +        sl811_alloc_dev_priv,
  2104. +        sl811_free_dev_priv,
  2105. +        sl811_get_current_frame_number,
  2106. +        sl811_submit_urb,
  2107. +        sl811_unlink_urb
  2108. +};
  2109. +
  2110. +/*
  2111. + * This        functions transmit a td.
  2112. + */
  2113. +static inline void sl811_trans_cur_td(struct sl811_hc *hc, struct sl811_td *td)
  2114. +{
  2115. +        sl811_print_td(4, td);
  2116. +        sl811_write_buf(hc, SL811_ADDR_A,  &td->addr, 4);
  2117. +        if (td->len && (td->ctrl & SL811_USB_CTRL_DIR_OUT))
  2118. +                sl811_write_buf(hc, td->addr,  td->buf, td->len);
  2119. +
  2120. +        sl811_write(hc,        SL811_CTRL_A, td->ctrl);
  2121. +}
  2122. +
  2123. +               
  2124. +/*
  2125. + * This        function checks        the status of the transmitted or received packet
  2126. + * and copy the        data from the SL811HS register into a buffer.
  2127. + */
  2128. +static void sl811_parse_cur_td(struct sl811_hc *hc, struct sl811_td *td)
  2129. +{
  2130. +        struct urb *urb = td->urb;
  2131. +#ifdef SL811_DEBUG
  2132. +        int dev = usb_pipedevice(td->urb->pipe);
  2133. +        int ep = usb_pipeendpoint(td->urb->pipe);
  2134. +#endif
  2135. +
  2136. +        sl811_read_buf(hc, SL811_STS_A, &td->status, 2);
  2137. +       
  2138. +        if (td->status & SL811_USB_STS_ACK) {
  2139. +                td->done = 1;
  2140. +               
  2141. +/*                if ((td->ctrl & SL811_USB_CTRL_TOGGLE_1) != (td->status & SL811_USB_STS_TOGGLE_1)) {
  2142. +                        PDEBUG(2, "dev %d endpoint %d unexpect data toggle!", dev, ep);
  2143. +                        td->td_status = -EILSEQ;
  2144. +                }
  2145. +*/               
  2146. +                if (!(td->ctrl & SL811_USB_CTRL_DIR_OUT) && td->len > 0)
  2147. +                        sl811_read_buf(hc, td->addr, td->buf, td->len - td->left);
  2148. +                       
  2149. +                if (td->left && (urb->transfer_flags & USB_DISABLE_SPD)) {
  2150. +                        PDEBUG(2, "dev %d endpoint %d unexpect short packet! td = %p", dev, ep, td);
  2151. +                        td->td_status = -EREMOTEIO;
  2152. +                } else
  2153. +                        td->td_status = 0;
  2154. +        } else if (td->status & SL811_USB_STS_STALL) {
  2155. +                PDEBUG(2, "dev %d endpoint %d halt, td = %p", dev, ep, td);
  2156. +                td->td_status = -EPIPE;
  2157. +                if (urb->dev)
  2158. +                        usb_endpoint_halt(td->urb->dev, usb_pipeendpoint(td->urb->pipe), usb_pipeout(td->urb->pipe));
  2159. +                td->done = 1;
  2160. +        } else if (td->status & SL811_USB_STS_OVERFLOW) {
  2161. +                PDEBUG(1, "dev %d endpoint %d overflow, sl811 only support packet less than %d", dev, ep, SL811_DATA_LIMIT);       
  2162. +                td->td_status = -EOVERFLOW;
  2163. +                td->done = 1;
  2164. +        } else if (td->status & SL811_USB_STS_TIMEOUT ) {
  2165. +                PDEBUG(2, "dev %d endpoint %d timeout, td = %p", dev, ep, td);       
  2166. +                td->td_status = -ETIMEDOUT;
  2167. +                if (--td->errcnt == 0)
  2168. +                        td->done = 1;
  2169. +        } else if (td->status & SL811_USB_STS_ERROR) {
  2170. +                PDEBUG(2, "dev %d endpoint %d error, td = %p", dev, ep, td);
  2171. +                td->td_status = -EILSEQ;
  2172. +                if (--td->errcnt == 0)
  2173. +                        td->done = 1;
  2174. +        } else if (td->status & SL811_USB_STS_NAK) {
  2175. +                ++td->nakcnt;
  2176. +                PDEBUG(3, "dev %d endpoint %d nak, td = %p, count = %d", dev, ep, td, td->nakcnt);
  2177. +                td->td_status = -EINPROGRESS;
  2178. +                if (!usb_pipeslow(td->urb->pipe) && td->nakcnt > 1024) {
  2179. +                        PDEBUG(2, "too many naks, td = %p, count = %d", td, td->nakcnt);
  2180. +                        td->td_status = -ETIMEDOUT;
  2181. +                        td->done = 1;
  2182. +                }
  2183. +        }
  2184. +       
  2185. +        sl811_print_td(4, td);
  2186. +}
  2187. +
  2188. +/*
  2189. + * This        function checks        the status of current urb.
  2190. + */
  2191. +static int sl811_parse_cur_urb(struct urb *urb)
  2192. +{
  2193. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  2194. +        struct sl811_td *td = urbp->cur_td;
  2195. +        struct list_head *tmp;
  2196. +       
  2197. +        sl811_print_td(5, td);
  2198. +       
  2199. +        // this td not done yet.
  2200. +        if (!td->done)
  2201. +                return 0;
  2202. +       
  2203. +        // the last ld, so the urb is done.
  2204. +        if (td == urbp->last_td) {
  2205. +                PDEBUG(4, "urb = %p is done success", td->urb);
  2206. +                if (usb_pipeisoc(td->urb->pipe))
  2207. +                        PDEBUG(4, "ISO URB DONE, td = %p", td);
  2208. +                return 1;
  2209. +        }
  2210. +       
  2211. +        // iso transfer, we always advance to next td
  2212. +        if (usb_pipeisoc(td->urb->pipe)) {
  2213. +                tmp = &td->td_list;
  2214. +                tmp = tmp->next;
  2215. +                urbp->cur_td = list_entry(tmp, struct sl811_td, td_list);
  2216. +                PDEBUG(4, "ISO NEXT, td = %p", urbp->cur_td);       
  2217. +                return 0;
  2218. +        }
  2219. +               
  2220. +        // some error occur, so the urb is done.
  2221. +        if (td->td_status) {
  2222. +                PDEBUG(3, "urb = %p is done error, td status is = %d", td->urb, td->td_status);
  2223. +                return 1;
  2224. +        }
  2225. +               
  2226. +        // short packet.
  2227. +        if (td->left) {
  2228. +                if (usb_pipecontrol(td->urb->pipe)) {
  2229. +                        // control packet, we advance to the last td
  2230. +                        PDEBUG(3, "ctrl short packet, advance to last td");
  2231. +                        urbp->cur_td = urbp->last_td;
  2232. +                        return 0;
  2233. +                } else {
  2234. +                        // interrut and bulk packet, urb is over.
  2235. +                        PDEBUG(3, "bulk or intr short packet, urb is over");
  2236. +                        return 1;
  2237. +                }
  2238. +        }
  2239. +
  2240. +        // we advance to next td.       
  2241. +        tmp = &td->td_list;
  2242. +        tmp = tmp->next;
  2243. +        urbp->cur_td = list_entry(tmp, struct sl811_td, td_list);
  2244. +#ifdef SL811_DEBUG
  2245. +        PDEBUG(4, "advance to the next td, urb = %p, td = %p", urb, urbp->cur_td);
  2246. +        sl811_print_td(5, urbp->cur_td);
  2247. +        if (td == urbp->cur_td)
  2248. +                PDEBUG(1, "bug!!!");
  2249. +#endif               
  2250. +        return 0;
  2251. +}
  2252. +
  2253. +/*
  2254. + * Find the next td to transfer.
  2255. + */
  2256. +static inline struct sl811_td* sl811_schedule_next_td(struct urb *urb, struct sl811_td *cur_td)
  2257. +{
  2258. +        struct sl811_urb_priv *urbp = urb->hcpriv;
  2259. +       
  2260. +        PDEBUG(4, "urb at %p, cur td at %p", urb, cur_td);
  2261. +       
  2262. +        // iso don't schedule the td in the same frame.
  2263. +        if (usb_pipeisoc(cur_td->urb->pipe))
  2264. +                return NULL;
  2265. +       
  2266. +        // cur td is not complete
  2267. +        if (!cur_td->done)
  2268. +                return NULL;       
  2269. +       
  2270. +        // here, urbp->cur_td is already the next td;
  2271. +        return urbp->cur_td;
  2272. +}
  2273. +
  2274. +/*
  2275. + * Scan the list to find a active urb
  2276. + */
  2277. +static inline struct urb* sl811_get_list_next_urb(struct sl811_hc *hc, struct list_head *next)
  2278. +{
  2279. +        struct urb *urb;
  2280. +        int i;
  2281. +       
  2282. +        if (list_empty(next))
  2283. +                return NULL;
  2284. +       
  2285. +        if (next == hc->cur_list)
  2286. +                return NULL;
  2287. +                       
  2288. +        for (i = 0; i < 4; ++i)
  2289. +                if (next == &hc->urb_list[i])
  2290. +                        return NULL;
  2291. +                       
  2292. +        urb = list_entry(next, struct urb, urb_list);
  2293. +        PDEBUG(4, "next urb in list is at %p", urb);
  2294. +               
  2295. +        return urb;
  2296. +}
  2297. +
  2298. +/*
  2299. + * Find the next td to transfer.
  2300. + */
  2301. +static struct sl811_td* sl811_schedule_next_urb(struct sl811_hc *hc, struct list_head *next)
  2302. +{
  2303. +        struct urb *urb = NULL;
  2304. +        int back_loop = 1;
  2305. +        struct list_head *old_list = hc->cur_list;
  2306. +               
  2307. +        // try to get next urb in the same list.
  2308. +        if (next) {
  2309. +                urb = sl811_get_list_next_urb(hc, next);
  2310. +                if (!urb)
  2311. +                        ++hc->cur_list;
  2312. +        }
  2313. +
  2314. +        // try other list.
  2315. +        if (!urb) {                       
  2316. +re_loop:
  2317. +                // try all the list.
  2318. +                while (hc->cur_list < &hc->urb_list[4]) {
  2319. +                        if ((urb = sl811_get_list_next_urb(hc, hc->cur_list->next)))
  2320. +                                return ((struct sl811_urb_priv *)urb->hcpriv)->cur_td;
  2321. +                        ++hc->cur_list;
  2322. +                }
  2323. +                // the last list is try
  2324. +                if (back_loop && (old_list >= &hc->ctrl_list)) {
  2325. +                        hc->cur_list = &hc->ctrl_list;
  2326. +                        back_loop = 0;
  2327. +                        goto re_loop;
  2328. +                }
  2329. +        }
  2330. +       
  2331. +        if (hc->cur_list > &hc->urb_list[3])
  2332. +                hc->cur_list = &hc->ctrl_list;
  2333. +                       
  2334. +        return NULL;
  2335. +}
  2336. +
  2337. +/*
  2338. + * This function process the transfer rusult.
  2339. + */
  2340. +static void sl811_transfer_done(struct sl811_hc *hc, int sof)
  2341. +{
  2342. +        struct sl811_td *cur_td = hc->cur_td, *next_td = NULL;
  2343. +        struct urb *cur_urb = NULL;
  2344. +               struct list_head *next = NULL;
  2345. +               int done;
  2346. +       
  2347. +        PDEBUG(5, "enter");
  2348. +       
  2349. +        if (cur_td == NULL) {
  2350. +                PDEBUG(1, "in done interrupt, but td is null, be already parsed?");
  2351. +                return ;
  2352. +        }
  2353. +
  2354. +        cur_urb = cur_td->urb;
  2355. +        hc->cur_td = NULL;
  2356. +        next = &cur_urb->urb_list;
  2357. +        next = next->next;
  2358. +       
  2359. +        spin_lock(&cur_urb->lock);       
  2360. +        sl811_parse_cur_td(hc, cur_td);
  2361. +        done = sl811_parse_cur_urb(cur_urb);
  2362. +        spin_unlock(&cur_urb->lock);
  2363. +       
  2364. +        if (done) {
  2365. +                list_del_init(&cur_urb->urb_list);
  2366. +                cur_td = NULL;
  2367. +                sl811_result_urb(cur_urb);       
  2368. +        }
  2369. +
  2370. +        if (sof)
  2371. +                return ;
  2372. +       
  2373. +        if (!done) {
  2374. +                next_td = sl811_schedule_next_td(cur_urb, cur_td);
  2375. +                if (next_td && next_td != cur_td && (sl811_calc_bus_remainder(hc) > next_td->bustime)) {
  2376. +                        hc->cur_td = next_td;
  2377. +                        PDEBUG(5, "ADD TD");
  2378. +                        sl811_trans_cur_td(hc, next_td);
  2379. +                        return ;
  2380. +                }
  2381. +        }
  2382. +       
  2383. +        while (1) {
  2384. +                next_td = sl811_schedule_next_urb(hc, next);
  2385. +                if (!next_td)
  2386. +                        return;
  2387. +                if (next_td == cur_td)
  2388. +                        return;
  2389. +                next = &next_td->urb->urb_list;
  2390. +                next = next->next;
  2391. +                if (sl811_calc_bus_remainder(hc) > next_td->bustime) {
  2392. +                        hc->cur_td = next_td;
  2393. +                        PDEBUG(5, "ADD TD");
  2394. +                        sl811_trans_cur_td(hc, next_td);
  2395. +                        return ;
  2396. +                }
  2397. +        }
  2398. +}
  2399. +
  2400. +/*
  2401. + *
  2402. + */
  2403. +static void inline sl811_dec_intr_interval(struct sl811_hc *hc)
  2404. +{
  2405. +        struct list_head *head, *tmp;
  2406. +        struct urb *urb;
  2407. +        struct sl811_urb_priv *urbp;
  2408. +       
  2409. +        if (list_empty(&hc->idle_intr_list))
  2410. +                return ;
  2411. +       
  2412. +        head = &hc->idle_intr_list;
  2413. +        tmp = head->next;
  2414. +       
  2415. +        while (tmp != head) {
  2416. +                urb = list_entry(tmp, struct urb, urb_list);
  2417. +                tmp = tmp->next;
  2418. +                spin_lock(&urb->lock);
  2419. +                urbp = urb->hcpriv;
  2420. +                if (--urbp->interval == 0) {
  2421. +                        list_del(&urb->urb_list);
  2422. +                        list_add(&urb->urb_list, &hc->intr_list);
  2423. +                        PDEBUG(4, "intr urb active");
  2424. +                }
  2425. +                spin_unlock(&urb->lock);
  2426. +        }
  2427. +}
  2428. +
  2429. +/*
  2430. + * The sof interrupt is happen.       
  2431. + */
  2432. +static void sl811_start_sof(struct sl811_hc *hc)
  2433. +{
  2434. +        struct sl811_td *next_td;
  2435. +#ifdef SL811_DEBUG
  2436. +        static struct sl811_td *repeat_td = NULL;
  2437. +        static repeat_cnt = 1;
  2438. +#endif       
  2439. +        if (++hc->frame_number > 1024)
  2440. +                hc->frame_number = 0;
  2441. +       
  2442. +        if (hc->active_urbs == 0)
  2443. +                return ;
  2444. +       
  2445. +        sl811_dec_intr_interval(hc);
  2446. +       
  2447. +        if (hc->cur_td) {
  2448. +                if (sl811_read(hc, 0) & SL811_USB_CTRL_ARM) {
  2449. +#ifdef SL811_DEBUG
  2450. +                        if (repeat_td == hc->cur_td)
  2451. +                                ++repeat_cnt;
  2452. +                        else {
  2453. +                                if (repeat_cnt >= 2)
  2454. +                                        PDEBUG(2, "cur td = %p repeat %d", hc->cur_td, repeat_cnt);
  2455. +                                repeat_cnt = 1;
  2456. +                                repeat_td = hc->cur_td;
  2457. +                        }
  2458. +#endif
  2459. +                        return ;
  2460. +                } else {
  2461. +                        PDEBUG(2, "lost of interrupt in sof? do parse!");
  2462. +                        sl811_transfer_done(hc, 1);
  2463. +                       
  2464. +                        // let this frame idle       
  2465. +                        return;
  2466. +                }
  2467. +        }
  2468. +       
  2469. +        hc->cur_list = &hc->iso_list;
  2470. +       
  2471. +        if (hc->active_urbs == 0)
  2472. +                return ;
  2473. +       
  2474. +        next_td = sl811_schedule_next_urb(hc, NULL);
  2475. +        if (!next_td) {
  2476. +#ifdef SL811_DEBUG
  2477. +                if (list_empty(&hc->idle_intr_list))
  2478. +                        PDEBUG(2, "not schedule a td, why? urbs = %d", hc->active_urbs);
  2479. +#endif
  2480. +                return;
  2481. +        }
  2482. +        if (sl811_calc_bus_remainder(hc) > next_td->bustime) {
  2483. +                hc->cur_td = next_td;
  2484. +                sl811_trans_cur_td(hc, next_td);
  2485. +        } else
  2486. +                PDEBUG(2, "bus time if not enough, why?");
  2487. +}
  2488. +
  2489. +/*
  2490. + * This        function resets        SL811HS        controller and detects the speed of
  2491. + * the connecting device
  2492. + *
  2493. + * Return: 0 = no device attached; 1 = USB device attached
  2494. + */
  2495. +static int sl811_hc_reset(struct sl811_hc *hc)
  2496. +{
  2497. +        int status ;
  2498. +
  2499. +        sl811_write(hc,        SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
  2500. +        sl811_write(hc,        SL811_CTRL1, SL811_CTRL1_RESET);
  2501. +
  2502. +        mdelay(20);
  2503. +       
  2504. +        // Disable hardware SOF generation.
  2505. +        sl811_write(hc,        SL811_CTRL1, 0);
  2506. +        mdelay(2);
  2507. +        sl811_write(hc, SL811_INTRSTS, 0xff);
  2508. +        status = sl811_read(hc, SL811_INTRSTS);
  2509. +
  2510. +        if (status & SL811_INTR_NOTPRESENT) {
  2511. +                // Device is not present
  2512. +                PDEBUG(0, "Device not present");
  2513. +                hc->rh_status.wPortStatus &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE);
  2514. +                hc->rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
  2515. +                sl811_write(hc,        SL811_INTR, SL811_INTR_INSRMV);
  2516. +                return 0;
  2517. +        }
  2518. +
  2519. +        // Send SOF to address 0, endpoint 0.
  2520. +        sl811_write(hc, SL811_LEN_B, 0);
  2521. +        sl811_write(hc, SL811_PIDEP_B, PIDEP(USB_PID_SOF, 0));
  2522. +        sl811_write(hc, SL811_DEV_B, 0x00);
  2523. +        sl811_write (hc, SL811_SOFLOW, SL811_12M_HI);
  2524. +
  2525. +        if (status & SL811_INTR_SPEED_FULL) {
  2526. +                /* full        speed device connect directly to root hub */
  2527. +                PDEBUG (0, "Full speed Device attached");
  2528. +               
  2529. +                sl811_write(hc, SL811_CTRL1, SL811_CTRL1_RESET);
  2530. +                mdelay(20);
  2531. +                sl811_write(hc,        SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
  2532. +                sl811_write(hc, SL811_CTRL1, SL811_CTRL1_SOF);
  2533. +
  2534. +                /* start the SOF or EOP        */
  2535. +                sl811_write(hc, SL811_CTRL_B, SL811_USB_CTRL_ARM);
  2536. +                hc->rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION;
  2537. +                hc->rh_status.wPortStatus &= ~USB_PORT_STAT_LOW_SPEED;
  2538. +                mdelay(2);
  2539. +                sl811_write (hc, SL811_INTRSTS, 0xff);
  2540. +        } else {
  2541. +                /* slow        speed device connect directly to root-hub */
  2542. +                PDEBUG(0, "Low speed Device attached");
  2543. +               
  2544. +                sl811_write(hc, SL811_CTRL1, SL811_CTRL1_RESET);
  2545. +                mdelay(20);
  2546. +                sl811_write(hc,        SL811_CTRL2, SL811_CTL2_HOST | SL811_CTL2_DSWAP | SL811_12M_HI);
  2547. +                sl811_write(hc, SL811_CTRL1, SL811_CTRL1_SPEED_LOW | SL811_CTRL1_SOF);
  2548. +
  2549. +                /* start the SOF or EOP        */
  2550. +                sl811_write(hc, SL811_CTRL_B, SL811_USB_CTRL_ARM);
  2551. +                hc->rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION | USB_PORT_STAT_LOW_SPEED;
  2552. +                mdelay(2);
  2553. +                sl811_write(hc, SL811_INTRSTS, 0xff);
  2554. +        }
  2555. +
  2556. +        hc->rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
  2557. +        sl811_write(hc,        SL811_INTR, SL811_INTR_INSRMV);
  2558. +       
  2559. +        return 1;
  2560. +}
  2561. +
  2562. +/*
  2563. + * Interrupt service routine.
  2564. + */
  2565. +static void sl811_interrupt(int irq, void *__hc, struct pt_regs * r)
  2566. +{
  2567. +        __u8 status;
  2568. +        struct sl811_hc *hc = __hc;
  2569. +
  2570. +        status = sl811_read(hc, SL811_INTRSTS);
  2571. +        if (status == 0)
  2572. +                return ;
  2573. +
  2574. +        sl811_write(hc,        SL811_INTRSTS, 0xff);
  2575. +
  2576. +        if (status & SL811_INTR_INSRMV) {
  2577. +                sl811_write(hc,        SL811_INTR, 0);
  2578. +                sl811_write(hc,        SL811_CTRL1, 0);
  2579. +                // wait        for device stable
  2580. +                mdelay(100);                       
  2581. +                sl811_hc_reset(hc);
  2582. +                return ;
  2583. +        }
  2584. +
  2585. +        spin_lock(&hc->hc_lock);
  2586. +       
  2587. +        if (status & SL811_INTR_DONE_A) {
  2588. +                if (status & SL811_INTR_SOF) {
  2589. +                        sl811_transfer_done(hc, 1);
  2590. +                        PDEBUG(4, "sof in done!");
  2591. +                        sl811_start_sof(hc);
  2592. +                } else
  2593. +                        sl811_transfer_done(hc, 0);
  2594. +        } else if (status & SL811_INTR_SOF)
  2595. +                sl811_start_sof(hc);       
  2596. +
  2597. +        spin_unlock(&hc->hc_lock);       
  2598. +
  2599. +        return ;
  2600. +}
  2601. +
  2602. +/*
  2603. + * This        function allocates all data structure and store        in the
  2604. + * private data        structure.
  2605. + *
  2606. + * Return value         : data structure for the host controller
  2607. + */
  2608. +static struct sl811_hc* __devinit sl811_alloc_hc(void)
  2609. +{
  2610. +        struct sl811_hc *hc;
  2611. +        struct usb_bus *bus;
  2612. +        int i;
  2613. +
  2614. +        PDEBUG(5, "enter");
  2615. +
  2616. +        hc = (struct sl811_hc *)kmalloc(sizeof(struct sl811_hc), GFP_KERNEL);
  2617. +        if (!hc)
  2618. +                return NULL;
  2619. +
  2620. +        memset(hc, 0, sizeof(struct sl811_hc));
  2621. +
  2622. +        hc->rh_status.wPortStatus = USB_PORT_STAT_POWER;
  2623. +        hc->rh_status.wPortChange = 0;
  2624. +
  2625. +        hc->active_urbs        = 0;
  2626. +        INIT_LIST_HEAD(&hc->hc_hcd_list);
  2627. +        list_add(&hc->hc_hcd_list, &sl811_hcd_list);
  2628. +       
  2629. +        init_waitqueue_head(&hc->waitq);
  2630. +       
  2631. +        for (i = 0; i < 6; ++i)
  2632. +                INIT_LIST_HEAD(&hc->urb_list[i]);
  2633. +       
  2634. +        hc->cur_list = &hc->iso_list;
  2635. +
  2636. +        bus = usb_alloc_bus(&sl811_device_operations);
  2637. +        if (!bus) {
  2638. +                kfree (hc);
  2639. +                return NULL;
  2640. +        }
  2641. +
  2642. +        hc->bus        = bus;
  2643. +        bus->hcpriv = hc;
  2644. +
  2645. +        return hc;
  2646. +}
  2647. +
  2648. +/*
  2649. + * This        function De-allocate all resources
  2650. + */
  2651. +static void sl811_release_hc(struct sl811_hc *hc)
  2652. +{
  2653. +        PDEBUG(5, "enter");
  2654. +
  2655. +        /* disconnect all devices */
  2656. +        if (hc->bus->root_hub)
  2657. +                usb_disconnect(&hc->bus->root_hub);
  2658. +
  2659. +        if (hc->addr_io)
  2660. +                release_region(hc->addr_io, 1);
  2661. +
  2662. +        if (hc->data_io)
  2663. +                release_region(hc->data_io, 1);
  2664. +
  2665. +        if (hc->irq)
  2666. +                free_irq(hc->irq, hc);
  2667. +
  2668. +        usb_deregister_bus(hc->bus);
  2669. +        usb_free_bus(hc->bus);
  2670. +
  2671. +        list_del(&hc->hc_hcd_list);
  2672. +        INIT_LIST_HEAD(&hc->hc_hcd_list);
  2673. +
  2674. +        kfree (hc);
  2675. +}
  2676. +
  2677. +/*
  2678. + * This        function is board specific.  It        sets up        the interrupt to
  2679. + * be an edge trigger and trigger on the rising        edge
  2680. + */
  2681. +static void sl811_init_irq(void)
  2682. +{
  2683. +        GPDR &=        ~(1<<23);
  2684. +        set_GPIO_IRQ_edge(1<<23, GPIO_RISING_EDGE);
  2685. +}
  2686. +
  2687. +/*
  2688. + * This        function request IO memory regions, request IRQ, and
  2689. + * allocate all        other resources.
  2690. + *
  2691. + * Input: addr_io = first IO address
  2692. + *          data_io = second IO address
  2693. + *          irq =        interrupt number
  2694. + *
  2695. + * Return: 0 = success or error        condition
  2696. + */
  2697. +static int __devinit sl811_found_hc(int addr_io, int data_io, int irq)
  2698. +{
  2699. +        struct sl811_hc *hc;
  2700. +
  2701. +        PDEBUG(5, "enter");
  2702. +
  2703. +        hc = sl811_alloc_hc();
  2704. +        if (!hc)
  2705. +                return -ENOMEM;
  2706. +
  2707. +        sl811_init_irq();
  2708. +
  2709. +        if (!request_region(addr_io, 1, "SL811 USB HOST")) {
  2710. +                PDEBUG(1, "request address %d failed", addr_io);
  2711. +                sl811_release_hc(hc);
  2712. +                return -EBUSY;
  2713. +        }
  2714. +        hc->addr_io =        addr_io;
  2715. +
  2716. +        if (!request_region(data_io, 1, "SL811 USB HOST")) {
  2717. +                PDEBUG(1, "request address %d failed", data_io);
  2718. +                sl811_release_hc (hc);
  2719. +                return -EBUSY;
  2720. +        }
  2721. +        hc->data_io =        data_io;
  2722. +
  2723. +        usb_register_bus(hc->bus);
  2724. +
  2725. +        if (request_irq(irq, sl811_interrupt, 0, "SL811", hc)) {
  2726. +                PDEBUG(1, "request interrupt %d failed", irq);
  2727. +                sl811_release_hc(hc);
  2728. +                return -EBUSY;
  2729. +        }
  2730. +        hc->irq        = irq;
  2731. +
  2732. +        printk(KERN_INFO __FILE__ ": USB SL811 at %x, addr2 = %x, IRQ %d\n",
  2733. +                addr_io, data_io, irq);
  2734. +
  2735. +        if (sl811_reg_test(hc)) {
  2736. +                PDEBUG(1, "SL811 register test failed!");
  2737. +                sl811_release_hc(hc);
  2738. +                return -ENODEV;
  2739. +        }
  2740. +       
  2741. +        sl811_hc_reset(hc);
  2742. +        sl811_connect_rh(hc);
  2743. +       
  2744. +        return 0;
  2745. +}
  2746. +
  2747. +/*
  2748. + * This        is an init function, and it is the first function being        called
  2749. + *
  2750. + * Return: 0 = success or error        condition
  2751. + */
  2752. +static int __init sl811_hcd_init(void)
  2753. +{
  2754. +        int ret;
  2755. +
  2756. +        PDEBUG(5, "etner");
  2757. +
  2758. +        info(DRIVER_VERSION " : " DRIVER_DESC);
  2759. +       
  2760. +        ret = sl811_found_hc(sl811_addr_io, sl811_data_io, sl811_irq);
  2761. +
  2762. +        return ret;
  2763. +}
  2764. +
  2765. +/*
  2766. + * This        is a cleanup function, and it is called        when module is unloaded.
  2767. + */
  2768. +static void __exit sl811_hcd_cleanup(void)
  2769. +{
  2770. +        struct list_head *list = sl811_hcd_list.next;
  2771. +        struct sl811_hc *hc;
  2772. +
  2773. +        PDEBUG(5, "enter");
  2774. +
  2775. +        for (; list != &sl811_hcd_list; ) {
  2776. +                hc = list_entry(list, struct sl811_hc, hc_hcd_list);
  2777. +                list = list->next;
  2778. +                sl811_release_hc(hc);
  2779. +        }
  2780. +}
  2781. +
  2782. +module_init(sl811_hcd_init);
  2783. +module_exit(sl811_hcd_cleanup);
  2784. +
  2785. +MODULE_AUTHOR(DRIVER_AUTHOR);
  2786. +MODULE_DESCRIPTION(DRIVER_DESC);
  2787. diff -Nru a/drivers/usb/host/sl811.h b/drivers/usb/host/sl811.h
  2788. --- /dev/null        Wed Dec 31 16:00:00 1969
  2789. +++ b/drivers/usb/host/sl811.h        Mon Jul 14 10:04:12 2003
  2790. @@ -0,0 +1,177 @@
  2791. +#ifndef __LINUX_SL811_H
  2792. +#define __LINUX_SL811_H
  2793. +
  2794. +//#define SL811_DEBUG
  2795. +
  2796. +#ifdef SL811_DEBUG
  2797. +        #define PDEBUG(level, fmt, args...) \
  2798. +                if (debug >= (level)) info("[%s:%d] " fmt, \
  2799. +                __PRETTY_FUNCTION__, __LINE__ , ## args)
  2800. +#else
  2801. +        #define PDEBUG(level, fmt, args...) do {} while(0)
  2802. +#endif
  2803. +
  2804. +//#define SL811_TIMEOUT
  2805. +               
  2806. +/* Sl811 host control register */
  2807. +#define        SL811_CTRL_A                0x00
  2808. +#define        SL811_ADDR_A                0x01
  2809. +#define        SL811_LEN_A                0x02
  2810. +#define        SL811_STS_A                0x03        /* read        */
  2811. +#define        SL811_PIDEP_A                0x03        /* write */
  2812. +#define        SL811_CNT_A                0x04        /* read        */
  2813. +#define        SL811_DEV_A                0x04        /* write */
  2814. +#define        SL811_CTRL1                0x05
  2815. +#define        SL811_INTR                0x06
  2816. +#define        SL811_CTRL_B                0x08
  2817. +#define        SL811_ADDR_B                0x09
  2818. +#define        SL811_LEN_B                0x0A
  2819. +#define        SL811_STS_B                0x0B        /* read        */
  2820. +#define        SL811_PIDEP_B                0x0B        /* write */
  2821. +#define        SL811_CNT_B                0x0C        /* read        */
  2822. +#define        SL811_DEV_B                0x0C        /* write */
  2823. +#define        SL811_INTRSTS                0x0D        /* write clears        bitwise        */
  2824. +#define        SL811_HWREV                0x0E        /* read        */
  2825. +#define        SL811_SOFLOW                0x0E        /* write */
  2826. +#define        SL811_SOFCNTDIV                0x0F        /* read        */
  2827. +#define        SL811_CTRL2                0x0F        /* write */
  2828. +
  2829. +/* USB control register bits (addr 0x00 and addr 0x08) */
  2830. +#define        SL811_USB_CTRL_ARM        0x01
  2831. +#define        SL811_USB_CTRL_ENABLE        0x02
  2832. +#define        SL811_USB_CTRL_DIR_OUT        0x04
  2833. +#define        SL811_USB_CTRL_ISO        0x10
  2834. +#define        SL811_USB_CTRL_SOF        0x20
  2835. +#define        SL811_USB_CTRL_TOGGLE_1        0x40
  2836. +#define        SL811_USB_CTRL_PREAMBLE        0x80
  2837. +
  2838. +/* USB status register bits (addr 0x03 and addr 0x0B) */
  2839. +#define        SL811_USB_STS_ACK        0x01
  2840. +#define        SL811_USB_STS_ERROR        0x02
  2841. +#define        SL811_USB_STS_TIMEOUT        0x04
  2842. +#define        SL811_USB_STS_TOGGLE_1        0x08
  2843. +#define        SL811_USB_STS_SETUP        0x10
  2844. +#define        SL811_USB_STS_OVERFLOW        0x20
  2845. +#define        SL811_USB_STS_NAK        0x40
  2846. +#define        SL811_USB_STS_STALL        0x80
  2847. +
  2848. +/* Control register 1 bits (addr 0x05) */
  2849. +#define        SL811_CTRL1_SOF                0x01
  2850. +#define        SL811_CTRL1_RESET        0x08
  2851. +#define        SL811_CTRL1_JKSTATE        0x10
  2852. +#define        SL811_CTRL1_SPEED_LOW        0x20
  2853. +#define        SL811_CTRL1_SUSPEND        0x40
  2854. +
  2855. +/* Interrut enable (addr 0x06) and interrupt status register bits (addr 0x0D) */
  2856. +#define        SL811_INTR_DONE_A        0x01
  2857. +#define        SL811_INTR_DONE_B        0x02
  2858. +#define        SL811_INTR_SOF                0x10
  2859. +#define        SL811_INTR_INSRMV        0x20
  2860. +#define        SL811_INTR_DETECT        0x40
  2861. +#define        SL811_INTR_NOTPRESENT        0x40
  2862. +#define        SL811_INTR_SPEED_FULL        0x80    /* only in status reg */
  2863. +
  2864. +/* HW rev and SOF lo register bits (addr 0x0E) */
  2865. +#define        SL811_HWR_HWREV                0xF0
  2866. +
  2867. +/* SOF counter and control reg 2 (addr 0x0F) */
  2868. +#define        SL811_CTL2_SOFHI        0x3F
  2869. +#define        SL811_CTL2_DSWAP        0x40
  2870. +#define        SL811_CTL2_HOST                0x80
  2871. +
  2872. +/* Set up for 1-ms SOF time. */
  2873. +#define SL811_12M_LOW                0xE0
  2874. +#define SL811_12M_HI                0x2E
  2875. +
  2876. +#define SL811_DATA_START        0x10
  2877. +#define SL811_DATA_LIMIT        240
  2878. +
  2879. +
  2880. +/* Requests: bRequest << 8 | bmRequestType */
  2881. +#define RH_GET_STATUS           0x0080
  2882. +#define RH_CLEAR_FEATURE        0x0100
  2883. +#define RH_SET_FEATURE          0x0300
  2884. +#define RH_SET_ADDRESS                0x0500
  2885. +#define RH_GET_DESCRIPTOR        0x0680
  2886. +#define RH_SET_DESCRIPTOR       0x0700
  2887. +#define RH_GET_CONFIGURATION        0x0880
  2888. +#define RH_SET_CONFIGURATION        0x0900
  2889. +#define RH_GET_STATE            0x0280
  2890. +#define RH_GET_INTERFACE        0x0A80
  2891. +#define RH_SET_INTERFACE        0x0B00
  2892. +#define RH_SYNC_FRAME           0x0C80
  2893. +
  2894. +
  2895. +#define PIDEP(pid, ep) (((pid) & 0x0f) << 4 | (ep))
  2896. +
  2897. +/* Virtual Root HUB */
  2898. +struct virt_root_hub {
  2899. +        int devnum;                         /* Address of Root Hub endpoint */
  2900. +        void *urb;                        /* interrupt URB of root hub */
  2901. +        int send;                        /* active flag */
  2902. +        int interval;                        /* intervall of roothub interrupt transfers */
  2903. +        struct timer_list rh_int_timer; /* intervall timer for rh interrupt EP */
  2904. +};
  2905. +
  2906. +struct sl811_td {
  2907. +        /* hardware */
  2908. +        __u8 ctrl;                        /* control register */
  2909. +       
  2910. +        /* write */                       
  2911. +        __u8 addr;                        /* base adrress register */
  2912. +        __u8 len;                        /* base length register */
  2913. +        __u8 pidep;                        /* PId and endpoint register */
  2914. +        __u8 dev;                        /* device address register */
  2915. +       
  2916. +        /* read */
  2917. +        __u8 status;                        /* status register */
  2918. +        __u8 left;                        /* transfer count register */
  2919. +       
  2920. +        /* software */
  2921. +        __u8 errcnt;                        /* error count, begin with 3 */
  2922. +        __u8 done;                        /* is this td tranfer done */
  2923. +        __u8 *buf;                        /* point to data buffer for tranfer */
  2924. +        int bustime;                        /* the bus time need by this td */
  2925. +        int td_status;                        /* the status of this td */
  2926. +        int nakcnt;                        /* number of naks */
  2927. +        struct urb *urb;                        /* the urb this td belongs to */
  2928. +        struct list_head td_list;        /* link to a list of the urb */
  2929. +};
  2930. +
  2931. +struct sl811_urb_priv {
  2932. +        struct urb *urb;                        /* the urb this priv beloings to */
  2933. +        struct list_head td_list;        /* list of all the td of this urb */
  2934. +        struct sl811_td *cur_td;                /* current td is in processing or it will be */
  2935. +        struct sl811_td *first_td;                /* the first td of this urb */
  2936. +        struct sl811_td *last_td;                /* the last td of this urb */
  2937. +        int interval;                        /* the query time value for intr urb */
  2938. +        int unlink;                        /* is the this urb unlinked */
  2939. +        unsigned long inserttime;        /* the time when insert to list */
  2940. +};
  2941. +
  2942. +struct sl811_hc {
  2943. +        spinlock_t hc_lock;                /* Lock for this structure */
  2944. +       
  2945. +        int irq;                        /* IRQ number this hc use */
  2946. +        int addr_io;                        /* I/O address line address */
  2947. +        int data_io;                        /* I/O data line address */
  2948. +        struct virt_root_hub rh;                /* root hub */
  2949. +        struct usb_port_status rh_status;/* root hub port status */
  2950. +        struct list_head urb_list[6];        /* set of urbs, the order is iso,intr,ctrl,bulk,inactive intr, wait */
  2951. +        struct list_head *cur_list;        /* the current list is in process */
  2952. +        wait_queue_head_t waitq;        /* deletion of URBs and devices needs a waitqueue */
  2953. +        struct sl811_td *cur_td;                /* point to the td is in process */
  2954. +        struct list_head hc_hcd_list;        /* list of all hci_hcd */
  2955. +        struct usb_bus *bus;            /* our bus */
  2956. +        int active_urbs;                /* total number of active usbs */
  2957. +        int frame_number;                /* the current frame number, we do't use it, any one need it? */
  2958. +};
  2959. +
  2960. +#define iso_list         urb_list[0]        /* set of isoc urbs */
  2961. +#define intr_list        urb_list[1]        /* ordered (tree) set of int urbs */
  2962. +#define ctrl_list        urb_list[2]        /* set of ctrl urbs */
  2963. +#define bulk_list        urb_list[3]        /* set of bulk urbs */
  2964. +#define idle_intr_list        urb_list[4]        /* set of intr urbs in its idle time*/
  2965. +#define wait_list        urb_list[5]        /* set of wait urbs */
  2966. +
  2967. +#endif

复制代码
发表于 2005-1-10 18:09:36 | 显示全部楼层
patch -
发表于 2005-1-10 18:54:07 | 显示全部楼层
这是什么补丁啊?
发表于 2005-1-14 13:51:56 | 显示全部楼层
今天看到了一篇文章,其实很简单,只要把这个补丁文件cp到内核源代码的目录下/usr/src/linux/,然后运行命令
#patch -u -d drivers/usb/host/ < 补丁文件名
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表