diff options
Diffstat (limited to 'drivers/usb/net/pegasus.c')
| -rw-r--r-- | drivers/usb/net/pegasus.c | 144 |
1 files changed, 89 insertions, 55 deletions
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 683e3df5d607..156a2f1cb39a 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
| @@ -45,7 +45,7 @@ | |||
| 45 | /* | 45 | /* |
| 46 | * Version Information | 46 | * Version Information |
| 47 | */ | 47 | */ |
| 48 | #define DRIVER_VERSION "v0.6.12 (2005/01/13)" | 48 | #define DRIVER_VERSION "v0.6.13 (2005/11/13)" |
| 49 | #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" | 49 | #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" |
| 50 | #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" | 50 | #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" |
| 51 | 51 | ||
| @@ -57,12 +57,14 @@ static const char driver_name[] = "pegasus"; | |||
| 57 | 57 | ||
| 58 | static int loopback = 0; | 58 | static int loopback = 0; |
| 59 | static int mii_mode = 0; | 59 | static int mii_mode = 0; |
| 60 | static char *devid=NULL; | ||
| 60 | 61 | ||
| 61 | static struct usb_eth_dev usb_dev_id[] = { | 62 | static struct usb_eth_dev usb_dev_id[] = { |
| 62 | #define PEGASUS_DEV(pn, vid, pid, flags) \ | 63 | #define PEGASUS_DEV(pn, vid, pid, flags) \ |
| 63 | {.name = pn, .vendor = vid, .device = pid, .private = flags}, | 64 | {.name = pn, .vendor = vid, .device = pid, .private = flags}, |
| 64 | #include "pegasus.h" | 65 | #include "pegasus.h" |
| 65 | #undef PEGASUS_DEV | 66 | #undef PEGASUS_DEV |
| 67 | {NULL, 0, 0, 0}, | ||
| 66 | {NULL, 0, 0, 0} | 68 | {NULL, 0, 0, 0} |
| 67 | }; | 69 | }; |
| 68 | 70 | ||
| @@ -71,6 +73,7 @@ static struct usb_device_id pegasus_ids[] = { | |||
| 71 | {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, | 73 | {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, |
| 72 | #include "pegasus.h" | 74 | #include "pegasus.h" |
| 73 | #undef PEGASUS_DEV | 75 | #undef PEGASUS_DEV |
| 76 | {}, | ||
| 74 | {} | 77 | {} |
| 75 | }; | 78 | }; |
| 76 | 79 | ||
| @@ -79,8 +82,10 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
| 79 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
| 80 | module_param(loopback, bool, 0); | 83 | module_param(loopback, bool, 0); |
| 81 | module_param(mii_mode, bool, 0); | 84 | module_param(mii_mode, bool, 0); |
| 85 | module_param(devid, charp, 0); | ||
| 82 | MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); | 86 | MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); |
| 83 | MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); | 87 | MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); |
| 88 | MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'"); | ||
| 84 | 89 | ||
| 85 | /* use ethtool to change the level for any given device */ | 90 | /* use ethtool to change the level for any given device */ |
| 86 | static int msg_level = -1; | 91 | static int msg_level = -1; |
| @@ -113,7 +118,7 @@ static void ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
| 113 | break; | 118 | break; |
| 114 | default: | 119 | default: |
| 115 | if (netif_msg_drv(pegasus)) | 120 | if (netif_msg_drv(pegasus)) |
| 116 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 121 | dev_dbg(&pegasus->intf->dev, "%s, status %d\n", |
| 117 | __FUNCTION__, urb->status); | 122 | __FUNCTION__, urb->status); |
| 118 | } | 123 | } |
| 119 | pegasus->flags &= ~ETH_REGS_CHANGED; | 124 | pegasus->flags &= ~ETH_REGS_CHANGED; |
| @@ -308,9 +313,9 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
| 308 | __le16 regdi; | 313 | __le16 regdi; |
| 309 | int ret; | 314 | int ret; |
| 310 | 315 | ||
| 311 | ret = set_register(pegasus, PhyCtrl, 0); | 316 | set_register(pegasus, PhyCtrl, 0); |
| 312 | ret = set_registers(pegasus, PhyAddr, sizeof (data), data); | 317 | set_registers(pegasus, PhyAddr, sizeof (data), data); |
| 313 | ret = set_register(pegasus, PhyCtrl, (indx | PHY_READ)); | 318 | set_register(pegasus, PhyCtrl, (indx | PHY_READ)); |
| 314 | for (i = 0; i < REG_TIMEOUT; i++) { | 319 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 315 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 320 | ret = get_registers(pegasus, PhyCtrl, 1, data); |
| 316 | if (data[0] & PHY_DONE) | 321 | if (data[0] & PHY_DONE) |
| @@ -319,12 +324,12 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
| 319 | if (i < REG_TIMEOUT) { | 324 | if (i < REG_TIMEOUT) { |
| 320 | ret = get_registers(pegasus, PhyData, 2, ®di); | 325 | ret = get_registers(pegasus, PhyData, 2, ®di); |
| 321 | *regd = le16_to_cpu(regdi); | 326 | *regd = le16_to_cpu(regdi); |
| 322 | return 1; | 327 | return ret; |
| 323 | } | 328 | } |
| 324 | if (netif_msg_drv(pegasus)) | 329 | if (netif_msg_drv(pegasus)) |
| 325 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 330 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
| 326 | 331 | ||
| 327 | return 0; | 332 | return ret; |
| 328 | } | 333 | } |
| 329 | 334 | ||
| 330 | static int mdio_read(struct net_device *dev, int phy_id, int loc) | 335 | static int mdio_read(struct net_device *dev, int phy_id, int loc) |
| @@ -344,20 +349,20 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) | |||
| 344 | 349 | ||
| 345 | data[1] = (u8) regd; | 350 | data[1] = (u8) regd; |
| 346 | data[2] = (u8) (regd >> 8); | 351 | data[2] = (u8) (regd >> 8); |
| 347 | ret = set_register(pegasus, PhyCtrl, 0); | 352 | set_register(pegasus, PhyCtrl, 0); |
| 348 | ret = set_registers(pegasus, PhyAddr, sizeof(data), data); | 353 | set_registers(pegasus, PhyAddr, sizeof(data), data); |
| 349 | ret = set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); | 354 | set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); |
| 350 | for (i = 0; i < REG_TIMEOUT; i++) { | 355 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 351 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 356 | ret = get_registers(pegasus, PhyCtrl, 1, data); |
| 352 | if (data[0] & PHY_DONE) | 357 | if (data[0] & PHY_DONE) |
| 353 | break; | 358 | break; |
| 354 | } | 359 | } |
| 355 | if (i < REG_TIMEOUT) | 360 | if (i < REG_TIMEOUT) |
| 356 | return 0; | 361 | return ret; |
| 357 | 362 | ||
| 358 | if (netif_msg_drv(pegasus)) | 363 | if (netif_msg_drv(pegasus)) |
| 359 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 364 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
| 360 | return 1; | 365 | return -ETIMEDOUT; |
| 361 | } | 366 | } |
| 362 | 367 | ||
| 363 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) | 368 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) |
| @@ -374,9 +379,9 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
| 374 | __le16 retdatai; | 379 | __le16 retdatai; |
| 375 | int ret; | 380 | int ret; |
| 376 | 381 | ||
| 377 | ret = set_register(pegasus, EpromCtrl, 0); | 382 | set_register(pegasus, EpromCtrl, 0); |
| 378 | ret = set_register(pegasus, EpromOffset, index); | 383 | set_register(pegasus, EpromOffset, index); |
| 379 | ret = set_register(pegasus, EpromCtrl, EPROM_READ); | 384 | set_register(pegasus, EpromCtrl, EPROM_READ); |
| 380 | 385 | ||
| 381 | for (i = 0; i < REG_TIMEOUT; i++) { | 386 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 382 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); | 387 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
| @@ -386,12 +391,12 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
| 386 | if (i < REG_TIMEOUT) { | 391 | if (i < REG_TIMEOUT) { |
| 387 | ret = get_registers(pegasus, EpromData, 2, &retdatai); | 392 | ret = get_registers(pegasus, EpromData, 2, &retdatai); |
| 388 | *retdata = le16_to_cpu(retdatai); | 393 | *retdata = le16_to_cpu(retdatai); |
| 389 | return 0; | 394 | return ret; |
| 390 | } | 395 | } |
| 391 | 396 | ||
| 392 | if (netif_msg_drv(pegasus)) | 397 | if (netif_msg_drv(pegasus)) |
| 393 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 398 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
| 394 | return -1; | 399 | return -ETIMEDOUT; |
| 395 | } | 400 | } |
| 396 | 401 | ||
| 397 | #ifdef PEGASUS_WRITE_EEPROM | 402 | #ifdef PEGASUS_WRITE_EEPROM |
| @@ -400,8 +405,8 @@ static inline void enable_eprom_write(pegasus_t * pegasus) | |||
| 400 | __u8 tmp; | 405 | __u8 tmp; |
| 401 | int ret; | 406 | int ret; |
| 402 | 407 | ||
| 403 | ret = get_registers(pegasus, EthCtrl2, 1, &tmp); | 408 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
| 404 | ret = set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); | 409 | set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); |
| 405 | } | 410 | } |
| 406 | 411 | ||
| 407 | static inline void disable_eprom_write(pegasus_t * pegasus) | 412 | static inline void disable_eprom_write(pegasus_t * pegasus) |
| @@ -409,9 +414,9 @@ static inline void disable_eprom_write(pegasus_t * pegasus) | |||
| 409 | __u8 tmp; | 414 | __u8 tmp; |
| 410 | int ret; | 415 | int ret; |
| 411 | 416 | ||
| 412 | ret = get_registers(pegasus, EthCtrl2, 1, &tmp); | 417 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
| 413 | ret = set_register(pegasus, EpromCtrl, 0); | 418 | set_register(pegasus, EpromCtrl, 0); |
| 414 | ret = set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); | 419 | set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); |
| 415 | } | 420 | } |
| 416 | 421 | ||
| 417 | static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | 422 | static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) |
| @@ -420,11 +425,11 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
| 420 | __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; | 425 | __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; |
| 421 | int ret; | 426 | int ret; |
| 422 | 427 | ||
| 423 | ret = set_registers(pegasus, EpromOffset, 4, d); | 428 | set_registers(pegasus, EpromOffset, 4, d); |
| 424 | enable_eprom_write(pegasus); | 429 | enable_eprom_write(pegasus); |
| 425 | ret = set_register(pegasus, EpromOffset, index); | 430 | set_register(pegasus, EpromOffset, index); |
| 426 | ret = set_registers(pegasus, EpromData, 2, &data); | 431 | set_registers(pegasus, EpromData, 2, &data); |
| 427 | ret = set_register(pegasus, EpromCtrl, EPROM_WRITE); | 432 | set_register(pegasus, EpromCtrl, EPROM_WRITE); |
| 428 | 433 | ||
| 429 | for (i = 0; i < REG_TIMEOUT; i++) { | 434 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 430 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); | 435 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
| @@ -433,10 +438,10 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
| 433 | } | 438 | } |
| 434 | disable_eprom_write(pegasus); | 439 | disable_eprom_write(pegasus); |
| 435 | if (i < REG_TIMEOUT) | 440 | if (i < REG_TIMEOUT) |
| 436 | return 0; | 441 | return ret; |
| 437 | if (netif_msg_drv(pegasus)) | 442 | if (netif_msg_drv(pegasus)) |
| 438 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 443 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
| 439 | return -1; | 444 | return -ETIMEDOUT; |
| 440 | } | 445 | } |
| 441 | #endif /* PEGASUS_WRITE_EEPROM */ | 446 | #endif /* PEGASUS_WRITE_EEPROM */ |
| 442 | 447 | ||
| @@ -454,10 +459,9 @@ static inline void get_node_id(pegasus_t * pegasus, __u8 * id) | |||
| 454 | static void set_ethernet_addr(pegasus_t * pegasus) | 459 | static void set_ethernet_addr(pegasus_t * pegasus) |
| 455 | { | 460 | { |
| 456 | __u8 node_id[6]; | 461 | __u8 node_id[6]; |
| 457 | int ret; | ||
| 458 | 462 | ||
| 459 | get_node_id(pegasus, node_id); | 463 | get_node_id(pegasus, node_id); |
| 460 | ret = set_registers(pegasus, EthID, sizeof (node_id), node_id); | 464 | set_registers(pegasus, EthID, sizeof (node_id), node_id); |
| 461 | memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); | 465 | memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); |
| 462 | } | 466 | } |
| 463 | 467 | ||
| @@ -465,30 +469,29 @@ static inline int reset_mac(pegasus_t * pegasus) | |||
| 465 | { | 469 | { |
| 466 | __u8 data = 0x8; | 470 | __u8 data = 0x8; |
| 467 | int i; | 471 | int i; |
| 468 | int ret; | ||
| 469 | 472 | ||
| 470 | ret = set_register(pegasus, EthCtrl1, data); | 473 | set_register(pegasus, EthCtrl1, data); |
| 471 | for (i = 0; i < REG_TIMEOUT; i++) { | 474 | for (i = 0; i < REG_TIMEOUT; i++) { |
| 472 | ret = get_registers(pegasus, EthCtrl1, 1, &data); | 475 | get_registers(pegasus, EthCtrl1, 1, &data); |
| 473 | if (~data & 0x08) { | 476 | if (~data & 0x08) { |
| 474 | if (loopback & 1) | 477 | if (loopback & 1) |
| 475 | break; | 478 | break; |
| 476 | if (mii_mode && (pegasus->features & HAS_HOME_PNA)) | 479 | if (mii_mode && (pegasus->features & HAS_HOME_PNA)) |
| 477 | ret = set_register(pegasus, Gpio1, 0x34); | 480 | set_register(pegasus, Gpio1, 0x34); |
| 478 | else | 481 | else |
| 479 | ret = set_register(pegasus, Gpio1, 0x26); | 482 | set_register(pegasus, Gpio1, 0x26); |
| 480 | ret = set_register(pegasus, Gpio0, pegasus->features); | 483 | set_register(pegasus, Gpio0, pegasus->features); |
| 481 | ret = set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); | 484 | set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); |
| 482 | break; | 485 | break; |
| 483 | } | 486 | } |
| 484 | } | 487 | } |
| 485 | if (i == REG_TIMEOUT) | 488 | if (i == REG_TIMEOUT) |
| 486 | return 1; | 489 | return -ETIMEDOUT; |
| 487 | 490 | ||
| 488 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || | 491 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || |
| 489 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { | 492 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { |
| 490 | ret = set_register(pegasus, Gpio0, 0x24); | 493 | set_register(pegasus, Gpio0, 0x24); |
| 491 | ret = set_register(pegasus, Gpio0, 0x26); | 494 | set_register(pegasus, Gpio0, 0x26); |
| 492 | } | 495 | } |
| 493 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { | 496 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { |
| 494 | __u16 auxmode; | 497 | __u16 auxmode; |
| @@ -527,7 +530,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) | |||
| 527 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); | 530 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); |
| 528 | } | 531 | } |
| 529 | 532 | ||
| 530 | return 0; | 533 | return ret; |
| 531 | } | 534 | } |
| 532 | 535 | ||
| 533 | static void fill_skb_pool(pegasus_t * pegasus) | 536 | static void fill_skb_pool(pegasus_t * pegasus) |
| @@ -881,9 +884,8 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev) | |||
| 881 | static inline void disable_net_traffic(pegasus_t * pegasus) | 884 | static inline void disable_net_traffic(pegasus_t * pegasus) |
| 882 | { | 885 | { |
| 883 | int tmp = 0; | 886 | int tmp = 0; |
| 884 | int ret; | ||
| 885 | 887 | ||
| 886 | ret = set_registers(pegasus, EthCtrl0, 2, &tmp); | 888 | set_registers(pegasus, EthCtrl0, 2, &tmp); |
| 887 | } | 889 | } |
| 888 | 890 | ||
| 889 | static inline void get_interrupt_interval(pegasus_t * pegasus) | 891 | static inline void get_interrupt_interval(pegasus_t * pegasus) |
| @@ -1206,18 +1208,17 @@ static __u8 mii_phy_probe(pegasus_t * pegasus) | |||
| 1206 | static inline void setup_pegasus_II(pegasus_t * pegasus) | 1208 | static inline void setup_pegasus_II(pegasus_t * pegasus) |
| 1207 | { | 1209 | { |
| 1208 | __u8 data = 0xa5; | 1210 | __u8 data = 0xa5; |
| 1209 | int ret; | ||
| 1210 | 1211 | ||
| 1211 | ret = set_register(pegasus, Reg1d, 0); | 1212 | set_register(pegasus, Reg1d, 0); |
| 1212 | ret = set_register(pegasus, Reg7b, 1); | 1213 | set_register(pegasus, Reg7b, 1); |
| 1213 | mdelay(100); | 1214 | mdelay(100); |
| 1214 | if ((pegasus->features & HAS_HOME_PNA) && mii_mode) | 1215 | if ((pegasus->features & HAS_HOME_PNA) && mii_mode) |
| 1215 | ret = set_register(pegasus, Reg7b, 0); | 1216 | set_register(pegasus, Reg7b, 0); |
| 1216 | else | 1217 | else |
| 1217 | ret = set_register(pegasus, Reg7b, 2); | 1218 | set_register(pegasus, Reg7b, 2); |
| 1218 | 1219 | ||
| 1219 | ret = set_register(pegasus, 0x83, data); | 1220 | set_register(pegasus, 0x83, data); |
| 1220 | ret = get_registers(pegasus, 0x83, 1, &data); | 1221 | get_registers(pegasus, 0x83, 1, &data); |
| 1221 | 1222 | ||
| 1222 | if (data == 0xa5) { | 1223 | if (data == 0xa5) { |
| 1223 | pegasus->chip = 0x8513; | 1224 | pegasus->chip = 0x8513; |
| @@ -1225,14 +1226,14 @@ static inline void setup_pegasus_II(pegasus_t * pegasus) | |||
| 1225 | pegasus->chip = 0; | 1226 | pegasus->chip = 0; |
| 1226 | } | 1227 | } |
| 1227 | 1228 | ||
| 1228 | ret = set_register(pegasus, 0x80, 0xc0); | 1229 | set_register(pegasus, 0x80, 0xc0); |
| 1229 | ret = set_register(pegasus, 0x83, 0xff); | 1230 | set_register(pegasus, 0x83, 0xff); |
| 1230 | ret = set_register(pegasus, 0x84, 0x01); | 1231 | set_register(pegasus, 0x84, 0x01); |
| 1231 | 1232 | ||
| 1232 | if (pegasus->features & HAS_HOME_PNA && mii_mode) | 1233 | if (pegasus->features & HAS_HOME_PNA && mii_mode) |
| 1233 | ret = set_register(pegasus, Reg81, 6); | 1234 | set_register(pegasus, Reg81, 6); |
| 1234 | else | 1235 | else |
| 1235 | ret = set_register(pegasus, Reg81, 2); | 1236 | set_register(pegasus, Reg81, 2); |
| 1236 | } | 1237 | } |
| 1237 | 1238 | ||
| 1238 | 1239 | ||
| @@ -1414,9 +1415,42 @@ static struct usb_driver pegasus_driver = { | |||
| 1414 | .resume = pegasus_resume, | 1415 | .resume = pegasus_resume, |
| 1415 | }; | 1416 | }; |
| 1416 | 1417 | ||
| 1418 | static void parse_id(char *id) | ||
| 1419 | { | ||
| 1420 | unsigned int vendor_id=0, device_id=0, flags=0, i=0; | ||
| 1421 | char *token, *name=NULL; | ||
| 1422 | |||
| 1423 | if ((token = strsep(&id, ":")) != NULL) | ||
| 1424 | name = token; | ||
| 1425 | /* name now points to a null terminated string*/ | ||
| 1426 | if ((token = strsep(&id, ":")) != NULL) | ||
| 1427 | vendor_id = simple_strtoul(token, NULL, 16); | ||
| 1428 | if ((token = strsep(&id, ":")) != NULL) | ||
| 1429 | device_id = simple_strtoul(token, NULL, 16); | ||
| 1430 | flags = simple_strtoul(id, NULL, 16); | ||
| 1431 | pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n", | ||
| 1432 | driver_name, name, vendor_id, device_id, flags); | ||
| 1433 | |||
| 1434 | if (vendor_id > 0x10000 || vendor_id == 0) | ||
| 1435 | return; | ||
| 1436 | if (device_id > 0x10000 || device_id == 0) | ||
| 1437 | return; | ||
| 1438 | |||
| 1439 | for (i=0; usb_dev_id[i].name; i++); | ||
| 1440 | usb_dev_id[i].name = name; | ||
| 1441 | usb_dev_id[i].vendor = vendor_id; | ||
| 1442 | usb_dev_id[i].device = device_id; | ||
| 1443 | usb_dev_id[i].private = flags; | ||
| 1444 | pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
| 1445 | pegasus_ids[i].idVendor = vendor_id; | ||
| 1446 | pegasus_ids[i].idProduct = device_id; | ||
| 1447 | } | ||
| 1448 | |||
| 1417 | static int __init pegasus_init(void) | 1449 | static int __init pegasus_init(void) |
| 1418 | { | 1450 | { |
| 1419 | pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); | 1451 | pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); |
| 1452 | if (devid) | ||
| 1453 | parse_id(devid); | ||
| 1420 | pegasus_workqueue = create_singlethread_workqueue("pegasus"); | 1454 | pegasus_workqueue = create_singlethread_workqueue("pegasus"); |
| 1421 | if (!pegasus_workqueue) | 1455 | if (!pegasus_workqueue) |
| 1422 | return -ENOMEM; | 1456 | return -ENOMEM; |
