usbpipe.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. /*
  2. * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. *
  20. * File: usbpipe.c
  21. *
  22. * Purpose: Handle USB control endpoint
  23. *
  24. * Author: Warren Hsu
  25. *
  26. * Date: Mar. 29, 2005
  27. *
  28. * Functions:
  29. * CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM
  30. * CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM
  31. * ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM
  32. * ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM
  33. * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address
  34. *
  35. * Revision History:
  36. * 04-05-2004 Jerry Chen: Initial release
  37. * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
  38. *
  39. */
  40. #include "int.h"
  41. #include "rxtx.h"
  42. #include "dpc.h"
  43. #include "control.h"
  44. #include "desc.h"
  45. #include "device.h"
  46. /*--------------------- Static Definitions -------------------------*/
  47. //endpoint def
  48. //endpoint 0: control
  49. //endpoint 1: interrupt
  50. //endpoint 2: read bulk
  51. //endpoint 3: write bulk
  52. //RequestType:
  53. //#define REQUEST_OUT (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) // 0x40
  54. //#define REQUEST_IN (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE ) //0xc0
  55. //static int msglevel =MSG_LEVEL_DEBUG;
  56. static int msglevel =MSG_LEVEL_INFO;
  57. #define USB_CTL_WAIT 500 //ms
  58. #ifndef URB_ASYNC_UNLINK
  59. #define URB_ASYNC_UNLINK 0
  60. #endif
  61. /*--------------------- Static Classes ----------------------------*/
  62. /*--------------------- Static Variables --------------------------*/
  63. /*--------------------- Static Functions --------------------------*/
  64. static
  65. void
  66. s_nsInterruptUsbIoCompleteRead(
  67. struct urb *urb
  68. );
  69. static
  70. void
  71. s_nsBulkInUsbIoCompleteRead(
  72. struct urb *urb
  73. );
  74. static
  75. void
  76. s_nsBulkOutIoCompleteWrite(
  77. struct urb *urb
  78. );
  79. static
  80. void
  81. s_nsControlInUsbIoCompleteRead(
  82. struct urb *urb
  83. );
  84. static
  85. void
  86. s_nsControlInUsbIoCompleteWrite(
  87. struct urb *urb
  88. );
  89. /*--------------------- Export Variables --------------------------*/
  90. /*--------------------- Export Functions --------------------------*/
  91. int PIPEnsControlOutAsyn(
  92. PSDevice pDevice,
  93. BYTE byRequest,
  94. WORD wValue,
  95. WORD wIndex,
  96. WORD wLength,
  97. PBYTE pbyBuffer
  98. )
  99. {
  100. int ntStatus;
  101. if (pDevice->Flags & fMP_DISCONNECTED)
  102. return STATUS_FAILURE;
  103. if (pDevice->Flags & fMP_CONTROL_WRITES)
  104. return STATUS_FAILURE;
  105. if (in_interrupt()) {
  106. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"in_interrupt return ..byRequest %x\n", byRequest);
  107. return STATUS_FAILURE;
  108. }
  109. ntStatus = usb_control_msg(
  110. pDevice->usb,
  111. usb_sndctrlpipe(pDevice->usb , 0),
  112. byRequest,
  113. 0x40, // RequestType
  114. wValue,
  115. wIndex,
  116. (void *) pbyBuffer,
  117. wLength,
  118. HZ
  119. );
  120. if (ntStatus >= 0) {
  121. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe ntStatus= %d\n", ntStatus);
  122. ntStatus = 0;
  123. } else {
  124. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe fail, ntStatus= %d\n", ntStatus);
  125. }
  126. return ntStatus;
  127. }
  128. int PIPEnsControlOut(
  129. PSDevice pDevice,
  130. BYTE byRequest,
  131. WORD wValue,
  132. WORD wIndex,
  133. WORD wLength,
  134. PBYTE pbyBuffer
  135. )
  136. {
  137. int ntStatus = 0;
  138. int ii;
  139. if (pDevice->Flags & fMP_DISCONNECTED)
  140. return STATUS_FAILURE;
  141. if (pDevice->Flags & fMP_CONTROL_WRITES)
  142. return STATUS_FAILURE;
  143. pDevice->sUsbCtlRequest.bRequestType = 0x40;
  144. pDevice->sUsbCtlRequest.bRequest = byRequest;
  145. pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
  146. pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
  147. pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
  148. pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
  149. pDevice->pControlURB->actual_length = 0;
  150. // Notice, pbyBuffer limited point to variable buffer, can't be constant.
  151. usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
  152. usb_sndctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
  153. pbyBuffer, wLength, s_nsControlInUsbIoCompleteWrite, pDevice);
  154. ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC);
  155. if (ntStatus != 0) {
  156. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus);
  157. return STATUS_FAILURE;
  158. }
  159. else {
  160. MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
  161. }
  162. spin_unlock_irq(&pDevice->lock);
  163. for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
  164. if (pDevice->Flags & fMP_CONTROL_WRITES)
  165. mdelay(1);
  166. else
  167. break;
  168. if (ii >= USB_CTL_WAIT) {
  169. DBG_PRT(MSG_LEVEL_DEBUG,
  170. KERN_INFO "control send request submission timeout\n");
  171. spin_lock_irq(&pDevice->lock);
  172. MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
  173. return STATUS_FAILURE;
  174. }
  175. }
  176. spin_lock_irq(&pDevice->lock);
  177. return STATUS_SUCCESS;
  178. }
  179. int PIPEnsControlIn(
  180. PSDevice pDevice,
  181. BYTE byRequest,
  182. WORD wValue,
  183. WORD wIndex,
  184. WORD wLength,
  185. PBYTE pbyBuffer
  186. )
  187. {
  188. int ntStatus = 0;
  189. int ii;
  190. if (pDevice->Flags & fMP_DISCONNECTED)
  191. return STATUS_FAILURE;
  192. if (pDevice->Flags & fMP_CONTROL_READS)
  193. return STATUS_FAILURE;
  194. pDevice->sUsbCtlRequest.bRequestType = 0xC0;
  195. pDevice->sUsbCtlRequest.bRequest = byRequest;
  196. pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
  197. pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
  198. pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
  199. pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
  200. pDevice->pControlURB->actual_length = 0;
  201. usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
  202. usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
  203. pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice);
  204. ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC);
  205. if (ntStatus != 0) {
  206. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus);
  207. }else {
  208. MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
  209. }
  210. spin_unlock_irq(&pDevice->lock);
  211. for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
  212. if (pDevice->Flags & fMP_CONTROL_READS)
  213. mdelay(1);
  214. else
  215. break;
  216. if (ii >= USB_CTL_WAIT) {
  217. DBG_PRT(MSG_LEVEL_DEBUG,
  218. KERN_INFO "control rcv request submission timeout\n");
  219. spin_lock_irq(&pDevice->lock);
  220. MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
  221. return STATUS_FAILURE;
  222. }
  223. }
  224. spin_lock_irq(&pDevice->lock);
  225. return ntStatus;
  226. }
  227. static
  228. void
  229. s_nsControlInUsbIoCompleteWrite(
  230. struct urb *urb
  231. )
  232. {
  233. PSDevice pDevice;
  234. pDevice = urb->context;
  235. switch (urb->status) {
  236. case 0:
  237. break;
  238. case -EINPROGRESS:
  239. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status EINPROGRESS%d\n", urb->status);
  240. break;
  241. case -ENOENT:
  242. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status ENOENT %d\n", urb->status);
  243. break;
  244. default:
  245. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status %d\n", urb->status);
  246. }
  247. MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
  248. }
  249. /*
  250. * Description:
  251. * Complete function of usb Control callback
  252. *
  253. * Parameters:
  254. * In:
  255. * pDevice - Pointer to the adapter
  256. *
  257. * Out:
  258. * none
  259. *
  260. * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
  261. *
  262. */
  263. static
  264. void
  265. s_nsControlInUsbIoCompleteRead(
  266. struct urb *urb
  267. )
  268. {
  269. PSDevice pDevice;
  270. pDevice = urb->context;
  271. switch (urb->status) {
  272. case 0:
  273. break;
  274. case -EINPROGRESS:
  275. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status EINPROGRESS%d\n", urb->status);
  276. break;
  277. case -ENOENT:
  278. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status = ENOENT %d\n", urb->status);
  279. break;
  280. default:
  281. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status %d\n", urb->status);
  282. }
  283. MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
  284. }
  285. /*
  286. * Description:
  287. * Allocates an usb interrupt in irp and calls USBD.
  288. *
  289. * Parameters:
  290. * In:
  291. * pDevice - Pointer to the adapter
  292. * Out:
  293. * none
  294. *
  295. * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
  296. *
  297. */
  298. int PIPEnsInterruptRead(PSDevice pDevice)
  299. {
  300. int ntStatus = STATUS_FAILURE;
  301. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n");
  302. if(pDevice->intBuf.bInUse == TRUE){
  303. return (STATUS_FAILURE);
  304. }
  305. pDevice->intBuf.bInUse = TRUE;
  306. // pDevice->bEventAvailable = FALSE;
  307. pDevice->ulIntInPosted++;
  308. //
  309. // Now that we have created the urb, we will send a
  310. // request to the USB device object.
  311. //
  312. pDevice->pInterruptURB->interval = pDevice->int_interval;
  313. usb_fill_bulk_urb(pDevice->pInterruptURB,
  314. pDevice->usb,
  315. usb_rcvbulkpipe(pDevice->usb, 1),
  316. (void *) pDevice->intBuf.pDataBuf,
  317. MAX_INTERRUPT_SIZE,
  318. s_nsInterruptUsbIoCompleteRead,
  319. pDevice);
  320. ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC);
  321. if (ntStatus != 0) {
  322. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
  323. }
  324. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----s_nsStartInterruptUsbRead Return(%x)\n",ntStatus);
  325. return ntStatus;
  326. }
  327. /*
  328. * Description:
  329. * Complete function of usb interrupt in irp.
  330. *
  331. * Parameters:
  332. * In:
  333. * pDevice - Pointer to the adapter
  334. *
  335. * Out:
  336. * none
  337. *
  338. * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
  339. *
  340. */
  341. static
  342. void
  343. s_nsInterruptUsbIoCompleteRead(
  344. struct urb *urb
  345. )
  346. {
  347. PSDevice pDevice;
  348. int ntStatus;
  349. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptUsbIoCompleteRead\n");
  350. //
  351. // The context given to IoSetCompletionRoutine is the receive buffer object
  352. //
  353. pDevice = (PSDevice)urb->context;
  354. //
  355. // We have a number of cases:
  356. // 1) The USB read timed out and we received no data.
  357. // 2) The USB read timed out and we received some data.
  358. // 3) The USB read was successful and fully filled our irp buffer.
  359. // 4) The irp was cancelled.
  360. // 5) Some other failure from the USB device object.
  361. //
  362. ntStatus = urb->status;
  363. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsInterruptUsbIoCompleteRead Status %d\n", ntStatus);
  364. // if we were not successful, we need to free the int buffer for future use right here
  365. // otherwise interrupt data handler will free int buffer after it handle it.
  366. if (( ntStatus != STATUS_SUCCESS )) {
  367. pDevice->ulBulkInError++;
  368. pDevice->intBuf.bInUse = FALSE;
  369. // if (ntStatus == USBD_STATUS_CRC) {
  370. // pDevice->ulIntInContCRCError++;
  371. // }
  372. // if (ntStatus == STATUS_NOT_CONNECTED )
  373. // {
  374. pDevice->fKillEventPollingThread = TRUE;
  375. // }
  376. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"IntUSBIoCompleteControl STATUS = %d\n", ntStatus );
  377. } else {
  378. pDevice->ulIntInBytesRead += (unsigned long) urb->actual_length;
  379. pDevice->ulIntInContCRCError = 0;
  380. pDevice->bEventAvailable = TRUE;
  381. INTnsProcessData(pDevice);
  382. }
  383. STAvUpdateUSBCounter(&pDevice->scStatistic.USB_InterruptStat, ntStatus);
  384. if (pDevice->fKillEventPollingThread != TRUE) {
  385. usb_fill_bulk_urb(pDevice->pInterruptURB,
  386. pDevice->usb,
  387. usb_rcvbulkpipe(pDevice->usb, 1),
  388. (void *) pDevice->intBuf.pDataBuf,
  389. MAX_INTERRUPT_SIZE,
  390. s_nsInterruptUsbIoCompleteRead,
  391. pDevice);
  392. ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC);
  393. if (ntStatus != 0) {
  394. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
  395. }
  396. }
  397. //
  398. // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
  399. // routine (IofCompleteRequest) will stop working on the irp.
  400. //
  401. return ;
  402. }
  403. /*
  404. * Description:
  405. * Allocates an usb BulkIn irp and calls USBD.
  406. *
  407. * Parameters:
  408. * In:
  409. * pDevice - Pointer to the adapter
  410. * Out:
  411. * none
  412. *
  413. * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
  414. *
  415. */
  416. int PIPEnsBulkInUsbRead(PSDevice pDevice, PRCB pRCB)
  417. {
  418. int ntStatus = 0;
  419. struct urb *pUrb;
  420. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n");
  421. if (pDevice->Flags & fMP_DISCONNECTED)
  422. return STATUS_FAILURE;
  423. pDevice->ulBulkInPosted++;
  424. pUrb = pRCB->pUrb;
  425. //
  426. // Now that we have created the urb, we will send a
  427. // request to the USB device object.
  428. //
  429. if (pRCB->skb == NULL) {
  430. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pRCB->skb is null \n");
  431. return ntStatus;
  432. }
  433. usb_fill_bulk_urb(pUrb,
  434. pDevice->usb,
  435. usb_rcvbulkpipe(pDevice->usb, 2),
  436. (void *) (pRCB->skb->data),
  437. MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
  438. s_nsBulkInUsbIoCompleteRead,
  439. pRCB);
  440. ntStatus = usb_submit_urb(pUrb, GFP_ATOMIC);
  441. if (ntStatus != 0) {
  442. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Rx URB failed %d\n", ntStatus);
  443. return STATUS_FAILURE ;
  444. }
  445. pRCB->Ref = 1;
  446. pRCB->bBoolInUse= TRUE;
  447. return ntStatus;
  448. }
  449. /*
  450. * Description:
  451. * Complete function of usb BulkIn irp.
  452. *
  453. * Parameters:
  454. * In:
  455. * pDevice - Pointer to the adapter
  456. *
  457. * Out:
  458. * none
  459. *
  460. * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
  461. *
  462. */
  463. static
  464. void
  465. s_nsBulkInUsbIoCompleteRead(
  466. struct urb *urb
  467. )
  468. {
  469. PRCB pRCB = (PRCB)urb->context;
  470. PSDevice pDevice = (PSDevice)pRCB->pDevice;
  471. unsigned long bytesRead;
  472. BOOL bIndicateReceive = FALSE;
  473. BOOL bReAllocSkb = FALSE;
  474. int status;
  475. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkInUsbIoCompleteRead\n");
  476. status = urb->status;
  477. bytesRead = urb->actual_length;
  478. if (status) {
  479. pDevice->ulBulkInError++;
  480. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK In failed %d\n", status);
  481. pDevice->scStatistic.RxFcsErrCnt ++;
  482. //todo...xxxxxx
  483. // if (status == USBD_STATUS_CRC) {
  484. // pDevice->ulBulkInContCRCError++;
  485. // }
  486. // if (status == STATUS_DEVICE_NOT_CONNECTED )
  487. // {
  488. // MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
  489. // }
  490. } else {
  491. bIndicateReceive = TRUE;
  492. pDevice->ulBulkInContCRCError = 0;
  493. pDevice->ulBulkInBytesRead += bytesRead;
  494. pDevice->scStatistic.RxOkCnt ++;
  495. }
  496. STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkInStat, status);
  497. if (bIndicateReceive) {
  498. spin_lock(&pDevice->lock);
  499. if (RXbBulkInProcessData(pDevice, pRCB, bytesRead) == TRUE)
  500. bReAllocSkb = TRUE;
  501. spin_unlock(&pDevice->lock);
  502. }
  503. pRCB->Ref--;
  504. if (pRCB->Ref == 0)
  505. {
  506. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeNormal %d \n",pDevice->NumRecvFreeList);
  507. spin_lock(&pDevice->lock);
  508. RXvFreeRCB(pRCB, bReAllocSkb);
  509. spin_unlock(&pDevice->lock);
  510. }
  511. return;
  512. }
  513. /*
  514. * Description:
  515. * Allocates an usb BulkOut irp and calls USBD.
  516. *
  517. * Parameters:
  518. * In:
  519. * pDevice - Pointer to the adapter
  520. * Out:
  521. * none
  522. *
  523. * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
  524. *
  525. */
  526. int
  527. PIPEnsSendBulkOut(
  528. PSDevice pDevice,
  529. PUSB_SEND_CONTEXT pContext
  530. )
  531. {
  532. int status;
  533. struct urb *pUrb;
  534. pDevice->bPWBitOn = FALSE;
  535. /*
  536. if (pDevice->pPendingBulkOutContext != NULL) {
  537. pDevice->NumContextsQueued++;
  538. EnqueueContext(pDevice->FirstTxContextQueue, pDevice->LastTxContextQueue, pContext);
  539. status = STATUS_PENDING;
  540. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send pending!\n");
  541. return status;
  542. }
  543. */
  544. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsSendBulkOut\n");
  545. if (MP_IS_READY(pDevice) && (pDevice->Flags & fMP_POST_WRITES)) {
  546. pUrb = pContext->pUrb;
  547. pDevice->ulBulkOutPosted++;
  548. // pDevice->pPendingBulkOutContext = pContext;
  549. usb_fill_bulk_urb(
  550. pUrb,
  551. pDevice->usb,
  552. usb_sndbulkpipe(pDevice->usb, 3),
  553. (void *) &(pContext->Data[0]),
  554. pContext->uBufLen,
  555. s_nsBulkOutIoCompleteWrite,
  556. pContext);
  557. status = usb_submit_urb(pUrb, GFP_ATOMIC);
  558. if (status != 0)
  559. {
  560. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status);
  561. return STATUS_FAILURE;
  562. }
  563. return STATUS_PENDING;
  564. }
  565. else {
  566. pContext->bBoolInUse = FALSE;
  567. return STATUS_RESOURCES;
  568. }
  569. }
  570. /*
  571. * Description: s_nsBulkOutIoCompleteWrite
  572. * 1a) Indicate to the protocol the status of the write.
  573. * 1b) Return ownership of the packet to the protocol.
  574. *
  575. * 2) If any more packets are queue for sending, send another packet
  576. * to USBD.
  577. * If the attempt to send the packet to the driver fails,
  578. * return ownership of the packet to the protocol and
  579. * try another packet (until one succeeds).
  580. *
  581. * Parameters:
  582. * In:
  583. * pdoUsbDevObj - pointer to the USB device object which
  584. * completed the irp
  585. * pIrp - the irp which was completed by the
  586. * device object
  587. * pContext - the context given to IoSetCompletionRoutine
  588. * before calling IoCallDriver on the irp
  589. * The pContext is a pointer to the USB device object.
  590. * Out:
  591. * none
  592. *
  593. * Return Value: STATUS_MORE_PROCESSING_REQUIRED - allows the completion routine
  594. * (IofCompleteRequest) to stop working on the irp.
  595. *
  596. */
  597. static
  598. void
  599. s_nsBulkOutIoCompleteWrite(
  600. struct urb *urb
  601. )
  602. {
  603. PSDevice pDevice;
  604. int status;
  605. CONTEXT_TYPE ContextType;
  606. unsigned long ulBufLen;
  607. PUSB_SEND_CONTEXT pContext;
  608. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkOutIoCompleteWrite\n");
  609. //
  610. // The context given to IoSetCompletionRoutine is an USB_CONTEXT struct
  611. //
  612. pContext = (PUSB_SEND_CONTEXT) urb->context;
  613. ASSERT( NULL != pContext );
  614. pDevice = pContext->pDevice;
  615. ContextType = pContext->Type;
  616. ulBufLen = pContext->uBufLen;
  617. if (!netif_device_present(pDevice->dev))
  618. return;
  619. //
  620. // Perform various IRP, URB, and buffer 'sanity checks'
  621. //
  622. status = urb->status;
  623. //we should have failed, succeeded, or cancelled, but NOT be pending
  624. STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkOutStat, status);
  625. if(status == STATUS_SUCCESS) {
  626. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
  627. pDevice->ulBulkOutBytesWrite += ulBufLen;
  628. pDevice->ulBulkOutContCRCError = 0;
  629. pDevice->nTxDataTimeCout = 0;
  630. } else {
  631. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
  632. pDevice->ulBulkOutError++;
  633. }
  634. // pDevice->ulCheckForHangCount = 0;
  635. // pDevice->pPendingBulkOutContext = NULL;
  636. if ( CONTEXT_DATA_PACKET == ContextType ) {
  637. // Indicate to the protocol the status of the sent packet and return
  638. // ownership of the packet.
  639. if (pContext->pPacket != NULL) {
  640. dev_kfree_skb_irq(pContext->pPacket);
  641. pContext->pPacket = NULL;
  642. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"tx %d bytes\n",(int)ulBufLen);
  643. }
  644. pDevice->dev->trans_start = jiffies;
  645. if (status == STATUS_SUCCESS) {
  646. pDevice->packetsSent++;
  647. }
  648. else {
  649. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send USB error! [%08xh]\n", status);
  650. pDevice->packetsSentDropped++;
  651. }
  652. }
  653. if (pDevice->bLinkPass == TRUE) {
  654. if (netif_queue_stopped(pDevice->dev))
  655. netif_wake_queue(pDevice->dev);
  656. }
  657. pContext->bBoolInUse = FALSE;
  658. return;
  659. }