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