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