diff options
Diffstat (limited to 'drivers/net/usb/pegasus.c')
-rw-r--r-- | drivers/net/usb/pegasus.c | 96 |
1 files changed, 42 insertions, 54 deletions
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index e92cb51a2c77..32e1335c94ad 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -124,62 +124,31 @@ static void async_ctrl_callback(struct urb *urb) static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) { - u8 *buf; - int ret; - - buf = kmalloc(size, GFP_NOIO); - if (!buf) - return -ENOMEM; - - ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0), - PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0, - indx, buf, size, 1000); - if (ret < 0) - netif_dbg(pegasus, drv, pegasus->net, - "%s returned %d\n", __func__, ret); - else if (ret <= size) - memcpy(data, buf, ret); - kfree(buf); - return ret; + return usb_control_msg_recv(pegasus->usb, 0, PEGASUS_REQ_GET_REGS, + PEGASUS_REQT_READ, 0, indx, data, size, + 1000, GFP_NOIO); } static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, const void *data) { - u8 *buf; - int ret; - - buf = kmemdup(data, size, GFP_NOIO); - if (!buf) - return -ENOMEM; - - ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), - PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0, - indx, buf, size, 100); - if (ret < 0) - netif_dbg(pegasus, drv, pegasus->net, - "%s returned %d\n", __func__, ret); - kfree(buf); - return ret; + return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REGS, + PEGASUS_REQT_WRITE, 0, indx, data, size, + 1000, GFP_NOIO); } +/* + * There is only one way to write to a single ADM8511 register and this is via + * specific control request. 'data' is ignored by the device, but it is here to + * not break the API. + */ static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) { - u8 *buf; - int ret; - - buf = kmemdup(&data, 1, GFP_NOIO); - if (!buf) - return -ENOMEM; + void *buf = &data; - ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), - PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data, - indx, buf, 1, 1000); - if (ret < 0) - netif_dbg(pegasus, drv, pegasus->net, - "%s returned %d\n", __func__, ret); - kfree(buf); - return ret; + return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REG, + PEGASUS_REQT_WRITE, data, indx, buf, 1, + 1000, GFP_NOIO); } static int update_eth_regs_async(pegasus_t *pegasus) @@ -360,28 +329,47 @@ fail: } #endif /* PEGASUS_WRITE_EEPROM */ -static inline void get_node_id(pegasus_t *pegasus, __u8 *id) +static inline int get_node_id(pegasus_t *pegasus, u8 *id) { - int i; - __u16 w16; + int i, ret; + u16 w16; for (i = 0; i < 3; i++) { - read_eprom_word(pegasus, i, &w16); + ret = read_eprom_word(pegasus, i, &w16); + if (ret < 0) + return ret; ((__le16 *) id)[i] = cpu_to_le16(w16); } + + return 0; } static void set_ethernet_addr(pegasus_t *pegasus) { - __u8 node_id[6]; + int ret; + u8 node_id[6]; if (pegasus->features & PEGASUS_II) { - get_registers(pegasus, 0x10, sizeof(node_id), node_id); + ret = get_registers(pegasus, 0x10, sizeof(node_id), node_id); + if (ret < 0) + goto err; } else { - get_node_id(pegasus, node_id); - set_registers(pegasus, EthID, sizeof(node_id), node_id); + ret = get_node_id(pegasus, node_id); + if (ret < 0) + goto err; + ret = set_registers(pegasus, EthID, sizeof(node_id), node_id); + if (ret < 0) + goto err; } + memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id)); + + return; +err: + eth_hw_addr_random(pegasus->net); + dev_info(&pegasus->intf->dev, "software assigned MAC address.\n"); + + return; } static inline int reset_mac(pegasus_t *pegasus) |