Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
InterfaceTx.c
Go to the documentation of this file.
1 #include "headers.h"
2 
3 /*this is transmit call-back(BULK OUT)*/
4 static 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 ;
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 
104 err_exit :
105  usb_free_coherent(urb->dev, urb->transfer_buffer_length,
106  urb->transfer_buffer, urb->transfer_dma);
107 }
108 
109 
110 static 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 
131 static 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 
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