at v3.6 197 lines 6.4 kB view raw
1#include "headers.h" 2 3/*this is transmit call-back(BULK OUT)*/ 4static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) 5{ 6 PUSB_TCB pTcb= (PUSB_TCB)urb->context; 7 PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; 8 struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; 9 struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter ; 10 BOOLEAN bpowerDownMsg = FALSE ; 11 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); 12 13 if (unlikely(netif_msg_tx_done(Adapter))) 14 pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); 15 16 if(urb->status != STATUS_SUCCESS) 17 { 18 if(urb->status == -EPIPE) 19 { 20 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; 21 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); 22 } 23 else 24 { 25 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status); 26 } 27 } 28 29 pTcb->bUsed = FALSE; 30 atomic_dec(&psIntfAdapter->uNumTcbUsed); 31 32 33 34 if(TRUE == psAdapter->bPreparingForLowPowerMode) 35 { 36 37 if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && 38 (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) 39 40 { 41 bpowerDownMsg = TRUE ; 42 //This covers the bus err while Idle Request msg sent down. 43 if(urb->status != STATUS_SUCCESS) 44 { 45 psAdapter->bPreparingForLowPowerMode = FALSE ; 46 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem"); 47 //Signalling the cntrl pkt path in Ioctl 48 wake_up(&psAdapter->lowpower_mode_wait_queue); 49 StartInterruptUrb(psIntfAdapter); 50 goto err_exit; 51 } 52 53 if(psAdapter->bDoSuspend == FALSE) 54 { 55 psAdapter->IdleMode = TRUE; 56 //since going in Idle mode completed hence making this var false; 57 psAdapter->bPreparingForLowPowerMode = FALSE ; 58 59 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); 60 //Signalling the cntrl pkt path in Ioctl 61 wake_up(&psAdapter->lowpower_mode_wait_queue); 62 } 63 64 } 65 else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && 66 (pControlMsg->szData[0] == LINK_UP_ACK) && 67 (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && 68 (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) 69 { 70 //This covers the bus err while shutdown Request msg sent down. 71 if(urb->status != STATUS_SUCCESS) 72 { 73 psAdapter->bPreparingForLowPowerMode = FALSE ; 74 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem"); 75 //Signalling the cntrl pkt path in Ioctl 76 wake_up(&psAdapter->lowpower_mode_wait_queue); 77 StartInterruptUrb(psIntfAdapter); 78 goto err_exit; 79 } 80 81 bpowerDownMsg = TRUE ; 82 if(psAdapter->bDoSuspend == FALSE) 83 { 84 psAdapter->bShutStatus = TRUE; 85 //since going in shutdown mode completed hence making this var false; 86 psAdapter->bPreparingForLowPowerMode = FALSE ; 87 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State..."); 88 //Signalling the cntrl pkt path in Ioctl 89 wake_up(&psAdapter->lowpower_mode_wait_queue); 90 } 91 } 92 93 if(psAdapter->bDoSuspend && bpowerDownMsg) 94 { 95 //issuing bus suspend request 96 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack"); 97 psIntfAdapter->bPreparingForBusSuspend = TRUE; 98 schedule_work(&psIntfAdapter->usbSuspendWork); 99 100 } 101 102 } 103 104err_exit : 105 usb_free_coherent(urb->dev, urb->transfer_buffer_length, 106 urb->transfer_buffer, urb->transfer_dma); 107} 108 109 110static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter) 111{ 112 PUSB_TCB pTcb = NULL; 113 UINT index = 0; 114 115 if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) && 116 (psIntfAdapter->psAdapter->StopAllXaction ==FALSE)) 117 { 118 index = atomic_read(&psIntfAdapter->uCurrTcb); 119 pTcb = &psIntfAdapter->asUsbTcb[index]; 120 pTcb->bUsed = TRUE; 121 pTcb->psIntfAdapter= psIntfAdapter; 122 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got Tx desc %d used %d", 123 index, atomic_read(&psIntfAdapter->uNumTcbUsed)); 124 index = (index + 1) % MAXIMUM_USB_TCB; 125 atomic_set(&psIntfAdapter->uCurrTcb, index); 126 atomic_inc(&psIntfAdapter->uNumTcbUsed); 127 } 128 return pTcb; 129} 130 131static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len) 132{ 133 134 struct urb *urb = pTcb->urb; 135 int retval = 0; 136 137 urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, 138 GFP_ATOMIC, &urb->transfer_dma); 139 if (!urb->transfer_buffer) 140 { 141 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n"); 142 return -ENOMEM; 143 } 144 memcpy(urb->transfer_buffer, data, len); 145 urb->transfer_buffer_length = len; 146 147 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n"); 148 //For T3B,INT OUT end point will be used as bulk out end point 149 if((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE)) 150 { 151 usb_fill_int_urb(urb, psIntfAdapter->udev, 152 psIntfAdapter->sBulkOut.bulk_out_pipe, 153 urb->transfer_buffer, len, write_bulk_callback, pTcb, 154 psIntfAdapter->sBulkOut.int_out_interval); 155 } 156 else 157 { 158 usb_fill_bulk_urb(urb, psIntfAdapter->udev, 159 psIntfAdapter->sBulkOut.bulk_out_pipe, 160 urb->transfer_buffer, len, write_bulk_callback, pTcb); 161 } 162 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */ 163 164 if(FALSE == psIntfAdapter->psAdapter->device_removed && 165 FALSE == psIntfAdapter->psAdapter->bEndPointHalted && 166 FALSE == psIntfAdapter->bSuspended && 167 FALSE == psIntfAdapter->bPreparingForBusSuspend) 168 { 169 retval = usb_submit_urb(urb, GFP_ATOMIC); 170 if (retval) 171 { 172 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval); 173 if(retval == -EPIPE) 174 { 175 psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; 176 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); 177 } 178 } 179 } 180 return retval; 181} 182 183int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) 184{ 185 PUSB_TCB pTcb= NULL; 186 187 PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; 188 pTcb= GetBulkOutTcb(psIntfAdapter); 189 if(pTcb == NULL) 190 { 191 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet"); 192 return -EFAULT; 193 } 194 return TransmitTcb(psIntfAdapter, pTcb, data, len); 195} 196 197