mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-17 16:15:18 +00:00
c6e50bafd0
Cleans up a few needless comparisons with booleans and cleans up an interupt handler to take advantage of earlier bailout shortcircuit. Signed-off-by: Jade Bilkey <herself@thefumon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
190 lines
5.6 KiB
C
190 lines
5.6 KiB
C
#include "headers.h"
|
|
|
|
|
|
static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
|
{
|
|
int status = urb->status;
|
|
struct bcm_interface_adapter *psIntfAdapter =
|
|
(struct bcm_interface_adapter *)urb->context;
|
|
struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter;
|
|
|
|
if (netif_msg_intr(Adapter))
|
|
pr_info(PFX "%s: interrupt status %d\n",
|
|
Adapter->dev->name, status);
|
|
|
|
if (Adapter->device_removed) {
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
|
|
DBG_LVL_ALL, "Device has Got Removed.");
|
|
return;
|
|
}
|
|
|
|
if ((Adapter->bPreparingForLowPowerMode && Adapter->bDoSuspend) ||
|
|
psIntfAdapter->bSuspended ||
|
|
psIntfAdapter->bPreparingForBusSuspend) {
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
|
|
DBG_LVL_ALL,
|
|
"Interrupt call back is called while suspending the device");
|
|
return;
|
|
}
|
|
|
|
switch (status) {
|
|
/* success */
|
|
case STATUS_SUCCESS:
|
|
if (urb->actual_length) {
|
|
|
|
if (psIntfAdapter->ulInterruptData[1] & 0xFF) {
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
|
|
INTF_INIT, DBG_LVL_ALL,
|
|
"Got USIM interrupt");
|
|
}
|
|
|
|
if (psIntfAdapter->ulInterruptData[1] & 0xFF00) {
|
|
atomic_set(&Adapter->CurrNumFreeTxDesc,
|
|
(psIntfAdapter->ulInterruptData[1] &
|
|
0xFF00) >> 8);
|
|
atomic_set(&Adapter->uiMBupdate, TRUE);
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
|
|
INTF_INIT, DBG_LVL_ALL,
|
|
"TX mailbox contains %d",
|
|
atomic_read(&Adapter->CurrNumFreeTxDesc));
|
|
}
|
|
if (psIntfAdapter->ulInterruptData[1] >> 16) {
|
|
Adapter->CurrNumRecvDescs =
|
|
(psIntfAdapter->ulInterruptData[1] >> 16);
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
|
|
INTF_INIT, DBG_LVL_ALL,
|
|
"RX mailbox contains %d",
|
|
Adapter->CurrNumRecvDescs);
|
|
InterfaceRx(psIntfAdapter);
|
|
}
|
|
if (Adapter->fw_download_done &&
|
|
!Adapter->downloadDDR &&
|
|
atomic_read(&Adapter->CurrNumFreeTxDesc)) {
|
|
|
|
psIntfAdapter->psAdapter->downloadDDR += 1;
|
|
wake_up(&Adapter->tx_packet_wait_queue);
|
|
}
|
|
if (!Adapter->waiting_to_fw_download_done) {
|
|
Adapter->waiting_to_fw_download_done = TRUE;
|
|
wake_up(&Adapter->ioctl_fw_dnld_wait_queue);
|
|
}
|
|
if (!atomic_read(&Adapter->TxPktAvail)) {
|
|
atomic_set(&Adapter->TxPktAvail, 1);
|
|
wake_up(&Adapter->tx_packet_wait_queue);
|
|
}
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
|
|
DBG_LVL_ALL, "Firing interrupt in URB");
|
|
}
|
|
break;
|
|
case -ENOENT:
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
|
|
DBG_LVL_ALL, "URB has got disconnected....");
|
|
return;
|
|
case -EINPROGRESS:
|
|
/*
|
|
* This situation may happened when URBunlink is used. for
|
|
* detail check usb_unlink_urb documentation.
|
|
*/
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
|
|
DBG_LVL_ALL,
|
|
"Impossibe condition has occurred... something very bad is going on");
|
|
break;
|
|
/* return; */
|
|
case -EPIPE:
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
|
|
DBG_LVL_ALL,
|
|
"Interrupt IN endPoint has got halted/stalled...need to clear this");
|
|
Adapter->bEndPointHalted = TRUE;
|
|
wake_up(&Adapter->tx_packet_wait_queue);
|
|
urb->status = STATUS_SUCCESS;
|
|
return;
|
|
/* software-driven interface shutdown */
|
|
case -ECONNRESET: /* URB got unlinked */
|
|
case -ESHUTDOWN: /* hardware gone. this is the serious problem */
|
|
/*
|
|
* Occurs only when something happens with the
|
|
* host controller device
|
|
*/
|
|
case -ENODEV: /* Device got removed */
|
|
case -EINVAL:
|
|
/*
|
|
* Some thing very bad happened with the URB. No
|
|
* description is available.
|
|
*/
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
|
|
DBG_LVL_ALL, "interrupt urb error %d", status);
|
|
urb->status = STATUS_SUCCESS;
|
|
break;
|
|
/* return; */
|
|
default:
|
|
/*
|
|
* This is required to check what is the defaults conditions
|
|
* when it occurs..
|
|
*/
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
|
|
"GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...",
|
|
status);
|
|
break;
|
|
}
|
|
|
|
StartInterruptUrb(psIntfAdapter);
|
|
|
|
|
|
}
|
|
|
|
int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
|
|
{
|
|
psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL);
|
|
if (!psIntfAdapter->psInterruptUrb) {
|
|
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS,
|
|
INTF_INIT, DBG_LVL_ALL,
|
|
"Cannot allocate interrupt urb");
|
|
return -ENOMEM;
|
|
}
|
|
psIntfAdapter->psInterruptUrb->transfer_buffer =
|
|
psIntfAdapter->ulInterruptData;
|
|
psIntfAdapter->psInterruptUrb->transfer_buffer_length =
|
|
sizeof(psIntfAdapter->ulInterruptData);
|
|
|
|
psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev,
|
|
psIntfAdapter->sIntrIn.int_in_endpointAddr);
|
|
|
|
usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev,
|
|
psIntfAdapter->sIntrIn.int_in_pipe,
|
|
psIntfAdapter->psInterruptUrb->transfer_buffer,
|
|
psIntfAdapter->psInterruptUrb->transfer_buffer_length,
|
|
read_int_callback, psIntfAdapter,
|
|
psIntfAdapter->sIntrIn.int_in_interval);
|
|
|
|
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, INTF_INIT,
|
|
DBG_LVL_ALL, "Interrupt Interval: %d\n",
|
|
psIntfAdapter->sIntrIn.int_in_interval);
|
|
return 0;
|
|
}
|
|
|
|
|
|
INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
|
|
{
|
|
INT status = 0;
|
|
|
|
if (!(psIntfAdapter->psAdapter->device_removed ||
|
|
psIntfAdapter->psAdapter->bEndPointHalted ||
|
|
psIntfAdapter->bSuspended ||
|
|
psIntfAdapter->bPreparingForBusSuspend ||
|
|
psIntfAdapter->psAdapter->StopAllXaction)) {
|
|
status =
|
|
usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC);
|
|
if (status) {
|
|
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
|
|
DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,
|
|
"Cannot send inturb %d\n", status);
|
|
if (status == -EPIPE) {
|
|
psIntfAdapter->psAdapter->bEndPointHalted =
|
|
TRUE;
|
|
wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
|
|
}
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|