0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/netdevice.h>
0012 #include <linux/etherdevice.h>
0013 #include <linux/ethtool.h>
0014 #include <linux/workqueue.h>
0015 #include <linux/mii.h>
0016 #include <linux/usb.h>
0017 #include <linux/usb/usbnet.h>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #define PL_S_EN (1<<7)
0049
0050 #define PL_TX_READY (1<<5)
0051 #define PL_RESET_OUT (1<<4)
0052 #define PL_RESET_IN (1<<3)
0053 #define PL_TX_C (1<<2)
0054 #define PL_TX_REQ (1<<1)
0055 #define PL_PEER_E (1<<0)
0056
0057 static inline int
0058 pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index)
0059 {
0060 return usbnet_read_cmd(dev, req,
0061 USB_DIR_IN | USB_TYPE_VENDOR |
0062 USB_RECIP_DEVICE,
0063 val, index, NULL, 0);
0064 }
0065
0066 static inline int
0067 pl_clear_QuickLink_features(struct usbnet *dev, int val)
0068 {
0069 return pl_vendor_req(dev, 1, (u8) val, 0);
0070 }
0071
0072 static inline int
0073 pl_set_QuickLink_features(struct usbnet *dev, int val)
0074 {
0075 return pl_vendor_req(dev, 3, (u8) val, 0);
0076 }
0077
0078 static int pl_reset(struct usbnet *dev)
0079 {
0080 int status;
0081
0082
0083
0084
0085 status = pl_set_QuickLink_features(dev,
0086 PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
0087 if (status != 0 && netif_msg_probe(dev))
0088 netif_dbg(dev, link, dev->net, "pl_reset --> %d\n", status);
0089 return 0;
0090 }
0091
0092 static const struct driver_info prolific_info = {
0093 .description = "Prolific PL-2301/PL-2302/PL-25A1/PL-27A1",
0094 .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT,
0095
0096 .reset = pl_reset,
0097 };
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 static const struct usb_device_id products [] = {
0108
0109
0110 {
0111 USB_DEVICE(0x067b, 0x0000),
0112 .driver_info = (unsigned long) &prolific_info,
0113 }, {
0114 USB_DEVICE(0x067b, 0x0001),
0115 .driver_info = (unsigned long) &prolific_info,
0116 },
0117
0118
0119 {
0120 USB_DEVICE(0x067b, 0x25a1),
0121 .driver_info = (unsigned long) &prolific_info,
0122 }, {
0123 USB_DEVICE(0x050d, 0x258a),
0124 .driver_info = (unsigned long) &prolific_info,
0125 }, {
0126 USB_DEVICE(0x3923, 0x7825),
0127
0128
0129 .driver_info = (unsigned long) &prolific_info,
0130
0131 },
0132
0133
0134 {
0135 USB_DEVICE(0x067b, 0x27a1),
0136
0137
0138
0139
0140 .driver_info = (unsigned long) &prolific_info,
0141 },
0142
0143 { },
0144 };
0145 MODULE_DEVICE_TABLE(usb, products);
0146
0147 static struct usb_driver plusb_driver = {
0148 .name = "plusb",
0149 .id_table = products,
0150 .probe = usbnet_probe,
0151 .disconnect = usbnet_disconnect,
0152 .suspend = usbnet_suspend,
0153 .resume = usbnet_resume,
0154 .disable_hub_initiated_lpm = 1,
0155 };
0156
0157 module_usb_driver(plusb_driver);
0158
0159 MODULE_AUTHOR("David Brownell");
0160 MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1/27A1 USB Host to Host Link Driver");
0161 MODULE_LICENSE("GPL");