at v3.10 217 lines 6.8 kB view raw
1#include "headers.h" 2 3int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter, 4 unsigned int addr, 5 void *buff, 6 int len) 7{ 8 int bytes; 9 10 if (!psIntfAdapter) 11 return -EINVAL; 12 13 if (psIntfAdapter->psAdapter->device_removed == TRUE) { 14 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed"); 15 return -ENODEV; 16 } 17 18 if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) { 19 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus"); 20 return -EACCES; 21 } 22 23 if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) { 24 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed.."); 25 return -EACCES; 26 } 27 psIntfAdapter->psAdapter->DeviceAccess = TRUE; 28 29 bytes = usb_control_msg(psIntfAdapter->udev, 30 usb_rcvctrlpipe(psIntfAdapter->udev, 0), 31 0x02, 32 0xC2, 33 (addr & 0xFFFF), 34 ((addr >> 16) & 0xFFFF), 35 buff, 36 len, 37 5000); 38 39 if (-ENODEV == bytes) 40 psIntfAdapter->psAdapter->device_removed = TRUE; 41 42 if (bytes < 0) 43 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d", bytes); 44 else 45 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", bytes); 46 47 psIntfAdapter->psAdapter->DeviceAccess = FALSE; 48 return bytes; 49} 50 51int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter, 52 unsigned int addr, 53 void *buff, 54 int len) 55{ 56 int retval = 0; 57 58 if (!psIntfAdapter) 59 return -EINVAL; 60 61 if (psIntfAdapter->psAdapter->device_removed == TRUE) { 62 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed"); 63 return -ENODEV; 64 } 65 66 if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) { 67 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus..."); 68 return -EACCES; 69 } 70 71 if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) { 72 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed.."); 73 return -EACCES; 74 } 75 76 psIntfAdapter->psAdapter->DeviceAccess = TRUE; 77 78 retval = usb_control_msg(psIntfAdapter->udev, 79 usb_sndctrlpipe(psIntfAdapter->udev, 0), 80 0x01, 81 0x42, 82 (addr & 0xFFFF), 83 ((addr >> 16) & 0xFFFF), 84 buff, 85 len, 86 5000); 87 88 if (-ENODEV == retval) 89 psIntfAdapter->psAdapter->device_removed = TRUE; 90 91 if (retval < 0) { 92 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d", retval); 93 psIntfAdapter->psAdapter->DeviceAccess = FALSE; 94 return retval; 95 } else { 96 psIntfAdapter->psAdapter->DeviceAccess = FALSE; 97 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval); 98 return STATUS_SUCCESS; 99 } 100} 101 102int BcmRDM(void *arg, 103 unsigned int addr, 104 void *buff, 105 int len) 106{ 107 return InterfaceRDM((struct bcm_interface_adapter*)arg, addr, buff, len); 108} 109 110int BcmWRM(void *arg, 111 unsigned int addr, 112 void *buff, 113 int len) 114{ 115 return InterfaceWRM((struct bcm_interface_adapter *)arg, addr, buff, len); 116} 117 118int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) 119{ 120 struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter); 121 int status = STATUS_SUCCESS; 122 123 /* 124 * usb_clear_halt - tells device to clear endpoint halt/stall condition 125 * @dev: device whose endpoint is halted 126 * @pipe: endpoint "pipe" being cleared 127 * @ Context: !in_interrupt () 128 * 129 * usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code. 130 * This is used to clear halt conditions for bulk and interrupt endpoints only. 131 * Control and isochronous endpoints never halts. 132 * 133 * Any URBs queued for such an endpoint should normally be unlinked by the driver 134 * before clearing the halt condition. 135 * 136 */ 137 138 /* Killing all the submitted urbs to different end points. */ 139 Bcm_kill_all_URBs(psIntfAdapter); 140 141 /* clear the halted/stalled state for every end point */ 142 status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sIntrIn.int_in_pipe); 143 if (status != STATUS_SUCCESS) 144 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status); 145 146 status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_pipe); 147 if (status != STATUS_SUCCESS) 148 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status); 149 150 status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe); 151 if (status != STATUS_SUCCESS) 152 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status); 153 154 return status; 155} 156 157void Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter) 158{ 159 struct urb *tempUrb = NULL; 160 unsigned int i; 161 162 /* 163 * usb_kill_urb - cancel a transfer request and wait for it to finish 164 * @urb: pointer to URB describing a previously submitted request, 165 * returns nothing as it is void returned API. 166 * 167 * This routine cancels an in-progress request. It is guaranteed that 168 * upon return all completion handlers will have finished and the URB 169 * will be totally idle and available for reuse 170 * 171 * This routine may not be used in an interrupt context (such as a bottom 172 * half or a completion handler), or when holding a spinlock, or in other 173 * situations where the caller can't schedule(). 174 * 175 */ 176 177 /* Cancel submitted Interrupt-URB's */ 178 if (psIntfAdapter->psInterruptUrb) { 179 if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS) 180 usb_kill_urb(psIntfAdapter->psInterruptUrb); 181 } 182 183 /* Cancel All submitted TX URB's */ 184 for (i = 0; i < MAXIMUM_USB_TCB; i++) { 185 tempUrb = psIntfAdapter->asUsbTcb[i].urb; 186 if (tempUrb) { 187 if (tempUrb->status == -EINPROGRESS) 188 usb_kill_urb(tempUrb); 189 } 190 } 191 192 for (i = 0; i < MAXIMUM_USB_RCB; i++) { 193 tempUrb = psIntfAdapter->asUsbRcb[i].urb; 194 if (tempUrb) { 195 if (tempUrb->status == -EINPROGRESS) 196 usb_kill_urb(tempUrb); 197 } 198 } 199 200 atomic_set(&psIntfAdapter->uNumTcbUsed, 0); 201 atomic_set(&psIntfAdapter->uCurrTcb, 0); 202 203 atomic_set(&psIntfAdapter->uNumRcbUsed, 0); 204 atomic_set(&psIntfAdapter->uCurrRcb, 0); 205} 206 207void putUsbSuspend(struct work_struct *work) 208{ 209 struct bcm_interface_adapter *psIntfAdapter = NULL; 210 struct usb_interface *intf = NULL; 211 psIntfAdapter = container_of(work, struct bcm_interface_adapter, usbSuspendWork); 212 intf = psIntfAdapter->interface; 213 214 if (psIntfAdapter->bSuspended == FALSE) 215 usb_autopm_put_interface(intf); 216} 217