aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/irda/mcs7780.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/irda/mcs7780.c')
-rw-r--r--drivers/net/irda/mcs7780.c159
1 files changed, 65 insertions, 94 deletions
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 93916cf33f2..16f8ffb50e0 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -48,9 +48,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/kref.h>
#include <linux/usb.h>
#include <linux/device.h>
#include <linux/crc32.h>
@@ -192,8 +190,8 @@ static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs)
goto error;
ret = 0;
- error:
- return ret;
+error:
+ return ret;
}
/* Setup a communication between mcs7780 and agilent chip. */
@@ -403,8 +401,8 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len)
if(unlikely(new_len <= 0)) {
IRDA_ERROR("%s short frame length %d\n",
mcs->netdev->name, new_len);
- ++mcs->stats.rx_errors;
- ++mcs->stats.rx_length_errors;
+ ++mcs->netdev->stats.rx_errors;
+ ++mcs->netdev->stats.rx_length_errors;
return;
}
fcs = 0;
@@ -413,14 +411,14 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len)
if(fcs != GOOD_FCS) {
IRDA_ERROR("crc error calc 0x%x len %d\n",
fcs, new_len);
- mcs->stats.rx_errors++;
- mcs->stats.rx_crc_errors++;
+ mcs->netdev->stats.rx_errors++;
+ mcs->netdev->stats.rx_crc_errors++;
return;
}
skb = dev_alloc_skb(new_len + 1);
if(unlikely(!skb)) {
- ++mcs->stats.rx_dropped;
+ ++mcs->netdev->stats.rx_dropped;
return;
}
@@ -433,10 +431,8 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len)
netif_rx(skb);
- mcs->stats.rx_packets++;
- mcs->stats.rx_bytes += new_len;
-
- return;
+ mcs->netdev->stats.rx_packets++;
+ mcs->netdev->stats.rx_bytes += new_len;
}
/* Unwrap received packets at FIR speed. A 32 bit crc_ccitt checksum is
@@ -458,22 +454,22 @@ static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len)
if(unlikely(new_len <= 0)) {
IRDA_ERROR("%s short frame length %d\n",
mcs->netdev->name, new_len);
- ++mcs->stats.rx_errors;
- ++mcs->stats.rx_length_errors;
+ ++mcs->netdev->stats.rx_errors;
+ ++mcs->netdev->stats.rx_length_errors;
return;
}
fcs = ~(crc32_le(~0, buf, new_len));
- if(fcs != le32_to_cpu(get_unaligned((__le32 *)(buf+new_len)))) {
+ if(fcs != get_unaligned_le32(buf + new_len)) {
IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len);
- mcs->stats.rx_errors++;
- mcs->stats.rx_crc_errors++;
+ mcs->netdev->stats.rx_errors++;
+ mcs->netdev->stats.rx_crc_errors++;
return;
}
skb = dev_alloc_skb(new_len + 1);
if(unlikely(!skb)) {
- ++mcs->stats.rx_dropped;
+ ++mcs->netdev->stats.rx_dropped;
return;
}
@@ -486,10 +482,8 @@ static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len)
netif_rx(skb);
- mcs->stats.rx_packets++;
- mcs->stats.rx_bytes += new_len;
-
- return;
+ mcs->netdev->stats.rx_packets++;
+ mcs->netdev->stats.rx_bytes += new_len;
}
@@ -506,8 +500,11 @@ static inline int mcs_setup_urbs(struct mcs_cb *mcs)
return 0;
mcs->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!mcs->rx_urb)
+ if (!mcs->rx_urb) {
+ usb_free_urb(mcs->tx_urb);
+ mcs->tx_urb = NULL;
return 0;
+ }
return 1;
}
@@ -585,7 +582,7 @@ static int mcs_speed_change(struct mcs_cb *mcs)
mcs_get_reg(mcs, MCS_RESV_REG, &rval);
} while(cnt++ < 100 && (rval & MCS_IRINTX));
- if(cnt >= 100) {
+ if (cnt > 100) {
IRDA_ERROR("unable to change speed\n");
ret = -EIO;
goto error;
@@ -593,7 +590,7 @@ static int mcs_speed_change(struct mcs_cb *mcs)
mcs_get_reg(mcs, MCS_MODE_REG, &rval);
- /* MINRXPW values recomended by MosChip */
+ /* MINRXPW values recommended by MosChip */
if (mcs->new_speed <= 115200) {
rval &= ~MCS_FIR;
@@ -648,9 +645,9 @@ static int mcs_speed_change(struct mcs_cb *mcs)
ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
mcs->speed = mcs->new_speed;
- error:
- mcs->new_speed = 0;
- return ret;
+error:
+ mcs->new_speed = 0;
+ return ret;
}
/* Ioctl calls not supported at this time. Can be an area of future work. */
@@ -739,29 +736,24 @@ static int mcs_net_open(struct net_device *netdev)
}
if (!mcs_setup_urbs(mcs))
- goto error3;
+ goto error3;
ret = mcs_receive_start(mcs);
if (ret)
- goto error3;
+ goto error4;
netif_start_queue(netdev);
return 0;
- error3:
- irlap_close(mcs->irlap);
- error2:
- kfree_skb(mcs->rx_buff.skb);
- error1:
- return ret;
-}
-
-
-/* Get device stats for /proc/net/dev and ifconfig */
-static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev)
-{
- struct mcs_cb *mcs = netdev_priv(netdev);
- return &mcs->stats;
+error4:
+ usb_free_urb(mcs->rx_urb);
+ usb_free_urb(mcs->tx_urb);
+error3:
+ irlap_close(mcs->irlap);
+error2:
+ kfree_skb(mcs->rx_buff.skb);
+error1:
+ return ret;
}
/* Receive callback function. */
@@ -786,14 +778,14 @@ static void mcs_receive_irq(struct urb *urb)
*/
/* SIR speed */
if(mcs->speed < 576000) {
- async_unwrap_char(mcs->netdev, &mcs->stats,
+ async_unwrap_char(mcs->netdev, &mcs->netdev->stats,
&mcs->rx_buff, 0xc0);
for (i = 0; i < urb->actual_length; i++)
- async_unwrap_char(mcs->netdev, &mcs->stats,
+ async_unwrap_char(mcs->netdev, &mcs->netdev->stats,
&mcs->rx_buff, bytes[i]);
- async_unwrap_char(mcs->netdev, &mcs->stats,
+ async_unwrap_char(mcs->netdev, &mcs->netdev->stats,
&mcs->rx_buff, 0xc1);
}
/* MIR speed */
@@ -806,14 +798,13 @@ static void mcs_receive_irq(struct urb *urb)
mcs_unwrap_fir(mcs, urb->transfer_buffer,
urb->actual_length);
}
- mcs->netdev->last_rx = jiffies;
do_gettimeofday(&mcs->rx_time);
}
ret = usb_submit_urb(urb, GFP_ATOMIC);
}
-/* Transmit callback funtion. */
+/* Transmit callback function. */
static void mcs_send_irq(struct urb *urb)
{
struct mcs_cb *mcs = urb->context;
@@ -825,18 +816,15 @@ static void mcs_send_irq(struct urb *urb)
netif_wake_queue(ndev);
}
-/* Transmit callback funtion. */
-static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
+/* Transmit callback function. */
+static netdev_tx_t mcs_hard_xmit(struct sk_buff *skb,
+ struct net_device *ndev)
{
unsigned long flags;
struct mcs_cb *mcs;
int wraplen;
int ret = 0;
-
- if (skb == NULL || ndev == NULL)
- return -EINVAL;
-
netif_stop_queue(ndev);
mcs = netdev_priv(ndev);
@@ -869,19 +857,26 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
case -EPIPE:
break;
default:
- mcs->stats.tx_errors++;
+ mcs->netdev->stats.tx_errors++;
netif_start_queue(ndev);
}
} else {
- mcs->stats.tx_packets++;
- mcs->stats.tx_bytes += skb->len;
+ mcs->netdev->stats.tx_packets++;
+ mcs->netdev->stats.tx_bytes += skb->len;
}
dev_kfree_skb(skb);
spin_unlock_irqrestore(&mcs->lock, flags);
- return ret;
+ return NETDEV_TX_OK;
}
+static const struct net_device_ops mcs_netdev_ops = {
+ .ndo_open = mcs_net_open,
+ .ndo_stop = mcs_net_close,
+ .ndo_start_xmit = mcs_hard_xmit,
+ .ndo_do_ioctl = mcs_net_ioctl,
+};
+
/*
* This function is called by the USB subsystem for each new device in the
* system. Need to verify the device and if it is, then start handling it.
@@ -928,15 +923,12 @@ static int mcs_probe(struct usb_interface *intf,
/* Speed change work initialisation*/
INIT_WORK(&mcs->work, mcs_speed_work);
- /* Override the network functions we need to use */
- ndev->hard_start_xmit = mcs_hard_xmit;
- ndev->open = mcs_net_open;
- ndev->stop = mcs_net_close;
- ndev->get_stats = mcs_net_get_stats;
- ndev->do_ioctl = mcs_net_ioctl;
+ ndev->netdev_ops = &mcs_netdev_ops;
- if (!intf->cur_altsetting)
+ if (!intf->cur_altsetting) {
+ ret = -ENOMEM;
goto error2;
+ }
ret = mcs_find_endpoints(mcs, intf->cur_altsetting->endpoint,
intf->cur_altsetting->desc.bNumEndpoints);
@@ -959,11 +951,11 @@ static int mcs_probe(struct usb_interface *intf,
usb_set_intfdata(intf, mcs);
return 0;
- error2:
- free_netdev(ndev);
+error2:
+ free_netdev(ndev);
- error1:
- return ret;
+error1:
+ return ret;
}
/* The current device is removed, the USB layer tells us to shut down. */
@@ -974,7 +966,7 @@ static void mcs_disconnect(struct usb_interface *intf)
if (!mcs)
return;
- flush_scheduled_work();
+ cancel_work_sync(&mcs->work);
unregister_netdev(mcs->netdev);
free_netdev(mcs->netdev);
@@ -983,25 +975,4 @@ static void mcs_disconnect(struct usb_interface *intf)
IRDA_DEBUG(0, "MCS7780 now disconnected.\n");
}
-/* Module insertion */
-static int __init mcs_init(void)
-{
- int result;
-
- /* register this driver with the USB subsystem */
- result = usb_register(&mcs_driver);
- if (result)
- IRDA_ERROR("usb_register failed. Error number %d\n", result);
-
- return result;
-}
-module_init(mcs_init);
-
-/* Module removal */
-static void __exit mcs_exit(void)
-{
- /* deregister this driver with the USB subsystem */
- usb_deregister(&mcs_driver);
-}
-module_exit(mcs_exit);
-
+module_usb_driver(mcs_driver);