pegasus.c (fb58cf4f2881eeb21b2a5997871a1678772b746d) | pegasus.c (f30e25a9d1b25ac8d40071c4dc2679ad0fcdc55a) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 1999-2013 Petko Manolov (petkan@nucleusys.com) 4 * 5 * ChangeLog: 6 * .... Most of the time spent on reading sources & docs. 7 * v0.2.x First official release for the Linux kernel. 8 * v0.3.0 Beutified and structured, some bugs fixed. --- 110 unchanged lines hidden (view full) --- 119 if (status < 0) 120 dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status); 121 kfree(req); 122 usb_free_urb(urb); 123} 124 125static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) 126{ | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 1999-2013 Petko Manolov (petkan@nucleusys.com) 4 * 5 * ChangeLog: 6 * .... Most of the time spent on reading sources & docs. 7 * v0.2.x First official release for the Linux kernel. 8 * v0.3.0 Beutified and structured, some bugs fixed. --- 110 unchanged lines hidden (view full) --- 119 if (status < 0) 120 dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status); 121 kfree(req); 122 usb_free_urb(urb); 123} 124 125static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) 126{ |
127 return usb_control_msg_recv(pegasus->usb, 0, PEGASUS_REQ_GET_REGS, 128 PEGASUS_REQT_READ, 0, indx, data, size, 129 1000, GFP_NOIO); | 127 u8 *buf; 128 int ret; 129 130 buf = kmalloc(size, GFP_NOIO); 131 if (!buf) 132 return -ENOMEM; 133 134 ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0), 135 PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0, 136 indx, buf, size, 1000); 137 if (ret < 0) 138 netif_dbg(pegasus, drv, pegasus->net, 139 "%s returned %d\n", __func__, ret); 140 else if (ret <= size) 141 memcpy(data, buf, ret); 142 kfree(buf); 143 return ret; |
130} 131 132static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, 133 const void *data) 134{ | 144} 145 146static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, 147 const void *data) 148{ |
135 return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REGS, 136 PEGASUS_REQT_WRITE, 0, indx, data, size, 137 1000, GFP_NOIO); | 149 u8 *buf; 150 int ret; 151 152 buf = kmemdup(data, size, GFP_NOIO); 153 if (!buf) 154 return -ENOMEM; 155 156 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), 157 PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0, 158 indx, buf, size, 100); 159 if (ret < 0) 160 netif_dbg(pegasus, drv, pegasus->net, 161 "%s returned %d\n", __func__, ret); 162 kfree(buf); 163 return ret; |
138} 139 | 164} 165 |
140/* 141 * There is only one way to write to a single ADM8511 register and this is via 142 * specific control request. 'data' is ignored by the device, but it is here to 143 * not break the API. 144 */ | |
145static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) 146{ | 166static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) 167{ |
147 void *buf = &data; | 168 u8 *buf; 169 int ret; |
148 | 170 |
149 return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REG, 150 PEGASUS_REQT_WRITE, data, indx, buf, 1, 151 1000, GFP_NOIO); | 171 buf = kmemdup(&data, 1, GFP_NOIO); 172 if (!buf) 173 return -ENOMEM; 174 175 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), 176 PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data, 177 indx, buf, 1, 1000); 178 if (ret < 0) 179 netif_dbg(pegasus, drv, pegasus->net, 180 "%s returned %d\n", __func__, ret); 181 kfree(buf); 182 return ret; |
152} 153 154static int update_eth_regs_async(pegasus_t *pegasus) 155{ 156 int ret = -ENOMEM; 157 struct urb *async_urb; 158 struct usb_ctrlrequest *req; 159 --- 164 unchanged lines hidden (view full) --- 324 return ret; 325 326fail: 327 netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); 328 return -ETIMEDOUT; 329} 330#endif /* PEGASUS_WRITE_EEPROM */ 331 | 183} 184 185static int update_eth_regs_async(pegasus_t *pegasus) 186{ 187 int ret = -ENOMEM; 188 struct urb *async_urb; 189 struct usb_ctrlrequest *req; 190 --- 164 unchanged lines hidden (view full) --- 355 return ret; 356 357fail: 358 netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); 359 return -ETIMEDOUT; 360} 361#endif /* PEGASUS_WRITE_EEPROM */ 362 |
332static inline void get_node_id(pegasus_t *pegasus, __u8 *id) | 363static inline int get_node_id(pegasus_t *pegasus, u8 *id) |
333{ | 364{ |
334 int i; 335 __u16 w16; | 365 int i, ret; 366 u16 w16; |
336 337 for (i = 0; i < 3; i++) { | 367 368 for (i = 0; i < 3; i++) { |
338 read_eprom_word(pegasus, i, &w16); | 369 ret = read_eprom_word(pegasus, i, &w16); 370 if (ret < 0) 371 return ret; |
339 ((__le16 *) id)[i] = cpu_to_le16(w16); 340 } | 372 ((__le16 *) id)[i] = cpu_to_le16(w16); 373 } |
374 375 return 0; |
|
341} 342 343static void set_ethernet_addr(pegasus_t *pegasus) 344{ | 376} 377 378static void set_ethernet_addr(pegasus_t *pegasus) 379{ |
345 __u8 node_id[6]; | 380 int ret; 381 u8 node_id[6]; |
346 347 if (pegasus->features & PEGASUS_II) { | 382 383 if (pegasus->features & PEGASUS_II) { |
348 get_registers(pegasus, 0x10, sizeof(node_id), node_id); | 384 ret = get_registers(pegasus, 0x10, sizeof(node_id), node_id); 385 if (ret < 0) 386 goto err; |
349 } else { | 387 } else { |
350 get_node_id(pegasus, node_id); 351 set_registers(pegasus, EthID, sizeof(node_id), node_id); | 388 ret = get_node_id(pegasus, node_id); 389 if (ret < 0) 390 goto err; 391 ret = set_registers(pegasus, EthID, sizeof(node_id), node_id); 392 if (ret < 0) 393 goto err; |
352 } | 394 } |
395 |
|
353 memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id)); | 396 memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id)); |
397 398 return; 399err: 400 eth_hw_addr_random(pegasus->net); 401 dev_info(&pegasus->intf->dev, "software assigned MAC address.\n"); 402 403 return; |
|
354} 355 356static inline int reset_mac(pegasus_t *pegasus) 357{ 358 __u8 data = 0x8; 359 int i; 360 361 set_register(pegasus, EthCtrl1, data); --- 932 unchanged lines hidden --- | 404} 405 406static inline int reset_mac(pegasus_t *pegasus) 407{ 408 __u8 data = 0x8; 409 int i; 410 411 set_register(pegasus, EthCtrl1, data); --- 932 unchanged lines hidden --- |