diff options
Diffstat (limited to 'drivers')
410 files changed, 13926 insertions, 7193 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 35094f230b1e..7af7db1ba8c4 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -977,7 +977,7 @@ static int dock_add(acpi_handle handle) | |||
977 | sizeof(struct dock_station *)); | 977 | sizeof(struct dock_station *)); |
978 | 978 | ||
979 | /* we want the dock device to send uevents */ | 979 | /* we want the dock device to send uevents */ |
980 | dock_device->dev.uevent_suppress = 0; | 980 | dev_set_uevent_suppress(&dock_device->dev, 0); |
981 | 981 | ||
982 | if (is_dock(handle)) | 982 | if (is_dock(handle)) |
983 | dock_station->flags |= DOCK_IS_DOCK; | 983 | dock_station->flags |= DOCK_IS_DOCK; |
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 00c46e0b40e4..3d763fdf99b7 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -210,7 +210,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) | |||
210 | dev->dev.release = amba_device_release; | 210 | dev->dev.release = amba_device_release; |
211 | dev->dev.bus = &amba_bustype; | 211 | dev->dev.bus = &amba_bustype; |
212 | dev->dev.dma_mask = &dev->dma_mask; | 212 | dev->dev.dma_mask = &dev->dma_mask; |
213 | dev->res.name = dev->dev.bus_id; | 213 | dev->res.name = dev_name(&dev->dev); |
214 | 214 | ||
215 | if (!dev->dev.coherent_dma_mask && dev->dma_mask) | 215 | if (!dev->dev.coherent_dma_mask && dev->dma_mask) |
216 | dev_warn(&dev->dev, "coherent dma mask is unset\n"); | 216 | dev_warn(&dev->dev, "coherent dma mask is unset\n"); |
@@ -294,7 +294,7 @@ static int amba_find_match(struct device *dev, void *data) | |||
294 | if (d->parent) | 294 | if (d->parent) |
295 | r &= d->parent == dev->parent; | 295 | r &= d->parent == dev->parent; |
296 | if (d->busid) | 296 | if (d->busid) |
297 | r &= strcmp(dev->bus_id, d->busid) == 0; | 297 | r &= strcmp(dev_name(dev), d->busid) == 0; |
298 | 298 | ||
299 | if (r) { | 299 | if (r) { |
300 | get_device(dev); | 300 | get_device(dev); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 66e012cd3271..788bba2b1e17 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -404,7 +404,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
404 | /* board_ahci */ | 404 | /* board_ahci */ |
405 | { | 405 | { |
406 | .flags = AHCI_FLAG_COMMON, | 406 | .flags = AHCI_FLAG_COMMON, |
407 | .pio_mask = 0x1f, /* pio0-4 */ | 407 | .pio_mask = ATA_PIO4, |
408 | .udma_mask = ATA_UDMA6, | 408 | .udma_mask = ATA_UDMA6, |
409 | .port_ops = &ahci_ops, | 409 | .port_ops = &ahci_ops, |
410 | }, | 410 | }, |
@@ -412,7 +412,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
412 | { | 412 | { |
413 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), | 413 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), |
414 | .flags = AHCI_FLAG_COMMON, | 414 | .flags = AHCI_FLAG_COMMON, |
415 | .pio_mask = 0x1f, /* pio0-4 */ | 415 | .pio_mask = ATA_PIO4, |
416 | .udma_mask = ATA_UDMA6, | 416 | .udma_mask = ATA_UDMA6, |
417 | .port_ops = &ahci_vt8251_ops, | 417 | .port_ops = &ahci_vt8251_ops, |
418 | }, | 418 | }, |
@@ -420,7 +420,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
420 | { | 420 | { |
421 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), | 421 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), |
422 | .flags = AHCI_FLAG_COMMON, | 422 | .flags = AHCI_FLAG_COMMON, |
423 | .pio_mask = 0x1f, /* pio0-4 */ | 423 | .pio_mask = ATA_PIO4, |
424 | .udma_mask = ATA_UDMA6, | 424 | .udma_mask = ATA_UDMA6, |
425 | .port_ops = &ahci_ops, | 425 | .port_ops = &ahci_ops, |
426 | }, | 426 | }, |
@@ -430,7 +430,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
430 | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | | 430 | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | |
431 | AHCI_HFLAG_SECT255), | 431 | AHCI_HFLAG_SECT255), |
432 | .flags = AHCI_FLAG_COMMON, | 432 | .flags = AHCI_FLAG_COMMON, |
433 | .pio_mask = 0x1f, /* pio0-4 */ | 433 | .pio_mask = ATA_PIO4, |
434 | .udma_mask = ATA_UDMA6, | 434 | .udma_mask = ATA_UDMA6, |
435 | .port_ops = &ahci_sb600_ops, | 435 | .port_ops = &ahci_sb600_ops, |
436 | }, | 436 | }, |
@@ -440,7 +440,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
440 | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), | 440 | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), |
441 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 441 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
442 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, | 442 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, |
443 | .pio_mask = 0x1f, /* pio0-4 */ | 443 | .pio_mask = ATA_PIO4, |
444 | .udma_mask = ATA_UDMA6, | 444 | .udma_mask = ATA_UDMA6, |
445 | .port_ops = &ahci_ops, | 445 | .port_ops = &ahci_ops, |
446 | }, | 446 | }, |
@@ -448,7 +448,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
448 | { | 448 | { |
449 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), | 449 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), |
450 | .flags = AHCI_FLAG_COMMON, | 450 | .flags = AHCI_FLAG_COMMON, |
451 | .pio_mask = 0x1f, /* pio0-4 */ | 451 | .pio_mask = ATA_PIO4, |
452 | .udma_mask = ATA_UDMA6, | 452 | .udma_mask = ATA_UDMA6, |
453 | .port_ops = &ahci_sb600_ops, | 453 | .port_ops = &ahci_sb600_ops, |
454 | }, | 454 | }, |
@@ -456,7 +456,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
456 | { | 456 | { |
457 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), | 457 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), |
458 | .flags = AHCI_FLAG_COMMON, | 458 | .flags = AHCI_FLAG_COMMON, |
459 | .pio_mask = 0x1f, /* pio0-4 */ | 459 | .pio_mask = ATA_PIO4, |
460 | .udma_mask = ATA_UDMA6, | 460 | .udma_mask = ATA_UDMA6, |
461 | .port_ops = &ahci_ops, | 461 | .port_ops = &ahci_ops, |
462 | }, | 462 | }, |
@@ -464,7 +464,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
464 | { | 464 | { |
465 | AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), | 465 | AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), |
466 | .flags = AHCI_FLAG_COMMON, | 466 | .flags = AHCI_FLAG_COMMON, |
467 | .pio_mask = 0x1f, /* pio0-4 */ | 467 | .pio_mask = ATA_PIO4, |
468 | .udma_mask = ATA_UDMA6, | 468 | .udma_mask = ATA_UDMA6, |
469 | .port_ops = &ahci_ops, | 469 | .port_ops = &ahci_ops, |
470 | }, | 470 | }, |
@@ -1348,7 +1348,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | |||
1348 | writel(message[1], mmio + hpriv->em_loc+4); | 1348 | writel(message[1], mmio + hpriv->em_loc+4); |
1349 | 1349 | ||
1350 | /* save off new led state for port/slot */ | 1350 | /* save off new led state for port/slot */ |
1351 | emp->led_state = message[1]; | 1351 | emp->led_state = state; |
1352 | 1352 | ||
1353 | /* | 1353 | /* |
1354 | * tell hardware to transmit the message | 1354 | * tell hardware to transmit the message |
@@ -2565,6 +2565,15 @@ static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | |||
2565 | /* PCI slot number of the controller */ | 2565 | /* PCI slot number of the controller */ |
2566 | .driver_data = (void *)0x1FUL, | 2566 | .driver_data = (void *)0x1FUL, |
2567 | }, | 2567 | }, |
2568 | { | ||
2569 | .ident = "HP Compaq 6720s", | ||
2570 | .matches = { | ||
2571 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2572 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6720s"), | ||
2573 | }, | ||
2574 | /* PCI slot number of the controller */ | ||
2575 | .driver_data = (void *)0x1FUL, | ||
2576 | }, | ||
2568 | 2577 | ||
2569 | { } /* terminate list */ | 2578 | { } /* terminate list */ |
2570 | }; | 2579 | }; |
@@ -2647,8 +2656,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2647 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) | 2656 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) |
2648 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; | 2657 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; |
2649 | 2658 | ||
2650 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) | 2659 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) |
2651 | pci_intx(pdev, 1); | 2660 | pci_enable_msi(pdev); |
2652 | 2661 | ||
2653 | /* save initial config */ | 2662 | /* save initial config */ |
2654 | ahci_save_initial_config(pdev, hpriv); | 2663 | ahci_save_initial_config(pdev, hpriv); |
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index dc48a6398abe..ecfd22b4f1ce 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c | |||
@@ -118,8 +118,8 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id | |||
118 | u16 command; | 118 | u16 command; |
119 | static const struct ata_port_info info = { | 119 | static const struct ata_port_info info = { |
120 | .flags = ATA_FLAG_SLAVE_POSS, | 120 | .flags = ATA_FLAG_SLAVE_POSS, |
121 | .pio_mask = 0x1f, | 121 | .pio_mask = ATA_PIO4, |
122 | .mwdma_mask = 0x07, | 122 | .mwdma_mask = ATA_MWDMA2, |
123 | .udma_mask = ATA_UDMA5, | 123 | .udma_mask = ATA_UDMA5, |
124 | .port_ops = &generic_port_ops | 124 | .port_ops = &generic_port_ops |
125 | }; | 125 | }; |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index ef8b30d577bd..e5cbe80ce172 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -446,34 +446,34 @@ static struct ata_port_info piix_port_info[] = { | |||
446 | [piix_pata_mwdma] = /* PIIX3 MWDMA only */ | 446 | [piix_pata_mwdma] = /* PIIX3 MWDMA only */ |
447 | { | 447 | { |
448 | .flags = PIIX_PATA_FLAGS, | 448 | .flags = PIIX_PATA_FLAGS, |
449 | .pio_mask = 0x1f, /* pio0-4 */ | 449 | .pio_mask = ATA_PIO4, |
450 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ | 450 | .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ |
451 | .port_ops = &piix_pata_ops, | 451 | .port_ops = &piix_pata_ops, |
452 | }, | 452 | }, |
453 | 453 | ||
454 | [piix_pata_33] = /* PIIX4 at 33MHz */ | 454 | [piix_pata_33] = /* PIIX4 at 33MHz */ |
455 | { | 455 | { |
456 | .flags = PIIX_PATA_FLAGS, | 456 | .flags = PIIX_PATA_FLAGS, |
457 | .pio_mask = 0x1f, /* pio0-4 */ | 457 | .pio_mask = ATA_PIO4, |
458 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ | 458 | .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ |
459 | .udma_mask = ATA_UDMA_MASK_40C, | 459 | .udma_mask = ATA_UDMA2, |
460 | .port_ops = &piix_pata_ops, | 460 | .port_ops = &piix_pata_ops, |
461 | }, | 461 | }, |
462 | 462 | ||
463 | [ich_pata_33] = /* ICH0 - ICH at 33Mhz*/ | 463 | [ich_pata_33] = /* ICH0 - ICH at 33Mhz*/ |
464 | { | 464 | { |
465 | .flags = PIIX_PATA_FLAGS, | 465 | .flags = PIIX_PATA_FLAGS, |
466 | .pio_mask = 0x1f, /* pio 0-4 */ | 466 | .pio_mask = ATA_PIO4, |
467 | .mwdma_mask = 0x06, /* Check: maybe 0x07 */ | 467 | .mwdma_mask = ATA_MWDMA12_ONLY, /* Check: maybe MWDMA0 is ok */ |
468 | .udma_mask = ATA_UDMA2, /* UDMA33 */ | 468 | .udma_mask = ATA_UDMA2, |
469 | .port_ops = &ich_pata_ops, | 469 | .port_ops = &ich_pata_ops, |
470 | }, | 470 | }, |
471 | 471 | ||
472 | [ich_pata_66] = /* ICH controllers up to 66MHz */ | 472 | [ich_pata_66] = /* ICH controllers up to 66MHz */ |
473 | { | 473 | { |
474 | .flags = PIIX_PATA_FLAGS, | 474 | .flags = PIIX_PATA_FLAGS, |
475 | .pio_mask = 0x1f, /* pio 0-4 */ | 475 | .pio_mask = ATA_PIO4, |
476 | .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ | 476 | .mwdma_mask = ATA_MWDMA12_ONLY, /* MWDMA0 is broken on chip */ |
477 | .udma_mask = ATA_UDMA4, | 477 | .udma_mask = ATA_UDMA4, |
478 | .port_ops = &ich_pata_ops, | 478 | .port_ops = &ich_pata_ops, |
479 | }, | 479 | }, |
@@ -481,17 +481,17 @@ static struct ata_port_info piix_port_info[] = { | |||
481 | [ich_pata_100] = | 481 | [ich_pata_100] = |
482 | { | 482 | { |
483 | .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, | 483 | .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR, |
484 | .pio_mask = 0x1f, /* pio0-4 */ | 484 | .pio_mask = ATA_PIO4, |
485 | .mwdma_mask = 0x06, /* mwdma1-2 */ | 485 | .mwdma_mask = ATA_MWDMA12_ONLY, |
486 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 486 | .udma_mask = ATA_UDMA5, |
487 | .port_ops = &ich_pata_ops, | 487 | .port_ops = &ich_pata_ops, |
488 | }, | 488 | }, |
489 | 489 | ||
490 | [ich5_sata] = | 490 | [ich5_sata] = |
491 | { | 491 | { |
492 | .flags = PIIX_SATA_FLAGS, | 492 | .flags = PIIX_SATA_FLAGS, |
493 | .pio_mask = 0x1f, /* pio0-4 */ | 493 | .pio_mask = ATA_PIO4, |
494 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 494 | .mwdma_mask = ATA_MWDMA2, |
495 | .udma_mask = ATA_UDMA6, | 495 | .udma_mask = ATA_UDMA6, |
496 | .port_ops = &piix_sata_ops, | 496 | .port_ops = &piix_sata_ops, |
497 | }, | 497 | }, |
@@ -499,8 +499,8 @@ static struct ata_port_info piix_port_info[] = { | |||
499 | [ich6_sata] = | 499 | [ich6_sata] = |
500 | { | 500 | { |
501 | .flags = PIIX_SATA_FLAGS, | 501 | .flags = PIIX_SATA_FLAGS, |
502 | .pio_mask = 0x1f, /* pio0-4 */ | 502 | .pio_mask = ATA_PIO4, |
503 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 503 | .mwdma_mask = ATA_MWDMA2, |
504 | .udma_mask = ATA_UDMA6, | 504 | .udma_mask = ATA_UDMA6, |
505 | .port_ops = &piix_sata_ops, | 505 | .port_ops = &piix_sata_ops, |
506 | }, | 506 | }, |
@@ -508,8 +508,8 @@ static struct ata_port_info piix_port_info[] = { | |||
508 | [ich6m_sata] = | 508 | [ich6m_sata] = |
509 | { | 509 | { |
510 | .flags = PIIX_SATA_FLAGS, | 510 | .flags = PIIX_SATA_FLAGS, |
511 | .pio_mask = 0x1f, /* pio0-4 */ | 511 | .pio_mask = ATA_PIO4, |
512 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 512 | .mwdma_mask = ATA_MWDMA2, |
513 | .udma_mask = ATA_UDMA6, | 513 | .udma_mask = ATA_UDMA6, |
514 | .port_ops = &piix_sata_ops, | 514 | .port_ops = &piix_sata_ops, |
515 | }, | 515 | }, |
@@ -517,8 +517,8 @@ static struct ata_port_info piix_port_info[] = { | |||
517 | [ich8_sata] = | 517 | [ich8_sata] = |
518 | { | 518 | { |
519 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, | 519 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, |
520 | .pio_mask = 0x1f, /* pio0-4 */ | 520 | .pio_mask = ATA_PIO4, |
521 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 521 | .mwdma_mask = ATA_MWDMA2, |
522 | .udma_mask = ATA_UDMA6, | 522 | .udma_mask = ATA_UDMA6, |
523 | .port_ops = &piix_sata_ops, | 523 | .port_ops = &piix_sata_ops, |
524 | }, | 524 | }, |
@@ -526,8 +526,8 @@ static struct ata_port_info piix_port_info[] = { | |||
526 | [ich8_2port_sata] = | 526 | [ich8_2port_sata] = |
527 | { | 527 | { |
528 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, | 528 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, |
529 | .pio_mask = 0x1f, /* pio0-4 */ | 529 | .pio_mask = ATA_PIO4, |
530 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 530 | .mwdma_mask = ATA_MWDMA2, |
531 | .udma_mask = ATA_UDMA6, | 531 | .udma_mask = ATA_UDMA6, |
532 | .port_ops = &piix_sata_ops, | 532 | .port_ops = &piix_sata_ops, |
533 | }, | 533 | }, |
@@ -535,8 +535,8 @@ static struct ata_port_info piix_port_info[] = { | |||
535 | [tolapai_sata] = | 535 | [tolapai_sata] = |
536 | { | 536 | { |
537 | .flags = PIIX_SATA_FLAGS, | 537 | .flags = PIIX_SATA_FLAGS, |
538 | .pio_mask = 0x1f, /* pio0-4 */ | 538 | .pio_mask = ATA_PIO4, |
539 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 539 | .mwdma_mask = ATA_MWDMA2, |
540 | .udma_mask = ATA_UDMA6, | 540 | .udma_mask = ATA_UDMA6, |
541 | .port_ops = &piix_sata_ops, | 541 | .port_ops = &piix_sata_ops, |
542 | }, | 542 | }, |
@@ -544,8 +544,8 @@ static struct ata_port_info piix_port_info[] = { | |||
544 | [ich8m_apple_sata] = | 544 | [ich8m_apple_sata] = |
545 | { | 545 | { |
546 | .flags = PIIX_SATA_FLAGS, | 546 | .flags = PIIX_SATA_FLAGS, |
547 | .pio_mask = 0x1f, /* pio0-4 */ | 547 | .pio_mask = ATA_PIO4, |
548 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 548 | .mwdma_mask = ATA_MWDMA2, |
549 | .udma_mask = ATA_UDMA6, | 549 | .udma_mask = ATA_UDMA6, |
550 | .port_ops = &piix_sata_ops, | 550 | .port_ops = &piix_sata_ops, |
551 | }, | 551 | }, |
@@ -553,9 +553,9 @@ static struct ata_port_info piix_port_info[] = { | |||
553 | [piix_pata_vmw] = | 553 | [piix_pata_vmw] = |
554 | { | 554 | { |
555 | .flags = PIIX_PATA_FLAGS, | 555 | .flags = PIIX_PATA_FLAGS, |
556 | .pio_mask = 0x1f, /* pio0-4 */ | 556 | .pio_mask = ATA_PIO4, |
557 | .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ | 557 | .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ |
558 | .udma_mask = ATA_UDMA_MASK_40C, | 558 | .udma_mask = ATA_UDMA2, |
559 | .port_ops = &piix_vmw_ops, | 559 | .port_ops = &piix_vmw_ops, |
560 | }, | 560 | }, |
561 | 561 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 060bcd601f57..e7ea77cf6069 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/scatterlist.h> | 57 | #include <linux/scatterlist.h> |
58 | #include <linux/io.h> | 58 | #include <linux/io.h> |
59 | #include <linux/async.h> | 59 | #include <linux/async.h> |
60 | #include <linux/log2.h> | ||
60 | #include <scsi/scsi.h> | 61 | #include <scsi/scsi.h> |
61 | #include <scsi/scsi_cmnd.h> | 62 | #include <scsi/scsi_cmnd.h> |
62 | #include <scsi/scsi_host.h> | 63 | #include <scsi/scsi_host.h> |
@@ -2389,6 +2390,7 @@ int ata_dev_configure(struct ata_device *dev) | |||
2389 | dev->cylinders = 0; | 2390 | dev->cylinders = 0; |
2390 | dev->heads = 0; | 2391 | dev->heads = 0; |
2391 | dev->sectors = 0; | 2392 | dev->sectors = 0; |
2393 | dev->multi_count = 0; | ||
2392 | 2394 | ||
2393 | /* | 2395 | /* |
2394 | * common ATA, ATAPI feature tests | 2396 | * common ATA, ATAPI feature tests |
@@ -2426,8 +2428,15 @@ int ata_dev_configure(struct ata_device *dev) | |||
2426 | 2428 | ||
2427 | dev->n_sectors = ata_id_n_sectors(id); | 2429 | dev->n_sectors = ata_id_n_sectors(id); |
2428 | 2430 | ||
2429 | if (dev->id[59] & 0x100) | 2431 | /* get current R/W Multiple count setting */ |
2430 | dev->multi_count = dev->id[59] & 0xff; | 2432 | if ((dev->id[47] >> 8) == 0x80 && (dev->id[59] & 0x100)) { |
2433 | unsigned int max = dev->id[47] & 0xff; | ||
2434 | unsigned int cnt = dev->id[59] & 0xff; | ||
2435 | /* only recognize/allow powers of two here */ | ||
2436 | if (is_power_of_2(max) && is_power_of_2(cnt)) | ||
2437 | if (cnt <= max) | ||
2438 | dev->multi_count = cnt; | ||
2439 | } | ||
2431 | 2440 | ||
2432 | if (ata_id_has_lba(id)) { | 2441 | if (ata_id_has_lba(id)) { |
2433 | const char *lba_desc; | 2442 | const char *lba_desc; |
@@ -6709,6 +6718,7 @@ EXPORT_SYMBOL_GPL(ata_id_c_string); | |||
6709 | EXPORT_SYMBOL_GPL(ata_do_dev_read_id); | 6718 | EXPORT_SYMBOL_GPL(ata_do_dev_read_id); |
6710 | EXPORT_SYMBOL_GPL(ata_scsi_simulate); | 6719 | EXPORT_SYMBOL_GPL(ata_scsi_simulate); |
6711 | 6720 | ||
6721 | EXPORT_SYMBOL_GPL(ata_pio_queue_task); | ||
6712 | EXPORT_SYMBOL_GPL(ata_pio_need_iordy); | 6722 | EXPORT_SYMBOL_GPL(ata_pio_need_iordy); |
6713 | EXPORT_SYMBOL_GPL(ata_timing_find_mode); | 6723 | EXPORT_SYMBOL_GPL(ata_timing_find_mode); |
6714 | EXPORT_SYMBOL_GPL(ata_timing_compute); | 6724 | EXPORT_SYMBOL_GPL(ata_timing_compute); |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index ea890911d4fa..01831312c360 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -547,7 +547,7 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
547 | 547 | ||
548 | /* For new EH, all qcs are finished in one of three ways - | 548 | /* For new EH, all qcs are finished in one of three ways - |
549 | * normal completion, error completion, and SCSI timeout. | 549 | * normal completion, error completion, and SCSI timeout. |
550 | * Both cmpletions can race against SCSI timeout. When normal | 550 | * Both completions can race against SCSI timeout. When normal |
551 | * completion wins, the qc never reaches EH. When error | 551 | * completion wins, the qc never reaches EH. When error |
552 | * completion wins, the qc has ATA_QCFLAG_FAILED set. | 552 | * completion wins, the qc has ATA_QCFLAG_FAILED set. |
553 | * | 553 | * |
@@ -562,7 +562,19 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
562 | int nr_timedout = 0; | 562 | int nr_timedout = 0; |
563 | 563 | ||
564 | spin_lock_irqsave(ap->lock, flags); | 564 | spin_lock_irqsave(ap->lock, flags); |
565 | 565 | ||
566 | /* This must occur under the ap->lock as we don't want | ||
567 | a polled recovery to race the real interrupt handler | ||
568 | |||
569 | The lost_interrupt handler checks for any completed but | ||
570 | non-notified command and completes much like an IRQ handler. | ||
571 | |||
572 | We then fall into the error recovery code which will treat | ||
573 | this as if normal completion won the race */ | ||
574 | |||
575 | if (ap->ops->lost_interrupt) | ||
576 | ap->ops->lost_interrupt(ap); | ||
577 | |||
566 | list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { | 578 | list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { |
567 | struct ata_queued_cmd *qc; | 579 | struct ata_queued_cmd *qc; |
568 | 580 | ||
@@ -606,6 +618,9 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
606 | ap->eh_tries = ATA_EH_MAX_TRIES; | 618 | ap->eh_tries = ATA_EH_MAX_TRIES; |
607 | } else | 619 | } else |
608 | spin_unlock_wait(ap->lock); | 620 | spin_unlock_wait(ap->lock); |
621 | |||
622 | /* If we timed raced normal completion and there is nothing to | ||
623 | recover nr_timedout == 0 why exactly are we doing error recovery ? */ | ||
609 | 624 | ||
610 | repeat: | 625 | repeat: |
611 | /* invoke error handler */ | 626 | /* invoke error handler */ |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index f93dc029dfde..8332e97a9de3 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -52,6 +52,7 @@ const struct ata_port_operations ata_sff_port_ops = { | |||
52 | .softreset = ata_sff_softreset, | 52 | .softreset = ata_sff_softreset, |
53 | .hardreset = sata_sff_hardreset, | 53 | .hardreset = sata_sff_hardreset, |
54 | .postreset = ata_sff_postreset, | 54 | .postreset = ata_sff_postreset, |
55 | .drain_fifo = ata_sff_drain_fifo, | ||
55 | .error_handler = ata_sff_error_handler, | 56 | .error_handler = ata_sff_error_handler, |
56 | .post_internal_cmd = ata_sff_post_internal_cmd, | 57 | .post_internal_cmd = ata_sff_post_internal_cmd, |
57 | 58 | ||
@@ -64,6 +65,8 @@ const struct ata_port_operations ata_sff_port_ops = { | |||
64 | .sff_irq_on = ata_sff_irq_on, | 65 | .sff_irq_on = ata_sff_irq_on, |
65 | .sff_irq_clear = ata_sff_irq_clear, | 66 | .sff_irq_clear = ata_sff_irq_clear, |
66 | 67 | ||
68 | .lost_interrupt = ata_sff_lost_interrupt, | ||
69 | |||
67 | .port_start = ata_sff_port_start, | 70 | .port_start = ata_sff_port_start, |
68 | }; | 71 | }; |
69 | EXPORT_SYMBOL_GPL(ata_sff_port_ops); | 72 | EXPORT_SYMBOL_GPL(ata_sff_port_ops); |
@@ -1646,7 +1649,7 @@ EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf); | |||
1646 | * RETURNS: | 1649 | * RETURNS: |
1647 | * One if interrupt was handled, zero if not (shared irq). | 1650 | * One if interrupt was handled, zero if not (shared irq). |
1648 | */ | 1651 | */ |
1649 | inline unsigned int ata_sff_host_intr(struct ata_port *ap, | 1652 | unsigned int ata_sff_host_intr(struct ata_port *ap, |
1650 | struct ata_queued_cmd *qc) | 1653 | struct ata_queued_cmd *qc) |
1651 | { | 1654 | { |
1652 | struct ata_eh_info *ehi = &ap->link.eh_info; | 1655 | struct ata_eh_info *ehi = &ap->link.eh_info; |
@@ -1775,6 +1778,48 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) | |||
1775 | EXPORT_SYMBOL_GPL(ata_sff_interrupt); | 1778 | EXPORT_SYMBOL_GPL(ata_sff_interrupt); |
1776 | 1779 | ||
1777 | /** | 1780 | /** |
1781 | * ata_sff_lost_interrupt - Check for an apparent lost interrupt | ||
1782 | * @ap: port that appears to have timed out | ||
1783 | * | ||
1784 | * Called from the libata error handlers when the core code suspects | ||
1785 | * an interrupt has been lost. If it has complete anything we can and | ||
1786 | * then return. Interface must support altstatus for this faster | ||
1787 | * recovery to occur. | ||
1788 | * | ||
1789 | * Locking: | ||
1790 | * Caller holds host lock | ||
1791 | */ | ||
1792 | |||
1793 | void ata_sff_lost_interrupt(struct ata_port *ap) | ||
1794 | { | ||
1795 | u8 status; | ||
1796 | struct ata_queued_cmd *qc; | ||
1797 | |||
1798 | /* Only one outstanding command per SFF channel */ | ||
1799 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | ||
1800 | /* Check we have a live one.. */ | ||
1801 | if (qc == NULL || !(qc->flags & ATA_QCFLAG_ACTIVE)) | ||
1802 | return; | ||
1803 | /* We cannot lose an interrupt on a polled command */ | ||
1804 | if (qc->tf.flags & ATA_TFLAG_POLLING) | ||
1805 | return; | ||
1806 | /* See if the controller thinks it is still busy - if so the command | ||
1807 | isn't a lost IRQ but is still in progress */ | ||
1808 | status = ata_sff_altstatus(ap); | ||
1809 | if (status & ATA_BUSY) | ||
1810 | return; | ||
1811 | |||
1812 | /* There was a command running, we are no longer busy and we have | ||
1813 | no interrupt. */ | ||
1814 | ata_port_printk(ap, KERN_WARNING, "lost interrupt (Status 0x%x)\n", | ||
1815 | status); | ||
1816 | /* Run the host interrupt logic as if the interrupt had not been | ||
1817 | lost */ | ||
1818 | ata_sff_host_intr(ap, qc); | ||
1819 | } | ||
1820 | EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt); | ||
1821 | |||
1822 | /** | ||
1778 | * ata_sff_freeze - Freeze SFF controller port | 1823 | * ata_sff_freeze - Freeze SFF controller port |
1779 | * @ap: port to freeze | 1824 | * @ap: port to freeze |
1780 | * | 1825 | * |
@@ -2199,6 +2244,39 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes) | |||
2199 | EXPORT_SYMBOL_GPL(ata_sff_postreset); | 2244 | EXPORT_SYMBOL_GPL(ata_sff_postreset); |
2200 | 2245 | ||
2201 | /** | 2246 | /** |
2247 | * ata_sff_drain_fifo - Stock FIFO drain logic for SFF controllers | ||
2248 | * @qc: command | ||
2249 | * | ||
2250 | * Drain the FIFO and device of any stuck data following a command | ||
2251 | * failing to complete. In some cases this is neccessary before a | ||
2252 | * reset will recover the device. | ||
2253 | * | ||
2254 | */ | ||
2255 | |||
2256 | void ata_sff_drain_fifo(struct ata_queued_cmd *qc) | ||
2257 | { | ||
2258 | int count; | ||
2259 | struct ata_port *ap; | ||
2260 | |||
2261 | /* We only need to flush incoming data when a command was running */ | ||
2262 | if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE) | ||
2263 | return; | ||
2264 | |||
2265 | ap = qc->ap; | ||
2266 | /* Drain up to 64K of data before we give up this recovery method */ | ||
2267 | for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) | ||
2268 | && count < 32768; count++) | ||
2269 | ioread16(ap->ioaddr.data_addr); | ||
2270 | |||
2271 | /* Can become DEBUG later */ | ||
2272 | if (count) | ||
2273 | ata_port_printk(ap, KERN_DEBUG, | ||
2274 | "drained %d bytes to clear DRQ.\n", count); | ||
2275 | |||
2276 | } | ||
2277 | EXPORT_SYMBOL_GPL(ata_sff_drain_fifo); | ||
2278 | |||
2279 | /** | ||
2202 | * ata_sff_error_handler - Stock error handler for BMDMA controller | 2280 | * ata_sff_error_handler - Stock error handler for BMDMA controller |
2203 | * @ap: port to handle error for | 2281 | * @ap: port to handle error for |
2204 | * | 2282 | * |
@@ -2239,7 +2317,8 @@ void ata_sff_error_handler(struct ata_port *ap) | |||
2239 | * really a timeout event, adjust error mask and | 2317 | * really a timeout event, adjust error mask and |
2240 | * cancel frozen state. | 2318 | * cancel frozen state. |
2241 | */ | 2319 | */ |
2242 | if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) { | 2320 | if (qc->err_mask == AC_ERR_TIMEOUT |
2321 | && (host_stat & ATA_DMA_ERR)) { | ||
2243 | qc->err_mask = AC_ERR_HOST_BUS; | 2322 | qc->err_mask = AC_ERR_HOST_BUS; |
2244 | thaw = 1; | 2323 | thaw = 1; |
2245 | } | 2324 | } |
@@ -2250,6 +2329,13 @@ void ata_sff_error_handler(struct ata_port *ap) | |||
2250 | ata_sff_sync(ap); /* FIXME: We don't need this */ | 2329 | ata_sff_sync(ap); /* FIXME: We don't need this */ |
2251 | ap->ops->sff_check_status(ap); | 2330 | ap->ops->sff_check_status(ap); |
2252 | ap->ops->sff_irq_clear(ap); | 2331 | ap->ops->sff_irq_clear(ap); |
2332 | /* We *MUST* do FIFO draining before we issue a reset as several | ||
2333 | * devices helpfully clear their internal state and will lock solid | ||
2334 | * if we touch the data port post reset. Pass qc in case anyone wants | ||
2335 | * to do different PIO/DMA recovery or has per command fixups | ||
2336 | */ | ||
2337 | if (ap->ops->drain_fifo) | ||
2338 | ap->ops->drain_fifo(qc); | ||
2253 | 2339 | ||
2254 | spin_unlock_irqrestore(ap->lock, flags); | 2340 | spin_unlock_irqrestore(ap->lock, flags); |
2255 | 2341 | ||
@@ -2959,4 +3045,3 @@ out: | |||
2959 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); | 3045 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); |
2960 | 3046 | ||
2961 | #endif /* CONFIG_PCI */ | 3047 | #endif /* CONFIG_PCI */ |
2962 | |||
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index cea8014cd87e..89a1e0018e71 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -79,8 +79,6 @@ extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, | |||
79 | u64 block, u32 n_block, unsigned int tf_flags, | 79 | u64 block, u32 n_block, unsigned int tf_flags, |
80 | unsigned int tag); | 80 | unsigned int tag); |
81 | extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev); | 81 | extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev); |
82 | extern void ata_pio_queue_task(struct ata_port *ap, void *data, | ||
83 | unsigned long delay); | ||
84 | extern void ata_port_flush_task(struct ata_port *ap); | 82 | extern void ata_port_flush_task(struct ata_port *ap); |
85 | extern unsigned ata_exec_internal(struct ata_device *dev, | 83 | extern unsigned ata_exec_internal(struct ata_device *dev, |
86 | struct ata_taskfile *tf, const u8 *cdb, | 84 | struct ata_taskfile *tf, const u8 *cdb, |
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 8b77a9802df1..d8f35fe44421 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c | |||
@@ -246,9 +246,9 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id) | |||
246 | static const struct ata_port_info info = { | 246 | static const struct ata_port_info info = { |
247 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, | 247 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, |
248 | 248 | ||
249 | .pio_mask = 0x1f, | 249 | .pio_mask = ATA_PIO4, |
250 | .mwdma_mask = 0x07, | 250 | .mwdma_mask = ATA_MWDMA2, |
251 | .udma_mask = 0x7f, | 251 | .udma_mask = ATA_UDMA6, |
252 | 252 | ||
253 | .port_ops = &pacpi_ops, | 253 | .port_ops = &pacpi_ops, |
254 | }; | 254 | }; |
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index eb99dbe78081..751b7ea4816c 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
@@ -492,53 +492,53 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
492 | { | 492 | { |
493 | static const struct ata_port_info info_early = { | 493 | static const struct ata_port_info info_early = { |
494 | .flags = ATA_FLAG_SLAVE_POSS, | 494 | .flags = ATA_FLAG_SLAVE_POSS, |
495 | .pio_mask = 0x1f, | 495 | .pio_mask = ATA_PIO4, |
496 | .port_ops = &ali_early_port_ops | 496 | .port_ops = &ali_early_port_ops |
497 | }; | 497 | }; |
498 | /* Revision 0x20 added DMA */ | 498 | /* Revision 0x20 added DMA */ |
499 | static const struct ata_port_info info_20 = { | 499 | static const struct ata_port_info info_20 = { |
500 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 500 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
501 | .pio_mask = 0x1f, | 501 | .pio_mask = ATA_PIO4, |
502 | .mwdma_mask = 0x07, | 502 | .mwdma_mask = ATA_MWDMA2, |
503 | .port_ops = &ali_20_port_ops | 503 | .port_ops = &ali_20_port_ops |
504 | }; | 504 | }; |
505 | /* Revision 0x20 with support logic added UDMA */ | 505 | /* Revision 0x20 with support logic added UDMA */ |
506 | static const struct ata_port_info info_20_udma = { | 506 | static const struct ata_port_info info_20_udma = { |
507 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 507 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
508 | .pio_mask = 0x1f, | 508 | .pio_mask = ATA_PIO4, |
509 | .mwdma_mask = 0x07, | 509 | .mwdma_mask = ATA_MWDMA2, |
510 | .udma_mask = 0x07, /* UDMA33 */ | 510 | .udma_mask = ATA_UDMA2, |
511 | .port_ops = &ali_20_port_ops | 511 | .port_ops = &ali_20_port_ops |
512 | }; | 512 | }; |
513 | /* Revision 0xC2 adds UDMA66 */ | 513 | /* Revision 0xC2 adds UDMA66 */ |
514 | static const struct ata_port_info info_c2 = { | 514 | static const struct ata_port_info info_c2 = { |
515 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 515 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
516 | .pio_mask = 0x1f, | 516 | .pio_mask = ATA_PIO4, |
517 | .mwdma_mask = 0x07, | 517 | .mwdma_mask = ATA_MWDMA2, |
518 | .udma_mask = ATA_UDMA4, | 518 | .udma_mask = ATA_UDMA4, |
519 | .port_ops = &ali_c2_port_ops | 519 | .port_ops = &ali_c2_port_ops |
520 | }; | 520 | }; |
521 | /* Revision 0xC3 is UDMA66 for now */ | 521 | /* Revision 0xC3 is UDMA66 for now */ |
522 | static const struct ata_port_info info_c3 = { | 522 | static const struct ata_port_info info_c3 = { |
523 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 523 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
524 | .pio_mask = 0x1f, | 524 | .pio_mask = ATA_PIO4, |
525 | .mwdma_mask = 0x07, | 525 | .mwdma_mask = ATA_MWDMA2, |
526 | .udma_mask = ATA_UDMA4, | 526 | .udma_mask = ATA_UDMA4, |
527 | .port_ops = &ali_c2_port_ops | 527 | .port_ops = &ali_c2_port_ops |
528 | }; | 528 | }; |
529 | /* Revision 0xC4 is UDMA100 */ | 529 | /* Revision 0xC4 is UDMA100 */ |
530 | static const struct ata_port_info info_c4 = { | 530 | static const struct ata_port_info info_c4 = { |
531 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 531 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, |
532 | .pio_mask = 0x1f, | 532 | .pio_mask = ATA_PIO4, |
533 | .mwdma_mask = 0x07, | 533 | .mwdma_mask = ATA_MWDMA2, |
534 | .udma_mask = ATA_UDMA5, | 534 | .udma_mask = ATA_UDMA5, |
535 | .port_ops = &ali_c4_port_ops | 535 | .port_ops = &ali_c4_port_ops |
536 | }; | 536 | }; |
537 | /* Revision 0xC5 is UDMA133 with LBA48 DMA */ | 537 | /* Revision 0xC5 is UDMA133 with LBA48 DMA */ |
538 | static const struct ata_port_info info_c5 = { | 538 | static const struct ata_port_info info_c5 = { |
539 | .flags = ATA_FLAG_SLAVE_POSS, | 539 | .flags = ATA_FLAG_SLAVE_POSS, |
540 | .pio_mask = 0x1f, | 540 | .pio_mask = ATA_PIO4, |
541 | .mwdma_mask = 0x07, | 541 | .mwdma_mask = ATA_MWDMA2, |
542 | .udma_mask = ATA_UDMA6, | 542 | .udma_mask = ATA_UDMA6, |
543 | .port_ops = &ali_c5_port_ops | 543 | .port_ops = &ali_c5_port_ops |
544 | }; | 544 | }; |
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 115b1cd6dcf5..33a74f11171c 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
@@ -455,74 +455,74 @@ static void amd_clear_fifo(struct pci_dev *pdev) | |||
455 | static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 455 | static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
456 | { | 456 | { |
457 | static const struct ata_port_info info[10] = { | 457 | static const struct ata_port_info info[10] = { |
458 | { /* 0: AMD 7401 */ | 458 | { /* 0: AMD 7401 - no swdma */ |
459 | .flags = ATA_FLAG_SLAVE_POSS, | 459 | .flags = ATA_FLAG_SLAVE_POSS, |
460 | .pio_mask = 0x1f, | 460 | .pio_mask = ATA_PIO4, |
461 | .mwdma_mask = 0x07, /* No SWDMA */ | 461 | .mwdma_mask = ATA_MWDMA2, |
462 | .udma_mask = 0x07, /* UDMA 33 */ | 462 | .udma_mask = ATA_UDMA2, |
463 | .port_ops = &amd33_port_ops | 463 | .port_ops = &amd33_port_ops |
464 | }, | 464 | }, |
465 | { /* 1: Early AMD7409 - no swdma */ | 465 | { /* 1: Early AMD7409 - no swdma */ |
466 | .flags = ATA_FLAG_SLAVE_POSS, | 466 | .flags = ATA_FLAG_SLAVE_POSS, |
467 | .pio_mask = 0x1f, | 467 | .pio_mask = ATA_PIO4, |
468 | .mwdma_mask = 0x07, | 468 | .mwdma_mask = ATA_MWDMA2, |
469 | .udma_mask = ATA_UDMA4, /* UDMA 66 */ | 469 | .udma_mask = ATA_UDMA4, |
470 | .port_ops = &amd66_port_ops | 470 | .port_ops = &amd66_port_ops |
471 | }, | 471 | }, |
472 | { /* 2: AMD 7409, no swdma errata */ | 472 | { /* 2: AMD 7409 */ |
473 | .flags = ATA_FLAG_SLAVE_POSS, | 473 | .flags = ATA_FLAG_SLAVE_POSS, |
474 | .pio_mask = 0x1f, | 474 | .pio_mask = ATA_PIO4, |
475 | .mwdma_mask = 0x07, | 475 | .mwdma_mask = ATA_MWDMA2, |
476 | .udma_mask = ATA_UDMA4, /* UDMA 66 */ | 476 | .udma_mask = ATA_UDMA4, |
477 | .port_ops = &amd66_port_ops | 477 | .port_ops = &amd66_port_ops |
478 | }, | 478 | }, |
479 | { /* 3: AMD 7411 */ | 479 | { /* 3: AMD 7411 */ |
480 | .flags = ATA_FLAG_SLAVE_POSS, | 480 | .flags = ATA_FLAG_SLAVE_POSS, |
481 | .pio_mask = 0x1f, | 481 | .pio_mask = ATA_PIO4, |
482 | .mwdma_mask = 0x07, | 482 | .mwdma_mask = ATA_MWDMA2, |
483 | .udma_mask = ATA_UDMA5, /* UDMA 100 */ | 483 | .udma_mask = ATA_UDMA5, |
484 | .port_ops = &amd100_port_ops | 484 | .port_ops = &amd100_port_ops |
485 | }, | 485 | }, |
486 | { /* 4: AMD 7441 */ | 486 | { /* 4: AMD 7441 */ |
487 | .flags = ATA_FLAG_SLAVE_POSS, | 487 | .flags = ATA_FLAG_SLAVE_POSS, |
488 | .pio_mask = 0x1f, | 488 | .pio_mask = ATA_PIO4, |
489 | .mwdma_mask = 0x07, | 489 | .mwdma_mask = ATA_MWDMA2, |
490 | .udma_mask = ATA_UDMA5, /* UDMA 100 */ | 490 | .udma_mask = ATA_UDMA5, |
491 | .port_ops = &amd100_port_ops | 491 | .port_ops = &amd100_port_ops |
492 | }, | 492 | }, |
493 | { /* 5: AMD 8111*/ | 493 | { /* 5: AMD 8111 - no swdma */ |
494 | .flags = ATA_FLAG_SLAVE_POSS, | 494 | .flags = ATA_FLAG_SLAVE_POSS, |
495 | .pio_mask = 0x1f, | 495 | .pio_mask = ATA_PIO4, |
496 | .mwdma_mask = 0x07, | 496 | .mwdma_mask = ATA_MWDMA2, |
497 | .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */ | 497 | .udma_mask = ATA_UDMA6, |
498 | .port_ops = &amd133_port_ops | 498 | .port_ops = &amd133_port_ops |
499 | }, | 499 | }, |
500 | { /* 6: AMD 8111 UDMA 100 (Serenade) */ | 500 | { /* 6: AMD 8111 UDMA 100 (Serenade) - no swdma */ |
501 | .flags = ATA_FLAG_SLAVE_POSS, | 501 | .flags = ATA_FLAG_SLAVE_POSS, |
502 | .pio_mask = 0x1f, | 502 | .pio_mask = ATA_PIO4, |
503 | .mwdma_mask = 0x07, | 503 | .mwdma_mask = ATA_MWDMA2, |
504 | .udma_mask = ATA_UDMA5, /* UDMA 100, no swdma */ | 504 | .udma_mask = ATA_UDMA5, |
505 | .port_ops = &amd133_port_ops | 505 | .port_ops = &amd133_port_ops |
506 | }, | 506 | }, |
507 | { /* 7: Nvidia Nforce */ | 507 | { /* 7: Nvidia Nforce */ |
508 | .flags = ATA_FLAG_SLAVE_POSS, | 508 | .flags = ATA_FLAG_SLAVE_POSS, |
509 | .pio_mask = 0x1f, | 509 | .pio_mask = ATA_PIO4, |
510 | .mwdma_mask = 0x07, | 510 | .mwdma_mask = ATA_MWDMA2, |
511 | .udma_mask = ATA_UDMA5, /* UDMA 100 */ | 511 | .udma_mask = ATA_UDMA5, |
512 | .port_ops = &nv100_port_ops | 512 | .port_ops = &nv100_port_ops |
513 | }, | 513 | }, |
514 | { /* 8: Nvidia Nforce2 and later */ | 514 | { /* 8: Nvidia Nforce2 and later - no swdma */ |
515 | .flags = ATA_FLAG_SLAVE_POSS, | 515 | .flags = ATA_FLAG_SLAVE_POSS, |
516 | .pio_mask = 0x1f, | 516 | .pio_mask = ATA_PIO4, |
517 | .mwdma_mask = 0x07, | 517 | .mwdma_mask = ATA_MWDMA2, |
518 | .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */ | 518 | .udma_mask = ATA_UDMA6, |
519 | .port_ops = &nv133_port_ops | 519 | .port_ops = &nv133_port_ops |
520 | }, | 520 | }, |
521 | { /* 9: AMD CS5536 (Geode companion) */ | 521 | { /* 9: AMD CS5536 (Geode companion) */ |
522 | .flags = ATA_FLAG_SLAVE_POSS, | 522 | .flags = ATA_FLAG_SLAVE_POSS, |
523 | .pio_mask = 0x1f, | 523 | .pio_mask = ATA_PIO4, |
524 | .mwdma_mask = 0x07, | 524 | .mwdma_mask = ATA_MWDMA2, |
525 | .udma_mask = ATA_UDMA5, /* UDMA 100 */ | 525 | .udma_mask = ATA_UDMA5, |
526 | .port_ops = &amd100_port_ops | 526 | .port_ops = &amd100_port_ops |
527 | } | 527 | } |
528 | }; | 528 | }; |
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 6b3092c75ffe..d332cfdb0f30 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * performance Alessandro Zummo <alessandro.zummo@towertech.it> | 12 | * performance Alessandro Zummo <alessandro.zummo@towertech.it> |
13 | * | 13 | * |
14 | * TODO | 14 | * TODO |
15 | * 850 serialization once the core supports it | ||
16 | * Investigate no_dsc on 850R | 15 | * Investigate no_dsc on 850R |
17 | * Clock detect | 16 | * Clock detect |
18 | */ | 17 | */ |
@@ -29,7 +28,7 @@ | |||
29 | #include <linux/ata.h> | 28 | #include <linux/ata.h> |
30 | 29 | ||
31 | #define DRV_NAME "pata_artop" | 30 | #define DRV_NAME "pata_artop" |
32 | #define DRV_VERSION "0.4.4" | 31 | #define DRV_VERSION "0.4.5" |
33 | 32 | ||
34 | /* | 33 | /* |
35 | * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we | 34 | * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we |
@@ -283,6 +282,31 @@ static void artop6260_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
283 | pci_write_config_byte(pdev, 0x44 + ap->port_no, ultra); | 282 | pci_write_config_byte(pdev, 0x44 + ap->port_no, ultra); |
284 | } | 283 | } |
285 | 284 | ||
285 | /** | ||
286 | * artop_6210_qc_defer - implement serialization | ||
287 | * @qc: command | ||
288 | * | ||
289 | * Issue commands per host on this chip. | ||
290 | */ | ||
291 | |||
292 | static int artop6210_qc_defer(struct ata_queued_cmd *qc) | ||
293 | { | ||
294 | struct ata_host *host = qc->ap->host; | ||
295 | struct ata_port *alt = host->ports[1 ^ qc->ap->port_no]; | ||
296 | int rc; | ||
297 | |||
298 | /* First apply the usual rules */ | ||
299 | rc = ata_std_qc_defer(qc); | ||
300 | if (rc != 0) | ||
301 | return rc; | ||
302 | |||
303 | /* Now apply serialization rules. Only allow a command if the | ||
304 | other channel state machine is idle */ | ||
305 | if (alt && alt->qc_active) | ||
306 | return ATA_DEFER_PORT; | ||
307 | return 0; | ||
308 | } | ||
309 | |||
286 | static struct scsi_host_template artop_sht = { | 310 | static struct scsi_host_template artop_sht = { |
287 | ATA_BMDMA_SHT(DRV_NAME), | 311 | ATA_BMDMA_SHT(DRV_NAME), |
288 | }; | 312 | }; |
@@ -293,6 +317,7 @@ static struct ata_port_operations artop6210_ops = { | |||
293 | .set_piomode = artop6210_set_piomode, | 317 | .set_piomode = artop6210_set_piomode, |
294 | .set_dmamode = artop6210_set_dmamode, | 318 | .set_dmamode = artop6210_set_dmamode, |
295 | .prereset = artop6210_pre_reset, | 319 | .prereset = artop6210_pre_reset, |
320 | .qc_defer = artop6210_qc_defer, | ||
296 | }; | 321 | }; |
297 | 322 | ||
298 | static struct ata_port_operations artop6260_ops = { | 323 | static struct ata_port_operations artop6260_ops = { |
@@ -323,29 +348,29 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) | |||
323 | static int printed_version; | 348 | static int printed_version; |
324 | static const struct ata_port_info info_6210 = { | 349 | static const struct ata_port_info info_6210 = { |
325 | .flags = ATA_FLAG_SLAVE_POSS, | 350 | .flags = ATA_FLAG_SLAVE_POSS, |
326 | .pio_mask = 0x1f, /* pio0-4 */ | 351 | .pio_mask = ATA_PIO4, |
327 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 352 | .mwdma_mask = ATA_MWDMA2, |
328 | .udma_mask = ATA_UDMA2, | 353 | .udma_mask = ATA_UDMA2, |
329 | .port_ops = &artop6210_ops, | 354 | .port_ops = &artop6210_ops, |
330 | }; | 355 | }; |
331 | static const struct ata_port_info info_626x = { | 356 | static const struct ata_port_info info_626x = { |
332 | .flags = ATA_FLAG_SLAVE_POSS, | 357 | .flags = ATA_FLAG_SLAVE_POSS, |
333 | .pio_mask = 0x1f, /* pio0-4 */ | 358 | .pio_mask = ATA_PIO4, |
334 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 359 | .mwdma_mask = ATA_MWDMA2, |
335 | .udma_mask = ATA_UDMA4, | 360 | .udma_mask = ATA_UDMA4, |
336 | .port_ops = &artop6260_ops, | 361 | .port_ops = &artop6260_ops, |
337 | }; | 362 | }; |
338 | static const struct ata_port_info info_628x = { | 363 | static const struct ata_port_info info_628x = { |
339 | .flags = ATA_FLAG_SLAVE_POSS, | 364 | .flags = ATA_FLAG_SLAVE_POSS, |
340 | .pio_mask = 0x1f, /* pio0-4 */ | 365 | .pio_mask = ATA_PIO4, |
341 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 366 | .mwdma_mask = ATA_MWDMA2, |
342 | .udma_mask = ATA_UDMA5, | 367 | .udma_mask = ATA_UDMA5, |
343 | .port_ops = &artop6260_ops, | 368 | .port_ops = &artop6260_ops, |
344 | }; | 369 | }; |
345 | static const struct ata_port_info info_628x_fast = { | 370 | static const struct ata_port_info info_628x_fast = { |
346 | .flags = ATA_FLAG_SLAVE_POSS, | 371 | .flags = ATA_FLAG_SLAVE_POSS, |
347 | .pio_mask = 0x1f, /* pio0-4 */ | 372 | .pio_mask = ATA_PIO4, |
348 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 373 | .mwdma_mask = ATA_MWDMA2, |
349 | .udma_mask = ATA_UDMA6, | 374 | .udma_mask = ATA_UDMA6, |
350 | .port_ops = &artop6260_ops, | 375 | .port_ops = &artop6260_ops, |
351 | }; | 376 | }; |
@@ -362,12 +387,8 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) | |||
362 | 387 | ||
363 | if (id->driver_data == 0) { /* 6210 variant */ | 388 | if (id->driver_data == 0) { /* 6210 variant */ |
364 | ppi[0] = &info_6210; | 389 | ppi[0] = &info_6210; |
365 | ppi[1] = &ata_dummy_port_info; | ||
366 | /* BIOS may have left us in UDMA, clear it before libata probe */ | 390 | /* BIOS may have left us in UDMA, clear it before libata probe */ |
367 | pci_write_config_byte(pdev, 0x54, 0); | 391 | pci_write_config_byte(pdev, 0x54, 0); |
368 | /* For the moment (also lacks dsc) */ | ||
369 | printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n"); | ||
370 | printk(KERN_WARNING "Secondary ATA ports will not be activated.\n"); | ||
371 | } | 392 | } |
372 | else if (id->driver_data == 1) /* 6260 */ | 393 | else if (id->driver_data == 1) /* 6260 */ |
373 | ppi[0] = &info_626x; | 394 | ppi[0] = &info_626x; |
diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c index ab61095093b9..5c129f99a7e3 100644 --- a/drivers/ata/pata_at32.c +++ b/drivers/ata/pata_at32.c | |||
@@ -67,7 +67,9 @@ | |||
67 | * | 67 | * |
68 | * Alter PIO_MASK below according to table to set maximal PIO mode. | 68 | * Alter PIO_MASK below according to table to set maximal PIO mode. |
69 | */ | 69 | */ |
70 | #define PIO_MASK (0x1f) | 70 | enum { |
71 | PIO_MASK = ATA_PIO4, | ||
72 | }; | ||
71 | 73 | ||
72 | /* | 74 | /* |
73 | * Struct containing private information about device. | 75 | * Struct containing private information about device. |
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 506adde8ebb3..bec0b8ade66d 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c | |||
@@ -220,9 +220,9 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
220 | { | 220 | { |
221 | static const struct ata_port_info info = { | 221 | static const struct ata_port_info info = { |
222 | .flags = ATA_FLAG_SLAVE_POSS, | 222 | .flags = ATA_FLAG_SLAVE_POSS, |
223 | .pio_mask = 0x1f, | 223 | .pio_mask = ATA_PIO4, |
224 | .mwdma_mask = 0x06, /* No MWDMA0 support */ | 224 | .mwdma_mask = ATA_MWDMA12_ONLY, |
225 | .udma_mask = 0x3F, | 225 | .udma_mask = ATA_UDMA5, |
226 | .port_ops = &atiixp_port_ops | 226 | .port_ops = &atiixp_port_ops |
227 | }; | 227 | }; |
228 | static const struct pci_bits atiixp_enable_bits[] = { | 228 | static const struct pci_bits atiixp_enable_bits[] = { |
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 1050fed96b2b..c4b47a3e5446 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c | |||
@@ -1502,7 +1502,7 @@ static struct ata_port_info bfin_port_info[] = { | |||
1502 | .flags = ATA_FLAG_SLAVE_POSS | 1502 | .flags = ATA_FLAG_SLAVE_POSS |
1503 | | ATA_FLAG_MMIO | 1503 | | ATA_FLAG_MMIO |
1504 | | ATA_FLAG_NO_LEGACY, | 1504 | | ATA_FLAG_NO_LEGACY, |
1505 | .pio_mask = 0x1f, /* pio0-4 */ | 1505 | .pio_mask = ATA_PIO4, |
1506 | .mwdma_mask = 0, | 1506 | .mwdma_mask = 0, |
1507 | .udma_mask = 0, | 1507 | .udma_mask = 0, |
1508 | .port_ops = &bfin_pata_ops, | 1508 | .port_ops = &bfin_pata_ops, |
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 34a394264c3d..5acf9fa9b39f 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c | |||
@@ -211,7 +211,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
211 | { | 211 | { |
212 | static const struct ata_port_info info = { | 212 | static const struct ata_port_info info = { |
213 | .flags = ATA_FLAG_SLAVE_POSS, | 213 | .flags = ATA_FLAG_SLAVE_POSS, |
214 | .pio_mask = 0x1f, | 214 | .pio_mask = ATA_PIO4, |
215 | .port_ops = &cmd640_port_ops | 215 | .port_ops = &cmd640_port_ops |
216 | }; | 216 | }; |
217 | const struct ata_port_info *ppi[] = { &info, NULL }; | 217 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 3167d8fed2f2..f98dffedf4bc 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -299,40 +299,40 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
299 | static const struct ata_port_info cmd_info[6] = { | 299 | static const struct ata_port_info cmd_info[6] = { |
300 | { /* CMD 643 - no UDMA */ | 300 | { /* CMD 643 - no UDMA */ |
301 | .flags = ATA_FLAG_SLAVE_POSS, | 301 | .flags = ATA_FLAG_SLAVE_POSS, |
302 | .pio_mask = 0x1f, | 302 | .pio_mask = ATA_PIO4, |
303 | .mwdma_mask = 0x07, | 303 | .mwdma_mask = ATA_MWDMA2, |
304 | .port_ops = &cmd64x_port_ops | 304 | .port_ops = &cmd64x_port_ops |
305 | }, | 305 | }, |
306 | { /* CMD 646 with broken UDMA */ | 306 | { /* CMD 646 with broken UDMA */ |
307 | .flags = ATA_FLAG_SLAVE_POSS, | 307 | .flags = ATA_FLAG_SLAVE_POSS, |
308 | .pio_mask = 0x1f, | 308 | .pio_mask = ATA_PIO4, |
309 | .mwdma_mask = 0x07, | 309 | .mwdma_mask = ATA_MWDMA2, |
310 | .port_ops = &cmd64x_port_ops | 310 | .port_ops = &cmd64x_port_ops |
311 | }, | 311 | }, |
312 | { /* CMD 646 with working UDMA */ | 312 | { /* CMD 646 with working UDMA */ |
313 | .flags = ATA_FLAG_SLAVE_POSS, | 313 | .flags = ATA_FLAG_SLAVE_POSS, |
314 | .pio_mask = 0x1f, | 314 | .pio_mask = ATA_PIO4, |
315 | .mwdma_mask = 0x07, | 315 | .mwdma_mask = ATA_MWDMA2, |
316 | .udma_mask = ATA_UDMA2, | 316 | .udma_mask = ATA_UDMA2, |
317 | .port_ops = &cmd64x_port_ops | 317 | .port_ops = &cmd64x_port_ops |
318 | }, | 318 | }, |
319 | { /* CMD 646 rev 1 */ | 319 | { /* CMD 646 rev 1 */ |
320 | .flags = ATA_FLAG_SLAVE_POSS, | 320 | .flags = ATA_FLAG_SLAVE_POSS, |
321 | .pio_mask = 0x1f, | 321 | .pio_mask = ATA_PIO4, |
322 | .mwdma_mask = 0x07, | 322 | .mwdma_mask = ATA_MWDMA2, |
323 | .port_ops = &cmd646r1_port_ops | 323 | .port_ops = &cmd646r1_port_ops |
324 | }, | 324 | }, |
325 | { /* CMD 648 */ | 325 | { /* CMD 648 */ |
326 | .flags = ATA_FLAG_SLAVE_POSS, | 326 | .flags = ATA_FLAG_SLAVE_POSS, |
327 | .pio_mask = 0x1f, | 327 | .pio_mask = ATA_PIO4, |
328 | .mwdma_mask = 0x07, | 328 | .mwdma_mask = ATA_MWDMA2, |
329 | .udma_mask = ATA_UDMA4, | 329 | .udma_mask = ATA_UDMA4, |
330 | .port_ops = &cmd648_port_ops | 330 | .port_ops = &cmd648_port_ops |
331 | }, | 331 | }, |
332 | { /* CMD 649 */ | 332 | { /* CMD 649 */ |
333 | .flags = ATA_FLAG_SLAVE_POSS, | 333 | .flags = ATA_FLAG_SLAVE_POSS, |
334 | .pio_mask = 0x1f, | 334 | .pio_mask = ATA_PIO4, |
335 | .mwdma_mask = 0x07, | 335 | .mwdma_mask = ATA_MWDMA2, |
336 | .udma_mask = ATA_UDMA5, | 336 | .udma_mask = ATA_UDMA5, |
337 | .port_ops = &cmd648_port_ops | 337 | .port_ops = &cmd648_port_ops |
338 | } | 338 | } |
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 1186bcd2781c..db6a96984f3f 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
@@ -158,7 +158,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi | |||
158 | static const unsigned int ctl_port[] = { 0x3F6, 0x376 }; | 158 | static const unsigned int ctl_port[] = { 0x3F6, 0x376 }; |
159 | struct ata_port_info pi = { | 159 | struct ata_port_info pi = { |
160 | .flags = ATA_FLAG_SLAVE_POSS, | 160 | .flags = ATA_FLAG_SLAVE_POSS, |
161 | .pio_mask = 0x1f, | 161 | .pio_mask = ATA_PIO4, |
162 | .port_ops = &cs5520_port_ops, | 162 | .port_ops = &cs5520_port_ops, |
163 | }; | 163 | }; |
164 | const struct ata_port_info *ppi[2]; | 164 | const struct ata_port_info *ppi[2]; |
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index bba453381f44..c974b05e4129 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c | |||
@@ -298,15 +298,15 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
298 | { | 298 | { |
299 | static const struct ata_port_info info = { | 299 | static const struct ata_port_info info = { |
300 | .flags = ATA_FLAG_SLAVE_POSS, | 300 | .flags = ATA_FLAG_SLAVE_POSS, |
301 | .pio_mask = 0x1f, | 301 | .pio_mask = ATA_PIO4, |
302 | .mwdma_mask = 0x07, | 302 | .mwdma_mask = ATA_MWDMA2, |
303 | .udma_mask = 0x07, | 303 | .udma_mask = ATA_UDMA2, |
304 | .port_ops = &cs5530_port_ops | 304 | .port_ops = &cs5530_port_ops |
305 | }; | 305 | }; |
306 | /* The docking connector doesn't do UDMA, and it seems not MWDMA */ | 306 | /* The docking connector doesn't do UDMA, and it seems not MWDMA */ |
307 | static const struct ata_port_info info_palmax_secondary = { | 307 | static const struct ata_port_info info_palmax_secondary = { |
308 | .flags = ATA_FLAG_SLAVE_POSS, | 308 | .flags = ATA_FLAG_SLAVE_POSS, |
309 | .pio_mask = 0x1f, | 309 | .pio_mask = ATA_PIO4, |
310 | .port_ops = &cs5530_port_ops | 310 | .port_ops = &cs5530_port_ops |
311 | }; | 311 | }; |
312 | const struct ata_port_info *ppi[] = { &info, NULL }; | 312 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index 8b236af84c2e..d33aa28239a9 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c | |||
@@ -181,8 +181,8 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
181 | { | 181 | { |
182 | static const struct ata_port_info info = { | 182 | static const struct ata_port_info info = { |
183 | .flags = ATA_FLAG_SLAVE_POSS, | 183 | .flags = ATA_FLAG_SLAVE_POSS, |
184 | .pio_mask = 0x1f, | 184 | .pio_mask = ATA_PIO4, |
185 | .mwdma_mask = 0x07, | 185 | .mwdma_mask = ATA_MWDMA2, |
186 | .udma_mask = ATA_UDMA4, | 186 | .udma_mask = ATA_UDMA4, |
187 | .port_ops = &cs5535_port_ops | 187 | .port_ops = &cs5535_port_ops |
188 | }; | 188 | }; |
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index afed92976198..6da4cb486c8d 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c | |||
@@ -241,8 +241,8 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
241 | { | 241 | { |
242 | static const struct ata_port_info info = { | 242 | static const struct ata_port_info info = { |
243 | .flags = ATA_FLAG_SLAVE_POSS, | 243 | .flags = ATA_FLAG_SLAVE_POSS, |
244 | .pio_mask = 0x1f, | 244 | .pio_mask = ATA_PIO4, |
245 | .mwdma_mask = 0x07, | 245 | .mwdma_mask = ATA_MWDMA2, |
246 | .udma_mask = ATA_UDMA5, | 246 | .udma_mask = ATA_UDMA5, |
247 | .port_ops = &cs5536_port_ops, | 247 | .port_ops = &cs5536_port_ops, |
248 | }; | 248 | }; |
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index d546425cd380..8fb040bf7361 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c | |||
@@ -124,8 +124,8 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i | |||
124 | { | 124 | { |
125 | static const struct ata_port_info info = { | 125 | static const struct ata_port_info info = { |
126 | .flags = ATA_FLAG_SLAVE_POSS, | 126 | .flags = ATA_FLAG_SLAVE_POSS, |
127 | .pio_mask = 0x1f, | 127 | .pio_mask = ATA_PIO4, |
128 | .mwdma_mask = 0x07, | 128 | .mwdma_mask = ATA_MWDMA2, |
129 | .port_ops = &cy82c693_port_ops | 129 | .port_ops = &cy82c693_port_ops |
130 | }; | 130 | }; |
131 | const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; | 131 | const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; |
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index ac6392ea35b0..2085e0a3a05a 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c | |||
@@ -251,9 +251,9 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
251 | static int printed_version; | 251 | static int printed_version; |
252 | static const struct ata_port_info info = { | 252 | static const struct ata_port_info info = { |
253 | .flags = ATA_FLAG_SLAVE_POSS, | 253 | .flags = ATA_FLAG_SLAVE_POSS, |
254 | .pio_mask = 0x1f, /* pio0-4 */ | 254 | .pio_mask = ATA_PIO4, |
255 | .mwdma_mask = 0x07, /* mwdma1-2 */ | 255 | .mwdma_mask = ATA_MWDMA2, |
256 | .udma_mask = 0x0f, /* UDMA 66 */ | 256 | .udma_mask = ATA_UDMA4, |
257 | .port_ops = &efar_ops, | 257 | .port_ops = &efar_ops, |
258 | }; | 258 | }; |
259 | const struct ata_port_info *ppi[] = { &info, NULL }; | 259 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 65c28e5a6cd7..d7f2da127d13 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c | |||
@@ -336,8 +336,8 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
336 | { | 336 | { |
337 | static const struct ata_port_info info_hpt366 = { | 337 | static const struct ata_port_info info_hpt366 = { |
338 | .flags = ATA_FLAG_SLAVE_POSS, | 338 | .flags = ATA_FLAG_SLAVE_POSS, |
339 | .pio_mask = 0x1f, | 339 | .pio_mask = ATA_PIO4, |
340 | .mwdma_mask = 0x07, | 340 | .mwdma_mask = ATA_MWDMA2, |
341 | .udma_mask = ATA_UDMA4, | 341 | .udma_mask = ATA_UDMA4, |
342 | .port_ops = &hpt366_port_ops | 342 | .port_ops = &hpt366_port_ops |
343 | }; | 343 | }; |
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 42163998de9a..81ab57003aba 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
@@ -753,55 +753,55 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
753 | /* HPT370 - UDMA100 */ | 753 | /* HPT370 - UDMA100 */ |
754 | static const struct ata_port_info info_hpt370 = { | 754 | static const struct ata_port_info info_hpt370 = { |
755 | .flags = ATA_FLAG_SLAVE_POSS, | 755 | .flags = ATA_FLAG_SLAVE_POSS, |
756 | .pio_mask = 0x1f, | 756 | .pio_mask = ATA_PIO4, |
757 | .mwdma_mask = 0x07, | 757 | .mwdma_mask = ATA_MWDMA2, |
758 | .udma_mask = ATA_UDMA5, | 758 | .udma_mask = ATA_UDMA5, |
759 | .port_ops = &hpt370_port_ops | 759 | .port_ops = &hpt370_port_ops |
760 | }; | 760 | }; |
761 | /* HPT370A - UDMA100 */ | 761 | /* HPT370A - UDMA100 */ |
762 | static const struct ata_port_info info_hpt370a = { | 762 | static const struct ata_port_info info_hpt370a = { |
763 | .flags = ATA_FLAG_SLAVE_POSS, | 763 | .flags = ATA_FLAG_SLAVE_POSS, |
764 | .pio_mask = 0x1f, | 764 | .pio_mask = ATA_PIO4, |
765 | .mwdma_mask = 0x07, | 765 | .mwdma_mask = ATA_MWDMA2, |
766 | .udma_mask = ATA_UDMA5, | 766 | .udma_mask = ATA_UDMA5, |
767 | .port_ops = &hpt370a_port_ops | 767 | .port_ops = &hpt370a_port_ops |
768 | }; | 768 | }; |
769 | /* HPT370 - UDMA100 */ | 769 | /* HPT370 - UDMA100 */ |
770 | static const struct ata_port_info info_hpt370_33 = { | 770 | static const struct ata_port_info info_hpt370_33 = { |
771 | .flags = ATA_FLAG_SLAVE_POSS, | 771 | .flags = ATA_FLAG_SLAVE_POSS, |
772 | .pio_mask = 0x1f, | 772 | .pio_mask = ATA_PIO4, |
773 | .mwdma_mask = 0x07, | 773 | .mwdma_mask = ATA_MWDMA2, |
774 | .udma_mask = ATA_UDMA5, | 774 | .udma_mask = ATA_UDMA5, |
775 | .port_ops = &hpt370_port_ops | 775 | .port_ops = &hpt370_port_ops |
776 | }; | 776 | }; |
777 | /* HPT370A - UDMA100 */ | 777 | /* HPT370A - UDMA100 */ |
778 | static const struct ata_port_info info_hpt370a_33 = { | 778 | static const struct ata_port_info info_hpt370a_33 = { |
779 | .flags = ATA_FLAG_SLAVE_POSS, | 779 | .flags = ATA_FLAG_SLAVE_POSS, |
780 | .pio_mask = 0x1f, | 780 | .pio_mask = ATA_PIO4, |
781 | .mwdma_mask = 0x07, | 781 | .mwdma_mask = ATA_MWDMA2, |
782 | .udma_mask = ATA_UDMA5, | 782 | .udma_mask = ATA_UDMA5, |
783 | .port_ops = &hpt370a_port_ops | 783 | .port_ops = &hpt370a_port_ops |
784 | }; | 784 | }; |
785 | /* HPT371, 372 and friends - UDMA133 */ | 785 | /* HPT371, 372 and friends - UDMA133 */ |
786 | static const struct ata_port_info info_hpt372 = { | 786 | static const struct ata_port_info info_hpt372 = { |
787 | .flags = ATA_FLAG_SLAVE_POSS, | 787 | .flags = ATA_FLAG_SLAVE_POSS, |
788 | .pio_mask = 0x1f, | 788 | .pio_mask = ATA_PIO4, |
789 | .mwdma_mask = 0x07, | 789 | .mwdma_mask = ATA_MWDMA2, |
790 | .udma_mask = ATA_UDMA6, | 790 | .udma_mask = ATA_UDMA6, |
791 | .port_ops = &hpt372_port_ops | 791 | .port_ops = &hpt372_port_ops |
792 | }; | 792 | }; |
793 | /* HPT374 - UDMA100, function 1 uses different prereset method */ | 793 | /* HPT374 - UDMA100, function 1 uses different prereset method */ |
794 | static const struct ata_port_info info_hpt374_fn0 = { | 794 | static const struct ata_port_info info_hpt374_fn0 = { |
795 | .flags = ATA_FLAG_SLAVE_POSS, | 795 | .flags = ATA_FLAG_SLAVE_POSS, |
796 | .pio_mask = 0x1f, | 796 | .pio_mask = ATA_PIO4, |
797 | .mwdma_mask = 0x07, | 797 | .mwdma_mask = ATA_MWDMA2, |
798 | .udma_mask = ATA_UDMA5, | 798 | .udma_mask = ATA_UDMA5, |
799 | .port_ops = &hpt372_port_ops | 799 | .port_ops = &hpt372_port_ops |
800 | }; | 800 | }; |
801 | static const struct ata_port_info info_hpt374_fn1 = { | 801 | static const struct ata_port_info info_hpt374_fn1 = { |
802 | .flags = ATA_FLAG_SLAVE_POSS, | 802 | .flags = ATA_FLAG_SLAVE_POSS, |
803 | .pio_mask = 0x1f, | 803 | .pio_mask = ATA_PIO4, |
804 | .mwdma_mask = 0x07, | 804 | .mwdma_mask = ATA_MWDMA2, |
805 | .udma_mask = ATA_UDMA5, | 805 | .udma_mask = ATA_UDMA5, |
806 | .port_ops = &hpt374_fn1_port_ops | 806 | .port_ops = &hpt374_fn1_port_ops |
807 | }; | 807 | }; |
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index d5c9fd7b82bb..3d59fe0a408d 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -441,8 +441,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
441 | /* HPT372N and friends - UDMA133 */ | 441 | /* HPT372N and friends - UDMA133 */ |
442 | static const struct ata_port_info info = { | 442 | static const struct ata_port_info info = { |
443 | .flags = ATA_FLAG_SLAVE_POSS, | 443 | .flags = ATA_FLAG_SLAVE_POSS, |
444 | .pio_mask = 0x1f, | 444 | .pio_mask = ATA_PIO4, |
445 | .mwdma_mask = 0x07, | 445 | .mwdma_mask = ATA_MWDMA2, |
446 | .udma_mask = ATA_UDMA6, | 446 | .udma_mask = ATA_UDMA6, |
447 | .port_ops = &hpt3x2n_port_ops | 447 | .port_ops = &hpt3x2n_port_ops |
448 | }; | 448 | }; |
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index f19cc645881a..7e310253b36b 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c | |||
@@ -188,11 +188,11 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
188 | static int printed_version; | 188 | static int printed_version; |
189 | static const struct ata_port_info info = { | 189 | static const struct ata_port_info info = { |
190 | .flags = ATA_FLAG_SLAVE_POSS, | 190 | .flags = ATA_FLAG_SLAVE_POSS, |
191 | .pio_mask = 0x1f, | 191 | .pio_mask = ATA_PIO4, |
192 | #if defined(CONFIG_PATA_HPT3X3_DMA) | 192 | #if defined(CONFIG_PATA_HPT3X3_DMA) |
193 | /* Further debug needed */ | 193 | /* Further debug needed */ |
194 | .mwdma_mask = 0x07, | 194 | .mwdma_mask = ATA_MWDMA2, |
195 | .udma_mask = 0x07, | 195 | .udma_mask = ATA_UDMA2, |
196 | #endif | 196 | #endif |
197 | .port_ops = &hpt3x3_port_ops | 197 | .port_ops = &hpt3x3_port_ops |
198 | }; | 198 | }; |
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index cf9e9848f8b5..e7347db5b6c4 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c | |||
@@ -297,7 +297,7 @@ static int icside_dma_init(struct pata_icside_info *info) | |||
297 | 297 | ||
298 | if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { | 298 | if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { |
299 | state->dma = ec->dma; | 299 | state->dma = ec->dma; |
300 | info->mwdma_mask = 0x07; /* MW0..2 */ | 300 | info->mwdma_mask = ATA_MWDMA2; |
301 | } | 301 | } |
302 | 302 | ||
303 | return 0; | 303 | return 0; |
@@ -473,7 +473,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info) | |||
473 | for (i = 0; i < info->nr_ports; i++) { | 473 | for (i = 0; i < info->nr_ports; i++) { |
474 | struct ata_port *ap = host->ports[i]; | 474 | struct ata_port *ap = host->ports[i]; |
475 | 475 | ||
476 | ap->pio_mask = 0x1f; | 476 | ap->pio_mask = ATA_PIO4; |
477 | ap->mwdma_mask = info->mwdma_mask; | 477 | ap->mwdma_mask = info->mwdma_mask; |
478 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 478 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
479 | ap->ops = &pata_icside_port_ops; | 479 | ap->ops = &pata_icside_port_ops; |
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index 15cdb9148aab..4bceb8803a10 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/libata.h> | 17 | #include <linux/libata.h> |
18 | 18 | ||
19 | #define DRV_NAME "pata_isapnp" | 19 | #define DRV_NAME "pata_isapnp" |
20 | #define DRV_VERSION "0.2.2" | 20 | #define DRV_VERSION "0.2.5" |
21 | 21 | ||
22 | static struct scsi_host_template isapnp_sht = { | 22 | static struct scsi_host_template isapnp_sht = { |
23 | ATA_PIO_SHT(DRV_NAME), | 23 | ATA_PIO_SHT(DRV_NAME), |
@@ -28,6 +28,13 @@ static struct ata_port_operations isapnp_port_ops = { | |||
28 | .cable_detect = ata_cable_40wire, | 28 | .cable_detect = ata_cable_40wire, |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static struct ata_port_operations isapnp_noalt_port_ops = { | ||
32 | .inherits = &ata_sff_port_ops, | ||
33 | .cable_detect = ata_cable_40wire, | ||
34 | /* No altstatus so we don't want to use the lost interrupt poll */ | ||
35 | .lost_interrupt = ATA_OP_NULL, | ||
36 | }; | ||
37 | |||
31 | /** | 38 | /** |
32 | * isapnp_init_one - attach an isapnp interface | 39 | * isapnp_init_one - attach an isapnp interface |
33 | * @idev: PnP device | 40 | * @idev: PnP device |
@@ -65,8 +72,8 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev | |||
65 | 72 | ||
66 | ap = host->ports[0]; | 73 | ap = host->ports[0]; |
67 | 74 | ||
68 | ap->ops = &isapnp_port_ops; | 75 | ap->ops = &isapnp_noalt_port_ops; |
69 | ap->pio_mask = 1; | 76 | ap->pio_mask = ATA_PIO0; |
70 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 77 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
71 | 78 | ||
72 | ap->ioaddr.cmd_addr = cmd_addr; | 79 | ap->ioaddr.cmd_addr = cmd_addr; |
@@ -76,6 +83,7 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev | |||
76 | pnp_port_start(idev, 1), 1); | 83 | pnp_port_start(idev, 1), 1); |
77 | ap->ioaddr.altstatus_addr = ctl_addr; | 84 | ap->ioaddr.altstatus_addr = ctl_addr; |
78 | ap->ioaddr.ctl_addr = ctl_addr; | 85 | ap->ioaddr.ctl_addr = ctl_addr; |
86 | ap->ops = &isapnp_port_ops; | ||
79 | } | 87 | } |
80 | 88 | ||
81 | ata_sff_std_ports(&ap->ioaddr); | 89 | ata_sff_std_ports(&ap->ioaddr); |
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index c113d7c079c8..f156da8076f7 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c | |||
@@ -262,8 +262,8 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en | |||
262 | static int printed_version; | 262 | static int printed_version; |
263 | static const struct ata_port_info info = { | 263 | static const struct ata_port_info info = { |
264 | .flags = ATA_FLAG_SLAVE_POSS, | 264 | .flags = ATA_FLAG_SLAVE_POSS, |
265 | .pio_mask = 0x1f, /* pio0-4 */ | 265 | .pio_mask = ATA_PIO4, |
266 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 266 | .mwdma_mask = ATA_MWDMA2, |
267 | .udma_mask = ATA_UDMA4, /* FIXME: want UDMA 100? */ | 267 | .udma_mask = ATA_UDMA4, /* FIXME: want UDMA 100? */ |
268 | .port_ops = &it8213_ops, | 268 | .port_ops = &it8213_ops, |
269 | }; | 269 | }; |
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index b05b86a912c5..188bc2fcd22c 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
@@ -875,29 +875,29 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
875 | 875 | ||
876 | static const struct ata_port_info info_smart = { | 876 | static const struct ata_port_info info_smart = { |
877 | .flags = ATA_FLAG_SLAVE_POSS, | 877 | .flags = ATA_FLAG_SLAVE_POSS, |
878 | .pio_mask = 0x1f, | 878 | .pio_mask = ATA_PIO4, |
879 | .mwdma_mask = 0x07, | 879 | .mwdma_mask = ATA_MWDMA2, |
880 | .udma_mask = ATA_UDMA6, | 880 | .udma_mask = ATA_UDMA6, |
881 | .port_ops = &it821x_smart_port_ops | 881 | .port_ops = &it821x_smart_port_ops |
882 | }; | 882 | }; |
883 | static const struct ata_port_info info_passthru = { | 883 | static const struct ata_port_info info_passthru = { |
884 | .flags = ATA_FLAG_SLAVE_POSS, | 884 | .flags = ATA_FLAG_SLAVE_POSS, |
885 | .pio_mask = 0x1f, | 885 | .pio_mask = ATA_PIO4, |
886 | .mwdma_mask = 0x07, | 886 | .mwdma_mask = ATA_MWDMA2, |
887 | .udma_mask = ATA_UDMA6, | 887 | .udma_mask = ATA_UDMA6, |
888 | .port_ops = &it821x_passthru_port_ops | 888 | .port_ops = &it821x_passthru_port_ops |
889 | }; | 889 | }; |
890 | static const struct ata_port_info info_rdc = { | 890 | static const struct ata_port_info info_rdc = { |
891 | .flags = ATA_FLAG_SLAVE_POSS, | 891 | .flags = ATA_FLAG_SLAVE_POSS, |
892 | .pio_mask = 0x1f, | 892 | .pio_mask = ATA_PIO4, |
893 | .mwdma_mask = 0x07, | 893 | .mwdma_mask = ATA_MWDMA2, |
894 | .udma_mask = ATA_UDMA6, | 894 | .udma_mask = ATA_UDMA6, |
895 | .port_ops = &it821x_rdc_port_ops | 895 | .port_ops = &it821x_rdc_port_ops |
896 | }; | 896 | }; |
897 | static const struct ata_port_info info_rdc_11 = { | 897 | static const struct ata_port_info info_rdc_11 = { |
898 | .flags = ATA_FLAG_SLAVE_POSS, | 898 | .flags = ATA_FLAG_SLAVE_POSS, |
899 | .pio_mask = 0x1f, | 899 | .pio_mask = ATA_PIO4, |
900 | .mwdma_mask = 0x07, | 900 | .mwdma_mask = ATA_MWDMA2, |
901 | /* No UDMA */ | 901 | /* No UDMA */ |
902 | .port_ops = &it821x_rdc_port_ops | 902 | .port_ops = &it821x_rdc_port_ops |
903 | }; | 903 | }; |
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index b173c157ab00..19fdecf319a6 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c | |||
@@ -176,7 +176,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) | |||
176 | ap = host->ports[0]; | 176 | ap = host->ports[0]; |
177 | 177 | ||
178 | ap->ops = &ixp4xx_port_ops; | 178 | ap->ops = &ixp4xx_port_ops; |
179 | ap->pio_mask = 0x1f; /* PIO4 */ | 179 | ap->pio_mask = ATA_PIO4; |
180 | ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI; | 180 | ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI; |
181 | 181 | ||
182 | ixp4xx_setup_port(ap, data, cs0->start, cs1->start); | 182 | ixp4xx_setup_port(ap, data, cs0->start, cs1->start); |
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 38cf1ab2d289..3a1474ac8838 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c | |||
@@ -136,8 +136,8 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i | |||
136 | static const struct ata_port_info info = { | 136 | static const struct ata_port_info info = { |
137 | .flags = ATA_FLAG_SLAVE_POSS, | 137 | .flags = ATA_FLAG_SLAVE_POSS, |
138 | 138 | ||
139 | .pio_mask = 0x1f, | 139 | .pio_mask = ATA_PIO4, |
140 | .mwdma_mask = 0x07, | 140 | .mwdma_mask = ATA_MWDMA2, |
141 | .udma_mask = ATA_UDMA5, | 141 | .udma_mask = ATA_UDMA5, |
142 | 142 | ||
143 | .port_ops = &jmicron_ops, | 143 | .port_ops = &jmicron_ops, |
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index e3bc1b436284..3f830f0fe2cc 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -129,7 +129,7 @@ static int qdi; /* Set to probe QDI controllers */ | |||
129 | static int winbond; /* Set to probe Winbond controllers, | 129 | static int winbond; /* Set to probe Winbond controllers, |
130 | give I/O port if non standard */ | 130 | give I/O port if non standard */ |
131 | static int autospeed; /* Chip present which snoops speed changes */ | 131 | static int autospeed; /* Chip present which snoops speed changes */ |
132 | static int pio_mask = 0x1F; /* PIO range for autospeed devices */ | 132 | static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ |
133 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ | 133 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ |
134 | 134 | ||
135 | /** | 135 | /** |
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 76e399bf8c1b..2096fb737f82 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c | |||
@@ -126,8 +126,8 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i | |||
126 | static const struct ata_port_info info = { | 126 | static const struct ata_port_info info = { |
127 | .flags = ATA_FLAG_SLAVE_POSS, | 127 | .flags = ATA_FLAG_SLAVE_POSS, |
128 | 128 | ||
129 | .pio_mask = 0x1f, | 129 | .pio_mask = ATA_PIO4, |
130 | .mwdma_mask = 0x07, | 130 | .mwdma_mask = ATA_MWDMA2, |
131 | .udma_mask = ATA_UDMA5, | 131 | .udma_mask = ATA_UDMA5, |
132 | 132 | ||
133 | .port_ops = &marvell_ops, | 133 | .port_ops = &marvell_ops, |
@@ -136,8 +136,8 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i | |||
136 | /* Slave possible as its magically mapped not real */ | 136 | /* Slave possible as its magically mapped not real */ |
137 | .flags = ATA_FLAG_SLAVE_POSS, | 137 | .flags = ATA_FLAG_SLAVE_POSS, |
138 | 138 | ||
139 | .pio_mask = 0x1f, | 139 | .pio_mask = ATA_PIO4, |
140 | .mwdma_mask = 0x07, | 140 | .mwdma_mask = ATA_MWDMA2, |
141 | .udma_mask = ATA_UDMA6, | 141 | .udma_mask = ATA_UDMA6, |
142 | 142 | ||
143 | .port_ops = &marvell_ops, | 143 | .port_ops = &marvell_ops, |
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 50ae6d13078a..68d27bc70d06 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c | |||
@@ -737,10 +737,10 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) | |||
737 | */ | 737 | */ |
738 | prop = of_get_property(op->node, "mwdma-mode", &proplen); | 738 | prop = of_get_property(op->node, "mwdma-mode", &proplen); |
739 | if ((prop) && (proplen >= 4)) | 739 | if ((prop) && (proplen >= 4)) |
740 | mwdma_mask = 0x7 & ((1 << (*prop + 1)) - 1); | 740 | mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1); |
741 | prop = of_get_property(op->node, "udma-mode", &proplen); | 741 | prop = of_get_property(op->node, "udma-mode", &proplen); |
742 | if ((prop) && (proplen >= 4)) | 742 | if ((prop) && (proplen >= 4)) |
743 | udma_mask = 0x7 & ((1 << (*prop + 1)) - 1); | 743 | udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1); |
744 | 744 | ||
745 | ata_irq = irq_of_parse_and_map(op->node, 0); | 745 | ata_irq = irq_of_parse_and_map(op->node, 0); |
746 | if (ata_irq == NO_IRQ) { | 746 | if (ata_irq == NO_IRQ) { |
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c index aa576cac4d17..b21f0021f54a 100644 --- a/drivers/ata/pata_mpiix.c +++ b/drivers/ata/pata_mpiix.c | |||
@@ -200,7 +200,7 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
200 | the MPIIX your box goes castors up */ | 200 | the MPIIX your box goes castors up */ |
201 | 201 | ||
202 | ap->ops = &mpiix_port_ops; | 202 | ap->ops = &mpiix_port_ops; |
203 | ap->pio_mask = 0x1F; | 203 | ap->pio_mask = ATA_PIO4; |
204 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 204 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
205 | 205 | ||
206 | ap->ioaddr.cmd_addr = cmd_addr; | 206 | ap->ioaddr.cmd_addr = cmd_addr; |
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index 9dc05e1656a8..bdb236957cb9 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c | |||
@@ -51,8 +51,8 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
51 | .flags = ATA_FLAG_SLAVE_POSS, | 51 | .flags = ATA_FLAG_SLAVE_POSS, |
52 | /* Actually we don't really care about these as the | 52 | /* Actually we don't really care about these as the |
53 | firmware deals with it */ | 53 | firmware deals with it */ |
54 | .pio_mask = 0x1f, /* pio0-4 */ | 54 | .pio_mask = ATA_PIO4, |
55 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 55 | .mwdma_mask = ATA_MWDMA2, |
56 | .udma_mask = ATA_UDMA5, /* UDMA 133 */ | 56 | .udma_mask = ATA_UDMA5, /* UDMA 133 */ |
57 | .port_ops = &netcell_ops, | 57 | .port_ops = &netcell_ops, |
58 | }; | 58 | }; |
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index 4dd9a3b031e4..0fb6b1b1e634 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c | |||
@@ -136,7 +136,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
136 | if (!base) | 136 | if (!base) |
137 | return -ENOMEM; | 137 | return -ENOMEM; |
138 | ap->ops = &ninja32_port_ops; | 138 | ap->ops = &ninja32_port_ops; |
139 | ap->pio_mask = 0x1F; | 139 | ap->pio_mask = ATA_PIO4; |
140 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 140 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
141 | 141 | ||
142 | ap->ioaddr.cmd_addr = base + 0x10; | 142 | ap->ioaddr.cmd_addr = base + 0x10; |
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index 40d411c460de..ca53fac06717 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c | |||
@@ -144,7 +144,7 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
144 | { | 144 | { |
145 | static const struct ata_port_info info = { | 145 | static const struct ata_port_info info = { |
146 | .flags = ATA_FLAG_SLAVE_POSS, | 146 | .flags = ATA_FLAG_SLAVE_POSS, |
147 | .pio_mask = 0x0F, | 147 | .pio_mask = ATA_PIO3, |
148 | .port_ops = &ns87410_port_ops | 148 | .port_ops = &ns87410_port_ops |
149 | }; | 149 | }; |
150 | const struct ata_port_info *ppi[] = { &info, NULL }; | 150 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index 89bf5f865d6a..773b1590b492 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c | |||
@@ -346,8 +346,8 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
346 | static int printed_version; | 346 | static int printed_version; |
347 | static const struct ata_port_info info = { | 347 | static const struct ata_port_info info = { |
348 | .flags = ATA_FLAG_SLAVE_POSS, | 348 | .flags = ATA_FLAG_SLAVE_POSS, |
349 | .pio_mask = 0x1f, /* pio0-4 */ | 349 | .pio_mask = ATA_PIO4, |
350 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 350 | .mwdma_mask = ATA_MWDMA2, |
351 | .port_ops = &ns87415_pata_ops, | 351 | .port_ops = &ns87415_pata_ops, |
352 | }; | 352 | }; |
353 | const struct ata_port_info *ppi[] = { &info, NULL }; | 353 | const struct ata_port_info *ppi[] = { &info, NULL }; |
@@ -355,8 +355,8 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
355 | #if defined(CONFIG_SUPERIO) | 355 | #if defined(CONFIG_SUPERIO) |
356 | static const struct ata_port_info info87560 = { | 356 | static const struct ata_port_info info87560 = { |
357 | .flags = ATA_FLAG_SLAVE_POSS, | 357 | .flags = ATA_FLAG_SLAVE_POSS, |
358 | .pio_mask = 0x1f, /* pio0-4 */ | 358 | .pio_mask = ATA_PIO4, |
359 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 359 | .mwdma_mask = ATA_MWDMA2, |
360 | .port_ops = &ns87560_pata_ops, | 360 | .port_ops = &ns87560_pata_ops, |
361 | }; | 361 | }; |
362 | 362 | ||
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 0fe4ef309c62..efe2c1985af3 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c | |||
@@ -871,7 +871,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev) | |||
871 | ap->private_data = cf_port; | 871 | ap->private_data = cf_port; |
872 | cf_port->ap = ap; | 872 | cf_port->ap = ap; |
873 | ap->ops = &octeon_cf_ops; | 873 | ap->ops = &octeon_cf_ops; |
874 | ap->pio_mask = 0x7f; /* Support PIO 0-6 */ | 874 | ap->pio_mask = ATA_PIO6; |
875 | ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | 875 | ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY |
876 | | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING; | 876 | | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING; |
877 | 877 | ||
@@ -900,7 +900,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev) | |||
900 | ap->ioaddr.ctl_addr = cs1 + (6 << 1) + 1; | 900 | ap->ioaddr.ctl_addr = cs1 + (6 << 1) + 1; |
901 | octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16; | 901 | octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16; |
902 | 902 | ||
903 | ap->mwdma_mask = 0x1f; /* Support MWDMA 0-4 */ | 903 | ap->mwdma_mask = ATA_MWDMA4; |
904 | irq = platform_get_irq(pdev, 0); | 904 | irq = platform_get_irq(pdev, 0); |
905 | irq_handler = octeon_cf_interrupt; | 905 | irq_handler = octeon_cf_interrupt; |
906 | 906 | ||
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index 2c1a91c40c1a..84ac5033ac89 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c | |||
@@ -238,8 +238,8 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
238 | static int printed_version; | 238 | static int printed_version; |
239 | static const struct ata_port_info info = { | 239 | static const struct ata_port_info info = { |
240 | .flags = ATA_FLAG_SLAVE_POSS, | 240 | .flags = ATA_FLAG_SLAVE_POSS, |
241 | .pio_mask = 0x1f, /* pio0-4 */ | 241 | .pio_mask = ATA_PIO4, |
242 | .mwdma_mask = 0x07, /* mwdma1-2 */ | 242 | .mwdma_mask = ATA_MWDMA2, |
243 | .port_ops = &oldpiix_pata_ops, | 243 | .port_ops = &oldpiix_pata_ops, |
244 | }; | 244 | }; |
245 | const struct ata_port_info *ppi[] = { &info, NULL }; | 245 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c index e4fa4d565e96..99eddda2d2e5 100644 --- a/drivers/ata/pata_opti.c +++ b/drivers/ata/pata_opti.c | |||
@@ -163,7 +163,7 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
163 | { | 163 | { |
164 | static const struct ata_port_info info = { | 164 | static const struct ata_port_info info = { |
165 | .flags = ATA_FLAG_SLAVE_POSS, | 165 | .flags = ATA_FLAG_SLAVE_POSS, |
166 | .pio_mask = 0x1f, | 166 | .pio_mask = ATA_PIO4, |
167 | .port_ops = &opti_port_ops | 167 | .port_ops = &opti_port_ops |
168 | }; | 168 | }; |
169 | const struct ata_port_info *ppi[] = { &info, NULL }; | 169 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index 93bb6e91973f..86885a445f97 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c | |||
@@ -399,15 +399,15 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
399 | { | 399 | { |
400 | static const struct ata_port_info info_82c700 = { | 400 | static const struct ata_port_info info_82c700 = { |
401 | .flags = ATA_FLAG_SLAVE_POSS, | 401 | .flags = ATA_FLAG_SLAVE_POSS, |
402 | .pio_mask = 0x1f, | 402 | .pio_mask = ATA_PIO4, |
403 | .mwdma_mask = 0x07, | 403 | .mwdma_mask = ATA_MWDMA2, |
404 | .port_ops = &optidma_port_ops | 404 | .port_ops = &optidma_port_ops |
405 | }; | 405 | }; |
406 | static const struct ata_port_info info_82c700_udma = { | 406 | static const struct ata_port_info info_82c700_udma = { |
407 | .flags = ATA_FLAG_SLAVE_POSS, | 407 | .flags = ATA_FLAG_SLAVE_POSS, |
408 | .pio_mask = 0x1f, | 408 | .pio_mask = ATA_PIO4, |
409 | .mwdma_mask = 0x07, | 409 | .mwdma_mask = ATA_MWDMA2, |
410 | .udma_mask = 0x07, | 410 | .udma_mask = ATA_UDMA2, |
411 | .port_ops = &optiplus_port_ops | 411 | .port_ops = &optiplus_port_ops |
412 | }; | 412 | }; |
413 | const struct ata_port_info *ppi[] = { &info_82c700, NULL }; | 413 | const struct ata_port_info *ppi[] = { &info_82c700, NULL }; |
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 64b2e2281ee7..f4d009ed50ac 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -42,7 +42,7 @@ | |||
42 | 42 | ||
43 | 43 | ||
44 | #define DRV_NAME "pata_pcmcia" | 44 | #define DRV_NAME "pata_pcmcia" |
45 | #define DRV_VERSION "0.3.3" | 45 | #define DRV_VERSION "0.3.5" |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * Private data structure to glue stuff together | 48 | * Private data structure to glue stuff together |
@@ -126,6 +126,37 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev, | |||
126 | return buflen; | 126 | return buflen; |
127 | } | 127 | } |
128 | 128 | ||
129 | /** | ||
130 | * pcmcia_8bit_drain_fifo - Stock FIFO drain logic for SFF controllers | ||
131 | * @qc: command | ||
132 | * | ||
133 | * Drain the FIFO and device of any stuck data following a command | ||
134 | * failing to complete. In some cases this is neccessary before a | ||
135 | * reset will recover the device. | ||
136 | * | ||
137 | */ | ||
138 | |||
139 | void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc) | ||
140 | { | ||
141 | int count; | ||
142 | struct ata_port *ap; | ||
143 | |||
144 | /* We only need to flush incoming data when a command was running */ | ||
145 | if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE) | ||
146 | return; | ||
147 | |||
148 | ap = qc->ap; | ||
149 | |||
150 | /* Drain up to 64K of data before we give up this recovery method */ | ||
151 | for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) | ||
152 | && count++ < 65536;) | ||
153 | ioread8(ap->ioaddr.data_addr); | ||
154 | |||
155 | if (count) | ||
156 | ata_port_printk(ap, KERN_WARNING, "drained %d bytes to clear DRQ.\n", | ||
157 | count); | ||
158 | |||
159 | } | ||
129 | 160 | ||
130 | static struct scsi_host_template pcmcia_sht = { | 161 | static struct scsi_host_template pcmcia_sht = { |
131 | ATA_PIO_SHT(DRV_NAME), | 162 | ATA_PIO_SHT(DRV_NAME), |
@@ -143,6 +174,7 @@ static struct ata_port_operations pcmcia_8bit_port_ops = { | |||
143 | .sff_data_xfer = ata_data_xfer_8bit, | 174 | .sff_data_xfer = ata_data_xfer_8bit, |
144 | .cable_detect = ata_cable_40wire, | 175 | .cable_detect = ata_cable_40wire, |
145 | .set_mode = pcmcia_set_mode_8bit, | 176 | .set_mode = pcmcia_set_mode_8bit, |
177 | .drain_fifo = pcmcia_8bit_drain_fifo, | ||
146 | }; | 178 | }; |
147 | 179 | ||
148 | #define CS_CHECK(fn, ret) \ | 180 | #define CS_CHECK(fn, ret) \ |
@@ -299,7 +331,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) | |||
299 | ap = host->ports[p]; | 331 | ap = host->ports[p]; |
300 | 332 | ||
301 | ap->ops = ops; | 333 | ap->ops = ops; |
302 | ap->pio_mask = 1; /* ISA so PIO 0 cycles */ | 334 | ap->pio_mask = ATA_PIO0; /* ISA so PIO 0 cycles */ |
303 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 335 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
304 | ap->ioaddr.cmd_addr = io_addr + 0x10 * p; | 336 | ap->ioaddr.cmd_addr = io_addr + 0x10 * p; |
305 | ap->ioaddr.altstatus_addr = ctl_addr + 0x10 * p; | 337 | ap->ioaddr.altstatus_addr = ctl_addr + 0x10 * p; |
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index e94efccaa482..ca5cad0fd80b 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c | |||
@@ -152,18 +152,18 @@ static struct ata_port_info pdc2027x_port_info[] = { | |||
152 | { | 152 | { |
153 | .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | | 153 | .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | |
154 | ATA_FLAG_MMIO, | 154 | ATA_FLAG_MMIO, |
155 | .pio_mask = 0x1f, /* pio0-4 */ | 155 | .pio_mask = ATA_PIO4, |
156 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 156 | .mwdma_mask = ATA_MWDMA2, |
157 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 157 | .udma_mask = ATA_UDMA5, |
158 | .port_ops = &pdc2027x_pata100_ops, | 158 | .port_ops = &pdc2027x_pata100_ops, |
159 | }, | 159 | }, |
160 | /* PDC_UDMA_133 */ | 160 | /* PDC_UDMA_133 */ |
161 | { | 161 | { |
162 | .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | | 162 | .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | |
163 | ATA_FLAG_MMIO, | 163 | ATA_FLAG_MMIO, |
164 | .pio_mask = 0x1f, /* pio0-4 */ | 164 | .pio_mask = ATA_PIO4, |
165 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 165 | .mwdma_mask = ATA_MWDMA2, |
166 | .udma_mask = ATA_UDMA6, /* udma0-6 */ | 166 | .udma_mask = ATA_UDMA6, |
167 | .port_ops = &pdc2027x_pata133_ops, | 167 | .port_ops = &pdc2027x_pata133_ops, |
168 | }, | 168 | }, |
169 | }; | 169 | }; |
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 799a6a098712..5fedb3d4032b 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c | |||
@@ -291,22 +291,22 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id | |||
291 | static const struct ata_port_info info[3] = { | 291 | static const struct ata_port_info info[3] = { |
292 | { | 292 | { |
293 | .flags = ATA_FLAG_SLAVE_POSS, | 293 | .flags = ATA_FLAG_SLAVE_POSS, |
294 | .pio_mask = 0x1f, | 294 | .pio_mask = ATA_PIO4, |
295 | .mwdma_mask = 0x07, | 295 | .mwdma_mask = ATA_MWDMA2, |
296 | .udma_mask = ATA_UDMA2, | 296 | .udma_mask = ATA_UDMA2, |
297 | .port_ops = &pdc2024x_port_ops | 297 | .port_ops = &pdc2024x_port_ops |
298 | }, | 298 | }, |
299 | { | 299 | { |
300 | .flags = ATA_FLAG_SLAVE_POSS, | 300 | .flags = ATA_FLAG_SLAVE_POSS, |
301 | .pio_mask = 0x1f, | 301 | .pio_mask = ATA_PIO4, |
302 | .mwdma_mask = 0x07, | 302 | .mwdma_mask = ATA_MWDMA2, |
303 | .udma_mask = ATA_UDMA4, | 303 | .udma_mask = ATA_UDMA4, |
304 | .port_ops = &pdc2026x_port_ops | 304 | .port_ops = &pdc2026x_port_ops |
305 | }, | 305 | }, |
306 | { | 306 | { |
307 | .flags = ATA_FLAG_SLAVE_POSS, | 307 | .flags = ATA_FLAG_SLAVE_POSS, |
308 | .pio_mask = 0x1f, | 308 | .pio_mask = ATA_PIO4, |
309 | .mwdma_mask = 0x07, | 309 | .mwdma_mask = ATA_MWDMA2, |
310 | .udma_mask = ATA_UDMA5, | 310 | .udma_mask = ATA_UDMA5, |
311 | .port_ops = &pdc2026x_port_ops | 311 | .port_ops = &pdc2026x_port_ops |
312 | } | 312 | } |
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index f1b26f7c8e4d..45879dc6fa41 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c | |||
@@ -212,11 +212,11 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i | |||
212 | 212 | ||
213 | if (type == 6580) { | 213 | if (type == 6580) { |
214 | ap->ops = &qdi6580_port_ops; | 214 | ap->ops = &qdi6580_port_ops; |
215 | ap->pio_mask = 0x1F; | 215 | ap->pio_mask = ATA_PIO4; |
216 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 216 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
217 | } else { | 217 | } else { |
218 | ap->ops = &qdi6500_port_ops; | 218 | ap->ops = &qdi6500_port_ops; |
219 | ap->pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */ | 219 | ap->pio_mask = ATA_PIO2; /* Actually PIO3 !IORDY is possible */ |
220 | ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY; | 220 | ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY; |
221 | } | 221 | } |
222 | 222 | ||
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index 695d44ae52c6..4401b332eaab 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c | |||
@@ -216,9 +216,9 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
216 | static int printed_version; | 216 | static int printed_version; |
217 | static const struct ata_port_info info = { | 217 | static const struct ata_port_info info = { |
218 | .flags = ATA_FLAG_SLAVE_POSS, | 218 | .flags = ATA_FLAG_SLAVE_POSS, |
219 | .pio_mask = 0x1f, /* pio0-4 */ | 219 | .pio_mask = ATA_PIO4, |
220 | .mwdma_mask = 0x07, /* mwdma1-2 */ | 220 | .mwdma_mask = ATA_MWDMA12_ONLY, |
221 | .udma_mask = 0x14, /* UDMA33/66 only */ | 221 | .udma_mask = ATA_UDMA24_ONLY, |
222 | .port_ops = &radisys_pata_ops, | 222 | .port_ops = &radisys_pata_ops, |
223 | }; | 223 | }; |
224 | const struct ata_port_info *ppi[] = { &info, NULL }; | 224 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index ebfcda26d639..8e3cdef8a25f 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c | |||
@@ -48,63 +48,11 @@ | |||
48 | struct rb532_cf_info { | 48 | struct rb532_cf_info { |
49 | void __iomem *iobase; | 49 | void __iomem *iobase; |
50 | unsigned int gpio_line; | 50 | unsigned int gpio_line; |
51 | int frozen; | ||
52 | unsigned int irq; | 51 | unsigned int irq; |
53 | }; | 52 | }; |
54 | 53 | ||
55 | /* ------------------------------------------------------------------------ */ | 54 | /* ------------------------------------------------------------------------ */ |
56 | 55 | ||
57 | static inline void rb532_pata_finish_io(struct ata_port *ap) | ||
58 | { | ||
59 | struct ata_host *ah = ap->host; | ||
60 | struct rb532_cf_info *info = ah->private_data; | ||
61 | |||
62 | /* FIXME: Keep previous delay. If this is merely a fence then | ||
63 | ata_sff_sync might be sufficient. */ | ||
64 | ata_sff_dma_pause(ap); | ||
65 | ndelay(RB500_CF_IO_DELAY); | ||
66 | } | ||
67 | |||
68 | static void rb532_pata_exec_command(struct ata_port *ap, | ||
69 | const struct ata_taskfile *tf) | ||
70 | { | ||
71 | writeb(tf->command, ap->ioaddr.command_addr); | ||
72 | rb532_pata_finish_io(ap); | ||
73 | } | ||
74 | |||
75 | static unsigned int rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf, | ||
76 | unsigned int buflen, int write_data) | ||
77 | { | ||
78 | struct ata_port *ap = adev->link->ap; | ||
79 | void __iomem *ioaddr = ap->ioaddr.data_addr; | ||
80 | int retlen = buflen; | ||
81 | |||
82 | if (write_data) { | ||
83 | for (; buflen > 0; buflen--, buf++) | ||
84 | writeb(*buf, ioaddr); | ||
85 | } else { | ||
86 | for (; buflen > 0; buflen--, buf++) | ||
87 | *buf = readb(ioaddr); | ||
88 | } | ||
89 | |||
90 | rb532_pata_finish_io(adev->link->ap); | ||
91 | return retlen; | ||
92 | } | ||
93 | |||
94 | static void rb532_pata_freeze(struct ata_port *ap) | ||
95 | { | ||
96 | struct rb532_cf_info *info = ap->host->private_data; | ||
97 | |||
98 | info->frozen = 1; | ||
99 | } | ||
100 | |||
101 | static void rb532_pata_thaw(struct ata_port *ap) | ||
102 | { | ||
103 | struct rb532_cf_info *info = ap->host->private_data; | ||
104 | |||
105 | info->frozen = 0; | ||
106 | } | ||
107 | |||
108 | static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance) | 56 | static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance) |
109 | { | 57 | { |
110 | struct ata_host *ah = dev_instance; | 58 | struct ata_host *ah = dev_instance; |
@@ -112,8 +60,7 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance) | |||
112 | 60 | ||
113 | if (gpio_get_value(info->gpio_line)) { | 61 | if (gpio_get_value(info->gpio_line)) { |
114 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); | 62 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); |
115 | if (!info->frozen) | 63 | ata_sff_interrupt(info->irq, dev_instance); |
116 | ata_sff_interrupt(info->irq, dev_instance); | ||
117 | } else { | 64 | } else { |
118 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); | 65 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); |
119 | } | 66 | } |
@@ -123,10 +70,7 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance) | |||
123 | 70 | ||
124 | static struct ata_port_operations rb532_pata_port_ops = { | 71 | static struct ata_port_operations rb532_pata_port_ops = { |
125 | .inherits = &ata_sff_port_ops, | 72 | .inherits = &ata_sff_port_ops, |
126 | .sff_exec_command = rb532_pata_exec_command, | 73 | .sff_data_xfer = ata_sff_data_xfer32, |
127 | .sff_data_xfer = rb532_pata_data_xfer, | ||
128 | .freeze = rb532_pata_freeze, | ||
129 | .thaw = rb532_pata_thaw, | ||
130 | }; | 74 | }; |
131 | 75 | ||
132 | /* ------------------------------------------------------------------------ */ | 76 | /* ------------------------------------------------------------------------ */ |
@@ -145,7 +89,7 @@ static void rb532_pata_setup_ports(struct ata_host *ah) | |||
145 | ap = ah->ports[0]; | 89 | ap = ah->ports[0]; |
146 | 90 | ||
147 | ap->ops = &rb532_pata_port_ops; | 91 | ap->ops = &rb532_pata_port_ops; |
148 | ap->pio_mask = 0x1f; /* PIO4 */ | 92 | ap->pio_mask = ATA_PIO4; |
149 | ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; | 93 | ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; |
150 | 94 | ||
151 | ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_BASE; | 95 | ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_BASE; |
@@ -160,7 +104,7 @@ static void rb532_pata_setup_ports(struct ata_host *ah) | |||
160 | 104 | ||
161 | static __devinit int rb532_pata_driver_probe(struct platform_device *pdev) | 105 | static __devinit int rb532_pata_driver_probe(struct platform_device *pdev) |
162 | { | 106 | { |
163 | unsigned int irq; | 107 | int irq; |
164 | int gpio; | 108 | int gpio; |
165 | struct resource *res; | 109 | struct resource *res; |
166 | struct ata_host *ah; | 110 | struct ata_host *ah; |
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index 46d6bc1bf1e9..0c574c065c62 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c | |||
@@ -88,7 +88,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en | |||
88 | static int printed_version; | 88 | static int printed_version; |
89 | static const struct ata_port_info info = { | 89 | static const struct ata_port_info info = { |
90 | .flags = ATA_FLAG_SLAVE_POSS, | 90 | .flags = ATA_FLAG_SLAVE_POSS, |
91 | .pio_mask = 0x1f, | 91 | .pio_mask = ATA_PIO4, |
92 | .port_ops = &rz1000_port_ops | 92 | .port_ops = &rz1000_port_ops |
93 | }; | 93 | }; |
94 | const struct ata_port_info *ppi[] = { &info, NULL }; | 94 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 9a4bdca54616..f49814d6fd2e 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c | |||
@@ -2,7 +2,6 @@ | |||
2 | * New ATA layer SC1200 driver Alan Cox <alan@lxorguk.ukuu.org.uk> | 2 | * New ATA layer SC1200 driver Alan Cox <alan@lxorguk.ukuu.org.uk> |
3 | * | 3 | * |
4 | * TODO: Mode selection filtering | 4 | * TODO: Mode selection filtering |
5 | * TODO: Can't enable second channel until ATA core has serialize | ||
6 | * TODO: Needs custom DMA cleanup code | 5 | * TODO: Needs custom DMA cleanup code |
7 | * | 6 | * |
8 | * Based very heavily on | 7 | * Based very heavily on |
@@ -178,6 +177,31 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc) | |||
178 | return ata_sff_qc_issue(qc); | 177 | return ata_sff_qc_issue(qc); |
179 | } | 178 | } |
180 | 179 | ||
180 | /** | ||
181 | * sc1200_qc_defer - implement serialization | ||
182 | * @qc: command | ||
183 | * | ||
184 | * Serialize command issue on this controller. | ||
185 | */ | ||
186 | |||
187 | static int sc1200_qc_defer(struct ata_queued_cmd *qc) | ||
188 | { | ||
189 | struct ata_host *host = qc->ap->host; | ||
190 | struct ata_port *alt = host->ports[1 ^ qc->ap->port_no]; | ||
191 | int rc; | ||
192 | |||
193 | /* First apply the usual rules */ | ||
194 | rc = ata_std_qc_defer(qc); | ||
195 | if (rc != 0) | ||
196 | return rc; | ||
197 | |||
198 | /* Now apply serialization rules. Only allow a command if the | ||
199 | other channel state machine is idle */ | ||
200 | if (alt && alt->qc_active) | ||
201 | return ATA_DEFER_PORT; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
181 | static struct scsi_host_template sc1200_sht = { | 205 | static struct scsi_host_template sc1200_sht = { |
182 | ATA_BMDMA_SHT(DRV_NAME), | 206 | ATA_BMDMA_SHT(DRV_NAME), |
183 | .sg_tablesize = LIBATA_DUMB_MAX_PRD, | 207 | .sg_tablesize = LIBATA_DUMB_MAX_PRD, |
@@ -187,6 +211,7 @@ static struct ata_port_operations sc1200_port_ops = { | |||
187 | .inherits = &ata_bmdma_port_ops, | 211 | .inherits = &ata_bmdma_port_ops, |
188 | .qc_prep = ata_sff_dumb_qc_prep, | 212 | .qc_prep = ata_sff_dumb_qc_prep, |
189 | .qc_issue = sc1200_qc_issue, | 213 | .qc_issue = sc1200_qc_issue, |
214 | .qc_defer = sc1200_qc_defer, | ||
190 | .cable_detect = ata_cable_40wire, | 215 | .cable_detect = ata_cable_40wire, |
191 | .set_piomode = sc1200_set_piomode, | 216 | .set_piomode = sc1200_set_piomode, |
192 | .set_dmamode = sc1200_set_dmamode, | 217 | .set_dmamode = sc1200_set_dmamode, |
@@ -205,13 +230,13 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
205 | { | 230 | { |
206 | static const struct ata_port_info info = { | 231 | static const struct ata_port_info info = { |
207 | .flags = ATA_FLAG_SLAVE_POSS, | 232 | .flags = ATA_FLAG_SLAVE_POSS, |
208 | .pio_mask = 0x1f, | 233 | .pio_mask = ATA_PIO4, |
209 | .mwdma_mask = 0x07, | 234 | .mwdma_mask = ATA_MWDMA2, |
210 | .udma_mask = 0x07, | 235 | .udma_mask = ATA_UDMA2, |
211 | .port_ops = &sc1200_port_ops | 236 | .port_ops = &sc1200_port_ops |
212 | }; | 237 | }; |
213 | /* Can't enable port 2 yet, see top comments */ | 238 | /* Can't enable port 2 yet, see top comments */ |
214 | const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; | 239 | const struct ata_port_info *ppi[] = { &info, }; |
215 | 240 | ||
216 | return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL); | 241 | return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL); |
217 | } | 242 | } |
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index d447f1cb46ec..4257d6b40af4 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
@@ -1001,8 +1001,8 @@ static struct ata_port_operations scc_pata_ops = { | |||
1001 | static struct ata_port_info scc_port_info[] = { | 1001 | static struct ata_port_info scc_port_info[] = { |
1002 | { | 1002 | { |
1003 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY, | 1003 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY, |
1004 | .pio_mask = 0x1f, /* pio0-4 */ | 1004 | .pio_mask = ATA_PIO4, |
1005 | .mwdma_mask = 0x00, | 1005 | /* No MWDMA */ |
1006 | .udma_mask = ATA_UDMA6, | 1006 | .udma_mask = ATA_UDMA6, |
1007 | .port_ops = &scc_pata_ops, | 1007 | .port_ops = &scc_pata_ops, |
1008 | }, | 1008 | }, |
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c index 6aeeeeb34124..99cceb458e2a 100644 --- a/drivers/ata/pata_sch.c +++ b/drivers/ata/pata_sch.c | |||
@@ -84,9 +84,9 @@ static struct ata_port_operations sch_pata_ops = { | |||
84 | 84 | ||
85 | static struct ata_port_info sch_port_info = { | 85 | static struct ata_port_info sch_port_info = { |
86 | .flags = ATA_FLAG_SLAVE_POSS, | 86 | .flags = ATA_FLAG_SLAVE_POSS, |
87 | .pio_mask = ATA_PIO4, /* pio0-4 */ | 87 | .pio_mask = ATA_PIO4, |
88 | .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */ | 88 | .mwdma_mask = ATA_MWDMA2, |
89 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 89 | .udma_mask = ATA_UDMA5, |
90 | .port_ops = &sch_pata_ops, | 90 | .port_ops = &sch_pata_ops, |
91 | }; | 91 | }; |
92 | 92 | ||
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 8d2fd9dd40c7..beaed12d50e4 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c | |||
@@ -398,26 +398,26 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id | |||
398 | static const struct ata_port_info info[4] = { | 398 | static const struct ata_port_info info[4] = { |
399 | { /* OSB4 */ | 399 | { /* OSB4 */ |
400 | .flags = ATA_FLAG_SLAVE_POSS, | 400 | .flags = ATA_FLAG_SLAVE_POSS, |
401 | .pio_mask = 0x1f, | 401 | .pio_mask = ATA_PIO4, |
402 | .mwdma_mask = 0x07, | 402 | .mwdma_mask = ATA_MWDMA2, |
403 | .udma_mask = 0x07, | 403 | .udma_mask = ATA_UDMA2, |
404 | .port_ops = &serverworks_osb4_port_ops | 404 | .port_ops = &serverworks_osb4_port_ops |
405 | }, { /* OSB4 no UDMA */ | 405 | }, { /* OSB4 no UDMA */ |
406 | .flags = ATA_FLAG_SLAVE_POSS, | 406 | .flags = ATA_FLAG_SLAVE_POSS, |
407 | .pio_mask = 0x1f, | 407 | .pio_mask = ATA_PIO4, |
408 | .mwdma_mask = 0x07, | 408 | .mwdma_mask = ATA_MWDMA2, |
409 | .udma_mask = 0x00, | 409 | /* No UDMA */ |
410 | .port_ops = &serverworks_osb4_port_ops | 410 | .port_ops = &serverworks_osb4_port_ops |
411 | }, { /* CSB5 */ | 411 | }, { /* CSB5 */ |
412 | .flags = ATA_FLAG_SLAVE_POSS, | 412 | .flags = ATA_FLAG_SLAVE_POSS, |
413 | .pio_mask = 0x1f, | 413 | .pio_mask = ATA_PIO4, |
414 | .mwdma_mask = 0x07, | 414 | .mwdma_mask = ATA_MWDMA2, |
415 | .udma_mask = ATA_UDMA4, | 415 | .udma_mask = ATA_UDMA4, |
416 | .port_ops = &serverworks_csb_port_ops | 416 | .port_ops = &serverworks_csb_port_ops |
417 | }, { /* CSB5 - later revisions*/ | 417 | }, { /* CSB5 - later revisions*/ |
418 | .flags = ATA_FLAG_SLAVE_POSS, | 418 | .flags = ATA_FLAG_SLAVE_POSS, |
419 | .pio_mask = 0x1f, | 419 | .pio_mask = ATA_PIO4, |
420 | .mwdma_mask = 0x07, | 420 | .mwdma_mask = ATA_MWDMA2, |
421 | .udma_mask = ATA_UDMA5, | 421 | .udma_mask = ATA_UDMA5, |
422 | .port_ops = &serverworks_csb_port_ops | 422 | .port_ops = &serverworks_csb_port_ops |
423 | } | 423 | } |
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 9e764e5747e6..4cb649d8d38c 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c | |||
@@ -282,15 +282,15 @@ static int __devinit sil680_init_one(struct pci_dev *pdev, | |||
282 | { | 282 | { |
283 | static const struct ata_port_info info = { | 283 | static const struct ata_port_info info = { |
284 | .flags = ATA_FLAG_SLAVE_POSS, | 284 | .flags = ATA_FLAG_SLAVE_POSS, |
285 | .pio_mask = 0x1f, | 285 | .pio_mask = ATA_PIO4, |
286 | .mwdma_mask = 0x07, | 286 | .mwdma_mask = ATA_MWDMA2, |
287 | .udma_mask = ATA_UDMA6, | 287 | .udma_mask = ATA_UDMA6, |
288 | .port_ops = &sil680_port_ops | 288 | .port_ops = &sil680_port_ops |
289 | }; | 289 | }; |
290 | static const struct ata_port_info info_slow = { | 290 | static const struct ata_port_info info_slow = { |
291 | .flags = ATA_FLAG_SLAVE_POSS, | 291 | .flags = ATA_FLAG_SLAVE_POSS, |
292 | .pio_mask = 0x1f, | 292 | .pio_mask = ATA_PIO4, |
293 | .mwdma_mask = 0x07, | 293 | .mwdma_mask = ATA_MWDMA2, |
294 | .udma_mask = ATA_UDMA5, | 294 | .udma_mask = ATA_UDMA5, |
295 | .port_ops = &sil680_port_ops | 295 | .port_ops = &sil680_port_ops |
296 | }; | 296 | }; |
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 27ceb42a774b..488e77bcd22b 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c | |||
@@ -552,51 +552,57 @@ static struct ata_port_operations sis_old_ops = { | |||
552 | 552 | ||
553 | static const struct ata_port_info sis_info = { | 553 | static const struct ata_port_info sis_info = { |
554 | .flags = ATA_FLAG_SLAVE_POSS, | 554 | .flags = ATA_FLAG_SLAVE_POSS, |
555 | .pio_mask = 0x1f, /* pio0-4 */ | 555 | .pio_mask = ATA_PIO4, |
556 | .mwdma_mask = 0x07, | 556 | .mwdma_mask = ATA_MWDMA2, |
557 | .udma_mask = 0, | 557 | /* No UDMA */ |
558 | .port_ops = &sis_old_ops, | 558 | .port_ops = &sis_old_ops, |
559 | }; | 559 | }; |
560 | static const struct ata_port_info sis_info33 = { | 560 | static const struct ata_port_info sis_info33 = { |
561 | .flags = ATA_FLAG_SLAVE_POSS, | 561 | .flags = ATA_FLAG_SLAVE_POSS, |
562 | .pio_mask = 0x1f, /* pio0-4 */ | 562 | .pio_mask = ATA_PIO4, |
563 | .mwdma_mask = 0x07, | 563 | .mwdma_mask = ATA_MWDMA2, |
564 | .udma_mask = ATA_UDMA2, /* UDMA 33 */ | 564 | .udma_mask = ATA_UDMA2, |
565 | .port_ops = &sis_old_ops, | 565 | .port_ops = &sis_old_ops, |
566 | }; | 566 | }; |
567 | static const struct ata_port_info sis_info66 = { | 567 | static const struct ata_port_info sis_info66 = { |
568 | .flags = ATA_FLAG_SLAVE_POSS, | 568 | .flags = ATA_FLAG_SLAVE_POSS, |
569 | .pio_mask = 0x1f, /* pio0-4 */ | 569 | .pio_mask = ATA_PIO4, |
570 | .udma_mask = ATA_UDMA4, /* UDMA 66 */ | 570 | /* No MWDMA */ |
571 | .udma_mask = ATA_UDMA4, | ||
571 | .port_ops = &sis_66_ops, | 572 | .port_ops = &sis_66_ops, |
572 | }; | 573 | }; |
573 | static const struct ata_port_info sis_info100 = { | 574 | static const struct ata_port_info sis_info100 = { |
574 | .flags = ATA_FLAG_SLAVE_POSS, | 575 | .flags = ATA_FLAG_SLAVE_POSS, |
575 | .pio_mask = 0x1f, /* pio0-4 */ | 576 | .pio_mask = ATA_PIO4, |
577 | /* No MWDMA */ | ||
576 | .udma_mask = ATA_UDMA5, | 578 | .udma_mask = ATA_UDMA5, |
577 | .port_ops = &sis_100_ops, | 579 | .port_ops = &sis_100_ops, |
578 | }; | 580 | }; |
579 | static const struct ata_port_info sis_info100_early = { | 581 | static const struct ata_port_info sis_info100_early = { |
580 | .flags = ATA_FLAG_SLAVE_POSS, | 582 | .flags = ATA_FLAG_SLAVE_POSS, |
583 | .pio_mask = ATA_PIO4, | ||
584 | /* No MWDMA */ | ||
581 | .udma_mask = ATA_UDMA5, | 585 | .udma_mask = ATA_UDMA5, |
582 | .pio_mask = 0x1f, /* pio0-4 */ | ||
583 | .port_ops = &sis_66_ops, | 586 | .port_ops = &sis_66_ops, |
584 | }; | 587 | }; |
585 | static const struct ata_port_info sis_info133 = { | 588 | static const struct ata_port_info sis_info133 = { |
586 | .flags = ATA_FLAG_SLAVE_POSS, | 589 | .flags = ATA_FLAG_SLAVE_POSS, |
587 | .pio_mask = 0x1f, /* pio0-4 */ | 590 | .pio_mask = ATA_PIO4, |
591 | /* No MWDMA */ | ||
588 | .udma_mask = ATA_UDMA6, | 592 | .udma_mask = ATA_UDMA6, |
589 | .port_ops = &sis_133_ops, | 593 | .port_ops = &sis_133_ops, |
590 | }; | 594 | }; |
591 | const struct ata_port_info sis_info133_for_sata = { | 595 | const struct ata_port_info sis_info133_for_sata = { |
592 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, | 596 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, |
593 | .pio_mask = 0x1f, /* pio0-4 */ | 597 | .pio_mask = ATA_PIO4, |
598 | /* No MWDMA */ | ||
594 | .udma_mask = ATA_UDMA6, | 599 | .udma_mask = ATA_UDMA6, |
595 | .port_ops = &sis_133_for_sata_ops, | 600 | .port_ops = &sis_133_for_sata_ops, |
596 | }; | 601 | }; |
597 | static const struct ata_port_info sis_info133_early = { | 602 | static const struct ata_port_info sis_info133_early = { |
598 | .flags = ATA_FLAG_SLAVE_POSS, | 603 | .flags = ATA_FLAG_SLAVE_POSS, |
599 | .pio_mask = 0x1f, /* pio0-4 */ | 604 | .pio_mask = ATA_PIO4, |
605 | /* No MWDMA */ | ||
600 | .udma_mask = ATA_UDMA6, | 606 | .udma_mask = ATA_UDMA6, |
601 | .port_ops = &sis_133_early_ops, | 607 | .port_ops = &sis_133_early_ops, |
602 | }; | 608 | }; |
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 1b0e7b6d8ef5..29f733c32066 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c | |||
@@ -283,13 +283,13 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id | |||
283 | { | 283 | { |
284 | static const struct ata_port_info info_dma = { | 284 | static const struct ata_port_info info_dma = { |
285 | .flags = ATA_FLAG_SLAVE_POSS, | 285 | .flags = ATA_FLAG_SLAVE_POSS, |
286 | .pio_mask = 0x1f, | 286 | .pio_mask = ATA_PIO4, |
287 | .mwdma_mask = 0x07, | 287 | .mwdma_mask = ATA_MWDMA2, |
288 | .port_ops = &sl82c105_port_ops | 288 | .port_ops = &sl82c105_port_ops |
289 | }; | 289 | }; |
290 | static const struct ata_port_info info_early = { | 290 | static const struct ata_port_info info_early = { |
291 | .flags = ATA_FLAG_SLAVE_POSS, | 291 | .flags = ATA_FLAG_SLAVE_POSS, |
292 | .pio_mask = 0x1f, | 292 | .pio_mask = ATA_PIO4, |
293 | .port_ops = &sl82c105_port_ops | 293 | .port_ops = &sl82c105_port_ops |
294 | }; | 294 | }; |
295 | /* for now use only the first port */ | 295 | /* for now use only the first port */ |
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index ef9597517cdd..f1f13ff222fd 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c | |||
@@ -191,8 +191,8 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
191 | { | 191 | { |
192 | static const struct ata_port_info info = { | 192 | static const struct ata_port_info info = { |
193 | .flags = ATA_FLAG_SLAVE_POSS, | 193 | .flags = ATA_FLAG_SLAVE_POSS, |
194 | .pio_mask = 0x1f, | 194 | .pio_mask = ATA_PIO4, |
195 | .mwdma_mask = 0x07, | 195 | .mwdma_mask = ATA_MWDMA2, |
196 | .port_ops = &triflex_port_ops | 196 | .port_ops = &triflex_port_ops |
197 | }; | 197 | }; |
198 | const struct ata_port_info *ppi[] = { &info, NULL }; | 198 | const struct ata_port_info *ppi[] = { &info, NULL }; |
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index ba556d3e6963..b08e6e0f82b6 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -422,46 +422,46 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
422 | /* Early VIA without UDMA support */ | 422 | /* Early VIA without UDMA support */ |
423 | static const struct ata_port_info via_mwdma_info = { | 423 | static const struct ata_port_info via_mwdma_info = { |
424 | .flags = ATA_FLAG_SLAVE_POSS, | 424 | .flags = ATA_FLAG_SLAVE_POSS, |
425 | .pio_mask = 0x1f, | 425 | .pio_mask = ATA_PIO4, |
426 | .mwdma_mask = 0x07, | 426 | .mwdma_mask = ATA_MWDMA2, |
427 | .port_ops = &via_port_ops | 427 | .port_ops = &via_port_ops |
428 | }; | 428 | }; |
429 | /* Ditto with IRQ masking required */ | 429 | /* Ditto with IRQ masking required */ |
430 | static const struct ata_port_info via_mwdma_info_borked = { | 430 | static const struct ata_port_info via_mwdma_info_borked = { |
431 | .flags = ATA_FLAG_SLAVE_POSS, | 431 | .flags = ATA_FLAG_SLAVE_POSS, |
432 | .pio_mask = 0x1f, | 432 | .pio_mask = ATA_PIO4, |
433 | .mwdma_mask = 0x07, | 433 | .mwdma_mask = ATA_MWDMA2, |
434 | .port_ops = &via_port_ops_noirq, | 434 | .port_ops = &via_port_ops_noirq, |
435 | }; | 435 | }; |
436 | /* VIA UDMA 33 devices (and borked 66) */ | 436 | /* VIA UDMA 33 devices (and borked 66) */ |
437 | static const struct ata_port_info via_udma33_info = { | 437 | static const struct ata_port_info via_udma33_info = { |
438 | .flags = ATA_FLAG_SLAVE_POSS, | 438 | .flags = ATA_FLAG_SLAVE_POSS, |
439 | .pio_mask = 0x1f, | 439 | .pio_mask = ATA_PIO4, |
440 | .mwdma_mask = 0x07, | 440 | .mwdma_mask = ATA_MWDMA2, |
441 | .udma_mask = ATA_UDMA2, | 441 | .udma_mask = ATA_UDMA2, |
442 | .port_ops = &via_port_ops | 442 | .port_ops = &via_port_ops |
443 | }; | 443 | }; |
444 | /* VIA UDMA 66 devices */ | 444 | /* VIA UDMA 66 devices */ |
445 | static const struct ata_port_info via_udma66_info = { | 445 | static const struct ata_port_info via_udma66_info = { |
446 | .flags = ATA_FLAG_SLAVE_POSS, | 446 | .flags = ATA_FLAG_SLAVE_POSS, |
447 | .pio_mask = 0x1f, | 447 | .pio_mask = ATA_PIO4, |
448 | .mwdma_mask = 0x07, | 448 | .mwdma_mask = ATA_MWDMA2, |
449 | .udma_mask = ATA_UDMA4, | 449 | .udma_mask = ATA_UDMA4, |
450 | .port_ops = &via_port_ops | 450 | .port_ops = &via_port_ops |
451 | }; | 451 | }; |
452 | /* VIA UDMA 100 devices */ | 452 | /* VIA UDMA 100 devices */ |
453 | static const struct ata_port_info via_udma100_info = { | 453 | static const struct ata_port_info via_udma100_info = { |
454 | .flags = ATA_FLAG_SLAVE_POSS, | 454 | .flags = ATA_FLAG_SLAVE_POSS, |
455 | .pio_mask = 0x1f, | 455 | .pio_mask = ATA_PIO4, |
456 | .mwdma_mask = 0x07, | 456 | .mwdma_mask = ATA_MWDMA2, |
457 | .udma_mask = ATA_UDMA5, | 457 | .udma_mask = ATA_UDMA5, |
458 | .port_ops = &via_port_ops | 458 | .port_ops = &via_port_ops |
459 | }; | 459 | }; |
460 | /* UDMA133 with bad AST (All current 133) */ | 460 | /* UDMA133 with bad AST (All current 133) */ |
461 | static const struct ata_port_info via_udma133_info = { | 461 | static const struct ata_port_info via_udma133_info = { |
462 | .flags = ATA_FLAG_SLAVE_POSS, | 462 | .flags = ATA_FLAG_SLAVE_POSS, |
463 | .pio_mask = 0x1f, | 463 | .pio_mask = ATA_PIO4, |
464 | .mwdma_mask = 0x07, | 464 | .mwdma_mask = ATA_MWDMA2, |
465 | .udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */ | 465 | .udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */ |
466 | .port_ops = &via_port_ops | 466 | .port_ops = &via_port_ops |
467 | }; | 467 | }; |
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 319e164a3d74..6d8619b6f670 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c | |||
@@ -193,7 +193,7 @@ static __init int winbond_init_one(unsigned long port) | |||
193 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port); | 193 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port); |
194 | 194 | ||
195 | ap->ops = &winbond_port_ops; | 195 | ap->ops = &winbond_port_ops; |
196 | ap->pio_mask = 0x1F; | 196 | ap->pio_mask = ATA_PIO4; |
197 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 197 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
198 | ap->ioaddr.cmd_addr = cmd_addr; | 198 | ap->ioaddr.cmd_addr = cmd_addr; |
199 | ap->ioaddr.altstatus_addr = ctl_addr; | 199 | ap->ioaddr.altstatus_addr = ctl_addr; |
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index be53545c9f64..39588178d028 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c | |||
@@ -148,6 +148,8 @@ static struct scsi_host_template adma_ata_sht = { | |||
148 | static struct ata_port_operations adma_ata_ops = { | 148 | static struct ata_port_operations adma_ata_ops = { |
149 | .inherits = &ata_sff_port_ops, | 149 | .inherits = &ata_sff_port_ops, |
150 | 150 | ||
151 | .lost_interrupt = ATA_OP_NULL, | ||
152 | |||
151 | .check_atapi_dma = adma_check_atapi_dma, | 153 | .check_atapi_dma = adma_check_atapi_dma, |
152 | .qc_prep = adma_qc_prep, | 154 | .qc_prep = adma_qc_prep, |
153 | .qc_issue = adma_qc_issue, | 155 | .qc_issue = adma_qc_issue, |
@@ -166,7 +168,7 @@ static struct ata_port_info adma_port_info[] = { | |||
166 | .flags = ATA_FLAG_SLAVE_POSS | | 168 | .flags = ATA_FLAG_SLAVE_POSS | |
167 | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | | 169 | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | |
168 | ATA_FLAG_PIO_POLLING, | 170 | ATA_FLAG_PIO_POLLING, |
169 | .pio_mask = 0x10, /* pio4 */ | 171 | .pio_mask = ATA_PIO4_ONLY, |
170 | .udma_mask = ATA_UDMA4, | 172 | .udma_mask = ATA_UDMA4, |
171 | .port_ops = &adma_ata_ops, | 173 | .port_ops = &adma_ata_ops, |
172 | }, | 174 | }, |
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 55bc88c1707b..c2e90e1fece0 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -1279,8 +1279,8 @@ static struct ata_port_operations sata_fsl_ops = { | |||
1279 | static const struct ata_port_info sata_fsl_port_info[] = { | 1279 | static const struct ata_port_info sata_fsl_port_info[] = { |
1280 | { | 1280 | { |
1281 | .flags = SATA_FSL_HOST_FLAGS, | 1281 | .flags = SATA_FSL_HOST_FLAGS, |
1282 | .pio_mask = 0x1f, /* pio 0-4 */ | 1282 | .pio_mask = ATA_PIO4, |
1283 | .udma_mask = 0x7f, /* udma 0-6 */ | 1283 | .udma_mask = ATA_UDMA6, |
1284 | .port_ops = &sata_fsl_ops, | 1284 | .port_ops = &sata_fsl_ops, |
1285 | }, | 1285 | }, |
1286 | }; | 1286 | }; |
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index fbbd87c96f10..305a4f825f53 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c | |||
@@ -744,8 +744,8 @@ static struct ata_port_operations inic_port_ops = { | |||
744 | 744 | ||
745 | static struct ata_port_info inic_port_info = { | 745 | static struct ata_port_info inic_port_info = { |
746 | .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, | 746 | .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, |
747 | .pio_mask = 0x1f, /* pio0-4 */ | 747 | .pio_mask = ATA_PIO4, |
748 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 748 | .mwdma_mask = ATA_MWDMA2, |
749 | .udma_mask = ATA_UDMA6, | 749 | .udma_mask = ATA_UDMA6, |
750 | .port_ops = &inic_port_ops | 750 | .port_ops = &inic_port_ops |
751 | }; | 751 | }; |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 74b1080d116d..a377226b81c8 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1,10 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * sata_mv.c - Marvell SATA support | 2 | * sata_mv.c - Marvell SATA support |
3 | * | 3 | * |
4 | * Copyright 2008: Marvell Corporation, all rights reserved. | 4 | * Copyright 2008-2009: Marvell Corporation, all rights reserved. |
5 | * Copyright 2005: EMC Corporation, all rights reserved. | 5 | * Copyright 2005: EMC Corporation, all rights reserved. |
6 | * Copyright 2005 Red Hat, Inc. All rights reserved. | 6 | * Copyright 2005 Red Hat, Inc. All rights reserved. |
7 | * | 7 | * |
8 | * Originally written by Brett Russ. | ||
9 | * Extensive overhaul and enhancement by Mark Lord <mlord@pobox.com>. | ||
10 | * | ||
8 | * Please ALWAYS copy linux-ide@vger.kernel.org on emails. | 11 | * Please ALWAYS copy linux-ide@vger.kernel.org on emails. |
9 | * | 12 | * |
10 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
@@ -25,20 +28,13 @@ | |||
25 | /* | 28 | /* |
26 | * sata_mv TODO list: | 29 | * sata_mv TODO list: |
27 | * | 30 | * |
28 | * --> Errata workaround for NCQ device errors. | ||
29 | * | ||
30 | * --> More errata workarounds for PCI-X. | 31 | * --> More errata workarounds for PCI-X. |
31 | * | 32 | * |
32 | * --> Complete a full errata audit for all chipsets to identify others. | 33 | * --> Complete a full errata audit for all chipsets to identify others. |
33 | * | 34 | * |
34 | * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it). | ||
35 | * | ||
36 | * --> Develop a low-power-consumption strategy, and implement it. | 35 | * --> Develop a low-power-consumption strategy, and implement it. |
37 | * | 36 | * |
38 | * --> [Experiment, low priority] Investigate interrupt coalescing. | 37 | * --> Add sysfs attributes for per-chip / per-HC IRQ coalescing thresholds. |
39 | * Quite often, especially with PCI Message Signalled Interrupts (MSI), | ||
40 | * the overhead reduced by interrupt mitigation is quite often not | ||
41 | * worth the latency cost. | ||
42 | * | 38 | * |
43 | * --> [Experiment, Marvell value added] Is it possible to use target | 39 | * --> [Experiment, Marvell value added] Is it possible to use target |
44 | * mode to cross-connect two Linux boxes with Marvell cards? If so, | 40 | * mode to cross-connect two Linux boxes with Marvell cards? If so, |
@@ -68,7 +64,27 @@ | |||
68 | #include <linux/libata.h> | 64 | #include <linux/libata.h> |
69 | 65 | ||
70 | #define DRV_NAME "sata_mv" | 66 | #define DRV_NAME "sata_mv" |
71 | #define DRV_VERSION "1.25" | 67 | #define DRV_VERSION "1.27" |
68 | |||
69 | /* | ||
70 | * module options | ||
71 | */ | ||
72 | |||
73 | static int msi; | ||
74 | #ifdef CONFIG_PCI | ||
75 | module_param(msi, int, S_IRUGO); | ||
76 | MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)"); | ||
77 | #endif | ||
78 | |||
79 | static int irq_coalescing_io_count; | ||
80 | module_param(irq_coalescing_io_count, int, S_IRUGO); | ||
81 | MODULE_PARM_DESC(irq_coalescing_io_count, | ||
82 | "IRQ coalescing I/O count threshold (0..255)"); | ||
83 | |||
84 | static int irq_coalescing_usecs; | ||
85 | module_param(irq_coalescing_usecs, int, S_IRUGO); | ||
86 | MODULE_PARM_DESC(irq_coalescing_usecs, | ||
87 | "IRQ coalescing time threshold in usecs"); | ||
72 | 88 | ||
73 | enum { | 89 | enum { |
74 | /* BAR's are enumerated in terms of pci_resource_start() terms */ | 90 | /* BAR's are enumerated in terms of pci_resource_start() terms */ |
@@ -79,13 +95,32 @@ enum { | |||
79 | MV_MAJOR_REG_AREA_SZ = 0x10000, /* 64KB */ | 95 | MV_MAJOR_REG_AREA_SZ = 0x10000, /* 64KB */ |
80 | MV_MINOR_REG_AREA_SZ = 0x2000, /* 8KB */ | 96 | MV_MINOR_REG_AREA_SZ = 0x2000, /* 8KB */ |
81 | 97 | ||
98 | /* For use with both IRQ coalescing methods ("all ports" or "per-HC" */ | ||
99 | COAL_CLOCKS_PER_USEC = 150, /* for calculating COAL_TIMEs */ | ||
100 | MAX_COAL_TIME_THRESHOLD = ((1 << 24) - 1), /* internal clocks count */ | ||
101 | MAX_COAL_IO_COUNT = 255, /* completed I/O count */ | ||
102 | |||
82 | MV_PCI_REG_BASE = 0, | 103 | MV_PCI_REG_BASE = 0, |
83 | MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */ | 104 | |
84 | MV_IRQ_COAL_CAUSE = (MV_IRQ_COAL_REG_BASE + 0x08), | 105 | /* |
85 | MV_IRQ_COAL_CAUSE_LO = (MV_IRQ_COAL_REG_BASE + 0x88), | 106 | * Per-chip ("all ports") interrupt coalescing feature. |
86 | MV_IRQ_COAL_CAUSE_HI = (MV_IRQ_COAL_REG_BASE + 0x8c), | 107 | * This is only for GEN_II / GEN_IIE hardware. |
87 | MV_IRQ_COAL_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xcc), | 108 | * |
88 | MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0), | 109 | * Coalescing defers the interrupt until either the IO_THRESHOLD |
110 | * (count of completed I/Os) is met, or the TIME_THRESHOLD is met. | ||
111 | */ | ||
112 | MV_COAL_REG_BASE = 0x18000, | ||
113 | MV_IRQ_COAL_CAUSE = (MV_COAL_REG_BASE + 0x08), | ||
114 | ALL_PORTS_COAL_IRQ = (1 << 4), /* all ports irq event */ | ||
115 | |||
116 | MV_IRQ_COAL_IO_THRESHOLD = (MV_COAL_REG_BASE + 0xcc), | ||
117 | MV_IRQ_COAL_TIME_THRESHOLD = (MV_COAL_REG_BASE + 0xd0), | ||
118 | |||
119 | /* | ||
120 | * Registers for the (unused here) transaction coalescing feature: | ||
121 | */ | ||
122 | MV_TRAN_COAL_CAUSE_LO = (MV_COAL_REG_BASE + 0x88), | ||
123 | MV_TRAN_COAL_CAUSE_HI = (MV_COAL_REG_BASE + 0x8c), | ||
89 | 124 | ||
90 | MV_SATAHC0_REG_BASE = 0x20000, | 125 | MV_SATAHC0_REG_BASE = 0x20000, |
91 | MV_FLASH_CTL_OFS = 0x1046c, | 126 | MV_FLASH_CTL_OFS = 0x1046c, |
@@ -117,17 +152,16 @@ enum { | |||
117 | 152 | ||
118 | /* Host Flags */ | 153 | /* Host Flags */ |
119 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ | 154 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ |
120 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ | ||
121 | 155 | ||
122 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 156 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
123 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | | 157 | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, |
124 | ATA_FLAG_PIO_POLLING, | 158 | |
159 | MV_GEN_I_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NO_ATAPI, | ||
125 | 160 | ||
126 | MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, | 161 | MV_GEN_II_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NCQ | |
162 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA, | ||
127 | 163 | ||
128 | MV_GENIIE_FLAGS = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 164 | MV_GEN_IIE_FLAGS = MV_GEN_II_FLAGS | ATA_FLAG_AN, |
129 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
130 | ATA_FLAG_NCQ | ATA_FLAG_AN, | ||
131 | 165 | ||
132 | CRQB_FLAG_READ = (1 << 0), | 166 | CRQB_FLAG_READ = (1 << 0), |
133 | CRQB_TAG_SHIFT = 1, | 167 | CRQB_TAG_SHIFT = 1, |
@@ -180,16 +214,18 @@ enum { | |||
180 | PCI_HC_MAIN_IRQ_MASK_OFS = 0x1d64, | 214 | PCI_HC_MAIN_IRQ_MASK_OFS = 0x1d64, |
181 | SOC_HC_MAIN_IRQ_CAUSE_OFS = 0x20020, | 215 | SOC_HC_MAIN_IRQ_CAUSE_OFS = 0x20020, |
182 | SOC_HC_MAIN_IRQ_MASK_OFS = 0x20024, | 216 | SOC_HC_MAIN_IRQ_MASK_OFS = 0x20024, |
183 | ERR_IRQ = (1 << 0), /* shift by port # */ | 217 | ERR_IRQ = (1 << 0), /* shift by (2 * port #) */ |
184 | DONE_IRQ = (1 << 1), /* shift by port # */ | 218 | DONE_IRQ = (1 << 1), /* shift by (2 * port #) */ |
185 | HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */ | 219 | HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */ |
186 | HC_SHIFT = 9, /* bits 9-17 = HC1's ports */ | 220 | HC_SHIFT = 9, /* bits 9-17 = HC1's ports */ |
221 | DONE_IRQ_0_3 = 0x000000aa, /* DONE_IRQ ports 0,1,2,3 */ | ||
222 | DONE_IRQ_4_7 = (DONE_IRQ_0_3 << HC_SHIFT), /* 4,5,6,7 */ | ||
187 | PCI_ERR = (1 << 18), | 223 | PCI_ERR = (1 << 18), |
188 | TRAN_LO_DONE = (1 << 19), /* 6xxx: IRQ coalescing */ | 224 | TRAN_COAL_LO_DONE = (1 << 19), /* transaction coalescing */ |
189 | TRAN_HI_DONE = (1 << 20), /* 6xxx: IRQ coalescing */ | 225 | TRAN_COAL_HI_DONE = (1 << 20), /* transaction coalescing */ |
190 | PORTS_0_3_COAL_DONE = (1 << 8), | 226 | PORTS_0_3_COAL_DONE = (1 << 8), /* HC0 IRQ coalescing */ |
191 | PORTS_4_7_COAL_DONE = (1 << 17), | 227 | PORTS_4_7_COAL_DONE = (1 << 17), /* HC1 IRQ coalescing */ |
192 | PORTS_0_7_COAL_DONE = (1 << 21), /* 6xxx: IRQ coalescing */ | 228 | ALL_PORTS_COAL_DONE = (1 << 21), /* GEN_II(E) IRQ coalescing */ |
193 | GPIO_INT = (1 << 22), | 229 | GPIO_INT = (1 << 22), |
194 | SELF_INT = (1 << 23), | 230 | SELF_INT = (1 << 23), |
195 | TWSI_INT = (1 << 24), | 231 | TWSI_INT = (1 << 24), |
@@ -205,6 +241,21 @@ enum { | |||
205 | HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */ | 241 | HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */ |
206 | DEV_IRQ = (1 << 8), /* shift by port # */ | 242 | DEV_IRQ = (1 << 8), /* shift by port # */ |
207 | 243 | ||
244 | /* | ||
245 | * Per-HC (Host-Controller) interrupt coalescing feature. | ||
246 | * This is present on all chip generations. | ||
247 | * | ||
248 | * Coalescing defers the interrupt until either the IO_THRESHOLD | ||
249 | * (count of completed I/Os) is met, or the TIME_THRESHOLD is met. | ||
250 | */ | ||
251 | HC_IRQ_COAL_IO_THRESHOLD_OFS = 0x000c, | ||
252 | HC_IRQ_COAL_TIME_THRESHOLD_OFS = 0x0010, | ||
253 | |||
254 | SOC_LED_CTRL_OFS = 0x2c, | ||
255 | SOC_LED_CTRL_BLINK = (1 << 0), /* Active LED blink */ | ||
256 | SOC_LED_CTRL_ACT_PRESENCE = (1 << 2), /* Multiplex dev presence */ | ||
257 | /* with dev activity LED */ | ||
258 | |||
208 | /* Shadow block registers */ | 259 | /* Shadow block registers */ |
209 | SHD_BLK_OFS = 0x100, | 260 | SHD_BLK_OFS = 0x100, |
210 | SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */ | 261 | SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */ |
@@ -346,6 +397,12 @@ enum { | |||
346 | EDMA_ARB_CFG_OFS = 0x38, | 397 | EDMA_ARB_CFG_OFS = 0x38, |
347 | 398 | ||
348 | EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ | 399 | EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ |
400 | EDMA_UNKNOWN_RSVD_OFS = 0x6C, /* GenIIe unknown/reserved */ | ||
401 | |||
402 | BMDMA_CMD_OFS = 0x224, /* bmdma command register */ | ||
403 | BMDMA_STATUS_OFS = 0x228, /* bmdma status register */ | ||
404 | BMDMA_PRD_LOW_OFS = 0x22c, /* bmdma PRD addr 31:0 */ | ||
405 | BMDMA_PRD_HIGH_OFS = 0x230, /* bmdma PRD addr 63:32 */ | ||
349 | 406 | ||
350 | /* Host private flags (hp_flags) */ | 407 | /* Host private flags (hp_flags) */ |
351 | MV_HP_FLAG_MSI = (1 << 0), | 408 | MV_HP_FLAG_MSI = (1 << 0), |
@@ -359,12 +416,14 @@ enum { | |||
359 | MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ | 416 | MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ |
360 | MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */ | 417 | MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */ |
361 | MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */ | 418 | MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */ |
419 | MV_HP_QUIRK_LED_BLINK_EN = (1 << 12), /* is led blinking enabled? */ | ||
362 | 420 | ||
363 | /* Port private flags (pp_flags) */ | 421 | /* Port private flags (pp_flags) */ |
364 | MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ | 422 | MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ |
365 | MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */ | 423 | MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */ |
366 | MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */ | 424 | MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */ |
367 | MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */ | 425 | MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */ |
426 | MV_PP_FLAG_FAKE_ATA_BUSY = (1 << 4), /* ignore initial ATA_DRDY */ | ||
368 | }; | 427 | }; |
369 | 428 | ||
370 | #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) | 429 | #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) |
@@ -433,6 +492,18 @@ struct mv_sg { | |||
433 | __le32 reserved; | 492 | __le32 reserved; |
434 | }; | 493 | }; |
435 | 494 | ||
495 | /* | ||
496 | * We keep a local cache of a few frequently accessed port | ||
497 | * registers here, to avoid having to read them (very slow) | ||
498 | * when switching between EDMA and non-EDMA modes. | ||
499 | */ | ||
500 | struct mv_cached_regs { | ||
501 | u32 fiscfg; | ||
502 | u32 ltmode; | ||
503 | u32 haltcond; | ||
504 | u32 unknown_rsvd; | ||
505 | }; | ||
506 | |||
436 | struct mv_port_priv { | 507 | struct mv_port_priv { |
437 | struct mv_crqb *crqb; | 508 | struct mv_crqb *crqb; |
438 | dma_addr_t crqb_dma; | 509 | dma_addr_t crqb_dma; |
@@ -445,6 +516,7 @@ struct mv_port_priv { | |||
445 | unsigned int resp_idx; | 516 | unsigned int resp_idx; |
446 | 517 | ||
447 | u32 pp_flags; | 518 | u32 pp_flags; |
519 | struct mv_cached_regs cached; | ||
448 | unsigned int delayed_eh_pmp_map; | 520 | unsigned int delayed_eh_pmp_map; |
449 | }; | 521 | }; |
450 | 522 | ||
@@ -535,7 +607,7 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, | |||
535 | unsigned int port_no); | 607 | unsigned int port_no); |
536 | static int mv_stop_edma(struct ata_port *ap); | 608 | static int mv_stop_edma(struct ata_port *ap); |
537 | static int mv_stop_edma_engine(void __iomem *port_mmio); | 609 | static int mv_stop_edma_engine(void __iomem *port_mmio); |
538 | static void mv_edma_cfg(struct ata_port *ap, int want_ncq); | 610 | static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma); |
539 | 611 | ||
540 | static void mv_pmp_select(struct ata_port *ap, int pmp); | 612 | static void mv_pmp_select(struct ata_port *ap, int pmp); |
541 | static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class, | 613 | static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class, |
@@ -546,6 +618,14 @@ static void mv_pmp_error_handler(struct ata_port *ap); | |||
546 | static void mv_process_crpb_entries(struct ata_port *ap, | 618 | static void mv_process_crpb_entries(struct ata_port *ap, |
547 | struct mv_port_priv *pp); | 619 | struct mv_port_priv *pp); |
548 | 620 | ||
621 | static void mv_sff_irq_clear(struct ata_port *ap); | ||
622 | static int mv_check_atapi_dma(struct ata_queued_cmd *qc); | ||
623 | static void mv_bmdma_setup(struct ata_queued_cmd *qc); | ||
624 | static void mv_bmdma_start(struct ata_queued_cmd *qc); | ||
625 | static void mv_bmdma_stop(struct ata_queued_cmd *qc); | ||
626 | static u8 mv_bmdma_status(struct ata_port *ap); | ||
627 | static u8 mv_sff_check_status(struct ata_port *ap); | ||
628 | |||
549 | /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below | 629 | /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below |
550 | * because we have to allow room for worst case splitting of | 630 | * because we have to allow room for worst case splitting of |
551 | * PRDs for 64K boundaries in mv_fill_sg(). | 631 | * PRDs for 64K boundaries in mv_fill_sg(). |
@@ -566,6 +646,8 @@ static struct scsi_host_template mv6_sht = { | |||
566 | static struct ata_port_operations mv5_ops = { | 646 | static struct ata_port_operations mv5_ops = { |
567 | .inherits = &ata_sff_port_ops, | 647 | .inherits = &ata_sff_port_ops, |
568 | 648 | ||
649 | .lost_interrupt = ATA_OP_NULL, | ||
650 | |||
569 | .qc_defer = mv_qc_defer, | 651 | .qc_defer = mv_qc_defer, |
570 | .qc_prep = mv_qc_prep, | 652 | .qc_prep = mv_qc_prep, |
571 | .qc_issue = mv_qc_issue, | 653 | .qc_issue = mv_qc_issue, |
@@ -593,6 +675,14 @@ static struct ata_port_operations mv6_ops = { | |||
593 | .pmp_softreset = mv_softreset, | 675 | .pmp_softreset = mv_softreset, |
594 | .softreset = mv_softreset, | 676 | .softreset = mv_softreset, |
595 | .error_handler = mv_pmp_error_handler, | 677 | .error_handler = mv_pmp_error_handler, |
678 | |||
679 | .sff_check_status = mv_sff_check_status, | ||
680 | .sff_irq_clear = mv_sff_irq_clear, | ||
681 | .check_atapi_dma = mv_check_atapi_dma, | ||
682 | .bmdma_setup = mv_bmdma_setup, | ||
683 | .bmdma_start = mv_bmdma_start, | ||
684 | .bmdma_stop = mv_bmdma_stop, | ||
685 | .bmdma_status = mv_bmdma_status, | ||
596 | }; | 686 | }; |
597 | 687 | ||
598 | static struct ata_port_operations mv_iie_ops = { | 688 | static struct ata_port_operations mv_iie_ops = { |
@@ -603,53 +693,49 @@ static struct ata_port_operations mv_iie_ops = { | |||
603 | 693 | ||
604 | static const struct ata_port_info mv_port_info[] = { | 694 | static const struct ata_port_info mv_port_info[] = { |
605 | { /* chip_504x */ | 695 | { /* chip_504x */ |
606 | .flags = MV_COMMON_FLAGS, | 696 | .flags = MV_GEN_I_FLAGS, |
607 | .pio_mask = 0x1f, /* pio0-4 */ | 697 | .pio_mask = 0x1f, /* pio0-4 */ |
608 | .udma_mask = ATA_UDMA6, | 698 | .udma_mask = ATA_UDMA6, |
609 | .port_ops = &mv5_ops, | 699 | .port_ops = &mv5_ops, |
610 | }, | 700 | }, |
611 | { /* chip_508x */ | 701 | { /* chip_508x */ |
612 | .flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC, | 702 | .flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC, |
613 | .pio_mask = 0x1f, /* pio0-4 */ | 703 | .pio_mask = 0x1f, /* pio0-4 */ |
614 | .udma_mask = ATA_UDMA6, | 704 | .udma_mask = ATA_UDMA6, |
615 | .port_ops = &mv5_ops, | 705 | .port_ops = &mv5_ops, |
616 | }, | 706 | }, |
617 | { /* chip_5080 */ | 707 | { /* chip_5080 */ |
618 | .flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC, | 708 | .flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC, |
619 | .pio_mask = 0x1f, /* pio0-4 */ | 709 | .pio_mask = 0x1f, /* pio0-4 */ |
620 | .udma_mask = ATA_UDMA6, | 710 | .udma_mask = ATA_UDMA6, |
621 | .port_ops = &mv5_ops, | 711 | .port_ops = &mv5_ops, |
622 | }, | 712 | }, |
623 | { /* chip_604x */ | 713 | { /* chip_604x */ |
624 | .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 714 | .flags = MV_GEN_II_FLAGS, |
625 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
626 | ATA_FLAG_NCQ, | ||
627 | .pio_mask = 0x1f, /* pio0-4 */ | 715 | .pio_mask = 0x1f, /* pio0-4 */ |
628 | .udma_mask = ATA_UDMA6, | 716 | .udma_mask = ATA_UDMA6, |
629 | .port_ops = &mv6_ops, | 717 | .port_ops = &mv6_ops, |
630 | }, | 718 | }, |
631 | { /* chip_608x */ | 719 | { /* chip_608x */ |
632 | .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 720 | .flags = MV_GEN_II_FLAGS | MV_FLAG_DUAL_HC, |
633 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
634 | ATA_FLAG_NCQ | MV_FLAG_DUAL_HC, | ||
635 | .pio_mask = 0x1f, /* pio0-4 */ | 721 | .pio_mask = 0x1f, /* pio0-4 */ |
636 | .udma_mask = ATA_UDMA6, | 722 | .udma_mask = ATA_UDMA6, |
637 | .port_ops = &mv6_ops, | 723 | .port_ops = &mv6_ops, |
638 | }, | 724 | }, |
639 | { /* chip_6042 */ | 725 | { /* chip_6042 */ |
640 | .flags = MV_GENIIE_FLAGS, | 726 | .flags = MV_GEN_IIE_FLAGS, |
641 | .pio_mask = 0x1f, /* pio0-4 */ | 727 | .pio_mask = 0x1f, /* pio0-4 */ |
642 | .udma_mask = ATA_UDMA6, | 728 | .udma_mask = ATA_UDMA6, |
643 | .port_ops = &mv_iie_ops, | 729 | .port_ops = &mv_iie_ops, |
644 | }, | 730 | }, |
645 | { /* chip_7042 */ | 731 | { /* chip_7042 */ |
646 | .flags = MV_GENIIE_FLAGS, | 732 | .flags = MV_GEN_IIE_FLAGS, |
647 | .pio_mask = 0x1f, /* pio0-4 */ | 733 | .pio_mask = 0x1f, /* pio0-4 */ |
648 | .udma_mask = ATA_UDMA6, | 734 | .udma_mask = ATA_UDMA6, |
649 | .port_ops = &mv_iie_ops, | 735 | .port_ops = &mv_iie_ops, |
650 | }, | 736 | }, |
651 | { /* chip_soc */ | 737 | { /* chip_soc */ |
652 | .flags = MV_GENIIE_FLAGS, | 738 | .flags = MV_GEN_IIE_FLAGS, |
653 | .pio_mask = 0x1f, /* pio0-4 */ | 739 | .pio_mask = 0x1f, /* pio0-4 */ |
654 | .udma_mask = ATA_UDMA6, | 740 | .udma_mask = ATA_UDMA6, |
655 | .port_ops = &mv_iie_ops, | 741 | .port_ops = &mv_iie_ops, |
@@ -794,6 +880,44 @@ static inline int mv_get_hc_count(unsigned long port_flags) | |||
794 | return ((port_flags & MV_FLAG_DUAL_HC) ? 2 : 1); | 880 | return ((port_flags & MV_FLAG_DUAL_HC) ? 2 : 1); |
795 | } | 881 | } |
796 | 882 | ||
883 | /** | ||
884 | * mv_save_cached_regs - (re-)initialize cached port registers | ||
885 | * @ap: the port whose registers we are caching | ||
886 | * | ||
887 | * Initialize the local cache of port registers, | ||
888 | * so that reading them over and over again can | ||
889 | * be avoided on the hotter paths of this driver. | ||
890 | * This saves a few microseconds each time we switch | ||
891 | * to/from EDMA mode to perform (eg.) a drive cache flush. | ||
892 | */ | ||
893 | static void mv_save_cached_regs(struct ata_port *ap) | ||
894 | { | ||
895 | void __iomem *port_mmio = mv_ap_base(ap); | ||
896 | struct mv_port_priv *pp = ap->private_data; | ||
897 | |||
898 | pp->cached.fiscfg = readl(port_mmio + FISCFG_OFS); | ||
899 | pp->cached.ltmode = readl(port_mmio + LTMODE_OFS); | ||
900 | pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND_OFS); | ||
901 | pp->cached.unknown_rsvd = readl(port_mmio + EDMA_UNKNOWN_RSVD_OFS); | ||
902 | } | ||
903 | |||
904 | /** | ||
905 | * mv_write_cached_reg - write to a cached port register | ||
906 | * @addr: hardware address of the register | ||
907 | * @old: pointer to cached value of the register | ||
908 | * @new: new value for the register | ||
909 | * | ||
910 | * Write a new value to a cached register, | ||
911 | * but only if the value is different from before. | ||
912 | */ | ||
913 | static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new) | ||
914 | { | ||
915 | if (new != *old) { | ||
916 | *old = new; | ||
917 | writel(new, addr); | ||
918 | } | ||
919 | } | ||
920 | |||
797 | static void mv_set_edma_ptrs(void __iomem *port_mmio, | 921 | static void mv_set_edma_ptrs(void __iomem *port_mmio, |
798 | struct mv_host_priv *hpriv, | 922 | struct mv_host_priv *hpriv, |
799 | struct mv_port_priv *pp) | 923 | struct mv_port_priv *pp) |
@@ -825,6 +949,23 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, | |||
825 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); | 949 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); |
826 | } | 950 | } |
827 | 951 | ||
952 | static void mv_write_main_irq_mask(u32 mask, struct mv_host_priv *hpriv) | ||
953 | { | ||
954 | /* | ||
955 | * When writing to the main_irq_mask in hardware, | ||
956 | * we must ensure exclusivity between the interrupt coalescing bits | ||
957 | * and the corresponding individual port DONE_IRQ bits. | ||
958 | * | ||
959 | * Note that this register is really an "IRQ enable" register, | ||
960 | * not an "IRQ mask" register as Marvell's naming might suggest. | ||
961 | */ | ||
962 | if (mask & (ALL_PORTS_COAL_DONE | PORTS_0_3_COAL_DONE)) | ||
963 | mask &= ~DONE_IRQ_0_3; | ||
964 | if (mask & (ALL_PORTS_COAL_DONE | PORTS_4_7_COAL_DONE)) | ||
965 | mask &= ~DONE_IRQ_4_7; | ||
966 | writelfl(mask, hpriv->main_irq_mask_addr); | ||
967 | } | ||
968 | |||
828 | static void mv_set_main_irq_mask(struct ata_host *host, | 969 | static void mv_set_main_irq_mask(struct ata_host *host, |
829 | u32 disable_bits, u32 enable_bits) | 970 | u32 disable_bits, u32 enable_bits) |
830 | { | 971 | { |
@@ -835,7 +976,7 @@ static void mv_set_main_irq_mask(struct ata_host *host, | |||
835 | new_mask = (old_mask & ~disable_bits) | enable_bits; | 976 | new_mask = (old_mask & ~disable_bits) | enable_bits; |
836 | if (new_mask != old_mask) { | 977 | if (new_mask != old_mask) { |
837 | hpriv->main_irq_mask = new_mask; | 978 | hpriv->main_irq_mask = new_mask; |
838 | writelfl(new_mask, hpriv->main_irq_mask_addr); | 979 | mv_write_main_irq_mask(new_mask, hpriv); |
839 | } | 980 | } |
840 | } | 981 | } |
841 | 982 | ||
@@ -852,8 +993,94 @@ static void mv_enable_port_irqs(struct ata_port *ap, | |||
852 | mv_set_main_irq_mask(ap->host, disable_bits, enable_bits); | 993 | mv_set_main_irq_mask(ap->host, disable_bits, enable_bits); |
853 | } | 994 | } |
854 | 995 | ||
996 | static void mv_clear_and_enable_port_irqs(struct ata_port *ap, | ||
997 | void __iomem *port_mmio, | ||
998 | unsigned int port_irqs) | ||
999 | { | ||
1000 | struct mv_host_priv *hpriv = ap->host->private_data; | ||
1001 | int hardport = mv_hardport_from_port(ap->port_no); | ||
1002 | void __iomem *hc_mmio = mv_hc_base_from_port( | ||
1003 | mv_host_base(ap->host), ap->port_no); | ||
1004 | u32 hc_irq_cause; | ||
1005 | |||
1006 | /* clear EDMA event indicators, if any */ | ||
1007 | writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | ||
1008 | |||
1009 | /* clear pending irq events */ | ||
1010 | hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport); | ||
1011 | writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); | ||
1012 | |||
1013 | /* clear FIS IRQ Cause */ | ||
1014 | if (IS_GEN_IIE(hpriv)) | ||
1015 | writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
1016 | |||
1017 | mv_enable_port_irqs(ap, port_irqs); | ||
1018 | } | ||
1019 | |||
1020 | static void mv_set_irq_coalescing(struct ata_host *host, | ||
1021 | unsigned int count, unsigned int usecs) | ||
1022 | { | ||
1023 | struct mv_host_priv *hpriv = host->private_data; | ||
1024 | void __iomem *mmio = hpriv->base, *hc_mmio; | ||
1025 | u32 coal_enable = 0; | ||
1026 | unsigned long flags; | ||
1027 | unsigned int clks, is_dual_hc = hpriv->n_ports > MV_PORTS_PER_HC; | ||
1028 | const u32 coal_disable = PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | | ||
1029 | ALL_PORTS_COAL_DONE; | ||
1030 | |||
1031 | /* Disable IRQ coalescing if either threshold is zero */ | ||
1032 | if (!usecs || !count) { | ||
1033 | clks = count = 0; | ||
1034 | } else { | ||
1035 | /* Respect maximum limits of the hardware */ | ||
1036 | clks = usecs * COAL_CLOCKS_PER_USEC; | ||
1037 | if (clks > MAX_COAL_TIME_THRESHOLD) | ||
1038 | clks = MAX_COAL_TIME_THRESHOLD; | ||
1039 | if (count > MAX_COAL_IO_COUNT) | ||
1040 | count = MAX_COAL_IO_COUNT; | ||
1041 | } | ||
1042 | |||
1043 | spin_lock_irqsave(&host->lock, flags); | ||
1044 | mv_set_main_irq_mask(host, coal_disable, 0); | ||
1045 | |||
1046 | if (is_dual_hc && !IS_GEN_I(hpriv)) { | ||
1047 | /* | ||
1048 | * GEN_II/GEN_IIE with dual host controllers: | ||
1049 | * one set of global thresholds for the entire chip. | ||
1050 | */ | ||
1051 | writel(clks, mmio + MV_IRQ_COAL_TIME_THRESHOLD); | ||
1052 | writel(count, mmio + MV_IRQ_COAL_IO_THRESHOLD); | ||
1053 | /* clear leftover coal IRQ bit */ | ||
1054 | writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE); | ||
1055 | if (count) | ||
1056 | coal_enable = ALL_PORTS_COAL_DONE; | ||
1057 | clks = count = 0; /* force clearing of regular regs below */ | ||
1058 | } | ||
1059 | |||
1060 | /* | ||
1061 | * All chips: independent thresholds for each HC on the chip. | ||
1062 | */ | ||
1063 | hc_mmio = mv_hc_base_from_port(mmio, 0); | ||
1064 | writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS); | ||
1065 | writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS); | ||
1066 | writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS); | ||
1067 | if (count) | ||
1068 | coal_enable |= PORTS_0_3_COAL_DONE; | ||
1069 | if (is_dual_hc) { | ||
1070 | hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC); | ||
1071 | writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS); | ||
1072 | writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS); | ||
1073 | writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS); | ||
1074 | if (count) | ||
1075 | coal_enable |= PORTS_4_7_COAL_DONE; | ||
1076 | } | ||
1077 | |||
1078 | mv_set_main_irq_mask(host, 0, coal_enable); | ||
1079 | spin_unlock_irqrestore(&host->lock, flags); | ||
1080 | } | ||
1081 | |||
855 | /** | 1082 | /** |
856 | * mv_start_dma - Enable eDMA engine | 1083 | * mv_start_edma - Enable eDMA engine |
857 | * @base: port base address | 1084 | * @base: port base address |
858 | * @pp: port private data | 1085 | * @pp: port private data |
859 | * | 1086 | * |
@@ -863,7 +1090,7 @@ static void mv_enable_port_irqs(struct ata_port *ap, | |||
863 | * LOCKING: | 1090 | * LOCKING: |
864 | * Inherited from caller. | 1091 | * Inherited from caller. |
865 | */ | 1092 | */ |
866 | static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, | 1093 | static void mv_start_edma(struct ata_port *ap, void __iomem *port_mmio, |
867 | struct mv_port_priv *pp, u8 protocol) | 1094 | struct mv_port_priv *pp, u8 protocol) |
868 | { | 1095 | { |
869 | int want_ncq = (protocol == ATA_PROT_NCQ); | 1096 | int want_ncq = (protocol == ATA_PROT_NCQ); |
@@ -875,26 +1102,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, | |||
875 | } | 1102 | } |
876 | if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { | 1103 | if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { |
877 | struct mv_host_priv *hpriv = ap->host->private_data; | 1104 | struct mv_host_priv *hpriv = ap->host->private_data; |
878 | int hardport = mv_hardport_from_port(ap->port_no); | ||
879 | void __iomem *hc_mmio = mv_hc_base_from_port( | ||
880 | mv_host_base(ap->host), ap->port_no); | ||
881 | u32 hc_irq_cause; | ||
882 | |||
883 | /* clear EDMA event indicators, if any */ | ||
884 | writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | ||
885 | 1105 | ||
886 | /* clear pending irq events */ | 1106 | mv_edma_cfg(ap, want_ncq, 1); |
887 | hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport); | ||
888 | writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); | ||
889 | |||
890 | mv_edma_cfg(ap, want_ncq); | ||
891 | |||
892 | /* clear FIS IRQ Cause */ | ||
893 | if (IS_GEN_IIE(hpriv)) | ||
894 | writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
895 | 1107 | ||
896 | mv_set_edma_ptrs(port_mmio, hpriv, pp); | 1108 | mv_set_edma_ptrs(port_mmio, hpriv, pp); |
897 | mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ); | 1109 | mv_clear_and_enable_port_irqs(ap, port_mmio, DONE_IRQ|ERR_IRQ); |
898 | 1110 | ||
899 | writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); | 1111 | writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); |
900 | pp->pp_flags |= MV_PP_FLAG_EDMA_EN; | 1112 | pp->pp_flags |= MV_PP_FLAG_EDMA_EN; |
@@ -952,6 +1164,7 @@ static int mv_stop_edma(struct ata_port *ap) | |||
952 | { | 1164 | { |
953 | void __iomem *port_mmio = mv_ap_base(ap); | 1165 | void __iomem *port_mmio = mv_ap_base(ap); |
954 | struct mv_port_priv *pp = ap->private_data; | 1166 | struct mv_port_priv *pp = ap->private_data; |
1167 | int err = 0; | ||
955 | 1168 | ||
956 | if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) | 1169 | if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) |
957 | return 0; | 1170 | return 0; |
@@ -959,9 +1172,10 @@ static int mv_stop_edma(struct ata_port *ap) | |||
959 | mv_wait_for_edma_empty_idle(ap); | 1172 | mv_wait_for_edma_empty_idle(ap); |
960 | if (mv_stop_edma_engine(port_mmio)) { | 1173 | if (mv_stop_edma_engine(port_mmio)) { |
961 | ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n"); | 1174 | ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n"); |
962 | return -EIO; | 1175 | err = -EIO; |
963 | } | 1176 | } |
964 | return 0; | 1177 | mv_edma_cfg(ap, 0, 0); |
1178 | return err; | ||
965 | } | 1179 | } |
966 | 1180 | ||
967 | #ifdef ATA_DEBUG | 1181 | #ifdef ATA_DEBUG |
@@ -1130,35 +1344,33 @@ static int mv_qc_defer(struct ata_queued_cmd *qc) | |||
1130 | return ATA_DEFER_PORT; | 1344 | return ATA_DEFER_PORT; |
1131 | } | 1345 | } |
1132 | 1346 | ||
1133 | static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs) | 1347 | static void mv_config_fbs(struct ata_port *ap, int want_ncq, int want_fbs) |
1134 | { | 1348 | { |
1135 | u32 new_fiscfg, old_fiscfg; | 1349 | struct mv_port_priv *pp = ap->private_data; |
1136 | u32 new_ltmode, old_ltmode; | 1350 | void __iomem *port_mmio; |
1137 | u32 new_haltcond, old_haltcond; | ||
1138 | 1351 | ||
1139 | old_fiscfg = readl(port_mmio + FISCFG_OFS); | 1352 | u32 fiscfg, *old_fiscfg = &pp->cached.fiscfg; |
1140 | old_ltmode = readl(port_mmio + LTMODE_OFS); | 1353 | u32 ltmode, *old_ltmode = &pp->cached.ltmode; |
1141 | old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS); | 1354 | u32 haltcond, *old_haltcond = &pp->cached.haltcond; |
1142 | 1355 | ||
1143 | new_fiscfg = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR); | 1356 | ltmode = *old_ltmode & ~LTMODE_BIT8; |
1144 | new_ltmode = old_ltmode & ~LTMODE_BIT8; | 1357 | haltcond = *old_haltcond | EDMA_ERR_DEV; |
1145 | new_haltcond = old_haltcond | EDMA_ERR_DEV; | ||
1146 | 1358 | ||
1147 | if (want_fbs) { | 1359 | if (want_fbs) { |
1148 | new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC; | 1360 | fiscfg = *old_fiscfg | FISCFG_SINGLE_SYNC; |
1149 | new_ltmode = old_ltmode | LTMODE_BIT8; | 1361 | ltmode = *old_ltmode | LTMODE_BIT8; |
1150 | if (want_ncq) | 1362 | if (want_ncq) |
1151 | new_haltcond &= ~EDMA_ERR_DEV; | 1363 | haltcond &= ~EDMA_ERR_DEV; |
1152 | else | 1364 | else |
1153 | new_fiscfg |= FISCFG_WAIT_DEV_ERR; | 1365 | fiscfg |= FISCFG_WAIT_DEV_ERR; |
1366 | } else { | ||
1367 | fiscfg = *old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR); | ||
1154 | } | 1368 | } |
1155 | 1369 | ||
1156 | if (new_fiscfg != old_fiscfg) | 1370 | port_mmio = mv_ap_base(ap); |
1157 | writelfl(new_fiscfg, port_mmio + FISCFG_OFS); | 1371 | mv_write_cached_reg(port_mmio + FISCFG_OFS, old_fiscfg, fiscfg); |
1158 | if (new_ltmode != old_ltmode) | 1372 | mv_write_cached_reg(port_mmio + LTMODE_OFS, old_ltmode, ltmode); |
1159 | writelfl(new_ltmode, port_mmio + LTMODE_OFS); | 1373 | mv_write_cached_reg(port_mmio + EDMA_HALTCOND_OFS, old_haltcond, haltcond); |
1160 | if (new_haltcond != old_haltcond) | ||
1161 | writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS); | ||
1162 | } | 1374 | } |
1163 | 1375 | ||
1164 | static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq) | 1376 | static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq) |
@@ -1176,7 +1388,86 @@ static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq) | |||
1176 | writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS); | 1388 | writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS); |
1177 | } | 1389 | } |
1178 | 1390 | ||
1179 | static void mv_edma_cfg(struct ata_port *ap, int want_ncq) | 1391 | /** |
1392 | * mv_bmdma_enable - set a magic bit on GEN_IIE to allow bmdma | ||
1393 | * @ap: Port being initialized | ||
1394 | * | ||
1395 | * There are two DMA modes on these chips: basic DMA, and EDMA. | ||
1396 | * | ||
1397 | * Bit-0 of the "EDMA RESERVED" register enables/disables use | ||
1398 | * of basic DMA on the GEN_IIE versions of the chips. | ||
1399 | * | ||
1400 | * This bit survives EDMA resets, and must be set for basic DMA | ||
1401 | * to function, and should be cleared when EDMA is active. | ||
1402 | */ | ||
1403 | static void mv_bmdma_enable_iie(struct ata_port *ap, int enable_bmdma) | ||
1404 | { | ||
1405 | struct mv_port_priv *pp = ap->private_data; | ||
1406 | u32 new, *old = &pp->cached.unknown_rsvd; | ||
1407 | |||
1408 | if (enable_bmdma) | ||
1409 | new = *old | 1; | ||
1410 | else | ||
1411 | new = *old & ~1; | ||
1412 | mv_write_cached_reg(mv_ap_base(ap) + EDMA_UNKNOWN_RSVD_OFS, old, new); | ||
1413 | } | ||
1414 | |||
1415 | /* | ||
1416 | * SOC chips have an issue whereby the HDD LEDs don't always blink | ||
1417 | * during I/O when NCQ is enabled. Enabling a special "LED blink" mode | ||
1418 | * of the SOC takes care of it, generating a steady blink rate when | ||
1419 | * any drive on the chip is active. | ||
1420 | * | ||
1421 | * Unfortunately, the blink mode is a global hardware setting for the SOC, | ||
1422 | * so we must use it whenever at least one port on the SOC has NCQ enabled. | ||
1423 | * | ||
1424 | * We turn "LED blink" off when NCQ is not in use anywhere, because the normal | ||
1425 | * LED operation works then, and provides better (more accurate) feedback. | ||
1426 | * | ||
1427 | * Note that this code assumes that an SOC never has more than one HC onboard. | ||
1428 | */ | ||
1429 | static void mv_soc_led_blink_enable(struct ata_port *ap) | ||
1430 | { | ||
1431 | struct ata_host *host = ap->host; | ||
1432 | struct mv_host_priv *hpriv = host->private_data; | ||
1433 | void __iomem *hc_mmio; | ||
1434 | u32 led_ctrl; | ||
1435 | |||
1436 | if (hpriv->hp_flags & MV_HP_QUIRK_LED_BLINK_EN) | ||
1437 | return; | ||
1438 | hpriv->hp_flags |= MV_HP_QUIRK_LED_BLINK_EN; | ||
1439 | hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no); | ||
1440 | led_ctrl = readl(hc_mmio + SOC_LED_CTRL_OFS); | ||
1441 | writel(led_ctrl | SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL_OFS); | ||
1442 | } | ||
1443 | |||
1444 | static void mv_soc_led_blink_disable(struct ata_port *ap) | ||
1445 | { | ||
1446 | struct ata_host *host = ap->host; | ||
1447 | struct mv_host_priv *hpriv = host->private_data; | ||
1448 | void __iomem *hc_mmio; | ||
1449 | u32 led_ctrl; | ||
1450 | unsigned int port; | ||
1451 | |||
1452 | if (!(hpriv->hp_flags & MV_HP_QUIRK_LED_BLINK_EN)) | ||
1453 | return; | ||
1454 | |||
1455 | /* disable led-blink only if no ports are using NCQ */ | ||
1456 | for (port = 0; port < hpriv->n_ports; port++) { | ||
1457 | struct ata_port *this_ap = host->ports[port]; | ||
1458 | struct mv_port_priv *pp = this_ap->private_data; | ||
1459 | |||
1460 | if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) | ||
1461 | return; | ||
1462 | } | ||
1463 | |||
1464 | hpriv->hp_flags &= ~MV_HP_QUIRK_LED_BLINK_EN; | ||
1465 | hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no); | ||
1466 | led_ctrl = readl(hc_mmio + SOC_LED_CTRL_OFS); | ||
1467 | writel(led_ctrl & ~SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL_OFS); | ||
1468 | } | ||
1469 | |||
1470 | static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma) | ||
1180 | { | 1471 | { |
1181 | u32 cfg; | 1472 | u32 cfg; |
1182 | struct mv_port_priv *pp = ap->private_data; | 1473 | struct mv_port_priv *pp = ap->private_data; |
@@ -1185,7 +1476,8 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq) | |||
1185 | 1476 | ||
1186 | /* set up non-NCQ EDMA configuration */ | 1477 | /* set up non-NCQ EDMA configuration */ |
1187 | cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */ | 1478 | cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */ |
1188 | pp->pp_flags &= ~MV_PP_FLAG_FBS_EN; | 1479 | pp->pp_flags &= |
1480 | ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY); | ||
1189 | 1481 | ||
1190 | if (IS_GEN_I(hpriv)) | 1482 | if (IS_GEN_I(hpriv)) |
1191 | cfg |= (1 << 8); /* enab config burst size mask */ | 1483 | cfg |= (1 << 8); /* enab config burst size mask */ |
@@ -1206,7 +1498,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq) | |||
1206 | */ | 1498 | */ |
1207 | want_fbs &= want_ncq; | 1499 | want_fbs &= want_ncq; |
1208 | 1500 | ||
1209 | mv_config_fbs(port_mmio, want_ncq, want_fbs); | 1501 | mv_config_fbs(ap, want_ncq, want_fbs); |
1210 | 1502 | ||
1211 | if (want_fbs) { | 1503 | if (want_fbs) { |
1212 | pp->pp_flags |= MV_PP_FLAG_FBS_EN; | 1504 | pp->pp_flags |= MV_PP_FLAG_FBS_EN; |
@@ -1214,18 +1506,27 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq) | |||
1214 | } | 1506 | } |
1215 | 1507 | ||
1216 | cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ | 1508 | cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ |
1217 | cfg |= (1 << 22); /* enab 4-entry host queue cache */ | 1509 | if (want_edma) { |
1218 | if (!IS_SOC(hpriv)) | 1510 | cfg |= (1 << 22); /* enab 4-entry host queue cache */ |
1219 | cfg |= (1 << 18); /* enab early completion */ | 1511 | if (!IS_SOC(hpriv)) |
1512 | cfg |= (1 << 18); /* enab early completion */ | ||
1513 | } | ||
1220 | if (hpriv->hp_flags & MV_HP_CUT_THROUGH) | 1514 | if (hpriv->hp_flags & MV_HP_CUT_THROUGH) |
1221 | cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ | 1515 | cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ |
1516 | mv_bmdma_enable_iie(ap, !want_edma); | ||
1517 | |||
1518 | if (IS_SOC(hpriv)) { | ||
1519 | if (want_ncq) | ||
1520 | mv_soc_led_blink_enable(ap); | ||
1521 | else | ||
1522 | mv_soc_led_blink_disable(ap); | ||
1523 | } | ||
1222 | } | 1524 | } |
1223 | 1525 | ||
1224 | if (want_ncq) { | 1526 | if (want_ncq) { |
1225 | cfg |= EDMA_CFG_NCQ; | 1527 | cfg |= EDMA_CFG_NCQ; |
1226 | pp->pp_flags |= MV_PP_FLAG_NCQ_EN; | 1528 | pp->pp_flags |= MV_PP_FLAG_NCQ_EN; |
1227 | } else | 1529 | } |
1228 | pp->pp_flags &= ~MV_PP_FLAG_NCQ_EN; | ||
1229 | 1530 | ||
1230 | writelfl(cfg, port_mmio + EDMA_CFG_OFS); | 1531 | writelfl(cfg, port_mmio + EDMA_CFG_OFS); |
1231 | } | 1532 | } |
@@ -1309,6 +1610,8 @@ static int mv_port_start(struct ata_port *ap) | |||
1309 | pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0]; | 1610 | pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0]; |
1310 | } | 1611 | } |
1311 | } | 1612 | } |
1613 | mv_save_cached_regs(ap); | ||
1614 | mv_edma_cfg(ap, 0, 0); | ||
1312 | return 0; | 1615 | return 0; |
1313 | 1616 | ||
1314 | out_port_free_dma_mem: | 1617 | out_port_free_dma_mem: |
@@ -1357,12 +1660,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) | |||
1357 | u32 offset = addr & 0xffff; | 1660 | u32 offset = addr & 0xffff; |
1358 | u32 len = sg_len; | 1661 | u32 len = sg_len; |
1359 | 1662 | ||
1360 | if ((offset + sg_len > 0x10000)) | 1663 | if (offset + len > 0x10000) |
1361 | len = 0x10000 - offset; | 1664 | len = 0x10000 - offset; |
1362 | 1665 | ||
1363 | mv_sg->addr = cpu_to_le32(addr & 0xffffffff); | 1666 | mv_sg->addr = cpu_to_le32(addr & 0xffffffff); |
1364 | mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); | 1667 | mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); |
1365 | mv_sg->flags_size = cpu_to_le32(len & 0xffff); | 1668 | mv_sg->flags_size = cpu_to_le32(len & 0xffff); |
1669 | mv_sg->reserved = 0; | ||
1366 | 1670 | ||
1367 | sg_len -= len; | 1671 | sg_len -= len; |
1368 | addr += len; | 1672 | addr += len; |
@@ -1374,6 +1678,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) | |||
1374 | 1678 | ||
1375 | if (likely(last_sg)) | 1679 | if (likely(last_sg)) |
1376 | last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); | 1680 | last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); |
1681 | mb(); /* ensure data structure is visible to the chipset */ | ||
1377 | } | 1682 | } |
1378 | 1683 | ||
1379 | static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last) | 1684 | static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last) |
@@ -1384,6 +1689,147 @@ static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last) | |||
1384 | } | 1689 | } |
1385 | 1690 | ||
1386 | /** | 1691 | /** |
1692 | * mv_sff_irq_clear - Clear hardware interrupt after DMA. | ||
1693 | * @ap: Port associated with this ATA transaction. | ||
1694 | * | ||
1695 | * We need this only for ATAPI bmdma transactions, | ||
1696 | * as otherwise we experience spurious interrupts | ||
1697 | * after libata-sff handles the bmdma interrupts. | ||
1698 | */ | ||
1699 | static void mv_sff_irq_clear(struct ata_port *ap) | ||
1700 | { | ||
1701 | mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), ERR_IRQ); | ||
1702 | } | ||
1703 | |||
1704 | /** | ||
1705 | * mv_check_atapi_dma - Filter ATAPI cmds which are unsuitable for DMA. | ||
1706 | * @qc: queued command to check for chipset/DMA compatibility. | ||
1707 | * | ||
1708 | * The bmdma engines cannot handle speculative data sizes | ||
1709 | * (bytecount under/over flow). So only allow DMA for | ||
1710 | * data transfer commands with known data sizes. | ||
1711 | * | ||
1712 | * LOCKING: | ||
1713 | * Inherited from caller. | ||
1714 | */ | ||
1715 | static int mv_check_atapi_dma(struct ata_queued_cmd *qc) | ||
1716 | { | ||
1717 | struct scsi_cmnd *scmd = qc->scsicmd; | ||
1718 | |||
1719 | if (scmd) { | ||
1720 | switch (scmd->cmnd[0]) { | ||
1721 | case READ_6: | ||
1722 | case READ_10: | ||
1723 | case READ_12: | ||
1724 | case WRITE_6: | ||
1725 | case WRITE_10: | ||
1726 | case WRITE_12: | ||
1727 | case GPCMD_READ_CD: | ||
1728 | case GPCMD_SEND_DVD_STRUCTURE: | ||
1729 | case GPCMD_SEND_CUE_SHEET: | ||
1730 | return 0; /* DMA is safe */ | ||
1731 | } | ||
1732 | } | ||
1733 | return -EOPNOTSUPP; /* use PIO instead */ | ||
1734 | } | ||
1735 | |||
1736 | /** | ||
1737 | * mv_bmdma_setup - Set up BMDMA transaction | ||
1738 | * @qc: queued command to prepare DMA for. | ||
1739 | * | ||
1740 | * LOCKING: | ||
1741 | * Inherited from caller. | ||
1742 | */ | ||
1743 | static void mv_bmdma_setup(struct ata_queued_cmd *qc) | ||
1744 | { | ||
1745 | struct ata_port *ap = qc->ap; | ||
1746 | void __iomem *port_mmio = mv_ap_base(ap); | ||
1747 | struct mv_port_priv *pp = ap->private_data; | ||
1748 | |||
1749 | mv_fill_sg(qc); | ||
1750 | |||
1751 | /* clear all DMA cmd bits */ | ||
1752 | writel(0, port_mmio + BMDMA_CMD_OFS); | ||
1753 | |||
1754 | /* load PRD table addr. */ | ||
1755 | writel((pp->sg_tbl_dma[qc->tag] >> 16) >> 16, | ||
1756 | port_mmio + BMDMA_PRD_HIGH_OFS); | ||
1757 | writelfl(pp->sg_tbl_dma[qc->tag], | ||
1758 | port_mmio + BMDMA_PRD_LOW_OFS); | ||
1759 | |||
1760 | /* issue r/w command */ | ||
1761 | ap->ops->sff_exec_command(ap, &qc->tf); | ||
1762 | } | ||
1763 | |||
1764 | /** | ||
1765 | * mv_bmdma_start - Start a BMDMA transaction | ||
1766 | * @qc: queued command to start DMA on. | ||
1767 | * | ||
1768 | * LOCKING: | ||
1769 | * Inherited from caller. | ||
1770 | */ | ||
1771 | static void mv_bmdma_start(struct ata_queued_cmd *qc) | ||
1772 | { | ||
1773 | struct ata_port *ap = qc->ap; | ||
1774 | void __iomem *port_mmio = mv_ap_base(ap); | ||
1775 | unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); | ||
1776 | u32 cmd = (rw ? 0 : ATA_DMA_WR) | ATA_DMA_START; | ||
1777 | |||
1778 | /* start host DMA transaction */ | ||
1779 | writelfl(cmd, port_mmio + BMDMA_CMD_OFS); | ||
1780 | } | ||
1781 | |||
1782 | /** | ||
1783 | * mv_bmdma_stop - Stop BMDMA transfer | ||
1784 | * @qc: queued command to stop DMA on. | ||
1785 | * | ||
1786 | * Clears the ATA_DMA_START flag in the bmdma control register | ||
1787 | * | ||
1788 | * LOCKING: | ||
1789 | * Inherited from caller. | ||
1790 | */ | ||
1791 | static void mv_bmdma_stop(struct ata_queued_cmd *qc) | ||
1792 | { | ||
1793 | struct ata_port *ap = qc->ap; | ||
1794 | void __iomem *port_mmio = mv_ap_base(ap); | ||
1795 | u32 cmd; | ||
1796 | |||
1797 | /* clear start/stop bit */ | ||
1798 | cmd = readl(port_mmio + BMDMA_CMD_OFS); | ||
1799 | cmd &= ~ATA_DMA_START; | ||
1800 | writelfl(cmd, port_mmio + BMDMA_CMD_OFS); | ||
1801 | |||
1802 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | ||
1803 | ata_sff_dma_pause(ap); | ||
1804 | } | ||
1805 | |||
1806 | /** | ||
1807 | * mv_bmdma_status - Read BMDMA status | ||
1808 | * @ap: port for which to retrieve DMA status. | ||
1809 | * | ||
1810 | * Read and return equivalent of the sff BMDMA status register. | ||
1811 | * | ||
1812 | * LOCKING: | ||
1813 | * Inherited from caller. | ||
1814 | */ | ||
1815 | static u8 mv_bmdma_status(struct ata_port *ap) | ||
1816 | { | ||
1817 | void __iomem *port_mmio = mv_ap_base(ap); | ||
1818 | u32 reg, status; | ||
1819 | |||
1820 | /* | ||
1821 | * Other bits are valid only if ATA_DMA_ACTIVE==0, | ||
1822 | * and the ATA_DMA_INTR bit doesn't exist. | ||
1823 | */ | ||
1824 | reg = readl(port_mmio + BMDMA_STATUS_OFS); | ||
1825 | if (reg & ATA_DMA_ACTIVE) | ||
1826 | status = ATA_DMA_ACTIVE; | ||
1827 | else | ||
1828 | status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; | ||
1829 | return status; | ||
1830 | } | ||
1831 | |||
1832 | /** | ||
1387 | * mv_qc_prep - Host specific command preparation. | 1833 | * mv_qc_prep - Host specific command preparation. |
1388 | * @qc: queued command to prepare | 1834 | * @qc: queued command to prepare |
1389 | * | 1835 | * |
@@ -1545,6 +1991,132 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
1545 | } | 1991 | } |
1546 | 1992 | ||
1547 | /** | 1993 | /** |
1994 | * mv_sff_check_status - fetch device status, if valid | ||
1995 | * @ap: ATA port to fetch status from | ||
1996 | * | ||
1997 | * When using command issue via mv_qc_issue_fis(), | ||
1998 | * the initial ATA_BUSY state does not show up in the | ||
1999 | * ATA status (shadow) register. This can confuse libata! | ||
2000 | * | ||
2001 | * So we have a hook here to fake ATA_BUSY for that situation, | ||
2002 | * until the first time a BUSY, DRQ, or ERR bit is seen. | ||
2003 | * | ||
2004 | * The rest of the time, it simply returns the ATA status register. | ||
2005 | */ | ||
2006 | static u8 mv_sff_check_status(struct ata_port *ap) | ||
2007 | { | ||
2008 | u8 stat = ioread8(ap->ioaddr.status_addr); | ||
2009 | struct mv_port_priv *pp = ap->private_data; | ||
2010 | |||
2011 | if (pp->pp_flags & MV_PP_FLAG_FAKE_ATA_BUSY) { | ||
2012 | if (stat & (ATA_BUSY | ATA_DRQ | ATA_ERR)) | ||
2013 | pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY; | ||
2014 | else | ||
2015 | stat = ATA_BUSY; | ||
2016 | } | ||
2017 | return stat; | ||
2018 | } | ||
2019 | |||
2020 | /** | ||
2021 | * mv_send_fis - Send a FIS, using the "Vendor-Unique FIS" register | ||
2022 | * @fis: fis to be sent | ||
2023 | * @nwords: number of 32-bit words in the fis | ||
2024 | */ | ||
2025 | static unsigned int mv_send_fis(struct ata_port *ap, u32 *fis, int nwords) | ||
2026 | { | ||
2027 | void __iomem *port_mmio = mv_ap_base(ap); | ||
2028 | u32 ifctl, old_ifctl, ifstat; | ||
2029 | int i, timeout = 200, final_word = nwords - 1; | ||
2030 | |||
2031 | /* Initiate FIS transmission mode */ | ||
2032 | old_ifctl = readl(port_mmio + SATA_IFCTL_OFS); | ||
2033 | ifctl = 0x100 | (old_ifctl & 0xf); | ||
2034 | writelfl(ifctl, port_mmio + SATA_IFCTL_OFS); | ||
2035 | |||
2036 | /* Send all words of the FIS except for the final word */ | ||
2037 | for (i = 0; i < final_word; ++i) | ||
2038 | writel(fis[i], port_mmio + VENDOR_UNIQUE_FIS_OFS); | ||
2039 | |||
2040 | /* Flag end-of-transmission, and then send the final word */ | ||
2041 | writelfl(ifctl | 0x200, port_mmio + SATA_IFCTL_OFS); | ||
2042 | writelfl(fis[final_word], port_mmio + VENDOR_UNIQUE_FIS_OFS); | ||
2043 | |||
2044 | /* | ||
2045 | * Wait for FIS transmission to complete. | ||
2046 | * This typically takes just a single iteration. | ||
2047 | */ | ||
2048 | do { | ||
2049 | ifstat = readl(port_mmio + SATA_IFSTAT_OFS); | ||
2050 | } while (!(ifstat & 0x1000) && --timeout); | ||
2051 | |||
2052 | /* Restore original port configuration */ | ||
2053 | writelfl(old_ifctl, port_mmio + SATA_IFCTL_OFS); | ||
2054 | |||
2055 | /* See if it worked */ | ||
2056 | if ((ifstat & 0x3000) != 0x1000) { | ||
2057 | ata_port_printk(ap, KERN_WARNING, | ||
2058 | "%s transmission error, ifstat=%08x\n", | ||
2059 | __func__, ifstat); | ||
2060 | return AC_ERR_OTHER; | ||
2061 | } | ||
2062 | return 0; | ||
2063 | } | ||
2064 | |||
2065 | /** | ||
2066 | * mv_qc_issue_fis - Issue a command directly as a FIS | ||
2067 | * @qc: queued command to start | ||
2068 | * | ||
2069 | * Note that the ATA shadow registers are not updated | ||
2070 | * after command issue, so the device will appear "READY" | ||
2071 | * if polled, even while it is BUSY processing the command. | ||
2072 | * | ||
2073 | * So we use a status hook to fake ATA_BUSY until the drive changes state. | ||
2074 | * | ||
2075 | * Note: we don't get updated shadow regs on *completion* | ||
2076 | * of non-data commands. So avoid sending them via this function, | ||
2077 | * as they will appear to have completed immediately. | ||
2078 | * | ||
2079 | * GEN_IIE has special registers that we could get the result tf from, | ||
2080 | * but earlier chipsets do not. For now, we ignore those registers. | ||
2081 | */ | ||
2082 | static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc) | ||
2083 | { | ||
2084 | struct ata_port *ap = qc->ap; | ||
2085 | struct mv_port_priv *pp = ap->private_data; | ||
2086 | struct ata_link *link = qc->dev->link; | ||
2087 | u32 fis[5]; | ||
2088 | int err = 0; | ||
2089 | |||
2090 | ata_tf_to_fis(&qc->tf, link->pmp, 1, (void *)fis); | ||
2091 | err = mv_send_fis(ap, fis, sizeof(fis) / sizeof(fis[0])); | ||
2092 | if (err) | ||
2093 | return err; | ||
2094 | |||
2095 | switch (qc->tf.protocol) { | ||
2096 | case ATAPI_PROT_PIO: | ||
2097 | pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY; | ||
2098 | /* fall through */ | ||
2099 | case ATAPI_PROT_NODATA: | ||
2100 | ap->hsm_task_state = HSM_ST_FIRST; | ||
2101 | break; | ||
2102 | case ATA_PROT_PIO: | ||
2103 | pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY; | ||
2104 | if (qc->tf.flags & ATA_TFLAG_WRITE) | ||
2105 | ap->hsm_task_state = HSM_ST_FIRST; | ||
2106 | else | ||
2107 | ap->hsm_task_state = HSM_ST; | ||
2108 | break; | ||
2109 | default: | ||
2110 | ap->hsm_task_state = HSM_ST_LAST; | ||
2111 | break; | ||
2112 | } | ||
2113 | |||
2114 | if (qc->tf.flags & ATA_TFLAG_POLLING) | ||
2115 | ata_pio_queue_task(ap, qc, 0); | ||
2116 | return 0; | ||
2117 | } | ||
2118 | |||
2119 | /** | ||
1548 | * mv_qc_issue - Initiate a command to the host | 2120 | * mv_qc_issue - Initiate a command to the host |
1549 | * @qc: queued command to start | 2121 | * @qc: queued command to start |
1550 | * | 2122 | * |
@@ -1558,14 +2130,28 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
1558 | */ | 2130 | */ |
1559 | static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | 2131 | static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) |
1560 | { | 2132 | { |
2133 | static int limit_warnings = 10; | ||
1561 | struct ata_port *ap = qc->ap; | 2134 | struct ata_port *ap = qc->ap; |
1562 | void __iomem *port_mmio = mv_ap_base(ap); | 2135 | void __iomem *port_mmio = mv_ap_base(ap); |
1563 | struct mv_port_priv *pp = ap->private_data; | 2136 | struct mv_port_priv *pp = ap->private_data; |
1564 | u32 in_index; | 2137 | u32 in_index; |
2138 | unsigned int port_irqs; | ||
1565 | 2139 | ||
1566 | if ((qc->tf.protocol != ATA_PROT_DMA) && | 2140 | pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY; /* paranoia */ |
1567 | (qc->tf.protocol != ATA_PROT_NCQ)) { | 2141 | |
1568 | static int limit_warnings = 10; | 2142 | switch (qc->tf.protocol) { |
2143 | case ATA_PROT_DMA: | ||
2144 | case ATA_PROT_NCQ: | ||
2145 | mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); | ||
2146 | pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; | ||
2147 | in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT; | ||
2148 | |||
2149 | /* Write the request in pointer to kick the EDMA to life */ | ||
2150 | writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index, | ||
2151 | port_mmio + EDMA_REQ_Q_IN_PTR_OFS); | ||
2152 | return 0; | ||
2153 | |||
2154 | case ATA_PROT_PIO: | ||
1569 | /* | 2155 | /* |
1570 | * Errata SATA#16, SATA#24: warn if multiple DRQs expected. | 2156 | * Errata SATA#16, SATA#24: warn if multiple DRQs expected. |
1571 | * | 2157 | * |
@@ -1583,27 +2169,46 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
1583 | ": attempting PIO w/multiple DRQ: " | 2169 | ": attempting PIO w/multiple DRQ: " |
1584 | "this may fail due to h/w errata\n"); | 2170 | "this may fail due to h/w errata\n"); |
1585 | } | 2171 | } |
1586 | /* | 2172 | /* drop through */ |
1587 | * We're about to send a non-EDMA capable command to the | 2173 | case ATA_PROT_NODATA: |
1588 | * port. Turn off EDMA so there won't be problems accessing | 2174 | case ATAPI_PROT_PIO: |
1589 | * shadow block, etc registers. | 2175 | case ATAPI_PROT_NODATA: |
1590 | */ | 2176 | if (ap->flags & ATA_FLAG_PIO_POLLING) |
1591 | mv_stop_edma(ap); | 2177 | qc->tf.flags |= ATA_TFLAG_POLLING; |
1592 | mv_enable_port_irqs(ap, ERR_IRQ); | 2178 | break; |
1593 | mv_pmp_select(ap, qc->dev->link->pmp); | ||
1594 | return ata_sff_qc_issue(qc); | ||
1595 | } | 2179 | } |
1596 | 2180 | ||
1597 | mv_start_dma(ap, port_mmio, pp, qc->tf.protocol); | 2181 | if (qc->tf.flags & ATA_TFLAG_POLLING) |
1598 | 2182 | port_irqs = ERR_IRQ; /* mask device interrupt when polling */ | |
1599 | pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; | 2183 | else |
1600 | in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT; | 2184 | port_irqs = ERR_IRQ | DONE_IRQ; /* unmask all interrupts */ |
1601 | 2185 | ||
1602 | /* and write the request in pointer to kick the EDMA to life */ | 2186 | /* |
1603 | writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index, | 2187 | * We're about to send a non-EDMA capable command to the |
1604 | port_mmio + EDMA_REQ_Q_IN_PTR_OFS); | 2188 | * port. Turn off EDMA so there won't be problems accessing |
2189 | * shadow block, etc registers. | ||
2190 | */ | ||
2191 | mv_stop_edma(ap); | ||
2192 | mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs); | ||
2193 | mv_pmp_select(ap, qc->dev->link->pmp); | ||
1605 | 2194 | ||
1606 | return 0; | 2195 | if (qc->tf.command == ATA_CMD_READ_LOG_EXT) { |
2196 | struct mv_host_priv *hpriv = ap->host->private_data; | ||
2197 | /* | ||
2198 | * Workaround for 88SX60x1 FEr SATA#25 (part 2). | ||
2199 | * | ||
2200 | * After any NCQ error, the READ_LOG_EXT command | ||
2201 | * from libata-eh *must* use mv_qc_issue_fis(). | ||
2202 | * Otherwise it might fail, due to chip errata. | ||
2203 | * | ||
2204 | * Rather than special-case it, we'll just *always* | ||
2205 | * use this method here for READ_LOG_EXT, making for | ||
2206 | * easier testing. | ||
2207 | */ | ||
2208 | if (IS_GEN_II(hpriv)) | ||
2209 | return mv_qc_issue_fis(qc); | ||
2210 | } | ||
2211 | return ata_sff_qc_issue(qc); | ||
1607 | } | 2212 | } |
1608 | 2213 | ||
1609 | static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) | 2214 | static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) |
@@ -1614,8 +2219,12 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) | |||
1614 | if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) | 2219 | if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) |
1615 | return NULL; | 2220 | return NULL; |
1616 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 2221 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
1617 | if (qc && (qc->tf.flags & ATA_TFLAG_POLLING)) | 2222 | if (qc) { |
1618 | qc = NULL; | 2223 | if (qc->tf.flags & ATA_TFLAG_POLLING) |
2224 | qc = NULL; | ||
2225 | else if (!(qc->flags & ATA_QCFLAG_ACTIVE)) | ||
2226 | qc = NULL; | ||
2227 | } | ||
1619 | return qc; | 2228 | return qc; |
1620 | } | 2229 | } |
1621 | 2230 | ||
@@ -2084,6 +2693,10 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause) | |||
2084 | void __iomem *mmio = hpriv->base, *hc_mmio; | 2693 | void __iomem *mmio = hpriv->base, *hc_mmio; |
2085 | unsigned int handled = 0, port; | 2694 | unsigned int handled = 0, port; |
2086 | 2695 | ||
2696 | /* If asserted, clear the "all ports" IRQ coalescing bit */ | ||
2697 | if (main_irq_cause & ALL_PORTS_COAL_DONE) | ||
2698 | writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE); | ||
2699 | |||
2087 | for (port = 0; port < hpriv->n_ports; port++) { | 2700 | for (port = 0; port < hpriv->n_ports; port++) { |
2088 | struct ata_port *ap = host->ports[port]; | 2701 | struct ata_port *ap = host->ports[port]; |
2089 | unsigned int p, shift, hardport, port_cause; | 2702 | unsigned int p, shift, hardport, port_cause; |
@@ -2116,6 +2729,8 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause) | |||
2116 | * to ack (only) those ports via hc_irq_cause. | 2729 | * to ack (only) those ports via hc_irq_cause. |
2117 | */ | 2730 | */ |
2118 | ack_irqs = 0; | 2731 | ack_irqs = 0; |
2732 | if (hc_cause & PORTS_0_3_COAL_DONE) | ||
2733 | ack_irqs = HC_COAL_IRQ; | ||
2119 | for (p = 0; p < MV_PORTS_PER_HC; ++p) { | 2734 | for (p = 0; p < MV_PORTS_PER_HC; ++p) { |
2120 | if ((port + p) >= hpriv->n_ports) | 2735 | if ((port + p) >= hpriv->n_ports) |
2121 | break; | 2736 | break; |
@@ -2204,7 +2819,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
2204 | 2819 | ||
2205 | /* for MSI: block new interrupts while in here */ | 2820 | /* for MSI: block new interrupts while in here */ |
2206 | if (using_msi) | 2821 | if (using_msi) |
2207 | writel(0, hpriv->main_irq_mask_addr); | 2822 | mv_write_main_irq_mask(0, hpriv); |
2208 | 2823 | ||
2209 | main_irq_cause = readl(hpriv->main_irq_cause_addr); | 2824 | main_irq_cause = readl(hpriv->main_irq_cause_addr); |
2210 | pending_irqs = main_irq_cause & hpriv->main_irq_mask; | 2825 | pending_irqs = main_irq_cause & hpriv->main_irq_mask; |
@@ -2221,7 +2836,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
2221 | 2836 | ||
2222 | /* for MSI: unmask; interrupt cause bits will retrigger now */ | 2837 | /* for MSI: unmask; interrupt cause bits will retrigger now */ |
2223 | if (using_msi) | 2838 | if (using_msi) |
2224 | writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr); | 2839 | mv_write_main_irq_mask(hpriv->main_irq_mask, hpriv); |
2225 | 2840 | ||
2226 | spin_unlock(&host->lock); | 2841 | spin_unlock(&host->lock); |
2227 | 2842 | ||
@@ -2774,6 +3389,8 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, | |||
2774 | 3389 | ||
2775 | mv_reset_channel(hpriv, mmio, ap->port_no); | 3390 | mv_reset_channel(hpriv, mmio, ap->port_no); |
2776 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | 3391 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; |
3392 | pp->pp_flags &= | ||
3393 | ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY); | ||
2777 | 3394 | ||
2778 | /* Workaround for errata FEr SATA#10 (part 2) */ | 3395 | /* Workaround for errata FEr SATA#10 (part 2) */ |
2779 | do { | 3396 | do { |
@@ -2793,6 +3410,8 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, | |||
2793 | extra = HZ; /* only extend it once, max */ | 3410 | extra = HZ; /* only extend it once, max */ |
2794 | } | 3411 | } |
2795 | } while (sstatus != 0x0 && sstatus != 0x113 && sstatus != 0x123); | 3412 | } while (sstatus != 0x0 && sstatus != 0x113 && sstatus != 0x123); |
3413 | mv_save_cached_regs(ap); | ||
3414 | mv_edma_cfg(ap, 0, 0); | ||
2796 | 3415 | ||
2797 | return rc; | 3416 | return rc; |
2798 | } | 3417 | } |
@@ -3126,6 +3745,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3126 | * The per-port interrupts get done later as ports are set up. | 3745 | * The per-port interrupts get done later as ports are set up. |
3127 | */ | 3746 | */ |
3128 | mv_set_main_irq_mask(host, 0, PCI_ERR); | 3747 | mv_set_main_irq_mask(host, 0, PCI_ERR); |
3748 | mv_set_irq_coalescing(host, irq_coalescing_io_count, | ||
3749 | irq_coalescing_usecs); | ||
3129 | done: | 3750 | done: |
3130 | return rc; | 3751 | return rc; |
3131 | } | 3752 | } |
@@ -3287,12 +3908,6 @@ static struct pci_driver mv_pci_driver = { | |||
3287 | .remove = ata_pci_remove_one, | 3908 | .remove = ata_pci_remove_one, |
3288 | }; | 3909 | }; |
3289 | 3910 | ||
3290 | /* | ||
3291 | * module options | ||
3292 | */ | ||
3293 | static int msi; /* Use PCI msi; either zero (off, default) or non-zero */ | ||
3294 | |||
3295 | |||
3296 | /* move to PCI layer or libata core? */ | 3911 | /* move to PCI layer or libata core? */ |
3297 | static int pci_go_64(struct pci_dev *pdev) | 3912 | static int pci_go_64(struct pci_dev *pdev) |
3298 | { | 3913 | { |
@@ -3474,10 +4089,5 @@ MODULE_DEVICE_TABLE(pci, mv_pci_tbl); | |||
3474 | MODULE_VERSION(DRV_VERSION); | 4089 | MODULE_VERSION(DRV_VERSION); |
3475 | MODULE_ALIAS("platform:" DRV_NAME); | 4090 | MODULE_ALIAS("platform:" DRV_NAME); |
3476 | 4091 | ||
3477 | #ifdef CONFIG_PCI | ||
3478 | module_param(msi, int, 0444); | ||
3479 | MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)"); | ||
3480 | #endif | ||
3481 | |||
3482 | module_init(mv_init); | 4092 | module_init(mv_init); |
3483 | module_exit(mv_exit); | 4093 | module_exit(mv_exit); |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index f65b53785a8f..6cda12ba8122 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -57,9 +57,9 @@ enum { | |||
57 | NV_MMIO_BAR = 5, | 57 | NV_MMIO_BAR = 5, |
58 | 58 | ||
59 | NV_PORTS = 2, | 59 | NV_PORTS = 2, |
60 | NV_PIO_MASK = 0x1f, | 60 | NV_PIO_MASK = ATA_PIO4, |
61 | NV_MWDMA_MASK = 0x07, | 61 | NV_MWDMA_MASK = ATA_MWDMA2, |
62 | NV_UDMA_MASK = 0x7f, | 62 | NV_UDMA_MASK = ATA_UDMA6, |
63 | NV_PORT0_SCR_REG_OFFSET = 0x00, | 63 | NV_PORT0_SCR_REG_OFFSET = 0x00, |
64 | NV_PORT1_SCR_REG_OFFSET = 0x40, | 64 | NV_PORT1_SCR_REG_OFFSET = 0x40, |
65 | 65 | ||
@@ -408,6 +408,7 @@ static struct scsi_host_template nv_swncq_sht = { | |||
408 | 408 | ||
409 | static struct ata_port_operations nv_common_ops = { | 409 | static struct ata_port_operations nv_common_ops = { |
410 | .inherits = &ata_bmdma_port_ops, | 410 | .inherits = &ata_bmdma_port_ops, |
411 | .lost_interrupt = ATA_OP_NULL, | ||
411 | .scr_read = nv_scr_read, | 412 | .scr_read = nv_scr_read, |
412 | .scr_write = nv_scr_write, | 413 | .scr_write = nv_scr_write, |
413 | }; | 414 | }; |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index ba9a2570a742..b1fd7d62071a 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -176,7 +176,9 @@ static const struct ata_port_operations pdc_common_ops = { | |||
176 | .check_atapi_dma = pdc_check_atapi_dma, | 176 | .check_atapi_dma = pdc_check_atapi_dma, |
177 | .qc_prep = pdc_qc_prep, | 177 | .qc_prep = pdc_qc_prep, |
178 | .qc_issue = pdc_qc_issue, | 178 | .qc_issue = pdc_qc_issue, |
179 | |||
179 | .sff_irq_clear = pdc_irq_clear, | 180 | .sff_irq_clear = pdc_irq_clear, |
181 | .lost_interrupt = ATA_OP_NULL, | ||
180 | 182 | ||
181 | .post_internal_cmd = pdc_post_internal_cmd, | 183 | .post_internal_cmd = pdc_post_internal_cmd, |
182 | .error_handler = pdc_error_handler, | 184 | .error_handler = pdc_error_handler, |
@@ -213,8 +215,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
213 | { | 215 | { |
214 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | | 216 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | |
215 | PDC_FLAG_SATA_PATA, | 217 | PDC_FLAG_SATA_PATA, |
216 | .pio_mask = 0x1f, /* pio0-4 */ | 218 | .pio_mask = ATA_PIO4, |
217 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 219 | .mwdma_mask = ATA_MWDMA2, |
218 | .udma_mask = ATA_UDMA6, | 220 | .udma_mask = ATA_UDMA6, |
219 | .port_ops = &pdc_old_sata_ops, | 221 | .port_ops = &pdc_old_sata_ops, |
220 | }, | 222 | }, |
@@ -222,8 +224,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
222 | [board_2037x_pata] = | 224 | [board_2037x_pata] = |
223 | { | 225 | { |
224 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, | 226 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, |
225 | .pio_mask = 0x1f, /* pio0-4 */ | 227 | .pio_mask = ATA_PIO4, |
226 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 228 | .mwdma_mask = ATA_MWDMA2, |
227 | .udma_mask = ATA_UDMA6, | 229 | .udma_mask = ATA_UDMA6, |
228 | .port_ops = &pdc_pata_ops, | 230 | .port_ops = &pdc_pata_ops, |
229 | }, | 231 | }, |
@@ -232,8 +234,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
232 | { | 234 | { |
233 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | | 235 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | |
234 | PDC_FLAG_4_PORTS, | 236 | PDC_FLAG_4_PORTS, |
235 | .pio_mask = 0x1f, /* pio0-4 */ | 237 | .pio_mask = ATA_PIO4, |
236 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 238 | .mwdma_mask = ATA_MWDMA2, |
237 | .udma_mask = ATA_UDMA6, | 239 | .udma_mask = ATA_UDMA6, |
238 | .port_ops = &pdc_old_sata_ops, | 240 | .port_ops = &pdc_old_sata_ops, |
239 | }, | 241 | }, |
@@ -242,8 +244,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
242 | { | 244 | { |
243 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS | | 245 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS | |
244 | PDC_FLAG_4_PORTS, | 246 | PDC_FLAG_4_PORTS, |
245 | .pio_mask = 0x1f, /* pio0-4 */ | 247 | .pio_mask = ATA_PIO4, |
246 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 248 | .mwdma_mask = ATA_MWDMA2, |
247 | .udma_mask = ATA_UDMA6, | 249 | .udma_mask = ATA_UDMA6, |
248 | .port_ops = &pdc_pata_ops, | 250 | .port_ops = &pdc_pata_ops, |
249 | }, | 251 | }, |
@@ -252,8 +254,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
252 | { | 254 | { |
253 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | | 255 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | |
254 | PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA, | 256 | PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA, |
255 | .pio_mask = 0x1f, /* pio0-4 */ | 257 | .pio_mask = ATA_PIO4, |
256 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 258 | .mwdma_mask = ATA_MWDMA2, |
257 | .udma_mask = ATA_UDMA6, | 259 | .udma_mask = ATA_UDMA6, |
258 | .port_ops = &pdc_sata_ops, | 260 | .port_ops = &pdc_sata_ops, |
259 | }, | 261 | }, |
@@ -262,8 +264,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
262 | { | 264 | { |
263 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS | | 265 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS | |
264 | PDC_FLAG_GEN_II, | 266 | PDC_FLAG_GEN_II, |
265 | .pio_mask = 0x1f, /* pio0-4 */ | 267 | .pio_mask = ATA_PIO4, |
266 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 268 | .mwdma_mask = ATA_MWDMA2, |
267 | .udma_mask = ATA_UDMA6, | 269 | .udma_mask = ATA_UDMA6, |
268 | .port_ops = &pdc_pata_ops, | 270 | .port_ops = &pdc_pata_ops, |
269 | }, | 271 | }, |
@@ -272,8 +274,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
272 | { | 274 | { |
273 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | | 275 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | |
274 | PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS, | 276 | PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS, |
275 | .pio_mask = 0x1f, /* pio0-4 */ | 277 | .pio_mask = ATA_PIO4, |
276 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 278 | .mwdma_mask = ATA_MWDMA2, |
277 | .udma_mask = ATA_UDMA6, | 279 | .udma_mask = ATA_UDMA6, |
278 | .port_ops = &pdc_sata_ops, | 280 | .port_ops = &pdc_sata_ops, |
279 | }, | 281 | }, |
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index a000c86ac859..c3936d35cdac 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -147,6 +147,7 @@ static struct ata_port_operations qs_ata_ops = { | |||
147 | .softreset = ATA_OP_NULL, | 147 | .softreset = ATA_OP_NULL, |
148 | .error_handler = qs_error_handler, | 148 | .error_handler = qs_error_handler, |
149 | .post_internal_cmd = ATA_OP_NULL, | 149 | .post_internal_cmd = ATA_OP_NULL, |
150 | .lost_interrupt = ATA_OP_NULL, | ||
150 | 151 | ||
151 | .scr_read = qs_scr_read, | 152 | .scr_read = qs_scr_read, |
152 | .scr_write = qs_scr_write, | 153 | .scr_write = qs_scr_write, |
@@ -160,7 +161,7 @@ static const struct ata_port_info qs_port_info[] = { | |||
160 | { | 161 | { |
161 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 162 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
162 | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, | 163 | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, |
163 | .pio_mask = 0x10, /* pio4 */ | 164 | .pio_mask = ATA_PIO4_ONLY, |
164 | .udma_mask = ATA_UDMA6, | 165 | .udma_mask = ATA_UDMA6, |
165 | .port_ops = &qs_ata_ops, | 166 | .port_ops = &qs_ata_ops, |
166 | }, | 167 | }, |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index d0091609e210..e67ce8e5caa5 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -200,8 +200,8 @@ static const struct ata_port_info sil_port_info[] = { | |||
200 | /* sil_3112 */ | 200 | /* sil_3112 */ |
201 | { | 201 | { |
202 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, | 202 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, |
203 | .pio_mask = 0x1f, /* pio0-4 */ | 203 | .pio_mask = ATA_PIO4, |
204 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 204 | .mwdma_mask = ATA_MWDMA2, |
205 | .udma_mask = ATA_UDMA5, | 205 | .udma_mask = ATA_UDMA5, |
206 | .port_ops = &sil_ops, | 206 | .port_ops = &sil_ops, |
207 | }, | 207 | }, |
@@ -209,24 +209,24 @@ static const struct ata_port_info sil_port_info[] = { | |||
209 | { | 209 | { |
210 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE | | 210 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE | |
211 | SIL_FLAG_NO_SATA_IRQ, | 211 | SIL_FLAG_NO_SATA_IRQ, |
212 | .pio_mask = 0x1f, /* pio0-4 */ | 212 | .pio_mask = ATA_PIO4, |
213 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 213 | .mwdma_mask = ATA_MWDMA2, |
214 | .udma_mask = ATA_UDMA5, | 214 | .udma_mask = ATA_UDMA5, |
215 | .port_ops = &sil_ops, | 215 | .port_ops = &sil_ops, |
216 | }, | 216 | }, |
217 | /* sil_3512 */ | 217 | /* sil_3512 */ |
218 | { | 218 | { |
219 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, | 219 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, |
220 | .pio_mask = 0x1f, /* pio0-4 */ | 220 | .pio_mask = ATA_PIO4, |
221 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 221 | .mwdma_mask = ATA_MWDMA2, |
222 | .udma_mask = ATA_UDMA5, | 222 | .udma_mask = ATA_UDMA5, |
223 | .port_ops = &sil_ops, | 223 | .port_ops = &sil_ops, |
224 | }, | 224 | }, |
225 | /* sil_3114 */ | 225 | /* sil_3114 */ |
226 | { | 226 | { |
227 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, | 227 | .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, |
228 | .pio_mask = 0x1f, /* pio0-4 */ | 228 | .pio_mask = ATA_PIO4, |
229 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 229 | .mwdma_mask = ATA_MWDMA2, |
230 | .udma_mask = ATA_UDMA5, | 230 | .udma_mask = ATA_UDMA5, |
231 | .port_ops = &sil_ops, | 231 | .port_ops = &sil_ops, |
232 | }, | 232 | }, |
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 2590c2279fa7..0d8990dcdfcd 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -429,25 +429,25 @@ static const struct ata_port_info sil24_port_info[] = { | |||
429 | { | 429 | { |
430 | .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) | | 430 | .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) | |
431 | SIL24_FLAG_PCIX_IRQ_WOC, | 431 | SIL24_FLAG_PCIX_IRQ_WOC, |
432 | .pio_mask = 0x1f, /* pio0-4 */ | 432 | .pio_mask = ATA_PIO4, |
433 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 433 | .mwdma_mask = ATA_MWDMA2, |
434 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 434 | .udma_mask = ATA_UDMA5, |
435 | .port_ops = &sil24_ops, | 435 | .port_ops = &sil24_ops, |
436 | }, | 436 | }, |
437 | /* sil_3132 */ | 437 | /* sil_3132 */ |
438 | { | 438 | { |
439 | .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), | 439 | .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), |
440 | .pio_mask = 0x1f, /* pio0-4 */ | 440 | .pio_mask = ATA_PIO4, |
441 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 441 | .mwdma_mask = ATA_MWDMA2, |
442 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 442 | .udma_mask = ATA_UDMA5, |
443 | .port_ops = &sil24_ops, | 443 | .port_ops = &sil24_ops, |
444 | }, | 444 | }, |
445 | /* sil_3131/sil_3531 */ | 445 | /* sil_3131/sil_3531 */ |
446 | { | 446 | { |
447 | .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), | 447 | .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), |
448 | .pio_mask = 0x1f, /* pio0-4 */ | 448 | .pio_mask = ATA_PIO4, |
449 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 449 | .mwdma_mask = ATA_MWDMA2, |
450 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 450 | .udma_mask = ATA_UDMA5, |
451 | .port_ops = &sil24_ops, | 451 | .port_ops = &sil24_ops, |
452 | }, | 452 | }, |
453 | }; | 453 | }; |
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 9c43b4e7c4a6..8f9833228619 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -97,8 +97,8 @@ static struct ata_port_operations sis_ops = { | |||
97 | 97 | ||
98 | static const struct ata_port_info sis_port_info = { | 98 | static const struct ata_port_info sis_port_info = { |
99 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | 99 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, |
100 | .pio_mask = 0x1f, | 100 | .pio_mask = ATA_PIO4, |
101 | .mwdma_mask = 0x7, | 101 | .mwdma_mask = ATA_MWDMA2, |
102 | .udma_mask = ATA_UDMA6, | 102 | .udma_mask = ATA_UDMA6, |
103 | .port_ops = &sis_ops, | 103 | .port_ops = &sis_ops, |
104 | }; | 104 | }; |
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 609d147813ae..7257f2d5c52c 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
@@ -361,8 +361,8 @@ static const struct ata_port_info k2_port_info[] = { | |||
361 | { | 361 | { |
362 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 362 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
363 | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, | 363 | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, |
364 | .pio_mask = 0x1f, | 364 | .pio_mask = ATA_PIO4, |
365 | .mwdma_mask = 0x07, | 365 | .mwdma_mask = ATA_MWDMA2, |
366 | .udma_mask = ATA_UDMA6, | 366 | .udma_mask = ATA_UDMA6, |
367 | .port_ops = &k2_sata_ops, | 367 | .port_ops = &k2_sata_ops, |
368 | }, | 368 | }, |
@@ -371,8 +371,8 @@ static const struct ata_port_info k2_port_info[] = { | |||
371 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 371 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
372 | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | | 372 | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | |
373 | K2_FLAG_SATA_8_PORTS, | 373 | K2_FLAG_SATA_8_PORTS, |
374 | .pio_mask = 0x1f, | 374 | .pio_mask = ATA_PIO4, |
375 | .mwdma_mask = 0x07, | 375 | .mwdma_mask = ATA_MWDMA2, |
376 | .udma_mask = ATA_UDMA6, | 376 | .udma_mask = ATA_UDMA6, |
377 | .port_ops = &k2_sata_ops, | 377 | .port_ops = &k2_sata_ops, |
378 | }, | 378 | }, |
@@ -380,8 +380,8 @@ static const struct ata_port_info k2_port_info[] = { | |||
380 | { | 380 | { |
381 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 381 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
382 | ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3, | 382 | ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3, |
383 | .pio_mask = 0x1f, | 383 | .pio_mask = ATA_PIO4, |
384 | .mwdma_mask = 0x07, | 384 | .mwdma_mask = ATA_MWDMA2, |
385 | .udma_mask = ATA_UDMA6, | 385 | .udma_mask = ATA_UDMA6, |
386 | .port_ops = &k2_sata_ops, | 386 | .port_ops = &k2_sata_ops, |
387 | }, | 387 | }, |
@@ -389,8 +389,8 @@ static const struct ata_port_info k2_port_info[] = { | |||
389 | { | 389 | { |
390 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 390 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
391 | ATA_FLAG_MMIO, | 391 | ATA_FLAG_MMIO, |
392 | .pio_mask = 0x1f, | 392 | .pio_mask = ATA_PIO4, |
393 | .mwdma_mask = 0x07, | 393 | .mwdma_mask = ATA_MWDMA2, |
394 | .udma_mask = ATA_UDMA6, | 394 | .udma_mask = ATA_UDMA6, |
395 | .port_ops = &k2_sata_ops, | 395 | .port_ops = &k2_sata_ops, |
396 | }, | 396 | }, |
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index ec04b8d3c791..dce3dccced3f 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c | |||
@@ -265,8 +265,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
265 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 265 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
266 | ATA_FLAG_SRST | ATA_FLAG_MMIO | | 266 | ATA_FLAG_SRST | ATA_FLAG_MMIO | |
267 | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, | 267 | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, |
268 | .pio_mask = 0x1f, /* pio0-4 */ | 268 | .pio_mask = ATA_PIO4, |
269 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 269 | .mwdma_mask = ATA_MWDMA2, |
270 | .udma_mask = ATA_UDMA6, | 270 | .udma_mask = ATA_UDMA6, |
271 | .port_ops = &pdc_20621_ops, | 271 | .port_ops = &pdc_20621_ops, |
272 | }, | 272 | }, |
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 019575bb3e08..e5bff47e8aa1 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c | |||
@@ -89,7 +89,7 @@ static struct ata_port_operations uli_ops = { | |||
89 | static const struct ata_port_info uli_port_info = { | 89 | static const struct ata_port_info uli_port_info = { |
90 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 90 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
91 | ATA_FLAG_IGN_SIMPLEX, | 91 | ATA_FLAG_IGN_SIMPLEX, |
92 | .pio_mask = 0x1f, /* pio0-4 */ | 92 | .pio_mask = ATA_PIO4, |
93 | .udma_mask = ATA_UDMA6, | 93 | .udma_mask = ATA_UDMA6, |
94 | .port_ops = &uli_ops, | 94 | .port_ops = &uli_ops, |
95 | }; | 95 | }; |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 5c62da9cd491..98e8c50703b3 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -146,24 +146,24 @@ static struct ata_port_operations vt8251_ops = { | |||
146 | 146 | ||
147 | static const struct ata_port_info vt6420_port_info = { | 147 | static const struct ata_port_info vt6420_port_info = { |
148 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | 148 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, |
149 | .pio_mask = 0x1f, | 149 | .pio_mask = ATA_PIO4, |
150 | .mwdma_mask = 0x07, | 150 | .mwdma_mask = ATA_MWDMA2, |
151 | .udma_mask = ATA_UDMA6, | 151 | .udma_mask = ATA_UDMA6, |
152 | .port_ops = &vt6420_sata_ops, | 152 | .port_ops = &vt6420_sata_ops, |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static struct ata_port_info vt6421_sport_info = { | 155 | static struct ata_port_info vt6421_sport_info = { |
156 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, | 156 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, |
157 | .pio_mask = 0x1f, | 157 | .pio_mask = ATA_PIO4, |
158 | .mwdma_mask = 0x07, | 158 | .mwdma_mask = ATA_MWDMA2, |
159 | .udma_mask = ATA_UDMA6, | 159 | .udma_mask = ATA_UDMA6, |
160 | .port_ops = &vt6421_sata_ops, | 160 | .port_ops = &vt6421_sata_ops, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static struct ata_port_info vt6421_pport_info = { | 163 | static struct ata_port_info vt6421_pport_info = { |
164 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY, | 164 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY, |
165 | .pio_mask = 0x1f, | 165 | .pio_mask = ATA_PIO4, |
166 | .mwdma_mask = 0, | 166 | /* No MWDMA */ |
167 | .udma_mask = ATA_UDMA6, | 167 | .udma_mask = ATA_UDMA6, |
168 | .port_ops = &vt6421_pata_ops, | 168 | .port_ops = &vt6421_pata_ops, |
169 | }; | 169 | }; |
@@ -171,8 +171,8 @@ static struct ata_port_info vt6421_pport_info = { | |||
171 | static struct ata_port_info vt8251_port_info = { | 171 | static struct ata_port_info vt8251_port_info = { |
172 | .flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS | | 172 | .flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS | |
173 | ATA_FLAG_NO_LEGACY, | 173 | ATA_FLAG_NO_LEGACY, |
174 | .pio_mask = 0x1f, | 174 | .pio_mask = ATA_PIO4, |
175 | .mwdma_mask = 0x07, | 175 | .mwdma_mask = ATA_MWDMA2, |
176 | .udma_mask = ATA_UDMA6, | 176 | .udma_mask = ATA_UDMA6, |
177 | .port_ops = &vt8251_ops, | 177 | .port_ops = &vt8251_ops, |
178 | }; | 178 | }; |
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index c57cdff9e6bd..ed70bd28fa2c 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c | |||
@@ -308,6 +308,9 @@ static struct scsi_host_template vsc_sata_sht = { | |||
308 | 308 | ||
309 | static struct ata_port_operations vsc_sata_ops = { | 309 | static struct ata_port_operations vsc_sata_ops = { |
310 | .inherits = &ata_bmdma_port_ops, | 310 | .inherits = &ata_bmdma_port_ops, |
311 | /* The IRQ handling is not quite standard SFF behaviour so we | ||
312 | cannot use the default lost interrupt handler */ | ||
313 | .lost_interrupt = ATA_OP_NULL, | ||
311 | .sff_tf_load = vsc_sata_tf_load, | 314 | .sff_tf_load = vsc_sata_tf_load, |
312 | .sff_tf_read = vsc_sata_tf_read, | 315 | .sff_tf_read = vsc_sata_tf_read, |
313 | .freeze = vsc_freeze, | 316 | .freeze = vsc_freeze, |
@@ -345,8 +348,8 @@ static int __devinit vsc_sata_init_one(struct pci_dev *pdev, | |||
345 | static const struct ata_port_info pi = { | 348 | static const struct ata_port_info pi = { |
346 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 349 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
347 | ATA_FLAG_MMIO, | 350 | ATA_FLAG_MMIO, |
348 | .pio_mask = 0x1f, | 351 | .pio_mask = ATA_PIO4, |
349 | .mwdma_mask = 0x07, | 352 | .mwdma_mask = ATA_MWDMA2, |
350 | .udma_mask = ATA_UDMA6, | 353 | .udma_mask = ATA_UDMA6, |
351 | .port_ops = &vsc_sata_ops, | 354 | .port_ops = &vsc_sata_ops, |
352 | }; | 355 | }; |
diff --git a/drivers/base/base.h b/drivers/base/base.h index 9f50f1b545dc..ddc97496db4a 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -63,6 +63,32 @@ struct class_private { | |||
63 | #define to_class(obj) \ | 63 | #define to_class(obj) \ |
64 | container_of(obj, struct class_private, class_subsys.kobj) | 64 | container_of(obj, struct class_private, class_subsys.kobj) |
65 | 65 | ||
66 | /** | ||
67 | * struct device_private - structure to hold the private to the driver core portions of the device structure. | ||
68 | * | ||
69 | * @klist_children - klist containing all children of this device | ||
70 | * @knode_parent - node in sibling list | ||
71 | * @knode_driver - node in driver list | ||
72 | * @knode_bus - node in bus list | ||
73 | * @device - pointer back to the struct class that this structure is | ||
74 | * associated with. | ||
75 | * | ||
76 | * Nothing outside of the driver core should ever touch these fields. | ||
77 | */ | ||
78 | struct device_private { | ||
79 | struct klist klist_children; | ||
80 | struct klist_node knode_parent; | ||
81 | struct klist_node knode_driver; | ||
82 | struct klist_node knode_bus; | ||
83 | struct device *device; | ||
84 | }; | ||
85 | #define to_device_private_parent(obj) \ | ||
86 | container_of(obj, struct device_private, knode_parent) | ||
87 | #define to_device_private_driver(obj) \ | ||
88 | container_of(obj, struct device_private, knode_driver) | ||
89 | #define to_device_private_bus(obj) \ | ||
90 | container_of(obj, struct device_private, knode_bus) | ||
91 | |||
66 | /* initialisation functions */ | 92 | /* initialisation functions */ |
67 | extern int devices_init(void); | 93 | extern int devices_init(void); |
68 | extern int buses_init(void); | 94 | extern int buses_init(void); |
@@ -86,6 +112,11 @@ extern void bus_remove_driver(struct device_driver *drv); | |||
86 | 112 | ||
87 | extern void driver_detach(struct device_driver *drv); | 113 | extern void driver_detach(struct device_driver *drv); |
88 | extern int driver_probe_device(struct device_driver *drv, struct device *dev); | 114 | extern int driver_probe_device(struct device_driver *drv, struct device *dev); |
115 | static inline int driver_match_device(struct device_driver *drv, | ||
116 | struct device *dev) | ||
117 | { | ||
118 | return drv->bus->match && drv->bus->match(dev, drv); | ||
119 | } | ||
89 | 120 | ||
90 | extern void sysdev_shutdown(void); | 121 | extern void sysdev_shutdown(void); |
91 | 122 | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 83f32b891fa9..dc030f1f00f1 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
198 | int err = -ENODEV; | 198 | int err = -ENODEV; |
199 | 199 | ||
200 | dev = bus_find_device_by_name(bus, NULL, buf); | 200 | dev = bus_find_device_by_name(bus, NULL, buf); |
201 | if (dev && dev->driver == NULL) { | 201 | if (dev && dev->driver == NULL && driver_match_device(drv, dev)) { |
202 | if (dev->parent) /* Needed for USB */ | 202 | if (dev->parent) /* Needed for USB */ |
203 | down(&dev->parent->sem); | 203 | down(&dev->parent->sem); |
204 | down(&dev->sem); | 204 | down(&dev->sem); |
@@ -253,7 +253,14 @@ static ssize_t store_drivers_probe(struct bus_type *bus, | |||
253 | static struct device *next_device(struct klist_iter *i) | 253 | static struct device *next_device(struct klist_iter *i) |
254 | { | 254 | { |
255 | struct klist_node *n = klist_next(i); | 255 | struct klist_node *n = klist_next(i); |
256 | return n ? container_of(n, struct device, knode_bus) : NULL; | 256 | struct device *dev = NULL; |
257 | struct device_private *dev_prv; | ||
258 | |||
259 | if (n) { | ||
260 | dev_prv = to_device_private_bus(n); | ||
261 | dev = dev_prv->device; | ||
262 | } | ||
263 | return dev; | ||
257 | } | 264 | } |
258 | 265 | ||
259 | /** | 266 | /** |
@@ -286,7 +293,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start, | |||
286 | return -EINVAL; | 293 | return -EINVAL; |
287 | 294 | ||
288 | klist_iter_init_node(&bus->p->klist_devices, &i, | 295 | klist_iter_init_node(&bus->p->klist_devices, &i, |
289 | (start ? &start->knode_bus : NULL)); | 296 | (start ? &start->p->knode_bus : NULL)); |
290 | while ((dev = next_device(&i)) && !error) | 297 | while ((dev = next_device(&i)) && !error) |
291 | error = fn(dev, data); | 298 | error = fn(dev, data); |
292 | klist_iter_exit(&i); | 299 | klist_iter_exit(&i); |
@@ -320,7 +327,7 @@ struct device *bus_find_device(struct bus_type *bus, | |||
320 | return NULL; | 327 | return NULL; |
321 | 328 | ||
322 | klist_iter_init_node(&bus->p->klist_devices, &i, | 329 | klist_iter_init_node(&bus->p->klist_devices, &i, |
323 | (start ? &start->knode_bus : NULL)); | 330 | (start ? &start->p->knode_bus : NULL)); |
324 | while ((dev = next_device(&i))) | 331 | while ((dev = next_device(&i))) |
325 | if (match(dev, data) && get_device(dev)) | 332 | if (match(dev, data) && get_device(dev)) |
326 | break; | 333 | break; |
@@ -507,7 +514,8 @@ void bus_attach_device(struct device *dev) | |||
507 | ret = device_attach(dev); | 514 | ret = device_attach(dev); |
508 | WARN_ON(ret < 0); | 515 | WARN_ON(ret < 0); |
509 | if (ret >= 0) | 516 | if (ret >= 0) |
510 | klist_add_tail(&dev->knode_bus, &bus->p->klist_devices); | 517 | klist_add_tail(&dev->p->knode_bus, |
518 | &bus->p->klist_devices); | ||
511 | } | 519 | } |
512 | } | 520 | } |
513 | 521 | ||
@@ -528,8 +536,8 @@ void bus_remove_device(struct device *dev) | |||
528 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, | 536 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
529 | dev_name(dev)); | 537 | dev_name(dev)); |
530 | device_remove_attrs(dev->bus, dev); | 538 | device_remove_attrs(dev->bus, dev); |
531 | if (klist_node_attached(&dev->knode_bus)) | 539 | if (klist_node_attached(&dev->p->knode_bus)) |
532 | klist_del(&dev->knode_bus); | 540 | klist_del(&dev->p->knode_bus); |
533 | 541 | ||
534 | pr_debug("bus: '%s': remove device %s\n", | 542 | pr_debug("bus: '%s': remove device %s\n", |
535 | dev->bus->name, dev_name(dev)); | 543 | dev->bus->name, dev_name(dev)); |
@@ -831,14 +839,16 @@ static void bus_remove_attrs(struct bus_type *bus) | |||
831 | 839 | ||
832 | static void klist_devices_get(struct klist_node *n) | 840 | static void klist_devices_get(struct klist_node *n) |
833 | { | 841 | { |
834 | struct device *dev = container_of(n, struct device, knode_bus); | 842 | struct device_private *dev_prv = to_device_private_bus(n); |
843 | struct device *dev = dev_prv->device; | ||
835 | 844 | ||
836 | get_device(dev); | 845 | get_device(dev); |
837 | } | 846 | } |
838 | 847 | ||
839 | static void klist_devices_put(struct klist_node *n) | 848 | static void klist_devices_put(struct klist_node *n) |
840 | { | 849 | { |
841 | struct device *dev = container_of(n, struct device, knode_bus); | 850 | struct device_private *dev_prv = to_device_private_bus(n); |
851 | struct device *dev = dev_prv->device; | ||
842 | 852 | ||
843 | put_device(dev); | 853 | put_device(dev); |
844 | } | 854 | } |
@@ -932,6 +942,7 @@ bus_uevent_fail: | |||
932 | kset_unregister(&bus->p->subsys); | 942 | kset_unregister(&bus->p->subsys); |
933 | kfree(bus->p); | 943 | kfree(bus->p); |
934 | out: | 944 | out: |
945 | bus->p = NULL; | ||
935 | return retval; | 946 | return retval; |
936 | } | 947 | } |
937 | EXPORT_SYMBOL_GPL(bus_register); | 948 | EXPORT_SYMBOL_GPL(bus_register); |
@@ -953,6 +964,7 @@ void bus_unregister(struct bus_type *bus) | |||
953 | bus_remove_file(bus, &bus_attr_uevent); | 964 | bus_remove_file(bus, &bus_attr_uevent); |
954 | kset_unregister(&bus->p->subsys); | 965 | kset_unregister(&bus->p->subsys); |
955 | kfree(bus->p); | 966 | kfree(bus->p); |
967 | bus->p = NULL; | ||
956 | } | 968 | } |
957 | EXPORT_SYMBOL_GPL(bus_unregister); | 969 | EXPORT_SYMBOL_GPL(bus_unregister); |
958 | 970 | ||
@@ -993,18 +1005,20 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list | |||
993 | { | 1005 | { |
994 | struct list_head *pos; | 1006 | struct list_head *pos; |
995 | struct klist_node *n; | 1007 | struct klist_node *n; |
1008 | struct device_private *dev_prv; | ||
996 | struct device *b; | 1009 | struct device *b; |
997 | 1010 | ||
998 | list_for_each(pos, list) { | 1011 | list_for_each(pos, list) { |
999 | n = container_of(pos, struct klist_node, n_node); | 1012 | n = container_of(pos, struct klist_node, n_node); |
1000 | b = container_of(n, struct device, knode_bus); | 1013 | dev_prv = to_device_private_bus(n); |
1014 | b = dev_prv->device; | ||
1001 | if (compare(a, b) <= 0) { | 1015 | if (compare(a, b) <= 0) { |
1002 | list_move_tail(&a->knode_bus.n_node, | 1016 | list_move_tail(&a->p->knode_bus.n_node, |
1003 | &b->knode_bus.n_node); | 1017 | &b->p->knode_bus.n_node); |
1004 | return; | 1018 | return; |
1005 | } | 1019 | } |
1006 | } | 1020 | } |
1007 | list_move_tail(&a->knode_bus.n_node, list); | 1021 | list_move_tail(&a->p->knode_bus.n_node, list); |
1008 | } | 1022 | } |
1009 | 1023 | ||
1010 | void bus_sort_breadthfirst(struct bus_type *bus, | 1024 | void bus_sort_breadthfirst(struct bus_type *bus, |
@@ -1014,6 +1028,7 @@ void bus_sort_breadthfirst(struct bus_type *bus, | |||
1014 | LIST_HEAD(sorted_devices); | 1028 | LIST_HEAD(sorted_devices); |
1015 | struct list_head *pos, *tmp; | 1029 | struct list_head *pos, *tmp; |
1016 | struct klist_node *n; | 1030 | struct klist_node *n; |
1031 | struct device_private *dev_prv; | ||
1017 | struct device *dev; | 1032 | struct device *dev; |
1018 | struct klist *device_klist; | 1033 | struct klist *device_klist; |
1019 | 1034 | ||
@@ -1022,7 +1037,8 @@ void bus_sort_breadthfirst(struct bus_type *bus, | |||
1022 | spin_lock(&device_klist->k_lock); | 1037 | spin_lock(&device_klist->k_lock); |
1023 | list_for_each_safe(pos, tmp, &device_klist->k_list) { | 1038 | list_for_each_safe(pos, tmp, &device_klist->k_list) { |
1024 | n = container_of(pos, struct klist_node, n_node); | 1039 | n = container_of(pos, struct klist_node, n_node); |
1025 | dev = container_of(n, struct device, knode_bus); | 1040 | dev_prv = to_device_private_bus(n); |
1041 | dev = dev_prv->device; | ||
1026 | device_insertion_sort_klist(dev, &sorted_devices, compare); | 1042 | device_insertion_sort_klist(dev, &sorted_devices, compare); |
1027 | } | 1043 | } |
1028 | list_splice(&sorted_devices, &device_klist->k_list); | 1044 | list_splice(&sorted_devices, &device_klist->k_list); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index f3eae630e589..e73c92d13a23 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -109,6 +109,7 @@ static struct sysfs_ops dev_sysfs_ops = { | |||
109 | static void device_release(struct kobject *kobj) | 109 | static void device_release(struct kobject *kobj) |
110 | { | 110 | { |
111 | struct device *dev = to_dev(kobj); | 111 | struct device *dev = to_dev(kobj); |
112 | struct device_private *p = dev->p; | ||
112 | 113 | ||
113 | if (dev->release) | 114 | if (dev->release) |
114 | dev->release(dev); | 115 | dev->release(dev); |
@@ -120,6 +121,7 @@ static void device_release(struct kobject *kobj) | |||
120 | WARN(1, KERN_ERR "Device '%s' does not have a release() " | 121 | WARN(1, KERN_ERR "Device '%s' does not have a release() " |
121 | "function, it is broken and must be fixed.\n", | 122 | "function, it is broken and must be fixed.\n", |
122 | dev_name(dev)); | 123 | dev_name(dev)); |
124 | kfree(p); | ||
123 | } | 125 | } |
124 | 126 | ||
125 | static struct kobj_type device_ktype = { | 127 | static struct kobj_type device_ktype = { |
@@ -134,8 +136,6 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) | |||
134 | 136 | ||
135 | if (ktype == &device_ktype) { | 137 | if (ktype == &device_ktype) { |
136 | struct device *dev = to_dev(kobj); | 138 | struct device *dev = to_dev(kobj); |
137 | if (dev->uevent_suppress) | ||
138 | return 0; | ||
139 | if (dev->bus) | 139 | if (dev->bus) |
140 | return 1; | 140 | return 1; |
141 | if (dev->class) | 141 | if (dev->class) |
@@ -507,14 +507,16 @@ EXPORT_SYMBOL_GPL(device_schedule_callback_owner); | |||
507 | 507 | ||
508 | static void klist_children_get(struct klist_node *n) | 508 | static void klist_children_get(struct klist_node *n) |
509 | { | 509 | { |
510 | struct device *dev = container_of(n, struct device, knode_parent); | 510 | struct device_private *p = to_device_private_parent(n); |
511 | struct device *dev = p->device; | ||
511 | 512 | ||
512 | get_device(dev); | 513 | get_device(dev); |
513 | } | 514 | } |
514 | 515 | ||
515 | static void klist_children_put(struct klist_node *n) | 516 | static void klist_children_put(struct klist_node *n) |
516 | { | 517 | { |
517 | struct device *dev = container_of(n, struct device, knode_parent); | 518 | struct device_private *p = to_device_private_parent(n); |
519 | struct device *dev = p->device; | ||
518 | 520 | ||
519 | put_device(dev); | 521 | put_device(dev); |
520 | } | 522 | } |
@@ -538,8 +540,6 @@ void device_initialize(struct device *dev) | |||
538 | { | 540 | { |
539 | dev->kobj.kset = devices_kset; | 541 | dev->kobj.kset = devices_kset; |
540 | kobject_init(&dev->kobj, &device_ktype); | 542 | kobject_init(&dev->kobj, &device_ktype); |
541 | klist_init(&dev->klist_children, klist_children_get, | ||
542 | klist_children_put); | ||
543 | INIT_LIST_HEAD(&dev->dma_pools); | 543 | INIT_LIST_HEAD(&dev->dma_pools); |
544 | init_MUTEX(&dev->sem); | 544 | init_MUTEX(&dev->sem); |
545 | spin_lock_init(&dev->devres_lock); | 545 | spin_lock_init(&dev->devres_lock); |
@@ -777,17 +777,12 @@ static void device_remove_class_symlinks(struct device *dev) | |||
777 | int dev_set_name(struct device *dev, const char *fmt, ...) | 777 | int dev_set_name(struct device *dev, const char *fmt, ...) |
778 | { | 778 | { |
779 | va_list vargs; | 779 | va_list vargs; |
780 | char *s; | 780 | int err; |
781 | 781 | ||
782 | va_start(vargs, fmt); | 782 | va_start(vargs, fmt); |
783 | vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs); | 783 | err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); |
784 | va_end(vargs); | 784 | va_end(vargs); |
785 | 785 | return err; | |
786 | /* ewww... some of these buggers have / in the name... */ | ||
787 | while ((s = strchr(dev->bus_id, '/'))) | ||
788 | *s = '!'; | ||
789 | |||
790 | return 0; | ||
791 | } | 786 | } |
792 | EXPORT_SYMBOL_GPL(dev_set_name); | 787 | EXPORT_SYMBOL_GPL(dev_set_name); |
793 | 788 | ||
@@ -864,12 +859,26 @@ int device_add(struct device *dev) | |||
864 | if (!dev) | 859 | if (!dev) |
865 | goto done; | 860 | goto done; |
866 | 861 | ||
867 | /* Temporarily support init_name if it is set. | 862 | dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); |
868 | * It will override bus_id for now */ | 863 | if (!dev->p) { |
869 | if (dev->init_name) | 864 | error = -ENOMEM; |
870 | dev_set_name(dev, "%s", dev->init_name); | 865 | goto done; |
866 | } | ||
867 | dev->p->device = dev; | ||
868 | klist_init(&dev->p->klist_children, klist_children_get, | ||
869 | klist_children_put); | ||
870 | |||
871 | /* | ||
872 | * for statically allocated devices, which should all be converted | ||
873 | * some day, we need to initialize the name. We prevent reading back | ||
874 | * the name, and force the use of dev_name() | ||
875 | */ | ||
876 | if (dev->init_name) { | ||
877 | dev_set_name(dev, dev->init_name); | ||
878 | dev->init_name = NULL; | ||
879 | } | ||
871 | 880 | ||
872 | if (!strlen(dev->bus_id)) | 881 | if (!dev_name(dev)) |
873 | goto done; | 882 | goto done; |
874 | 883 | ||
875 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | 884 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); |
@@ -928,7 +937,8 @@ int device_add(struct device *dev) | |||
928 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 937 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
929 | bus_attach_device(dev); | 938 | bus_attach_device(dev); |
930 | if (parent) | 939 | if (parent) |
931 | klist_add_tail(&dev->knode_parent, &parent->klist_children); | 940 | klist_add_tail(&dev->p->knode_parent, |
941 | &parent->p->klist_children); | ||
932 | 942 | ||
933 | if (dev->class) { | 943 | if (dev->class) { |
934 | mutex_lock(&dev->class->p->class_mutex); | 944 | mutex_lock(&dev->class->p->class_mutex); |
@@ -1042,7 +1052,7 @@ void device_del(struct device *dev) | |||
1042 | device_pm_remove(dev); | 1052 | device_pm_remove(dev); |
1043 | dpm_sysfs_remove(dev); | 1053 | dpm_sysfs_remove(dev); |
1044 | if (parent) | 1054 | if (parent) |
1045 | klist_del(&dev->knode_parent); | 1055 | klist_del(&dev->p->knode_parent); |
1046 | if (MAJOR(dev->devt)) { | 1056 | if (MAJOR(dev->devt)) { |
1047 | device_remove_sys_dev_entry(dev); | 1057 | device_remove_sys_dev_entry(dev); |
1048 | device_remove_file(dev, &devt_attr); | 1058 | device_remove_file(dev, &devt_attr); |
@@ -1103,7 +1113,14 @@ void device_unregister(struct device *dev) | |||
1103 | static struct device *next_device(struct klist_iter *i) | 1113 | static struct device *next_device(struct klist_iter *i) |
1104 | { | 1114 | { |
1105 | struct klist_node *n = klist_next(i); | 1115 | struct klist_node *n = klist_next(i); |
1106 | return n ? container_of(n, struct device, knode_parent) : NULL; | 1116 | struct device *dev = NULL; |
1117 | struct device_private *p; | ||
1118 | |||
1119 | if (n) { | ||
1120 | p = to_device_private_parent(n); | ||
1121 | dev = p->device; | ||
1122 | } | ||
1123 | return dev; | ||
1107 | } | 1124 | } |
1108 | 1125 | ||
1109 | /** | 1126 | /** |
@@ -1125,7 +1142,7 @@ int device_for_each_child(struct device *parent, void *data, | |||
1125 | struct device *child; | 1142 | struct device *child; |
1126 | int error = 0; | 1143 | int error = 0; |
1127 | 1144 | ||
1128 | klist_iter_init(&parent->klist_children, &i); | 1145 | klist_iter_init(&parent->p->klist_children, &i); |
1129 | while ((child = next_device(&i)) && !error) | 1146 | while ((child = next_device(&i)) && !error) |
1130 | error = fn(child, data); | 1147 | error = fn(child, data); |
1131 | klist_iter_exit(&i); | 1148 | klist_iter_exit(&i); |
@@ -1156,7 +1173,7 @@ struct device *device_find_child(struct device *parent, void *data, | |||
1156 | if (!parent) | 1173 | if (!parent) |
1157 | return NULL; | 1174 | return NULL; |
1158 | 1175 | ||
1159 | klist_iter_init(&parent->klist_children, &i); | 1176 | klist_iter_init(&parent->p->klist_children, &i); |
1160 | while ((child = next_device(&i))) | 1177 | while ((child = next_device(&i))) |
1161 | if (match(child, data) && get_device(child)) | 1178 | if (match(child, data) && get_device(child)) |
1162 | break; | 1179 | break; |
@@ -1348,7 +1365,10 @@ struct device *device_create_vargs(struct class *class, struct device *parent, | |||
1348 | dev->release = device_create_release; | 1365 | dev->release = device_create_release; |
1349 | dev_set_drvdata(dev, drvdata); | 1366 | dev_set_drvdata(dev, drvdata); |
1350 | 1367 | ||
1351 | vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args); | 1368 | retval = kobject_set_name_vargs(&dev->kobj, fmt, args); |
1369 | if (retval) | ||
1370 | goto error; | ||
1371 | |||
1352 | retval = device_register(dev); | 1372 | retval = device_register(dev); |
1353 | if (retval) | 1373 | if (retval) |
1354 | goto error; | 1374 | goto error; |
@@ -1452,19 +1472,15 @@ int device_rename(struct device *dev, char *new_name) | |||
1452 | old_class_name = make_class_name(dev->class->name, &dev->kobj); | 1472 | old_class_name = make_class_name(dev->class->name, &dev->kobj); |
1453 | #endif | 1473 | #endif |
1454 | 1474 | ||
1455 | old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); | 1475 | old_device_name = kstrdup(dev_name(dev), GFP_KERNEL); |
1456 | if (!old_device_name) { | 1476 | if (!old_device_name) { |
1457 | error = -ENOMEM; | 1477 | error = -ENOMEM; |
1458 | goto out; | 1478 | goto out; |
1459 | } | 1479 | } |
1460 | strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE); | ||
1461 | strlcpy(dev->bus_id, new_name, BUS_ID_SIZE); | ||
1462 | 1480 | ||
1463 | error = kobject_rename(&dev->kobj, new_name); | 1481 | error = kobject_rename(&dev->kobj, new_name); |
1464 | if (error) { | 1482 | if (error) |
1465 | strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE); | ||
1466 | goto out; | 1483 | goto out; |
1467 | } | ||
1468 | 1484 | ||
1469 | #ifdef CONFIG_SYSFS_DEPRECATED | 1485 | #ifdef CONFIG_SYSFS_DEPRECATED |
1470 | if (old_class_name) { | 1486 | if (old_class_name) { |
@@ -1545,8 +1561,10 @@ out: | |||
1545 | * device_move - moves a device to a new parent | 1561 | * device_move - moves a device to a new parent |
1546 | * @dev: the pointer to the struct device to be moved | 1562 | * @dev: the pointer to the struct device to be moved |
1547 | * @new_parent: the new parent of the device (can by NULL) | 1563 | * @new_parent: the new parent of the device (can by NULL) |
1564 | * @dpm_order: how to reorder the dpm_list | ||
1548 | */ | 1565 | */ |
1549 | int device_move(struct device *dev, struct device *new_parent) | 1566 | int device_move(struct device *dev, struct device *new_parent, |
1567 | enum dpm_order dpm_order) | ||
1550 | { | 1568 | { |
1551 | int error; | 1569 | int error; |
1552 | struct device *old_parent; | 1570 | struct device *old_parent; |
@@ -1556,6 +1574,7 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1556 | if (!dev) | 1574 | if (!dev) |
1557 | return -EINVAL; | 1575 | return -EINVAL; |
1558 | 1576 | ||
1577 | device_pm_lock(); | ||
1559 | new_parent = get_device(new_parent); | 1578 | new_parent = get_device(new_parent); |
1560 | new_parent_kobj = get_device_parent(dev, new_parent); | 1579 | new_parent_kobj = get_device_parent(dev, new_parent); |
1561 | 1580 | ||
@@ -1570,9 +1589,10 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1570 | old_parent = dev->parent; | 1589 | old_parent = dev->parent; |
1571 | dev->parent = new_parent; | 1590 | dev->parent = new_parent; |
1572 | if (old_parent) | 1591 | if (old_parent) |
1573 | klist_remove(&dev->knode_parent); | 1592 | klist_remove(&dev->p->knode_parent); |
1574 | if (new_parent) { | 1593 | if (new_parent) { |
1575 | klist_add_tail(&dev->knode_parent, &new_parent->klist_children); | 1594 | klist_add_tail(&dev->p->knode_parent, |
1595 | &new_parent->p->klist_children); | ||
1576 | set_dev_node(dev, dev_to_node(new_parent)); | 1596 | set_dev_node(dev, dev_to_node(new_parent)); |
1577 | } | 1597 | } |
1578 | 1598 | ||
@@ -1584,11 +1604,11 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1584 | device_move_class_links(dev, new_parent, old_parent); | 1604 | device_move_class_links(dev, new_parent, old_parent); |
1585 | if (!kobject_move(&dev->kobj, &old_parent->kobj)) { | 1605 | if (!kobject_move(&dev->kobj, &old_parent->kobj)) { |
1586 | if (new_parent) | 1606 | if (new_parent) |
1587 | klist_remove(&dev->knode_parent); | 1607 | klist_remove(&dev->p->knode_parent); |
1588 | dev->parent = old_parent; | 1608 | dev->parent = old_parent; |
1589 | if (old_parent) { | 1609 | if (old_parent) { |
1590 | klist_add_tail(&dev->knode_parent, | 1610 | klist_add_tail(&dev->p->knode_parent, |
1591 | &old_parent->klist_children); | 1611 | &old_parent->p->klist_children); |
1592 | set_dev_node(dev, dev_to_node(old_parent)); | 1612 | set_dev_node(dev, dev_to_node(old_parent)); |
1593 | } | 1613 | } |
1594 | } | 1614 | } |
@@ -1596,9 +1616,23 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1596 | put_device(new_parent); | 1616 | put_device(new_parent); |
1597 | goto out; | 1617 | goto out; |
1598 | } | 1618 | } |
1619 | switch (dpm_order) { | ||
1620 | case DPM_ORDER_NONE: | ||
1621 | break; | ||
1622 | case DPM_ORDER_DEV_AFTER_PARENT: | ||
1623 | device_pm_move_after(dev, new_parent); | ||
1624 | break; | ||
1625 | case DPM_ORDER_PARENT_BEFORE_DEV: | ||
1626 | device_pm_move_before(new_parent, dev); | ||
1627 | break; | ||
1628 | case DPM_ORDER_DEV_LAST: | ||
1629 | device_pm_move_last(dev); | ||
1630 | break; | ||
1631 | } | ||
1599 | out_put: | 1632 | out_put: |
1600 | put_device(old_parent); | 1633 | put_device(old_parent); |
1601 | out: | 1634 | out: |
1635 | device_pm_unlock(); | ||
1602 | put_device(dev); | 1636 | put_device(dev); |
1603 | return error; | 1637 | return error; |
1604 | } | 1638 | } |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 135231239103..f17c3266a0e0 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | static void driver_bound(struct device *dev) | 31 | static void driver_bound(struct device *dev) |
32 | { | 32 | { |
33 | if (klist_node_attached(&dev->knode_driver)) { | 33 | if (klist_node_attached(&dev->p->knode_driver)) { |
34 | printk(KERN_WARNING "%s: device %s already bound\n", | 34 | printk(KERN_WARNING "%s: device %s already bound\n", |
35 | __func__, kobject_name(&dev->kobj)); | 35 | __func__, kobject_name(&dev->kobj)); |
36 | return; | 36 | return; |
@@ -43,7 +43,7 @@ static void driver_bound(struct device *dev) | |||
43 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, | 43 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
44 | BUS_NOTIFY_BOUND_DRIVER, dev); | 44 | BUS_NOTIFY_BOUND_DRIVER, dev); |
45 | 45 | ||
46 | klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices); | 46 | klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); |
47 | } | 47 | } |
48 | 48 | ||
49 | static int driver_sysfs_add(struct device *dev) | 49 | static int driver_sysfs_add(struct device *dev) |
@@ -172,16 +172,12 @@ int driver_probe_done(void) | |||
172 | /** | 172 | /** |
173 | * wait_for_device_probe | 173 | * wait_for_device_probe |
174 | * Wait for device probing to be completed. | 174 | * Wait for device probing to be completed. |
175 | * | ||
176 | * Note: this function polls at 100 msec intervals. | ||
177 | */ | 175 | */ |
178 | int wait_for_device_probe(void) | 176 | void wait_for_device_probe(void) |
179 | { | 177 | { |
180 | /* wait for the known devices to complete their probing */ | 178 | /* wait for the known devices to complete their probing */ |
181 | while (driver_probe_done() != 0) | 179 | wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); |
182 | msleep(100); | ||
183 | async_synchronize_full(); | 180 | async_synchronize_full(); |
184 | return 0; | ||
185 | } | 181 | } |
186 | 182 | ||
187 | /** | 183 | /** |
@@ -189,14 +185,8 @@ int wait_for_device_probe(void) | |||
189 | * @drv: driver to bind a device to | 185 | * @drv: driver to bind a device to |
190 | * @dev: device to try to bind to the driver | 186 | * @dev: device to try to bind to the driver |
191 | * | 187 | * |
192 | * First, we call the bus's match function, if one present, which should | 188 | * This function returns -ENODEV if the device is not registered, |
193 | * compare the device IDs the driver supports with the device IDs of the | 189 | * 1 if the device is bound sucessfully and 0 otherwise. |
194 | * device. Note we don't do this ourselves because we don't know the | ||
195 | * format of the ID structures, nor what is to be considered a match and | ||
196 | * what is not. | ||
197 | * | ||
198 | * This function returns 1 if a match is found, -ENODEV if the device is | ||
199 | * not registered, and 0 otherwise. | ||
200 | * | 190 | * |
201 | * This function must be called with @dev->sem held. When called for a | 191 | * This function must be called with @dev->sem held. When called for a |
202 | * USB interface, @dev->parent->sem must be held as well. | 192 | * USB interface, @dev->parent->sem must be held as well. |
@@ -207,21 +197,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) | |||
207 | 197 | ||
208 | if (!device_is_registered(dev)) | 198 | if (!device_is_registered(dev)) |
209 | return -ENODEV; | 199 | return -ENODEV; |
210 | if (drv->bus->match && !drv->bus->match(dev, drv)) | ||
211 | goto done; | ||
212 | 200 | ||
213 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", | 201 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", |
214 | drv->bus->name, __func__, dev_name(dev), drv->name); | 202 | drv->bus->name, __func__, dev_name(dev), drv->name); |
215 | 203 | ||
216 | ret = really_probe(dev, drv); | 204 | ret = really_probe(dev, drv); |
217 | 205 | ||
218 | done: | ||
219 | return ret; | 206 | return ret; |
220 | } | 207 | } |
221 | 208 | ||
222 | static int __device_attach(struct device_driver *drv, void *data) | 209 | static int __device_attach(struct device_driver *drv, void *data) |
223 | { | 210 | { |
224 | struct device *dev = data; | 211 | struct device *dev = data; |
212 | |||
213 | if (!driver_match_device(drv, dev)) | ||
214 | return 0; | ||
215 | |||
225 | return driver_probe_device(drv, dev); | 216 | return driver_probe_device(drv, dev); |
226 | } | 217 | } |
227 | 218 | ||
@@ -274,7 +265,7 @@ static int __driver_attach(struct device *dev, void *data) | |||
274 | * is an error. | 265 | * is an error. |
275 | */ | 266 | */ |
276 | 267 | ||
277 | if (drv->bus->match && !drv->bus->match(dev, drv)) | 268 | if (!driver_match_device(drv, dev)) |
278 | return 0; | 269 | return 0; |
279 | 270 | ||
280 | if (dev->parent) /* Needed for USB */ | 271 | if (dev->parent) /* Needed for USB */ |
@@ -327,7 +318,7 @@ static void __device_release_driver(struct device *dev) | |||
327 | drv->remove(dev); | 318 | drv->remove(dev); |
328 | devres_release_all(dev); | 319 | devres_release_all(dev); |
329 | dev->driver = NULL; | 320 | dev->driver = NULL; |
330 | klist_remove(&dev->knode_driver); | 321 | klist_remove(&dev->p->knode_driver); |
331 | } | 322 | } |
332 | } | 323 | } |
333 | 324 | ||
@@ -357,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver); | |||
357 | */ | 348 | */ |
358 | void driver_detach(struct device_driver *drv) | 349 | void driver_detach(struct device_driver *drv) |
359 | { | 350 | { |
351 | struct device_private *dev_prv; | ||
360 | struct device *dev; | 352 | struct device *dev; |
361 | 353 | ||
362 | for (;;) { | 354 | for (;;) { |
@@ -365,8 +357,10 @@ void driver_detach(struct device_driver *drv) | |||
365 | spin_unlock(&drv->p->klist_devices.k_lock); | 357 | spin_unlock(&drv->p->klist_devices.k_lock); |
366 | break; | 358 | break; |
367 | } | 359 | } |
368 | dev = list_entry(drv->p->klist_devices.k_list.prev, | 360 | dev_prv = list_entry(drv->p->klist_devices.k_list.prev, |
369 | struct device, knode_driver.n_node); | 361 | struct device_private, |
362 | knode_driver.n_node); | ||
363 | dev = dev_prv->device; | ||
370 | get_device(dev); | 364 | get_device(dev); |
371 | spin_unlock(&drv->p->klist_devices.k_lock); | 365 | spin_unlock(&drv->p->klist_devices.k_lock); |
372 | 366 | ||
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 1e2bda780e48..c51f11bb29ae 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -19,7 +19,14 @@ | |||
19 | static struct device *next_device(struct klist_iter *i) | 19 | static struct device *next_device(struct klist_iter *i) |
20 | { | 20 | { |
21 | struct klist_node *n = klist_next(i); | 21 | struct klist_node *n = klist_next(i); |
22 | return n ? container_of(n, struct device, knode_driver) : NULL; | 22 | struct device *dev = NULL; |
23 | struct device_private *dev_prv; | ||
24 | |||
25 | if (n) { | ||
26 | dev_prv = to_device_private_driver(n); | ||
27 | dev = dev_prv->device; | ||
28 | } | ||
29 | return dev; | ||
23 | } | 30 | } |
24 | 31 | ||
25 | /** | 32 | /** |
@@ -42,7 +49,7 @@ int driver_for_each_device(struct device_driver *drv, struct device *start, | |||
42 | return -EINVAL; | 49 | return -EINVAL; |
43 | 50 | ||
44 | klist_iter_init_node(&drv->p->klist_devices, &i, | 51 | klist_iter_init_node(&drv->p->klist_devices, &i, |
45 | start ? &start->knode_driver : NULL); | 52 | start ? &start->p->knode_driver : NULL); |
46 | while ((dev = next_device(&i)) && !error) | 53 | while ((dev = next_device(&i)) && !error) |
47 | error = fn(dev, data); | 54 | error = fn(dev, data); |
48 | klist_iter_exit(&i); | 55 | klist_iter_exit(&i); |
@@ -76,7 +83,7 @@ struct device *driver_find_device(struct device_driver *drv, | |||
76 | return NULL; | 83 | return NULL; |
77 | 84 | ||
78 | klist_iter_init_node(&drv->p->klist_devices, &i, | 85 | klist_iter_init_node(&drv->p->klist_devices, &i, |
79 | (start ? &start->knode_driver : NULL)); | 86 | (start ? &start->p->knode_driver : NULL)); |
80 | while ((dev = next_device(&i))) | 87 | while ((dev = next_device(&i))) |
81 | if (match(dev, data) && get_device(dev)) | 88 | if (match(dev, data) && get_device(dev)) |
82 | break; | 89 | break; |
@@ -216,6 +223,8 @@ int driver_register(struct device_driver *drv) | |||
216 | int ret; | 223 | int ret; |
217 | struct device_driver *other; | 224 | struct device_driver *other; |
218 | 225 | ||
226 | BUG_ON(!drv->bus->p); | ||
227 | |||
219 | if ((drv->bus->probe && drv->probe) || | 228 | if ((drv->bus->probe && drv->probe) || |
220 | (drv->bus->remove && drv->remove) || | 229 | (drv->bus->remove && drv->remove) || |
221 | (drv->bus->shutdown && drv->shutdown)) | 230 | (drv->bus->shutdown && drv->shutdown)) |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 44699d9dd85c..d3a59c688fe4 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -319,7 +319,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name, | |||
319 | f_dev->parent = device; | 319 | f_dev->parent = device; |
320 | f_dev->class = &firmware_class; | 320 | f_dev->class = &firmware_class; |
321 | dev_set_drvdata(f_dev, fw_priv); | 321 | dev_set_drvdata(f_dev, fw_priv); |
322 | f_dev->uevent_suppress = 1; | 322 | dev_set_uevent_suppress(f_dev, 1); |
323 | retval = device_register(f_dev); | 323 | retval = device_register(f_dev); |
324 | if (retval) { | 324 | if (retval) { |
325 | dev_err(device, "%s: device_register failed\n", __func__); | 325 | dev_err(device, "%s: device_register failed\n", __func__); |
@@ -366,7 +366,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p, | |||
366 | } | 366 | } |
367 | 367 | ||
368 | if (uevent) | 368 | if (uevent) |
369 | f_dev->uevent_suppress = 0; | 369 | dev_set_uevent_suppress(f_dev, 0); |
370 | *dev_p = f_dev; | 370 | *dev_p = f_dev; |
371 | goto out; | 371 | goto out; |
372 | 372 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 349a1013603f..d2198f64ad4e 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -217,6 +217,7 @@ int platform_device_add_data(struct platform_device *pdev, const void *data, | |||
217 | if (d) { | 217 | if (d) { |
218 | memcpy(d, data, size); | 218 | memcpy(d, data, size); |
219 | pdev->dev.platform_data = d; | 219 | pdev->dev.platform_data = d; |
220 | pdev->platform_data = d; | ||
220 | } | 221 | } |
221 | return d ? 0 : -ENOMEM; | 222 | return d ? 0 : -ENOMEM; |
222 | } | 223 | } |
@@ -246,6 +247,21 @@ int platform_device_add(struct platform_device *pdev) | |||
246 | else | 247 | else |
247 | dev_set_name(&pdev->dev, pdev->name); | 248 | dev_set_name(&pdev->dev, pdev->name); |
248 | 249 | ||
250 | /* We will remove platform_data field from struct device | ||
251 | * if all platform devices pass its platform specific data | ||
252 | * from platform_device. The conversion is going to be a | ||
253 | * long time, so we allow the two cases coexist to make | ||
254 | * this kind of fix more easily*/ | ||
255 | if (pdev->platform_data && pdev->dev.platform_data) { | ||
256 | printk(KERN_ERR | ||
257 | "%s: use which platform_data?\n", | ||
258 | dev_name(&pdev->dev)); | ||
259 | } else if (pdev->platform_data) { | ||
260 | pdev->dev.platform_data = pdev->platform_data; | ||
261 | } else if (pdev->dev.platform_data) { | ||
262 | pdev->platform_data = pdev->dev.platform_data; | ||
263 | } | ||
264 | |||
249 | for (i = 0; i < pdev->num_resources; i++) { | 265 | for (i = 0; i < pdev->num_resources; i++) { |
250 | struct resource *p, *r = &pdev->resource[i]; | 266 | struct resource *p, *r = &pdev->resource[i]; |
251 | 267 | ||
@@ -584,10 +600,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
584 | { | 600 | { |
585 | struct platform_device *pdev = to_platform_device(dev); | 601 | struct platform_device *pdev = to_platform_device(dev); |
586 | 602 | ||
587 | add_uevent_var(env, "MODALIAS=platform:%s", pdev->name); | 603 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, |
604 | (pdev->id_entry) ? pdev->id_entry->name : pdev->name); | ||
588 | return 0; | 605 | return 0; |
589 | } | 606 | } |
590 | 607 | ||
608 | static const struct platform_device_id *platform_match_id( | ||
609 | struct platform_device_id *id, | ||
610 | struct platform_device *pdev) | ||
611 | { | ||
612 | while (id->name[0]) { | ||
613 | if (strcmp(pdev->name, id->name) == 0) { | ||
614 | pdev->id_entry = id; | ||
615 | return id; | ||
616 | } | ||
617 | id++; | ||
618 | } | ||
619 | return NULL; | ||
620 | } | ||
621 | |||
591 | /** | 622 | /** |
592 | * platform_match - bind platform device to platform driver. | 623 | * platform_match - bind platform device to platform driver. |
593 | * @dev: device. | 624 | * @dev: device. |
@@ -603,9 +634,14 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
603 | */ | 634 | */ |
604 | static int platform_match(struct device *dev, struct device_driver *drv) | 635 | static int platform_match(struct device *dev, struct device_driver *drv) |
605 | { | 636 | { |
606 | struct platform_device *pdev; | 637 | struct platform_device *pdev = to_platform_device(dev); |
638 | struct platform_driver *pdrv = to_platform_driver(drv); | ||
607 | 639 | ||
608 | pdev = container_of(dev, struct platform_device, dev); | 640 | /* match against the id table first */ |
641 | if (pdrv->id_table) | ||
642 | return platform_match_id(pdrv->id_table, pdev) != NULL; | ||
643 | |||
644 | /* fall-back to driver name match */ | ||
609 | return (strcmp(pdev->name, drv->name) == 0); | 645 | return (strcmp(pdev->name, drv->name) == 0); |
610 | } | 646 | } |
611 | 647 | ||
@@ -623,26 +659,24 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg) | |||
623 | 659 | ||
624 | static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg) | 660 | static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg) |
625 | { | 661 | { |
626 | struct platform_driver *drv = to_platform_driver(dev->driver); | 662 | struct platform_driver *pdrv = to_platform_driver(dev->driver); |
627 | struct platform_device *pdev; | 663 | struct platform_device *pdev = to_platform_device(dev); |
628 | int ret = 0; | 664 | int ret = 0; |
629 | 665 | ||
630 | pdev = container_of(dev, struct platform_device, dev); | 666 | if (dev->driver && pdrv->suspend_late) |
631 | if (dev->driver && drv->suspend_late) | 667 | ret = pdrv->suspend_late(pdev, mesg); |
632 | ret = drv->suspend_late(pdev, mesg); | ||
633 | 668 | ||
634 | return ret; | 669 | return ret; |
635 | } | 670 | } |
636 | 671 | ||
637 | static int platform_legacy_resume_early(struct device *dev) | 672 | static int platform_legacy_resume_early(struct device *dev) |
638 | { | 673 | { |
639 | struct platform_driver *drv = to_platform_driver(dev->driver); | 674 | struct platform_driver *pdrv = to_platform_driver(dev->driver); |
640 | struct platform_device *pdev; | 675 | struct platform_device *pdev = to_platform_device(dev); |
641 | int ret = 0; | 676 | int ret = 0; |
642 | 677 | ||
643 | pdev = container_of(dev, struct platform_device, dev); | 678 | if (dev->driver && pdrv->resume_early) |
644 | if (dev->driver && drv->resume_early) | 679 | ret = pdrv->resume_early(pdev); |
645 | ret = drv->resume_early(pdev); | ||
646 | 680 | ||
647 | return ret; | 681 | return ret; |
648 | } | 682 | } |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 2d14f4ae6c01..e255341682c8 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -107,6 +107,50 @@ void device_pm_remove(struct device *dev) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | /** | 109 | /** |
110 | * device_pm_move_before - move device in dpm_list | ||
111 | * @deva: Device to move in dpm_list | ||
112 | * @devb: Device @deva should come before | ||
113 | */ | ||
114 | void device_pm_move_before(struct device *deva, struct device *devb) | ||
115 | { | ||
116 | pr_debug("PM: Moving %s:%s before %s:%s\n", | ||
117 | deva->bus ? deva->bus->name : "No Bus", | ||
118 | kobject_name(&deva->kobj), | ||
119 | devb->bus ? devb->bus->name : "No Bus", | ||
120 | kobject_name(&devb->kobj)); | ||
121 | /* Delete deva from dpm_list and reinsert before devb. */ | ||
122 | list_move_tail(&deva->power.entry, &devb->power.entry); | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * device_pm_move_after - move device in dpm_list | ||
127 | * @deva: Device to move in dpm_list | ||
128 | * @devb: Device @deva should come after | ||
129 | */ | ||
130 | void device_pm_move_after(struct device *deva, struct device *devb) | ||
131 | { | ||
132 | pr_debug("PM: Moving %s:%s after %s:%s\n", | ||
133 | deva->bus ? deva->bus->name : "No Bus", | ||
134 | kobject_name(&deva->kobj), | ||
135 | devb->bus ? devb->bus->name : "No Bus", | ||
136 | kobject_name(&devb->kobj)); | ||
137 | /* Delete deva from dpm_list and reinsert after devb. */ | ||
138 | list_move(&deva->power.entry, &devb->power.entry); | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * device_pm_move_last - move device to end of dpm_list | ||
143 | * @dev: Device to move in dpm_list | ||
144 | */ | ||
145 | void device_pm_move_last(struct device *dev) | ||
146 | { | ||
147 | pr_debug("PM: Moving %s:%s to end of list\n", | ||
148 | dev->bus ? dev->bus->name : "No Bus", | ||
149 | kobject_name(&dev->kobj)); | ||
150 | list_move_tail(&dev->power.entry, &dpm_list); | ||
151 | } | ||
152 | |||
153 | /** | ||
110 | * pm_op - execute the PM operation appropiate for given PM event | 154 | * pm_op - execute the PM operation appropiate for given PM event |
111 | * @dev: Device. | 155 | * @dev: Device. |
112 | * @ops: PM operations to choose from. | 156 | * @ops: PM operations to choose from. |
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 41f51fae042f..c7cb4fc3735c 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -18,11 +18,19 @@ static inline struct device *to_device(struct list_head *entry) | |||
18 | 18 | ||
19 | extern void device_pm_add(struct device *); | 19 | extern void device_pm_add(struct device *); |
20 | extern void device_pm_remove(struct device *); | 20 | extern void device_pm_remove(struct device *); |
21 | extern void device_pm_move_before(struct device *, struct device *); | ||
22 | extern void device_pm_move_after(struct device *, struct device *); | ||
23 | extern void device_pm_move_last(struct device *); | ||
21 | 24 | ||
22 | #else /* CONFIG_PM_SLEEP */ | 25 | #else /* CONFIG_PM_SLEEP */ |
23 | 26 | ||
24 | static inline void device_pm_add(struct device *dev) {} | 27 | static inline void device_pm_add(struct device *dev) {} |
25 | static inline void device_pm_remove(struct device *dev) {} | 28 | static inline void device_pm_remove(struct device *dev) {} |
29 | static inline void device_pm_move_before(struct device *deva, | ||
30 | struct device *devb) {} | ||
31 | static inline void device_pm_move_after(struct device *deva, | ||
32 | struct device *devb) {} | ||
33 | static inline void device_pm_move_last(struct device *dev) {} | ||
26 | 34 | ||
27 | #endif | 35 | #endif |
28 | 36 | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index b428c8c4bc64..cbd36cf59a0f 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -30,10 +30,10 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | static ssize_t | 32 | static ssize_t |
33 | sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) | 33 | sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer) |
34 | { | 34 | { |
35 | struct sys_device * sysdev = to_sysdev(kobj); | 35 | struct sys_device *sysdev = to_sysdev(kobj); |
36 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 36 | struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); |
37 | 37 | ||
38 | if (sysdev_attr->show) | 38 | if (sysdev_attr->show) |
39 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); | 39 | return sysdev_attr->show(sysdev, sysdev_attr, buffer); |
@@ -42,11 +42,11 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer) | |||
42 | 42 | ||
43 | 43 | ||
44 | static ssize_t | 44 | static ssize_t |
45 | sysdev_store(struct kobject * kobj, struct attribute * attr, | 45 | sysdev_store(struct kobject *kobj, struct attribute *attr, |
46 | const char * buffer, size_t count) | 46 | const char *buffer, size_t count) |
47 | { | 47 | { |
48 | struct sys_device * sysdev = to_sysdev(kobj); | 48 | struct sys_device *sysdev = to_sysdev(kobj); |
49 | struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr); | 49 | struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); |
50 | 50 | ||
51 | if (sysdev_attr->store) | 51 | if (sysdev_attr->store) |
52 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); | 52 | return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); |
@@ -63,13 +63,13 @@ static struct kobj_type ktype_sysdev = { | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | 65 | ||
66 | int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a) | 66 | int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a) |
67 | { | 67 | { |
68 | return sysfs_create_file(&s->kobj, &a->attr); | 68 | return sysfs_create_file(&s->kobj, &a->attr); |
69 | } | 69 | } |
70 | 70 | ||
71 | 71 | ||
72 | void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a) | 72 | void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a) |
73 | { | 73 | { |
74 | sysfs_remove_file(&s->kobj, &a->attr); | 74 | sysfs_remove_file(&s->kobj, &a->attr); |
75 | } | 75 | } |
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file); | |||
84 | static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, | 84 | static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, |
85 | char *buffer) | 85 | char *buffer) |
86 | { | 86 | { |
87 | struct sysdev_class * class = to_sysdev_class(kobj); | 87 | struct sysdev_class *class = to_sysdev_class(kobj); |
88 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); | 88 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); |
89 | 89 | ||
90 | if (class_attr->show) | 90 | if (class_attr->show) |
@@ -95,8 +95,8 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, | |||
95 | static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, | 95 | static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, |
96 | const char *buffer, size_t count) | 96 | const char *buffer, size_t count) |
97 | { | 97 | { |
98 | struct sysdev_class * class = to_sysdev_class(kobj); | 98 | struct sysdev_class *class = to_sysdev_class(kobj); |
99 | struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr); | 99 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); |
100 | 100 | ||
101 | if (class_attr->store) | 101 | if (class_attr->store) |
102 | return class_attr->store(class, buffer, count); | 102 | return class_attr->store(class, buffer, count); |
@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_remove_file); | |||
128 | 128 | ||
129 | static struct kset *system_kset; | 129 | static struct kset *system_kset; |
130 | 130 | ||
131 | int sysdev_class_register(struct sysdev_class * cls) | 131 | int sysdev_class_register(struct sysdev_class *cls) |
132 | { | 132 | { |
133 | pr_debug("Registering sysdev class '%s'\n", cls->name); | 133 | pr_debug("Registering sysdev class '%s'\n", cls->name); |
134 | 134 | ||
@@ -141,7 +141,7 @@ int sysdev_class_register(struct sysdev_class * cls) | |||
141 | return kset_register(&cls->kset); | 141 | return kset_register(&cls->kset); |
142 | } | 142 | } |
143 | 143 | ||
144 | void sysdev_class_unregister(struct sysdev_class * cls) | 144 | void sysdev_class_unregister(struct sysdev_class *cls) |
145 | { | 145 | { |
146 | pr_debug("Unregistering sysdev class '%s'\n", | 146 | pr_debug("Unregistering sysdev class '%s'\n", |
147 | kobject_name(&cls->kset.kobj)); | 147 | kobject_name(&cls->kset.kobj)); |
@@ -203,8 +203,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) | |||
203 | * @cls: Class driver belongs to. | 203 | * @cls: Class driver belongs to. |
204 | * @drv: Driver. | 204 | * @drv: Driver. |
205 | */ | 205 | */ |
206 | void sysdev_driver_unregister(struct sysdev_class * cls, | 206 | void sysdev_driver_unregister(struct sysdev_class *cls, |
207 | struct sysdev_driver * drv) | 207 | struct sysdev_driver *drv) |
208 | { | 208 | { |
209 | mutex_lock(&sysdev_drivers_lock); | 209 | mutex_lock(&sysdev_drivers_lock); |
210 | list_del_init(&drv->entry); | 210 | list_del_init(&drv->entry); |
@@ -229,10 +229,10 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregister); | |||
229 | * @sysdev: device in question | 229 | * @sysdev: device in question |
230 | * | 230 | * |
231 | */ | 231 | */ |
232 | int sysdev_register(struct sys_device * sysdev) | 232 | int sysdev_register(struct sys_device *sysdev) |
233 | { | 233 | { |
234 | int error; | 234 | int error; |
235 | struct sysdev_class * cls = sysdev->cls; | 235 | struct sysdev_class *cls = sysdev->cls; |
236 | 236 | ||
237 | if (!cls) | 237 | if (!cls) |
238 | return -EINVAL; | 238 | return -EINVAL; |
@@ -252,7 +252,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
252 | sysdev->id); | 252 | sysdev->id); |
253 | 253 | ||
254 | if (!error) { | 254 | if (!error) { |
255 | struct sysdev_driver * drv; | 255 | struct sysdev_driver *drv; |
256 | 256 | ||
257 | pr_debug("Registering sys device '%s'\n", | 257 | pr_debug("Registering sys device '%s'\n", |
258 | kobject_name(&sysdev->kobj)); | 258 | kobject_name(&sysdev->kobj)); |
@@ -274,9 +274,9 @@ int sysdev_register(struct sys_device * sysdev) | |||
274 | return error; | 274 | return error; |
275 | } | 275 | } |
276 | 276 | ||
277 | void sysdev_unregister(struct sys_device * sysdev) | 277 | void sysdev_unregister(struct sys_device *sysdev) |
278 | { | 278 | { |
279 | struct sysdev_driver * drv; | 279 | struct sysdev_driver *drv; |
280 | 280 | ||
281 | mutex_lock(&sysdev_drivers_lock); | 281 | mutex_lock(&sysdev_drivers_lock); |
282 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { | 282 | list_for_each_entry(drv, &sysdev->cls->drivers, entry) { |
@@ -305,19 +305,19 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
305 | */ | 305 | */ |
306 | void sysdev_shutdown(void) | 306 | void sysdev_shutdown(void) |
307 | { | 307 | { |
308 | struct sysdev_class * cls; | 308 | struct sysdev_class *cls; |
309 | 309 | ||
310 | pr_debug("Shutting Down System Devices\n"); | 310 | pr_debug("Shutting Down System Devices\n"); |
311 | 311 | ||
312 | mutex_lock(&sysdev_drivers_lock); | 312 | mutex_lock(&sysdev_drivers_lock); |
313 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { | 313 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { |
314 | struct sys_device * sysdev; | 314 | struct sys_device *sysdev; |
315 | 315 | ||
316 | pr_debug("Shutting down type '%s':\n", | 316 | pr_debug("Shutting down type '%s':\n", |
317 | kobject_name(&cls->kset.kobj)); | 317 | kobject_name(&cls->kset.kobj)); |
318 | 318 | ||
319 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { | 319 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { |
320 | struct sysdev_driver * drv; | 320 | struct sysdev_driver *drv; |
321 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); | 321 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); |
322 | 322 | ||
323 | /* Call auxillary drivers first */ | 323 | /* Call auxillary drivers first */ |
@@ -364,7 +364,7 @@ static void __sysdev_resume(struct sys_device *dev) | |||
364 | */ | 364 | */ |
365 | int sysdev_suspend(pm_message_t state) | 365 | int sysdev_suspend(pm_message_t state) |
366 | { | 366 | { |
367 | struct sysdev_class * cls; | 367 | struct sysdev_class *cls; |
368 | struct sys_device *sysdev, *err_dev; | 368 | struct sys_device *sysdev, *err_dev; |
369 | struct sysdev_driver *drv, *err_drv; | 369 | struct sysdev_driver *drv, *err_drv; |
370 | int ret; | 370 | int ret; |
@@ -442,12 +442,12 @@ EXPORT_SYMBOL_GPL(sysdev_suspend); | |||
442 | */ | 442 | */ |
443 | int sysdev_resume(void) | 443 | int sysdev_resume(void) |
444 | { | 444 | { |
445 | struct sysdev_class * cls; | 445 | struct sysdev_class *cls; |
446 | 446 | ||
447 | pr_debug("Resuming System Devices\n"); | 447 | pr_debug("Resuming System Devices\n"); |
448 | 448 | ||
449 | list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { | 449 | list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { |
450 | struct sys_device * sysdev; | 450 | struct sys_device *sysdev; |
451 | 451 | ||
452 | pr_debug("Resuming type '%s':\n", | 452 | pr_debug("Resuming type '%s':\n", |
453 | kobject_name(&cls->kset.kobj)); | 453 | kobject_name(&cls->kset.kobj)); |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 83d8ed39433d..c2c95e614506 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -4135,10 +4135,9 @@ static int have_no_fdc = -ENODEV; | |||
4135 | static ssize_t floppy_cmos_show(struct device *dev, | 4135 | static ssize_t floppy_cmos_show(struct device *dev, |
4136 | struct device_attribute *attr, char *buf) | 4136 | struct device_attribute *attr, char *buf) |
4137 | { | 4137 | { |
4138 | struct platform_device *p; | 4138 | struct platform_device *p = to_platform_device(dev); |
4139 | int drive; | 4139 | int drive; |
4140 | 4140 | ||
4141 | p = container_of(dev, struct platform_device,dev); | ||
4142 | drive = p->id; | 4141 | drive = p->id; |
4143 | return sprintf(buf, "%X\n", UDP->cmos); | 4142 | return sprintf(buf, "%X\n", UDP->cmos); |
4144 | } | 4143 | } |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 12fb816db7b0..69b7f8e77596 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -391,7 +391,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum); | |||
391 | */ | 391 | */ |
392 | #ifdef CONFIG_USB_LIBUSUAL | 392 | #ifdef CONFIG_USB_LIBUSUAL |
393 | 393 | ||
394 | #define ub_usb_ids storage_usb_ids | 394 | #define ub_usb_ids usb_storage_usb_ids |
395 | #else | 395 | #else |
396 | 396 | ||
397 | static struct usb_device_id ub_usb_ids[] = { | 397 | static struct usb_device_id ub_usb_ids[] = { |
@@ -2146,10 +2146,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, | |||
2146 | ep = &altsetting->endpoint[i].desc; | 2146 | ep = &altsetting->endpoint[i].desc; |
2147 | 2147 | ||
2148 | /* Is it a BULK endpoint? */ | 2148 | /* Is it a BULK endpoint? */ |
2149 | if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 2149 | if (usb_endpoint_xfer_bulk(ep)) { |
2150 | == USB_ENDPOINT_XFER_BULK) { | ||
2151 | /* BULK in or out? */ | 2150 | /* BULK in or out? */ |
2152 | if (ep->bEndpointAddress & USB_DIR_IN) { | 2151 | if (usb_endpoint_dir_in(ep)) { |
2153 | if (ep_in == NULL) | 2152 | if (ep_in == NULL) |
2154 | ep_in = ep; | 2153 | ep_in = ep; |
2155 | } else { | 2154 | } else { |
@@ -2168,9 +2167,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, | |||
2168 | sc->send_ctrl_pipe = usb_sndctrlpipe(dev, 0); | 2167 | sc->send_ctrl_pipe = usb_sndctrlpipe(dev, 0); |
2169 | sc->recv_ctrl_pipe = usb_rcvctrlpipe(dev, 0); | 2168 | sc->recv_ctrl_pipe = usb_rcvctrlpipe(dev, 0); |
2170 | sc->send_bulk_pipe = usb_sndbulkpipe(dev, | 2169 | sc->send_bulk_pipe = usb_sndbulkpipe(dev, |
2171 | ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 2170 | usb_endpoint_num(ep_out)); |
2172 | sc->recv_bulk_pipe = usb_rcvbulkpipe(dev, | 2171 | sc->recv_bulk_pipe = usb_rcvbulkpipe(dev, |
2173 | ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 2172 | usb_endpoint_num(ep_in)); |
2174 | 2173 | ||
2175 | return 0; | 2174 | return 0; |
2176 | } | 2175 | } |
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 8822eca58ffa..5fab6470f4b2 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -20,6 +20,20 @@ config HW_RANDOM | |||
20 | 20 | ||
21 | If unsure, say Y. | 21 | If unsure, say Y. |
22 | 22 | ||
23 | config HW_RANDOM_TIMERIOMEM | ||
24 | tristate "Timer IOMEM HW Random Number Generator support" | ||
25 | depends on HW_RANDOM && HAS_IOMEM | ||
26 | ---help--- | ||
27 | This driver provides kernel-side support for a generic Random | ||
28 | Number Generator used by reading a 'dumb' iomem address that | ||
29 | is to be read no faster than, for example, once a second; | ||
30 | the default FPGA bitstream on the TS-7800 has such functionality. | ||
31 | |||
32 | To compile this driver as a module, choose M here: the | ||
33 | module will be called timeriomem-rng. | ||
34 | |||
35 | If unsure, say Y. | ||
36 | |||
23 | config HW_RANDOM_INTEL | 37 | config HW_RANDOM_INTEL |
24 | tristate "Intel HW Random Number Generator support" | 38 | tristate "Intel HW Random Number Generator support" |
25 | depends on HW_RANDOM && (X86 || IA64) && PCI | 39 | depends on HW_RANDOM && (X86 || IA64) && PCI |
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index b6effb7522c2..e81d21a5f28f 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_HW_RANDOM) += rng-core.o | 5 | obj-$(CONFIG_HW_RANDOM) += rng-core.o |
6 | rng-core-y := core.o | 6 | rng-core-y := core.o |
7 | obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o | ||
7 | obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o | 8 | obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o |
8 | obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o | 9 | obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o |
9 | obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o | 10 | obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o |
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c new file mode 100644 index 000000000000..10ad41be5897 --- /dev/null +++ b/drivers/char/hw_random/timeriomem-rng.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * drivers/char/hw_random/timeriomem-rng.c | ||
3 | * | ||
4 | * Copyright (C) 2009 Alexander Clouter <alex@digriz.org.uk> | ||
5 | * | ||
6 | * Derived from drivers/char/hw_random/omap-rng.c | ||
7 | * Copyright 2005 (c) MontaVista Software, Inc. | ||
8 | * Author: Deepak Saxena <dsaxena@plexity.net> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * Overview: | ||
15 | * This driver is useful for platforms that have an IO range that provides | ||
16 | * periodic random data from a single IO memory address. All the platform | ||
17 | * has to do is provide the address and 'wait time' that new data becomes | ||
18 | * available. | ||
19 | * | ||
20 | * TODO: add support for reading sizes other than 32bits and masking | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/hw_random.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/timeriomem-rng.h> | ||
29 | #include <linux/jiffies.h> | ||
30 | #include <linux/sched.h> | ||
31 | #include <linux/timer.h> | ||
32 | #include <linux/completion.h> | ||
33 | |||
34 | static struct timeriomem_rng_data *timeriomem_rng_data; | ||
35 | |||
36 | static void timeriomem_rng_trigger(unsigned long); | ||
37 | static DEFINE_TIMER(timeriomem_rng_timer, timeriomem_rng_trigger, 0, 0); | ||
38 | |||
39 | /* | ||
40 | * have data return 1, however return 0 if we have nothing | ||
41 | */ | ||
42 | static int timeriomem_rng_data_present(struct hwrng *rng, int wait) | ||
43 | { | ||
44 | if (rng->priv == 0) | ||
45 | return 1; | ||
46 | |||
47 | if (!wait || timeriomem_rng_data->present) | ||
48 | return timeriomem_rng_data->present; | ||
49 | |||
50 | wait_for_completion(&timeriomem_rng_data->completion); | ||
51 | |||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | static int timeriomem_rng_data_read(struct hwrng *rng, u32 *data) | ||
56 | { | ||
57 | unsigned long cur; | ||
58 | s32 delay; | ||
59 | |||
60 | *data = readl(timeriomem_rng_data->address); | ||
61 | |||
62 | if (rng->priv != 0) { | ||
63 | cur = jiffies; | ||
64 | |||
65 | delay = cur - timeriomem_rng_timer.expires; | ||
66 | delay = rng->priv - (delay % rng->priv); | ||
67 | |||
68 | timeriomem_rng_timer.expires = cur + delay; | ||
69 | timeriomem_rng_data->present = 0; | ||
70 | |||
71 | init_completion(&timeriomem_rng_data->completion); | ||
72 | add_timer(&timeriomem_rng_timer); | ||
73 | } | ||
74 | |||
75 | return 4; | ||
76 | } | ||
77 | |||
78 | static void timeriomem_rng_trigger(unsigned long dummy) | ||
79 | { | ||
80 | timeriomem_rng_data->present = 1; | ||
81 | complete(&timeriomem_rng_data->completion); | ||
82 | } | ||
83 | |||
84 | static struct hwrng timeriomem_rng_ops = { | ||
85 | .name = "timeriomem", | ||
86 | .data_present = timeriomem_rng_data_present, | ||
87 | .data_read = timeriomem_rng_data_read, | ||
88 | .priv = 0, | ||
89 | }; | ||
90 | |||
91 | static int __init timeriomem_rng_probe(struct platform_device *pdev) | ||
92 | { | ||
93 | int ret; | ||
94 | |||
95 | timeriomem_rng_data = pdev->dev.platform_data; | ||
96 | |||
97 | if (timeriomem_rng_data->period != 0 | ||
98 | && usecs_to_jiffies(timeriomem_rng_data->period) > 0) { | ||
99 | timeriomem_rng_timer.expires = jiffies; | ||
100 | |||
101 | timeriomem_rng_ops.priv = usecs_to_jiffies( | ||
102 | timeriomem_rng_data->period); | ||
103 | } | ||
104 | timeriomem_rng_data->present = 1; | ||
105 | |||
106 | ret = hwrng_register(&timeriomem_rng_ops); | ||
107 | if (ret) { | ||
108 | dev_err(&pdev->dev, "problem registering\n"); | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n", | ||
113 | timeriomem_rng_data->address, | ||
114 | timeriomem_rng_data->period); | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int __devexit timeriomem_rng_remove(struct platform_device *pdev) | ||
120 | { | ||
121 | del_timer_sync(&timeriomem_rng_timer); | ||
122 | hwrng_unregister(&timeriomem_rng_ops); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static struct platform_driver timeriomem_rng_driver = { | ||
128 | .driver = { | ||
129 | .name = "timeriomem_rng", | ||
130 | .owner = THIS_MODULE, | ||
131 | }, | ||
132 | .probe = timeriomem_rng_probe, | ||
133 | .remove = __devexit_p(timeriomem_rng_remove), | ||
134 | }; | ||
135 | |||
136 | static int __init timeriomem_rng_init(void) | ||
137 | { | ||
138 | return platform_driver_register(&timeriomem_rng_driver); | ||
139 | } | ||
140 | |||
141 | static void __exit timeriomem_rng_exit(void) | ||
142 | { | ||
143 | platform_driver_unregister(&timeriomem_rng_driver); | ||
144 | } | ||
145 | |||
146 | module_init(timeriomem_rng_init); | ||
147 | module_exit(timeriomem_rng_exit); | ||
148 | |||
149 | MODULE_LICENSE("GPL"); | ||
150 | MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>"); | ||
151 | MODULE_DESCRIPTION("Timer IOMEM H/W RNG driver"); | ||
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index d0e7926eb486..c64a1bc65349 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -168,12 +168,22 @@ static void atml_plat_remove(void) | |||
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | static struct device_driver atml_drv = { | 171 | static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg) |
172 | .name = "tpm_atmel", | 172 | { |
173 | .bus = &platform_bus_type, | 173 | return tpm_pm_suspend(&dev->dev, msg); |
174 | .owner = THIS_MODULE, | 174 | } |
175 | .suspend = tpm_pm_suspend, | 175 | |
176 | .resume = tpm_pm_resume, | 176 | static int tpm_atml_resume(struct platform_device *dev) |
177 | { | ||
178 | return tpm_pm_resume(&dev->dev); | ||
179 | } | ||
180 | static struct platform_driver atml_drv = { | ||
181 | .driver = { | ||
182 | .name = "tpm_atmel", | ||
183 | .owner = THIS_MODULE, | ||
184 | }, | ||
185 | .suspend = tpm_atml_suspend, | ||
186 | .resume = tpm_atml_resume, | ||
177 | }; | 187 | }; |
178 | 188 | ||
179 | static int __init init_atmel(void) | 189 | static int __init init_atmel(void) |
@@ -184,7 +194,7 @@ static int __init init_atmel(void) | |||
184 | unsigned long base; | 194 | unsigned long base; |
185 | struct tpm_chip *chip; | 195 | struct tpm_chip *chip; |
186 | 196 | ||
187 | rc = driver_register(&atml_drv); | 197 | rc = platform_driver_register(&atml_drv); |
188 | if (rc) | 198 | if (rc) |
189 | return rc; | 199 | return rc; |
190 | 200 | ||
@@ -223,13 +233,13 @@ err_rel_reg: | |||
223 | atmel_release_region(base, | 233 | atmel_release_region(base, |
224 | region_size); | 234 | region_size); |
225 | err_unreg_drv: | 235 | err_unreg_drv: |
226 | driver_unregister(&atml_drv); | 236 | platform_driver_unregister(&atml_drv); |
227 | return rc; | 237 | return rc; |
228 | } | 238 | } |
229 | 239 | ||
230 | static void __exit cleanup_atmel(void) | 240 | static void __exit cleanup_atmel(void) |
231 | { | 241 | { |
232 | driver_unregister(&atml_drv); | 242 | platform_driver_unregister(&atml_drv); |
233 | atml_plat_remove(); | 243 | atml_plat_remove(); |
234 | } | 244 | } |
235 | 245 | ||
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 717af7ad1bdf..aec1931608aa 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -654,12 +654,22 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, | |||
654 | sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); | 654 | sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); |
655 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | 655 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); |
656 | 656 | ||
657 | static struct device_driver tis_drv = { | 657 | static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg) |
658 | .name = "tpm_tis", | 658 | { |
659 | .bus = &platform_bus_type, | 659 | return tpm_pm_suspend(&dev->dev, msg); |
660 | .owner = THIS_MODULE, | 660 | } |
661 | .suspend = tpm_pm_suspend, | 661 | |
662 | .resume = tpm_pm_resume, | 662 | static int tpm_tis_resume(struct platform_device *dev) |
663 | { | ||
664 | return tpm_pm_resume(&dev->dev); | ||
665 | } | ||
666 | static struct platform_driver tis_drv = { | ||
667 | .driver = { | ||
668 | .name = "tpm_tis", | ||
669 | .owner = THIS_MODULE, | ||
670 | }, | ||
671 | .suspend = tpm_tis_suspend, | ||
672 | .resume = tpm_tis_resume, | ||
663 | }; | 673 | }; |
664 | 674 | ||
665 | static struct platform_device *pdev; | 675 | static struct platform_device *pdev; |
@@ -672,14 +682,14 @@ static int __init init_tis(void) | |||
672 | int rc; | 682 | int rc; |
673 | 683 | ||
674 | if (force) { | 684 | if (force) { |
675 | rc = driver_register(&tis_drv); | 685 | rc = platform_driver_register(&tis_drv); |
676 | if (rc < 0) | 686 | if (rc < 0) |
677 | return rc; | 687 | return rc; |
678 | if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0))) | 688 | if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0))) |
679 | return PTR_ERR(pdev); | 689 | return PTR_ERR(pdev); |
680 | if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) { | 690 | if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) { |
681 | platform_device_unregister(pdev); | 691 | platform_device_unregister(pdev); |
682 | driver_unregister(&tis_drv); | 692 | platform_driver_unregister(&tis_drv); |
683 | } | 693 | } |
684 | return rc; | 694 | return rc; |
685 | } | 695 | } |
@@ -711,7 +721,7 @@ static void __exit cleanup_tis(void) | |||
711 | 721 | ||
712 | if (force) { | 722 | if (force) { |
713 | platform_device_unregister(pdev); | 723 | platform_device_unregister(pdev); |
714 | driver_unregister(&tis_drv); | 724 | platform_driver_unregister(&tis_drv); |
715 | } else | 725 | } else |
716 | pnp_unregister_driver(&tis_pnp_driver); | 726 | pnp_unregister_driver(&tis_pnp_driver); |
717 | } | 727 | } |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 4f3b3f95fc42..d94d25c12aa8 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -479,18 +479,18 @@ static const struct file_operations vcs_fops = { | |||
479 | 479 | ||
480 | static struct class *vc_class; | 480 | static struct class *vc_class; |
481 | 481 | ||
482 | void vcs_make_sysfs(struct tty_struct *tty) | 482 | void vcs_make_sysfs(int index) |
483 | { | 483 | { |
484 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL, | 484 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL, |
485 | "vcs%u", tty->index + 1); | 485 | "vcs%u", index + 1); |
486 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL, | 486 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL, |
487 | "vcsa%u", tty->index + 1); | 487 | "vcsa%u", index + 1); |
488 | } | 488 | } |
489 | 489 | ||
490 | void vcs_remove_sysfs(struct tty_struct *tty) | 490 | void vcs_remove_sysfs(int index) |
491 | { | 491 | { |
492 | device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); | 492 | device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1)); |
493 | device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); | 493 | device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129)); |
494 | } | 494 | } |
495 | 495 | ||
496 | int __init vcs_init(void) | 496 | int __init vcs_init(void) |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 7900bd63b36d..2c1d133819b5 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -778,6 +778,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
778 | } | 778 | } |
779 | vc->vc_kmalloced = 1; | 779 | vc->vc_kmalloced = 1; |
780 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); | 780 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); |
781 | vcs_make_sysfs(currcons); | ||
781 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); | 782 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); |
782 | } | 783 | } |
783 | return 0; | 784 | return 0; |
@@ -987,7 +988,9 @@ void vc_deallocate(unsigned int currcons) | |||
987 | if (vc_cons_allocated(currcons)) { | 988 | if (vc_cons_allocated(currcons)) { |
988 | struct vc_data *vc = vc_cons[currcons].d; | 989 | struct vc_data *vc = vc_cons[currcons].d; |
989 | struct vt_notifier_param param = { .vc = vc }; | 990 | struct vt_notifier_param param = { .vc = vc }; |
991 | |||
990 | atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); | 992 | atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); |
993 | vcs_remove_sysfs(currcons); | ||
991 | vc->vc_sw->con_deinit(vc); | 994 | vc->vc_sw->con_deinit(vc); |
992 | put_pid(vc->vt_pid); | 995 | put_pid(vc->vt_pid); |
993 | module_put(vc->vc_sw->owner); | 996 | module_put(vc->vc_sw->owner); |
@@ -2775,7 +2778,6 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2775 | tty->termios->c_iflag |= IUTF8; | 2778 | tty->termios->c_iflag |= IUTF8; |
2776 | else | 2779 | else |
2777 | tty->termios->c_iflag &= ~IUTF8; | 2780 | tty->termios->c_iflag &= ~IUTF8; |
2778 | vcs_make_sysfs(tty); | ||
2779 | release_console_sem(); | 2781 | release_console_sem(); |
2780 | return ret; | 2782 | return ret; |
2781 | } | 2783 | } |
@@ -2795,7 +2797,6 @@ static void con_shutdown(struct tty_struct *tty) | |||
2795 | BUG_ON(vc == NULL); | 2797 | BUG_ON(vc == NULL); |
2796 | acquire_console_sem(); | 2798 | acquire_console_sem(); |
2797 | vc->vc_tty = NULL; | 2799 | vc->vc_tty = NULL; |
2798 | vcs_remove_sysfs(tty); | ||
2799 | release_console_sem(); | 2800 | release_console_sem(); |
2800 | tty_shutdown(tty); | 2801 | tty_shutdown(tty); |
2801 | } | 2802 | } |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 1525882190fd..1efb2879a94f 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -2,3 +2,4 @@ obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o | |||
2 | obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o | 2 | obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o |
3 | obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o | 3 | obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o |
4 | obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o | 4 | obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o |
5 | obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o | ||
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c new file mode 100644 index 000000000000..7783b42f6914 --- /dev/null +++ b/drivers/clocksource/sh_cmt.c | |||
@@ -0,0 +1,615 @@ | |||
1 | /* | ||
2 | * SuperH Timer Support - CMT | ||
3 | * | ||
4 | * Copyright (C) 2008 Magnus Damm | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/bootmem.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/clk.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/err.h> | ||
30 | #include <linux/clocksource.h> | ||
31 | #include <linux/clockchips.h> | ||
32 | #include <linux/sh_cmt.h> | ||
33 | |||
34 | struct sh_cmt_priv { | ||
35 | void __iomem *mapbase; | ||
36 | struct clk *clk; | ||
37 | unsigned long width; /* 16 or 32 bit version of hardware block */ | ||
38 | unsigned long overflow_bit; | ||
39 | unsigned long clear_bits; | ||
40 | struct irqaction irqaction; | ||
41 | struct platform_device *pdev; | ||
42 | |||
43 | unsigned long flags; | ||
44 | unsigned long match_value; | ||
45 | unsigned long next_match_value; | ||
46 | unsigned long max_match_value; | ||
47 | unsigned long rate; | ||
48 | spinlock_t lock; | ||
49 | struct clock_event_device ced; | ||
50 | unsigned long total_cycles; | ||
51 | }; | ||
52 | |||
53 | static DEFINE_SPINLOCK(sh_cmt_lock); | ||
54 | |||
55 | #define CMSTR -1 /* shared register */ | ||
56 | #define CMCSR 0 /* channel register */ | ||
57 | #define CMCNT 1 /* channel register */ | ||
58 | #define CMCOR 2 /* channel register */ | ||
59 | |||
60 | static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr) | ||
61 | { | ||
62 | struct sh_cmt_config *cfg = p->pdev->dev.platform_data; | ||
63 | void __iomem *base = p->mapbase; | ||
64 | unsigned long offs; | ||
65 | |||
66 | if (reg_nr == CMSTR) { | ||
67 | offs = 0; | ||
68 | base -= cfg->channel_offset; | ||
69 | } else | ||
70 | offs = reg_nr; | ||
71 | |||
72 | if (p->width == 16) | ||
73 | offs <<= 1; | ||
74 | else { | ||
75 | offs <<= 2; | ||
76 | if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) | ||
77 | return ioread32(base + offs); | ||
78 | } | ||
79 | |||
80 | return ioread16(base + offs); | ||
81 | } | ||
82 | |||
83 | static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr, | ||
84 | unsigned long value) | ||
85 | { | ||
86 | struct sh_cmt_config *cfg = p->pdev->dev.platform_data; | ||
87 | void __iomem *base = p->mapbase; | ||
88 | unsigned long offs; | ||
89 | |||
90 | if (reg_nr == CMSTR) { | ||
91 | offs = 0; | ||
92 | base -= cfg->channel_offset; | ||
93 | } else | ||
94 | offs = reg_nr; | ||
95 | |||
96 | if (p->width == 16) | ||
97 | offs <<= 1; | ||
98 | else { | ||
99 | offs <<= 2; | ||
100 | if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) { | ||
101 | iowrite32(value, base + offs); | ||
102 | return; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | iowrite16(value, base + offs); | ||
107 | } | ||
108 | |||
109 | static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, | ||
110 | int *has_wrapped) | ||
111 | { | ||
112 | unsigned long v1, v2, v3; | ||
113 | |||
114 | /* Make sure the timer value is stable. Stolen from acpi_pm.c */ | ||
115 | do { | ||
116 | v1 = sh_cmt_read(p, CMCNT); | ||
117 | v2 = sh_cmt_read(p, CMCNT); | ||
118 | v3 = sh_cmt_read(p, CMCNT); | ||
119 | } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) | ||
120 | || (v3 > v1 && v3 < v2))); | ||
121 | |||
122 | *has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit; | ||
123 | return v2; | ||
124 | } | ||
125 | |||
126 | |||
127 | static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) | ||
128 | { | ||
129 | struct sh_cmt_config *cfg = p->pdev->dev.platform_data; | ||
130 | unsigned long flags, value; | ||
131 | |||
132 | /* start stop register shared by multiple timer channels */ | ||
133 | spin_lock_irqsave(&sh_cmt_lock, flags); | ||
134 | value = sh_cmt_read(p, CMSTR); | ||
135 | |||
136 | if (start) | ||
137 | value |= 1 << cfg->timer_bit; | ||
138 | else | ||
139 | value &= ~(1 << cfg->timer_bit); | ||
140 | |||
141 | sh_cmt_write(p, CMSTR, value); | ||
142 | spin_unlock_irqrestore(&sh_cmt_lock, flags); | ||
143 | } | ||
144 | |||
145 | static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) | ||
146 | { | ||
147 | struct sh_cmt_config *cfg = p->pdev->dev.platform_data; | ||
148 | int ret; | ||
149 | |||
150 | /* enable clock */ | ||
151 | ret = clk_enable(p->clk); | ||
152 | if (ret) { | ||
153 | pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk); | ||
154 | return ret; | ||
155 | } | ||
156 | *rate = clk_get_rate(p->clk) / 8; | ||
157 | |||
158 | /* make sure channel is disabled */ | ||
159 | sh_cmt_start_stop_ch(p, 0); | ||
160 | |||
161 | /* configure channel, periodic mode and maximum timeout */ | ||
162 | if (p->width == 16) | ||
163 | sh_cmt_write(p, CMCSR, 0); | ||
164 | else | ||
165 | sh_cmt_write(p, CMCSR, 0x01a4); | ||
166 | |||
167 | sh_cmt_write(p, CMCOR, 0xffffffff); | ||
168 | sh_cmt_write(p, CMCNT, 0); | ||
169 | |||
170 | /* enable channel */ | ||
171 | sh_cmt_start_stop_ch(p, 1); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static void sh_cmt_disable(struct sh_cmt_priv *p) | ||
176 | { | ||
177 | /* disable channel */ | ||
178 | sh_cmt_start_stop_ch(p, 0); | ||
179 | |||
180 | /* stop clock */ | ||
181 | clk_disable(p->clk); | ||
182 | } | ||
183 | |||
184 | /* private flags */ | ||
185 | #define FLAG_CLOCKEVENT (1 << 0) | ||
186 | #define FLAG_CLOCKSOURCE (1 << 1) | ||
187 | #define FLAG_REPROGRAM (1 << 2) | ||
188 | #define FLAG_SKIPEVENT (1 << 3) | ||
189 | #define FLAG_IRQCONTEXT (1 << 4) | ||
190 | |||
191 | static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p, | ||
192 | int absolute) | ||
193 | { | ||
194 | unsigned long new_match; | ||
195 | unsigned long value = p->next_match_value; | ||
196 | unsigned long delay = 0; | ||
197 | unsigned long now = 0; | ||
198 | int has_wrapped; | ||
199 | |||
200 | now = sh_cmt_get_counter(p, &has_wrapped); | ||
201 | p->flags |= FLAG_REPROGRAM; /* force reprogram */ | ||
202 | |||
203 | if (has_wrapped) { | ||
204 | /* we're competing with the interrupt handler. | ||
205 | * -> let the interrupt handler reprogram the timer. | ||
206 | * -> interrupt number two handles the event. | ||
207 | */ | ||
208 | p->flags |= FLAG_SKIPEVENT; | ||
209 | return; | ||
210 | } | ||
211 | |||
212 | if (absolute) | ||
213 | now = 0; | ||
214 | |||
215 | do { | ||
216 | /* reprogram the timer hardware, | ||
217 | * but don't save the new match value yet. | ||
218 | */ | ||
219 | new_match = now + value + delay; | ||
220 | if (new_match > p->max_match_value) | ||
221 | new_match = p->max_match_value; | ||
222 | |||
223 | sh_cmt_write(p, CMCOR, new_match); | ||
224 | |||
225 | now = sh_cmt_get_counter(p, &has_wrapped); | ||
226 | if (has_wrapped && (new_match > p->match_value)) { | ||
227 | /* we are changing to a greater match value, | ||
228 | * so this wrap must be caused by the counter | ||
229 | * matching the old value. | ||
230 | * -> first interrupt reprograms the timer. | ||
231 | * -> interrupt number two handles the event. | ||
232 | */ | ||
233 | p->flags |= FLAG_SKIPEVENT; | ||
234 | break; | ||
235 | } | ||
236 | |||
237 | if (has_wrapped) { | ||
238 | /* we are changing to a smaller match value, | ||
239 | * so the wrap must be caused by the counter | ||
240 | * matching the new value. | ||
241 | * -> save programmed match value. | ||
242 | * -> let isr handle the event. | ||
243 | */ | ||
244 | p->match_value = new_match; | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | /* be safe: verify hardware settings */ | ||
249 | if (now < new_match) { | ||
250 | /* timer value is below match value, all good. | ||
251 | * this makes sure we won't miss any match events. | ||
252 | * -> save programmed match value. | ||
253 | * -> let isr handle the event. | ||
254 | */ | ||
255 | p->match_value = new_match; | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | /* the counter has reached a value greater | ||
260 | * than our new match value. and since the | ||
261 | * has_wrapped flag isn't set we must have | ||
262 | * programmed a too close event. | ||
263 | * -> increase delay and retry. | ||
264 | */ | ||
265 | if (delay) | ||
266 | delay <<= 1; | ||
267 | else | ||
268 | delay = 1; | ||
269 | |||
270 | if (!delay) | ||
271 | pr_warning("sh_cmt: too long delay\n"); | ||
272 | |||
273 | } while (delay); | ||
274 | } | ||
275 | |||
276 | static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) | ||
277 | { | ||
278 | unsigned long flags; | ||
279 | |||
280 | if (delta > p->max_match_value) | ||
281 | pr_warning("sh_cmt: delta out of range\n"); | ||
282 | |||
283 | spin_lock_irqsave(&p->lock, flags); | ||
284 | p->next_match_value = delta; | ||
285 | sh_cmt_clock_event_program_verify(p, 0); | ||
286 | spin_unlock_irqrestore(&p->lock, flags); | ||
287 | } | ||
288 | |||
289 | static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) | ||
290 | { | ||
291 | struct sh_cmt_priv *p = dev_id; | ||
292 | |||
293 | /* clear flags */ | ||
294 | sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits); | ||
295 | |||
296 | /* update clock source counter to begin with if enabled | ||
297 | * the wrap flag should be cleared by the timer specific | ||
298 | * isr before we end up here. | ||
299 | */ | ||
300 | if (p->flags & FLAG_CLOCKSOURCE) | ||
301 | p->total_cycles += p->match_value; | ||
302 | |||
303 | if (!(p->flags & FLAG_REPROGRAM)) | ||
304 | p->next_match_value = p->max_match_value; | ||
305 | |||
306 | p->flags |= FLAG_IRQCONTEXT; | ||
307 | |||
308 | if (p->flags & FLAG_CLOCKEVENT) { | ||
309 | if (!(p->flags & FLAG_SKIPEVENT)) { | ||
310 | if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) { | ||
311 | p->next_match_value = p->max_match_value; | ||
312 | p->flags |= FLAG_REPROGRAM; | ||
313 | } | ||
314 | |||
315 | p->ced.event_handler(&p->ced); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | p->flags &= ~FLAG_SKIPEVENT; | ||
320 | |||
321 | if (p->flags & FLAG_REPROGRAM) { | ||
322 | p->flags &= ~FLAG_REPROGRAM; | ||
323 | sh_cmt_clock_event_program_verify(p, 1); | ||
324 | |||
325 | if (p->flags & FLAG_CLOCKEVENT) | ||
326 | if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN) | ||
327 | || (p->match_value == p->next_match_value)) | ||
328 | p->flags &= ~FLAG_REPROGRAM; | ||
329 | } | ||
330 | |||
331 | p->flags &= ~FLAG_IRQCONTEXT; | ||
332 | |||
333 | return IRQ_HANDLED; | ||
334 | } | ||
335 | |||
336 | static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) | ||
337 | { | ||
338 | int ret = 0; | ||
339 | unsigned long flags; | ||
340 | |||
341 | spin_lock_irqsave(&p->lock, flags); | ||
342 | |||
343 | if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) | ||
344 | ret = sh_cmt_enable(p, &p->rate); | ||
345 | |||
346 | if (ret) | ||
347 | goto out; | ||
348 | p->flags |= flag; | ||
349 | |||
350 | /* setup timeout if no clockevent */ | ||
351 | if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) | ||
352 | sh_cmt_set_next(p, p->max_match_value); | ||
353 | out: | ||
354 | spin_unlock_irqrestore(&p->lock, flags); | ||
355 | |||
356 | return ret; | ||
357 | } | ||
358 | |||
359 | static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) | ||
360 | { | ||
361 | unsigned long flags; | ||
362 | unsigned long f; | ||
363 | |||
364 | spin_lock_irqsave(&p->lock, flags); | ||
365 | |||
366 | f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE); | ||
367 | p->flags &= ~flag; | ||
368 | |||
369 | if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) | ||
370 | sh_cmt_disable(p); | ||
371 | |||
372 | /* adjust the timeout to maximum if only clocksource left */ | ||
373 | if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) | ||
374 | sh_cmt_set_next(p, p->max_match_value); | ||
375 | |||
376 | spin_unlock_irqrestore(&p->lock, flags); | ||
377 | } | ||
378 | |||
379 | static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced) | ||
380 | { | ||
381 | return container_of(ced, struct sh_cmt_priv, ced); | ||
382 | } | ||
383 | |||
384 | static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic) | ||
385 | { | ||
386 | struct clock_event_device *ced = &p->ced; | ||
387 | |||
388 | sh_cmt_start(p, FLAG_CLOCKEVENT); | ||
389 | |||
390 | /* TODO: calculate good shift from rate and counter bit width */ | ||
391 | |||
392 | ced->shift = 32; | ||
393 | ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift); | ||
394 | ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced); | ||
395 | ced->min_delta_ns = clockevent_delta2ns(0x1f, ced); | ||
396 | |||
397 | if (periodic) | ||
398 | sh_cmt_set_next(p, (p->rate + HZ/2) / HZ); | ||
399 | else | ||
400 | sh_cmt_set_next(p, p->max_match_value); | ||
401 | } | ||
402 | |||
403 | static void sh_cmt_clock_event_mode(enum clock_event_mode mode, | ||
404 | struct clock_event_device *ced) | ||
405 | { | ||
406 | struct sh_cmt_priv *p = ced_to_sh_cmt(ced); | ||
407 | |||
408 | /* deal with old setting first */ | ||
409 | switch (ced->mode) { | ||
410 | case CLOCK_EVT_MODE_PERIODIC: | ||
411 | case CLOCK_EVT_MODE_ONESHOT: | ||
412 | sh_cmt_stop(p, FLAG_CLOCKEVENT); | ||
413 | break; | ||
414 | default: | ||
415 | break; | ||
416 | } | ||
417 | |||
418 | switch (mode) { | ||
419 | case CLOCK_EVT_MODE_PERIODIC: | ||
420 | pr_info("sh_cmt: %s used for periodic clock events\n", | ||
421 | ced->name); | ||
422 | sh_cmt_clock_event_start(p, 1); | ||
423 | break; | ||
424 | case CLOCK_EVT_MODE_ONESHOT: | ||
425 | pr_info("sh_cmt: %s used for oneshot clock events\n", | ||
426 | ced->name); | ||
427 | sh_cmt_clock_event_start(p, 0); | ||
428 | break; | ||
429 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
430 | case CLOCK_EVT_MODE_UNUSED: | ||
431 | sh_cmt_stop(p, FLAG_CLOCKEVENT); | ||
432 | break; | ||
433 | default: | ||
434 | break; | ||
435 | } | ||
436 | } | ||
437 | |||
438 | static int sh_cmt_clock_event_next(unsigned long delta, | ||
439 | struct clock_event_device *ced) | ||
440 | { | ||
441 | struct sh_cmt_priv *p = ced_to_sh_cmt(ced); | ||
442 | |||
443 | BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); | ||
444 | if (likely(p->flags & FLAG_IRQCONTEXT)) | ||
445 | p->next_match_value = delta; | ||
446 | else | ||
447 | sh_cmt_set_next(p, delta); | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static void sh_cmt_register_clockevent(struct sh_cmt_priv *p, | ||
453 | char *name, unsigned long rating) | ||
454 | { | ||
455 | struct clock_event_device *ced = &p->ced; | ||
456 | |||
457 | memset(ced, 0, sizeof(*ced)); | ||
458 | |||
459 | ced->name = name; | ||
460 | ced->features = CLOCK_EVT_FEAT_PERIODIC; | ||
461 | ced->features |= CLOCK_EVT_FEAT_ONESHOT; | ||
462 | ced->rating = rating; | ||
463 | ced->cpumask = cpumask_of(0); | ||
464 | ced->set_next_event = sh_cmt_clock_event_next; | ||
465 | ced->set_mode = sh_cmt_clock_event_mode; | ||
466 | |||
467 | pr_info("sh_cmt: %s used for clock events\n", ced->name); | ||
468 | ced->mult = 1; /* work around misplaced WARN_ON() in clockevents.c */ | ||
469 | clockevents_register_device(ced); | ||
470 | } | ||
471 | |||
472 | int sh_cmt_register(struct sh_cmt_priv *p, char *name, | ||
473 | unsigned long clockevent_rating, | ||
474 | unsigned long clocksource_rating) | ||
475 | { | ||
476 | if (p->width == (sizeof(p->max_match_value) * 8)) | ||
477 | p->max_match_value = ~0; | ||
478 | else | ||
479 | p->max_match_value = (1 << p->width) - 1; | ||
480 | |||
481 | p->match_value = p->max_match_value; | ||
482 | spin_lock_init(&p->lock); | ||
483 | |||
484 | if (clockevent_rating) | ||
485 | sh_cmt_register_clockevent(p, name, clockevent_rating); | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | ||
491 | { | ||
492 | struct sh_cmt_config *cfg = pdev->dev.platform_data; | ||
493 | struct resource *res; | ||
494 | int irq, ret; | ||
495 | ret = -ENXIO; | ||
496 | |||
497 | memset(p, 0, sizeof(*p)); | ||
498 | p->pdev = pdev; | ||
499 | |||
500 | if (!cfg) { | ||
501 | dev_err(&p->pdev->dev, "missing platform data\n"); | ||
502 | goto err0; | ||
503 | } | ||
504 | |||
505 | platform_set_drvdata(pdev, p); | ||
506 | |||
507 | res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); | ||
508 | if (!res) { | ||
509 | dev_err(&p->pdev->dev, "failed to get I/O memory\n"); | ||
510 | goto err0; | ||
511 | } | ||
512 | |||
513 | irq = platform_get_irq(p->pdev, 0); | ||
514 | if (irq < 0) { | ||
515 | dev_err(&p->pdev->dev, "failed to get irq\n"); | ||
516 | goto err0; | ||
517 | } | ||
518 | |||
519 | /* map memory, let mapbase point to our channel */ | ||
520 | p->mapbase = ioremap_nocache(res->start, resource_size(res)); | ||
521 | if (p->mapbase == NULL) { | ||
522 | pr_err("sh_cmt: failed to remap I/O memory\n"); | ||
523 | goto err0; | ||
524 | } | ||
525 | |||
526 | /* request irq using setup_irq() (too early for request_irq()) */ | ||
527 | p->irqaction.name = cfg->name; | ||
528 | p->irqaction.handler = sh_cmt_interrupt; | ||
529 | p->irqaction.dev_id = p; | ||
530 | p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL; | ||
531 | p->irqaction.mask = CPU_MASK_NONE; | ||
532 | ret = setup_irq(irq, &p->irqaction); | ||
533 | if (ret) { | ||
534 | pr_err("sh_cmt: failed to request irq %d\n", irq); | ||
535 | goto err1; | ||
536 | } | ||
537 | |||
538 | /* get hold of clock */ | ||
539 | p->clk = clk_get(&p->pdev->dev, cfg->clk); | ||
540 | if (IS_ERR(p->clk)) { | ||
541 | pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk); | ||
542 | ret = PTR_ERR(p->clk); | ||
543 | goto err2; | ||
544 | } | ||
545 | |||
546 | if (resource_size(res) == 6) { | ||
547 | p->width = 16; | ||
548 | p->overflow_bit = 0x80; | ||
549 | p->clear_bits = ~0xc0; | ||
550 | } else { | ||
551 | p->width = 32; | ||
552 | p->overflow_bit = 0x8000; | ||
553 | p->clear_bits = ~0xc000; | ||
554 | } | ||
555 | |||
556 | return sh_cmt_register(p, cfg->name, | ||
557 | cfg->clockevent_rating, | ||
558 | cfg->clocksource_rating); | ||
559 | err2: | ||
560 | free_irq(irq, p); | ||
561 | err1: | ||
562 | iounmap(p->mapbase); | ||
563 | err0: | ||
564 | return ret; | ||
565 | } | ||
566 | |||
567 | static int __devinit sh_cmt_probe(struct platform_device *pdev) | ||
568 | { | ||
569 | struct sh_cmt_priv *p = platform_get_drvdata(pdev); | ||
570 | int ret; | ||
571 | |||
572 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
573 | if (p == NULL) { | ||
574 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
575 | return -ENOMEM; | ||
576 | } | ||
577 | |||
578 | ret = sh_cmt_setup(p, pdev); | ||
579 | if (ret) { | ||
580 | kfree(p); | ||
581 | |||
582 | platform_set_drvdata(pdev, NULL); | ||
583 | } | ||
584 | return ret; | ||
585 | } | ||
586 | |||
587 | static int __devexit sh_cmt_remove(struct platform_device *pdev) | ||
588 | { | ||
589 | return -EBUSY; /* cannot unregister clockevent and clocksource */ | ||
590 | } | ||
591 | |||
592 | static struct platform_driver sh_cmt_device_driver = { | ||
593 | .probe = sh_cmt_probe, | ||
594 | .remove = __devexit_p(sh_cmt_remove), | ||
595 | .driver = { | ||
596 | .name = "sh_cmt", | ||
597 | } | ||
598 | }; | ||
599 | |||
600 | static int __init sh_cmt_init(void) | ||
601 | { | ||
602 | return platform_driver_register(&sh_cmt_device_driver); | ||
603 | } | ||
604 | |||
605 | static void __exit sh_cmt_exit(void) | ||
606 | { | ||
607 | platform_driver_unregister(&sh_cmt_device_driver); | ||
608 | } | ||
609 | |||
610 | module_init(sh_cmt_init); | ||
611 | module_exit(sh_cmt_exit); | ||
612 | |||
613 | MODULE_AUTHOR("Magnus Damm"); | ||
614 | MODULE_DESCRIPTION("SuperH CMT Timer Driver"); | ||
615 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index d6daf3c507d3..d270e8eb3e67 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -104,7 +104,8 @@ EXPORT_SYMBOL_GPL(unlock_policy_rwsem_write); | |||
104 | 104 | ||
105 | 105 | ||
106 | /* internal prototypes */ | 106 | /* internal prototypes */ |
107 | static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); | 107 | static int __cpufreq_governor(struct cpufreq_policy *policy, |
108 | unsigned int event); | ||
108 | static unsigned int __cpufreq_get(unsigned int cpu); | 109 | static unsigned int __cpufreq_get(unsigned int cpu); |
109 | static void handle_update(struct work_struct *work); | 110 | static void handle_update(struct work_struct *work); |
110 | 111 | ||
@@ -128,7 +129,7 @@ static int __init init_cpufreq_transition_notifier_list(void) | |||
128 | pure_initcall(init_cpufreq_transition_notifier_list); | 129 | pure_initcall(init_cpufreq_transition_notifier_list); |
129 | 130 | ||
130 | static LIST_HEAD(cpufreq_governor_list); | 131 | static LIST_HEAD(cpufreq_governor_list); |
131 | static DEFINE_MUTEX (cpufreq_governor_mutex); | 132 | static DEFINE_MUTEX(cpufreq_governor_mutex); |
132 | 133 | ||
133 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | 134 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) |
134 | { | 135 | { |
@@ -371,7 +372,7 @@ static struct cpufreq_governor *__find_governor(const char *str_governor) | |||
371 | struct cpufreq_governor *t; | 372 | struct cpufreq_governor *t; |
372 | 373 | ||
373 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) | 374 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) |
374 | if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) | 375 | if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN)) |
375 | return t; | 376 | return t; |
376 | 377 | ||
377 | return NULL; | 378 | return NULL; |
@@ -429,15 +430,11 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, | |||
429 | 430 | ||
430 | mutex_unlock(&cpufreq_governor_mutex); | 431 | mutex_unlock(&cpufreq_governor_mutex); |
431 | } | 432 | } |
432 | out: | 433 | out: |
433 | return err; | 434 | return err; |
434 | } | 435 | } |
435 | 436 | ||
436 | 437 | ||
437 | /* drivers/base/cpu.c */ | ||
438 | extern struct sysdev_class cpu_sysdev_class; | ||
439 | |||
440 | |||
441 | /** | 438 | /** |
442 | * cpufreq_per_cpu_attr_read() / show_##file_name() - | 439 | * cpufreq_per_cpu_attr_read() / show_##file_name() - |
443 | * print out cpufreq information | 440 | * print out cpufreq information |
@@ -450,11 +447,12 @@ extern struct sysdev_class cpu_sysdev_class; | |||
450 | static ssize_t show_##file_name \ | 447 | static ssize_t show_##file_name \ |
451 | (struct cpufreq_policy *policy, char *buf) \ | 448 | (struct cpufreq_policy *policy, char *buf) \ |
452 | { \ | 449 | { \ |
453 | return sprintf (buf, "%u\n", policy->object); \ | 450 | return sprintf(buf, "%u\n", policy->object); \ |
454 | } | 451 | } |
455 | 452 | ||
456 | show_one(cpuinfo_min_freq, cpuinfo.min_freq); | 453 | show_one(cpuinfo_min_freq, cpuinfo.min_freq); |
457 | show_one(cpuinfo_max_freq, cpuinfo.max_freq); | 454 | show_one(cpuinfo_max_freq, cpuinfo.max_freq); |
455 | show_one(cpuinfo_transition_latency, cpuinfo.transition_latency); | ||
458 | show_one(scaling_min_freq, min); | 456 | show_one(scaling_min_freq, min); |
459 | show_one(scaling_max_freq, max); | 457 | show_one(scaling_max_freq, max); |
460 | show_one(scaling_cur_freq, cur); | 458 | show_one(scaling_cur_freq, cur); |
@@ -476,7 +474,7 @@ static ssize_t store_##file_name \ | |||
476 | if (ret) \ | 474 | if (ret) \ |
477 | return -EINVAL; \ | 475 | return -EINVAL; \ |
478 | \ | 476 | \ |
479 | ret = sscanf (buf, "%u", &new_policy.object); \ | 477 | ret = sscanf(buf, "%u", &new_policy.object); \ |
480 | if (ret != 1) \ | 478 | if (ret != 1) \ |
481 | return -EINVAL; \ | 479 | return -EINVAL; \ |
482 | \ | 480 | \ |
@@ -486,8 +484,8 @@ static ssize_t store_##file_name \ | |||
486 | return ret ? ret : count; \ | 484 | return ret ? ret : count; \ |
487 | } | 485 | } |
488 | 486 | ||
489 | store_one(scaling_min_freq,min); | 487 | store_one(scaling_min_freq, min); |
490 | store_one(scaling_max_freq,max); | 488 | store_one(scaling_max_freq, max); |
491 | 489 | ||
492 | /** | 490 | /** |
493 | * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware | 491 | * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware |
@@ -507,12 +505,13 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, | |||
507 | */ | 505 | */ |
508 | static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) | 506 | static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) |
509 | { | 507 | { |
510 | if(policy->policy == CPUFREQ_POLICY_POWERSAVE) | 508 | if (policy->policy == CPUFREQ_POLICY_POWERSAVE) |
511 | return sprintf(buf, "powersave\n"); | 509 | return sprintf(buf, "powersave\n"); |
512 | else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) | 510 | else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) |
513 | return sprintf(buf, "performance\n"); | 511 | return sprintf(buf, "performance\n"); |
514 | else if (policy->governor) | 512 | else if (policy->governor) |
515 | return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name); | 513 | return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", |
514 | policy->governor->name); | ||
516 | return -EINVAL; | 515 | return -EINVAL; |
517 | } | 516 | } |
518 | 517 | ||
@@ -531,7 +530,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, | |||
531 | if (ret) | 530 | if (ret) |
532 | return ret; | 531 | return ret; |
533 | 532 | ||
534 | ret = sscanf (buf, "%15s", str_governor); | 533 | ret = sscanf(buf, "%15s", str_governor); |
535 | if (ret != 1) | 534 | if (ret != 1) |
536 | return -EINVAL; | 535 | return -EINVAL; |
537 | 536 | ||
@@ -575,7 +574,8 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, | |||
575 | } | 574 | } |
576 | 575 | ||
577 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) { | 576 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) { |
578 | if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2))) | 577 | if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) |
578 | - (CPUFREQ_NAME_LEN + 2))) | ||
579 | goto out; | 579 | goto out; |
580 | i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); | 580 | i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); |
581 | } | 581 | } |
@@ -594,7 +594,7 @@ static ssize_t show_cpus(const struct cpumask *mask, char *buf) | |||
594 | i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " "); | 594 | i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " "); |
595 | i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu); | 595 | i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu); |
596 | if (i >= (PAGE_SIZE - 5)) | 596 | if (i >= (PAGE_SIZE - 5)) |
597 | break; | 597 | break; |
598 | } | 598 | } |
599 | i += sprintf(&buf[i], "\n"); | 599 | i += sprintf(&buf[i], "\n"); |
600 | return i; | 600 | return i; |
@@ -660,6 +660,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name) | |||
660 | define_one_ro0400(cpuinfo_cur_freq); | 660 | define_one_ro0400(cpuinfo_cur_freq); |
661 | define_one_ro(cpuinfo_min_freq); | 661 | define_one_ro(cpuinfo_min_freq); |
662 | define_one_ro(cpuinfo_max_freq); | 662 | define_one_ro(cpuinfo_max_freq); |
663 | define_one_ro(cpuinfo_transition_latency); | ||
663 | define_one_ro(scaling_available_governors); | 664 | define_one_ro(scaling_available_governors); |
664 | define_one_ro(scaling_driver); | 665 | define_one_ro(scaling_driver); |
665 | define_one_ro(scaling_cur_freq); | 666 | define_one_ro(scaling_cur_freq); |
@@ -673,6 +674,7 @@ define_one_rw(scaling_setspeed); | |||
673 | static struct attribute *default_attrs[] = { | 674 | static struct attribute *default_attrs[] = { |
674 | &cpuinfo_min_freq.attr, | 675 | &cpuinfo_min_freq.attr, |
675 | &cpuinfo_max_freq.attr, | 676 | &cpuinfo_max_freq.attr, |
677 | &cpuinfo_transition_latency.attr, | ||
676 | &scaling_min_freq.attr, | 678 | &scaling_min_freq.attr, |
677 | &scaling_max_freq.attr, | 679 | &scaling_max_freq.attr, |
678 | &affected_cpus.attr, | 680 | &affected_cpus.attr, |
@@ -684,10 +686,10 @@ static struct attribute *default_attrs[] = { | |||
684 | NULL | 686 | NULL |
685 | }; | 687 | }; |
686 | 688 | ||
687 | #define to_policy(k) container_of(k,struct cpufreq_policy,kobj) | 689 | #define to_policy(k) container_of(k, struct cpufreq_policy, kobj) |
688 | #define to_attr(a) container_of(a,struct freq_attr,attr) | 690 | #define to_attr(a) container_of(a, struct freq_attr, attr) |
689 | 691 | ||
690 | static ssize_t show(struct kobject *kobj, struct attribute *attr ,char *buf) | 692 | static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) |
691 | { | 693 | { |
692 | struct cpufreq_policy *policy = to_policy(kobj); | 694 | struct cpufreq_policy *policy = to_policy(kobj); |
693 | struct freq_attr *fattr = to_attr(attr); | 695 | struct freq_attr *fattr = to_attr(attr); |
@@ -853,10 +855,10 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
853 | if (cpu == j) | 855 | if (cpu == j) |
854 | continue; | 856 | continue; |
855 | 857 | ||
856 | /* check for existing affected CPUs. They may not be aware | 858 | /* Check for existing affected CPUs. |
857 | * of it due to CPU Hotplug. | 859 | * They may not be aware of it due to CPU Hotplug. |
858 | */ | 860 | */ |
859 | managed_policy = cpufreq_cpu_get(j); // FIXME: Where is this released? What about error paths? | 861 | managed_policy = cpufreq_cpu_get(j); /* FIXME: Where is this released? What about error paths? */ |
860 | if (unlikely(managed_policy)) { | 862 | if (unlikely(managed_policy)) { |
861 | 863 | ||
862 | /* Set proper policy_cpu */ | 864 | /* Set proper policy_cpu */ |
@@ -1127,8 +1129,8 @@ static void handle_update(struct work_struct *work) | |||
1127 | * @old_freq: CPU frequency the kernel thinks the CPU runs at | 1129 | * @old_freq: CPU frequency the kernel thinks the CPU runs at |
1128 | * @new_freq: CPU frequency the CPU actually runs at | 1130 | * @new_freq: CPU frequency the CPU actually runs at |
1129 | * | 1131 | * |
1130 | * We adjust to current frequency first, and need to clean up later. So either call | 1132 | * We adjust to current frequency first, and need to clean up later. |
1131 | * to cpufreq_update_policy() or schedule handle_update()). | 1133 | * So either call to cpufreq_update_policy() or schedule handle_update()). |
1132 | */ | 1134 | */ |
1133 | static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, | 1135 | static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, |
1134 | unsigned int new_freq) | 1136 | unsigned int new_freq) |
@@ -1610,7 +1612,8 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_governor); | |||
1610 | 1612 | ||
1611 | /** | 1613 | /** |
1612 | * cpufreq_get_policy - get the current cpufreq_policy | 1614 | * cpufreq_get_policy - get the current cpufreq_policy |
1613 | * @policy: struct cpufreq_policy into which the current cpufreq_policy is written | 1615 | * @policy: struct cpufreq_policy into which the current cpufreq_policy |
1616 | * is written | ||
1614 | * | 1617 | * |
1615 | * Reads the current cpufreq policy. | 1618 | * Reads the current cpufreq policy. |
1616 | */ | 1619 | */ |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 0320962c4ec5..2ecd95e4ab1a 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2001 Russell King | 4 | * Copyright (C) 2001 Russell King |
5 | * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>. | 5 | * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>. |
6 | * Jun Nakajima <jun.nakajima@intel.com> | 6 | * Jun Nakajima <jun.nakajima@intel.com> |
7 | * (C) 2004 Alexander Clouter <alex-kernel@digriz.org.uk> | 7 | * (C) 2009 Alexander Clouter <alex@digriz.org.uk> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -13,22 +13,17 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/smp.h> | ||
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/ctype.h> | ||
20 | #include <linux/cpufreq.h> | 17 | #include <linux/cpufreq.h> |
21 | #include <linux/sysctl.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/sysfs.h> | ||
25 | #include <linux/cpu.h> | 18 | #include <linux/cpu.h> |
26 | #include <linux/kmod.h> | ||
27 | #include <linux/workqueue.h> | ||
28 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
29 | #include <linux/kernel_stat.h> | 20 | #include <linux/kernel_stat.h> |
30 | #include <linux/percpu.h> | ||
31 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/hrtimer.h> | ||
23 | #include <linux/tick.h> | ||
24 | #include <linux/ktime.h> | ||
25 | #include <linux/sched.h> | ||
26 | |||
32 | /* | 27 | /* |
33 | * dbs is used in this file as a shortform for demandbased switching | 28 | * dbs is used in this file as a shortform for demandbased switching |
34 | * It helps to keep variable names smaller, simpler | 29 | * It helps to keep variable names smaller, simpler |
@@ -43,19 +38,31 @@ | |||
43 | * latency of the processor. The governor will work on any processor with | 38 | * latency of the processor. The governor will work on any processor with |
44 | * transition latency <= 10mS, using appropriate sampling | 39 | * transition latency <= 10mS, using appropriate sampling |
45 | * rate. | 40 | * rate. |
46 | * For CPUs with transition latency > 10mS (mostly drivers | 41 | * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) |
47 | * with CPUFREQ_ETERNAL), this governor will not work. | 42 | * this governor will not work. |
48 | * All times here are in uS. | 43 | * All times here are in uS. |
49 | */ | 44 | */ |
50 | static unsigned int def_sampling_rate; | 45 | static unsigned int def_sampling_rate; |
51 | #define MIN_SAMPLING_RATE_RATIO (2) | 46 | #define MIN_SAMPLING_RATE_RATIO (2) |
52 | /* for correct statistics, we need at least 10 ticks between each measure */ | 47 | /* for correct statistics, we need at least 10 ticks between each measure */ |
53 | #define MIN_STAT_SAMPLING_RATE \ | 48 | #define MIN_STAT_SAMPLING_RATE \ |
54 | (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10)) | 49 | (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10)) |
55 | #define MIN_SAMPLING_RATE \ | 50 | #define MIN_SAMPLING_RATE \ |
56 | (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) | 51 | (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) |
52 | /* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon | ||
53 | * Define the minimal settable sampling rate to the greater of: | ||
54 | * - "HW transition latency" * 100 (same as default sampling / 10) | ||
55 | * - MIN_STAT_SAMPLING_RATE | ||
56 | * To avoid that userspace shoots itself. | ||
57 | */ | ||
58 | static unsigned int minimum_sampling_rate(void) | ||
59 | { | ||
60 | return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE); | ||
61 | } | ||
62 | |||
63 | /* This will also vanish soon with removing sampling_rate_max */ | ||
57 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | 64 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) |
58 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 65 | #define LATENCY_MULTIPLIER (1000) |
59 | #define DEF_SAMPLING_DOWN_FACTOR (1) | 66 | #define DEF_SAMPLING_DOWN_FACTOR (1) |
60 | #define MAX_SAMPLING_DOWN_FACTOR (10) | 67 | #define MAX_SAMPLING_DOWN_FACTOR (10) |
61 | #define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) | 68 | #define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) |
@@ -63,12 +70,15 @@ static unsigned int def_sampling_rate; | |||
63 | static void do_dbs_timer(struct work_struct *work); | 70 | static void do_dbs_timer(struct work_struct *work); |
64 | 71 | ||
65 | struct cpu_dbs_info_s { | 72 | struct cpu_dbs_info_s { |
73 | cputime64_t prev_cpu_idle; | ||
74 | cputime64_t prev_cpu_wall; | ||
75 | cputime64_t prev_cpu_nice; | ||
66 | struct cpufreq_policy *cur_policy; | 76 | struct cpufreq_policy *cur_policy; |
67 | unsigned int prev_cpu_idle_up; | 77 | struct delayed_work work; |
68 | unsigned int prev_cpu_idle_down; | ||
69 | unsigned int enable; | ||
70 | unsigned int down_skip; | 78 | unsigned int down_skip; |
71 | unsigned int requested_freq; | 79 | unsigned int requested_freq; |
80 | int cpu; | ||
81 | unsigned int enable:1; | ||
72 | }; | 82 | }; |
73 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 83 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); |
74 | 84 | ||
@@ -82,19 +92,18 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ | |||
82 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock | 92 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock |
83 | * is recursive for the same process. -Venki | 93 | * is recursive for the same process. -Venki |
84 | */ | 94 | */ |
85 | static DEFINE_MUTEX (dbs_mutex); | 95 | static DEFINE_MUTEX(dbs_mutex); |
86 | static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer); | ||
87 | 96 | ||
88 | struct dbs_tuners { | 97 | static struct workqueue_struct *kconservative_wq; |
98 | |||
99 | static struct dbs_tuners { | ||
89 | unsigned int sampling_rate; | 100 | unsigned int sampling_rate; |
90 | unsigned int sampling_down_factor; | 101 | unsigned int sampling_down_factor; |
91 | unsigned int up_threshold; | 102 | unsigned int up_threshold; |
92 | unsigned int down_threshold; | 103 | unsigned int down_threshold; |
93 | unsigned int ignore_nice; | 104 | unsigned int ignore_nice; |
94 | unsigned int freq_step; | 105 | unsigned int freq_step; |
95 | }; | 106 | } dbs_tuners_ins = { |
96 | |||
97 | static struct dbs_tuners dbs_tuners_ins = { | ||
98 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 107 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, |
99 | .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, | 108 | .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, |
100 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, | 109 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, |
@@ -102,18 +111,37 @@ static struct dbs_tuners dbs_tuners_ins = { | |||
102 | .freq_step = 5, | 111 | .freq_step = 5, |
103 | }; | 112 | }; |
104 | 113 | ||
105 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) | 114 | static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, |
115 | cputime64_t *wall) | ||
106 | { | 116 | { |
107 | unsigned int add_nice = 0, ret; | 117 | cputime64_t idle_time; |
118 | cputime64_t cur_wall_time; | ||
119 | cputime64_t busy_time; | ||
108 | 120 | ||
109 | if (dbs_tuners_ins.ignore_nice) | 121 | cur_wall_time = jiffies64_to_cputime64(get_jiffies_64()); |
110 | add_nice = kstat_cpu(cpu).cpustat.nice; | 122 | busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user, |
123 | kstat_cpu(cpu).cpustat.system); | ||
124 | |||
125 | busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq); | ||
126 | busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq); | ||
127 | busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal); | ||
128 | busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.nice); | ||
129 | |||
130 | idle_time = cputime64_sub(cur_wall_time, busy_time); | ||
131 | if (wall) | ||
132 | *wall = cur_wall_time; | ||
133 | |||
134 | return idle_time; | ||
135 | } | ||
136 | |||
137 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) | ||
138 | { | ||
139 | u64 idle_time = get_cpu_idle_time_us(cpu, wall); | ||
111 | 140 | ||
112 | ret = kstat_cpu(cpu).cpustat.idle + | 141 | if (idle_time == -1ULL) |
113 | kstat_cpu(cpu).cpustat.iowait + | 142 | return get_cpu_idle_time_jiffy(cpu, wall); |
114 | add_nice; | ||
115 | 143 | ||
116 | return ret; | 144 | return idle_time; |
117 | } | 145 | } |
118 | 146 | ||
119 | /* keep track of frequency transitions */ | 147 | /* keep track of frequency transitions */ |
@@ -125,10 +153,21 @@ dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
125 | struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, | 153 | struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, |
126 | freq->cpu); | 154 | freq->cpu); |
127 | 155 | ||
156 | struct cpufreq_policy *policy; | ||
157 | |||
128 | if (!this_dbs_info->enable) | 158 | if (!this_dbs_info->enable) |
129 | return 0; | 159 | return 0; |
130 | 160 | ||
131 | this_dbs_info->requested_freq = freq->new; | 161 | policy = this_dbs_info->cur_policy; |
162 | |||
163 | /* | ||
164 | * we only care if our internally tracked freq moves outside | ||
165 | * the 'valid' ranges of freqency available to us otherwise | ||
166 | * we do not change it | ||
167 | */ | ||
168 | if (this_dbs_info->requested_freq > policy->max | ||
169 | || this_dbs_info->requested_freq < policy->min) | ||
170 | this_dbs_info->requested_freq = freq->new; | ||
132 | 171 | ||
133 | return 0; | 172 | return 0; |
134 | } | 173 | } |
@@ -140,16 +179,31 @@ static struct notifier_block dbs_cpufreq_notifier_block = { | |||
140 | /************************** sysfs interface ************************/ | 179 | /************************** sysfs interface ************************/ |
141 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) | 180 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) |
142 | { | 181 | { |
143 | return sprintf (buf, "%u\n", MAX_SAMPLING_RATE); | 182 | static int print_once; |
183 | |||
184 | if (!print_once) { | ||
185 | printk(KERN_INFO "CPUFREQ: conservative sampling_rate_max " | ||
186 | "sysfs file is deprecated - used by: %s\n", | ||
187 | current->comm); | ||
188 | print_once = 1; | ||
189 | } | ||
190 | return sprintf(buf, "%u\n", MAX_SAMPLING_RATE); | ||
144 | } | 191 | } |
145 | 192 | ||
146 | static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) | 193 | static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) |
147 | { | 194 | { |
148 | return sprintf (buf, "%u\n", MIN_SAMPLING_RATE); | 195 | static int print_once; |
196 | |||
197 | if (!print_once) { | ||
198 | printk(KERN_INFO "CPUFREQ: conservative sampling_rate_max " | ||
199 | "sysfs file is deprecated - used by: %s\n", current->comm); | ||
200 | print_once = 1; | ||
201 | } | ||
202 | return sprintf(buf, "%u\n", MIN_SAMPLING_RATE); | ||
149 | } | 203 | } |
150 | 204 | ||
151 | #define define_one_ro(_name) \ | 205 | #define define_one_ro(_name) \ |
152 | static struct freq_attr _name = \ | 206 | static struct freq_attr _name = \ |
153 | __ATTR(_name, 0444, show_##_name, NULL) | 207 | __ATTR(_name, 0444, show_##_name, NULL) |
154 | 208 | ||
155 | define_one_ro(sampling_rate_max); | 209 | define_one_ro(sampling_rate_max); |
@@ -174,7 +228,8 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | |||
174 | { | 228 | { |
175 | unsigned int input; | 229 | unsigned int input; |
176 | int ret; | 230 | int ret; |
177 | ret = sscanf (buf, "%u", &input); | 231 | ret = sscanf(buf, "%u", &input); |
232 | |||
178 | if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1) | 233 | if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1) |
179 | return -EINVAL; | 234 | return -EINVAL; |
180 | 235 | ||
@@ -190,15 +245,13 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | |||
190 | { | 245 | { |
191 | unsigned int input; | 246 | unsigned int input; |
192 | int ret; | 247 | int ret; |
193 | ret = sscanf (buf, "%u", &input); | 248 | ret = sscanf(buf, "%u", &input); |
194 | 249 | ||
195 | mutex_lock(&dbs_mutex); | 250 | if (ret != 1) |
196 | if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { | ||
197 | mutex_unlock(&dbs_mutex); | ||
198 | return -EINVAL; | 251 | return -EINVAL; |
199 | } | ||
200 | 252 | ||
201 | dbs_tuners_ins.sampling_rate = input; | 253 | mutex_lock(&dbs_mutex); |
254 | dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate()); | ||
202 | mutex_unlock(&dbs_mutex); | 255 | mutex_unlock(&dbs_mutex); |
203 | 256 | ||
204 | return count; | 257 | return count; |
@@ -209,10 +262,11 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
209 | { | 262 | { |
210 | unsigned int input; | 263 | unsigned int input; |
211 | int ret; | 264 | int ret; |
212 | ret = sscanf (buf, "%u", &input); | 265 | ret = sscanf(buf, "%u", &input); |
213 | 266 | ||
214 | mutex_lock(&dbs_mutex); | 267 | mutex_lock(&dbs_mutex); |
215 | if (ret != 1 || input > 100 || input <= dbs_tuners_ins.down_threshold) { | 268 | if (ret != 1 || input > 100 || |
269 | input <= dbs_tuners_ins.down_threshold) { | ||
216 | mutex_unlock(&dbs_mutex); | 270 | mutex_unlock(&dbs_mutex); |
217 | return -EINVAL; | 271 | return -EINVAL; |
218 | } | 272 | } |
@@ -228,10 +282,12 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused, | |||
228 | { | 282 | { |
229 | unsigned int input; | 283 | unsigned int input; |
230 | int ret; | 284 | int ret; |
231 | ret = sscanf (buf, "%u", &input); | 285 | ret = sscanf(buf, "%u", &input); |
232 | 286 | ||
233 | mutex_lock(&dbs_mutex); | 287 | mutex_lock(&dbs_mutex); |
234 | if (ret != 1 || input > 100 || input >= dbs_tuners_ins.up_threshold) { | 288 | /* cannot be lower than 11 otherwise freq will not fall */ |
289 | if (ret != 1 || input < 11 || input > 100 || | ||
290 | input >= dbs_tuners_ins.up_threshold) { | ||
235 | mutex_unlock(&dbs_mutex); | 291 | mutex_unlock(&dbs_mutex); |
236 | return -EINVAL; | 292 | return -EINVAL; |
237 | } | 293 | } |
@@ -264,12 +320,14 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
264 | } | 320 | } |
265 | dbs_tuners_ins.ignore_nice = input; | 321 | dbs_tuners_ins.ignore_nice = input; |
266 | 322 | ||
267 | /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ | 323 | /* we need to re-evaluate prev_cpu_idle */ |
268 | for_each_online_cpu(j) { | 324 | for_each_online_cpu(j) { |
269 | struct cpu_dbs_info_s *j_dbs_info; | 325 | struct cpu_dbs_info_s *dbs_info; |
270 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 326 | dbs_info = &per_cpu(cpu_dbs_info, j); |
271 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | 327 | dbs_info->prev_cpu_idle = get_cpu_idle_time(j, |
272 | j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; | 328 | &dbs_info->prev_cpu_wall); |
329 | if (dbs_tuners_ins.ignore_nice) | ||
330 | dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice; | ||
273 | } | 331 | } |
274 | mutex_unlock(&dbs_mutex); | 332 | mutex_unlock(&dbs_mutex); |
275 | 333 | ||
@@ -281,7 +339,6 @@ static ssize_t store_freq_step(struct cpufreq_policy *policy, | |||
281 | { | 339 | { |
282 | unsigned int input; | 340 | unsigned int input; |
283 | int ret; | 341 | int ret; |
284 | |||
285 | ret = sscanf(buf, "%u", &input); | 342 | ret = sscanf(buf, "%u", &input); |
286 | 343 | ||
287 | if (ret != 1) | 344 | if (ret != 1) |
@@ -310,7 +367,7 @@ define_one_rw(down_threshold); | |||
310 | define_one_rw(ignore_nice_load); | 367 | define_one_rw(ignore_nice_load); |
311 | define_one_rw(freq_step); | 368 | define_one_rw(freq_step); |
312 | 369 | ||
313 | static struct attribute * dbs_attributes[] = { | 370 | static struct attribute *dbs_attributes[] = { |
314 | &sampling_rate_max.attr, | 371 | &sampling_rate_max.attr, |
315 | &sampling_rate_min.attr, | 372 | &sampling_rate_min.attr, |
316 | &sampling_rate.attr, | 373 | &sampling_rate.attr, |
@@ -329,55 +386,78 @@ static struct attribute_group dbs_attr_group = { | |||
329 | 386 | ||
330 | /************************** sysfs end ************************/ | 387 | /************************** sysfs end ************************/ |
331 | 388 | ||
332 | static void dbs_check_cpu(int cpu) | 389 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) |
333 | { | 390 | { |
334 | unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; | 391 | unsigned int load = 0; |
335 | unsigned int tmp_idle_ticks, total_idle_ticks; | ||
336 | unsigned int freq_target; | 392 | unsigned int freq_target; |
337 | unsigned int freq_down_sampling_rate; | ||
338 | struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
339 | struct cpufreq_policy *policy; | ||
340 | 393 | ||
341 | if (!this_dbs_info->enable) | 394 | struct cpufreq_policy *policy; |
342 | return; | 395 | unsigned int j; |
343 | 396 | ||
344 | policy = this_dbs_info->cur_policy; | 397 | policy = this_dbs_info->cur_policy; |
345 | 398 | ||
346 | /* | 399 | /* |
347 | * The default safe range is 20% to 80% | 400 | * Every sampling_rate, we check, if current idle time is less |
348 | * Every sampling_rate, we check | 401 | * than 20% (default), then we try to increase frequency |
349 | * - If current idle time is less than 20%, then we try to | 402 | * Every sampling_rate*sampling_down_factor, we check, if current |
350 | * increase frequency | 403 | * idle time is more than 80%, then we try to decrease frequency |
351 | * Every sampling_rate*sampling_down_factor, we check | ||
352 | * - If current idle time is more than 80%, then we try to | ||
353 | * decrease frequency | ||
354 | * | 404 | * |
355 | * Any frequency increase takes it to the maximum frequency. | 405 | * Any frequency increase takes it to the maximum frequency. |
356 | * Frequency reduction happens at minimum steps of | 406 | * Frequency reduction happens at minimum steps of |
357 | * 5% (default) of max_frequency | 407 | * 5% (default) of maximum frequency |
358 | */ | 408 | */ |
359 | 409 | ||
360 | /* Check for frequency increase */ | 410 | /* Get Absolute Load */ |
361 | idle_ticks = UINT_MAX; | 411 | for_each_cpu(j, policy->cpus) { |
412 | struct cpu_dbs_info_s *j_dbs_info; | ||
413 | cputime64_t cur_wall_time, cur_idle_time; | ||
414 | unsigned int idle_time, wall_time; | ||
362 | 415 | ||
363 | /* Check for frequency increase */ | 416 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
364 | total_idle_ticks = get_cpu_idle_time(cpu); | 417 | |
365 | tmp_idle_ticks = total_idle_ticks - | 418 | cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); |
366 | this_dbs_info->prev_cpu_idle_up; | 419 | |
367 | this_dbs_info->prev_cpu_idle_up = total_idle_ticks; | 420 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, |
421 | j_dbs_info->prev_cpu_wall); | ||
422 | j_dbs_info->prev_cpu_wall = cur_wall_time; | ||
423 | |||
424 | idle_time = (unsigned int) cputime64_sub(cur_idle_time, | ||
425 | j_dbs_info->prev_cpu_idle); | ||
426 | j_dbs_info->prev_cpu_idle = cur_idle_time; | ||
427 | |||
428 | if (dbs_tuners_ins.ignore_nice) { | ||
429 | cputime64_t cur_nice; | ||
430 | unsigned long cur_nice_jiffies; | ||
431 | |||
432 | cur_nice = cputime64_sub(kstat_cpu(j).cpustat.nice, | ||
433 | j_dbs_info->prev_cpu_nice); | ||
434 | /* | ||
435 | * Assumption: nice time between sampling periods will | ||
436 | * be less than 2^32 jiffies for 32 bit sys | ||
437 | */ | ||
438 | cur_nice_jiffies = (unsigned long) | ||
439 | cputime64_to_jiffies64(cur_nice); | ||
368 | 440 | ||
369 | if (tmp_idle_ticks < idle_ticks) | 441 | j_dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice; |
370 | idle_ticks = tmp_idle_ticks; | 442 | idle_time += jiffies_to_usecs(cur_nice_jiffies); |
443 | } | ||
444 | |||
445 | if (unlikely(!wall_time || wall_time < idle_time)) | ||
446 | continue; | ||
447 | |||
448 | load = 100 * (wall_time - idle_time) / wall_time; | ||
449 | } | ||
371 | 450 | ||
372 | /* Scale idle ticks by 100 and compare with up and down ticks */ | 451 | /* |
373 | idle_ticks *= 100; | 452 | * break out if we 'cannot' reduce the speed as the user might |
374 | up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * | 453 | * want freq_step to be zero |
375 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | 454 | */ |
455 | if (dbs_tuners_ins.freq_step == 0) | ||
456 | return; | ||
376 | 457 | ||
377 | if (idle_ticks < up_idle_ticks) { | 458 | /* Check for frequency increase */ |
459 | if (load > dbs_tuners_ins.up_threshold) { | ||
378 | this_dbs_info->down_skip = 0; | 460 | this_dbs_info->down_skip = 0; |
379 | this_dbs_info->prev_cpu_idle_down = | ||
380 | this_dbs_info->prev_cpu_idle_up; | ||
381 | 461 | ||
382 | /* if we are already at full speed then break out early */ | 462 | /* if we are already at full speed then break out early */ |
383 | if (this_dbs_info->requested_freq == policy->max) | 463 | if (this_dbs_info->requested_freq == policy->max) |
@@ -398,49 +478,24 @@ static void dbs_check_cpu(int cpu) | |||
398 | return; | 478 | return; |
399 | } | 479 | } |
400 | 480 | ||
401 | /* Check for frequency decrease */ | 481 | /* |
402 | this_dbs_info->down_skip++; | 482 | * The optimal frequency is the frequency that is the lowest that |
403 | if (this_dbs_info->down_skip < dbs_tuners_ins.sampling_down_factor) | 483 | * can support the current CPU usage without triggering the up |
404 | return; | 484 | * policy. To be safe, we focus 10 points under the threshold. |
405 | 485 | */ | |
406 | /* Check for frequency decrease */ | 486 | if (load < (dbs_tuners_ins.down_threshold - 10)) { |
407 | total_idle_ticks = this_dbs_info->prev_cpu_idle_up; | ||
408 | tmp_idle_ticks = total_idle_ticks - | ||
409 | this_dbs_info->prev_cpu_idle_down; | ||
410 | this_dbs_info->prev_cpu_idle_down = total_idle_ticks; | ||
411 | |||
412 | if (tmp_idle_ticks < idle_ticks) | ||
413 | idle_ticks = tmp_idle_ticks; | ||
414 | |||
415 | /* Scale idle ticks by 100 and compare with up and down ticks */ | ||
416 | idle_ticks *= 100; | ||
417 | this_dbs_info->down_skip = 0; | ||
418 | |||
419 | freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * | ||
420 | dbs_tuners_ins.sampling_down_factor; | ||
421 | down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * | ||
422 | usecs_to_jiffies(freq_down_sampling_rate); | ||
423 | |||
424 | if (idle_ticks > down_idle_ticks) { | ||
425 | /* | ||
426 | * if we are already at the lowest speed then break out early | ||
427 | * or if we 'cannot' reduce the speed as the user might want | ||
428 | * freq_target to be zero | ||
429 | */ | ||
430 | if (this_dbs_info->requested_freq == policy->min | ||
431 | || dbs_tuners_ins.freq_step == 0) | ||
432 | return; | ||
433 | |||
434 | freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100; | 487 | freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100; |
435 | 488 | ||
436 | /* max freq cannot be less than 100. But who knows.... */ | ||
437 | if (unlikely(freq_target == 0)) | ||
438 | freq_target = 5; | ||
439 | |||
440 | this_dbs_info->requested_freq -= freq_target; | 489 | this_dbs_info->requested_freq -= freq_target; |
441 | if (this_dbs_info->requested_freq < policy->min) | 490 | if (this_dbs_info->requested_freq < policy->min) |
442 | this_dbs_info->requested_freq = policy->min; | 491 | this_dbs_info->requested_freq = policy->min; |
443 | 492 | ||
493 | /* | ||
494 | * if we cannot reduce the frequency anymore, break out early | ||
495 | */ | ||
496 | if (policy->cur == policy->min) | ||
497 | return; | ||
498 | |||
444 | __cpufreq_driver_target(policy, this_dbs_info->requested_freq, | 499 | __cpufreq_driver_target(policy, this_dbs_info->requested_freq, |
445 | CPUFREQ_RELATION_H); | 500 | CPUFREQ_RELATION_H); |
446 | return; | 501 | return; |
@@ -449,27 +504,45 @@ static void dbs_check_cpu(int cpu) | |||
449 | 504 | ||
450 | static void do_dbs_timer(struct work_struct *work) | 505 | static void do_dbs_timer(struct work_struct *work) |
451 | { | 506 | { |
452 | int i; | 507 | struct cpu_dbs_info_s *dbs_info = |
453 | mutex_lock(&dbs_mutex); | 508 | container_of(work, struct cpu_dbs_info_s, work.work); |
454 | for_each_online_cpu(i) | 509 | unsigned int cpu = dbs_info->cpu; |
455 | dbs_check_cpu(i); | 510 | |
456 | schedule_delayed_work(&dbs_work, | 511 | /* We want all CPUs to do sampling nearly on same jiffy */ |
457 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | 512 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
458 | mutex_unlock(&dbs_mutex); | 513 | |
514 | delay -= jiffies % delay; | ||
515 | |||
516 | if (lock_policy_rwsem_write(cpu) < 0) | ||
517 | return; | ||
518 | |||
519 | if (!dbs_info->enable) { | ||
520 | unlock_policy_rwsem_write(cpu); | ||
521 | return; | ||
522 | } | ||
523 | |||
524 | dbs_check_cpu(dbs_info); | ||
525 | |||
526 | queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); | ||
527 | unlock_policy_rwsem_write(cpu); | ||
459 | } | 528 | } |
460 | 529 | ||
461 | static inline void dbs_timer_init(void) | 530 | static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) |
462 | { | 531 | { |
463 | init_timer_deferrable(&dbs_work.timer); | 532 | /* We want all CPUs to do sampling nearly on same jiffy */ |
464 | schedule_delayed_work(&dbs_work, | 533 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
465 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | 534 | delay -= jiffies % delay; |
466 | return; | 535 | |
536 | dbs_info->enable = 1; | ||
537 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); | ||
538 | queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work, | ||
539 | delay); | ||
467 | } | 540 | } |
468 | 541 | ||
469 | static inline void dbs_timer_exit(void) | 542 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) |
470 | { | 543 | { |
471 | cancel_delayed_work(&dbs_work); | 544 | dbs_info->enable = 0; |
472 | return; | 545 | cancel_delayed_work(&dbs_info->work); |
473 | } | 546 | } |
474 | 547 | ||
475 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 548 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, |
@@ -503,11 +576,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
503 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 576 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
504 | j_dbs_info->cur_policy = policy; | 577 | j_dbs_info->cur_policy = policy; |
505 | 578 | ||
506 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(cpu); | 579 | j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, |
507 | j_dbs_info->prev_cpu_idle_down | 580 | &j_dbs_info->prev_cpu_wall); |
508 | = j_dbs_info->prev_cpu_idle_up; | 581 | if (dbs_tuners_ins.ignore_nice) { |
582 | j_dbs_info->prev_cpu_nice = | ||
583 | kstat_cpu(j).cpustat.nice; | ||
584 | } | ||
509 | } | 585 | } |
510 | this_dbs_info->enable = 1; | ||
511 | this_dbs_info->down_skip = 0; | 586 | this_dbs_info->down_skip = 0; |
512 | this_dbs_info->requested_freq = policy->cur; | 587 | this_dbs_info->requested_freq = policy->cur; |
513 | 588 | ||
@@ -523,38 +598,36 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
523 | if (latency == 0) | 598 | if (latency == 0) |
524 | latency = 1; | 599 | latency = 1; |
525 | 600 | ||
526 | def_sampling_rate = 10 * latency * | 601 | def_sampling_rate = |
527 | DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; | 602 | max(latency * LATENCY_MULTIPLIER, |
528 | 603 | MIN_STAT_SAMPLING_RATE); | |
529 | if (def_sampling_rate < MIN_STAT_SAMPLING_RATE) | ||
530 | def_sampling_rate = MIN_STAT_SAMPLING_RATE; | ||
531 | 604 | ||
532 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | 605 | dbs_tuners_ins.sampling_rate = def_sampling_rate; |
533 | 606 | ||
534 | dbs_timer_init(); | ||
535 | cpufreq_register_notifier( | 607 | cpufreq_register_notifier( |
536 | &dbs_cpufreq_notifier_block, | 608 | &dbs_cpufreq_notifier_block, |
537 | CPUFREQ_TRANSITION_NOTIFIER); | 609 | CPUFREQ_TRANSITION_NOTIFIER); |
538 | } | 610 | } |
611 | dbs_timer_init(this_dbs_info); | ||
539 | 612 | ||
540 | mutex_unlock(&dbs_mutex); | 613 | mutex_unlock(&dbs_mutex); |
614 | |||
541 | break; | 615 | break; |
542 | 616 | ||
543 | case CPUFREQ_GOV_STOP: | 617 | case CPUFREQ_GOV_STOP: |
544 | mutex_lock(&dbs_mutex); | 618 | mutex_lock(&dbs_mutex); |
545 | this_dbs_info->enable = 0; | 619 | dbs_timer_exit(this_dbs_info); |
546 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 620 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); |
547 | dbs_enable--; | 621 | dbs_enable--; |
622 | |||
548 | /* | 623 | /* |
549 | * Stop the timerschedule work, when this governor | 624 | * Stop the timerschedule work, when this governor |
550 | * is used for first time | 625 | * is used for first time |
551 | */ | 626 | */ |
552 | if (dbs_enable == 0) { | 627 | if (dbs_enable == 0) |
553 | dbs_timer_exit(); | ||
554 | cpufreq_unregister_notifier( | 628 | cpufreq_unregister_notifier( |
555 | &dbs_cpufreq_notifier_block, | 629 | &dbs_cpufreq_notifier_block, |
556 | CPUFREQ_TRANSITION_NOTIFIER); | 630 | CPUFREQ_TRANSITION_NOTIFIER); |
557 | } | ||
558 | 631 | ||
559 | mutex_unlock(&dbs_mutex); | 632 | mutex_unlock(&dbs_mutex); |
560 | 633 | ||
@@ -571,6 +644,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
571 | this_dbs_info->cur_policy, | 644 | this_dbs_info->cur_policy, |
572 | policy->min, CPUFREQ_RELATION_L); | 645 | policy->min, CPUFREQ_RELATION_L); |
573 | mutex_unlock(&dbs_mutex); | 646 | mutex_unlock(&dbs_mutex); |
647 | |||
574 | break; | 648 | break; |
575 | } | 649 | } |
576 | return 0; | 650 | return 0; |
@@ -588,23 +662,33 @@ struct cpufreq_governor cpufreq_gov_conservative = { | |||
588 | 662 | ||
589 | static int __init cpufreq_gov_dbs_init(void) | 663 | static int __init cpufreq_gov_dbs_init(void) |
590 | { | 664 | { |
591 | return cpufreq_register_governor(&cpufreq_gov_conservative); | 665 | int err; |
666 | |||
667 | kconservative_wq = create_workqueue("kconservative"); | ||
668 | if (!kconservative_wq) { | ||
669 | printk(KERN_ERR "Creation of kconservative failed\n"); | ||
670 | return -EFAULT; | ||
671 | } | ||
672 | |||
673 | err = cpufreq_register_governor(&cpufreq_gov_conservative); | ||
674 | if (err) | ||
675 | destroy_workqueue(kconservative_wq); | ||
676 | |||
677 | return err; | ||
592 | } | 678 | } |
593 | 679 | ||
594 | static void __exit cpufreq_gov_dbs_exit(void) | 680 | static void __exit cpufreq_gov_dbs_exit(void) |
595 | { | 681 | { |
596 | /* Make sure that the scheduled work is indeed not running */ | ||
597 | flush_scheduled_work(); | ||
598 | |||
599 | cpufreq_unregister_governor(&cpufreq_gov_conservative); | 682 | cpufreq_unregister_governor(&cpufreq_gov_conservative); |
683 | destroy_workqueue(kconservative_wq); | ||
600 | } | 684 | } |
601 | 685 | ||
602 | 686 | ||
603 | MODULE_AUTHOR ("Alexander Clouter <alex-kernel@digriz.org.uk>"); | 687 | MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>"); |
604 | MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for " | 688 | MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for " |
605 | "Low Latency Frequency Transition capable processors " | 689 | "Low Latency Frequency Transition capable processors " |
606 | "optimised for use in a battery environment"); | 690 | "optimised for use in a battery environment"); |
607 | MODULE_LICENSE ("GPL"); | 691 | MODULE_LICENSE("GPL"); |
608 | 692 | ||
609 | #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE | 693 | #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE |
610 | fs_initcall(cpufreq_gov_dbs_init); | 694 | fs_initcall(cpufreq_gov_dbs_init); |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 6f45b1658a67..338f428a15b7 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/hrtimer.h> | 21 | #include <linux/hrtimer.h> |
22 | #include <linux/tick.h> | 22 | #include <linux/tick.h> |
23 | #include <linux/ktime.h> | 23 | #include <linux/ktime.h> |
24 | #include <linux/sched.h> | ||
24 | 25 | ||
25 | /* | 26 | /* |
26 | * dbs is used in this file as a shortform for demandbased switching | 27 | * dbs is used in this file as a shortform for demandbased switching |
@@ -51,8 +52,20 @@ static unsigned int def_sampling_rate; | |||
51 | (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10)) | 52 | (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10)) |
52 | #define MIN_SAMPLING_RATE \ | 53 | #define MIN_SAMPLING_RATE \ |
53 | (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) | 54 | (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) |
55 | /* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon | ||
56 | * Define the minimal settable sampling rate to the greater of: | ||
57 | * - "HW transition latency" * 100 (same as default sampling / 10) | ||
58 | * - MIN_STAT_SAMPLING_RATE | ||
59 | * To avoid that userspace shoots itself. | ||
60 | */ | ||
61 | static unsigned int minimum_sampling_rate(void) | ||
62 | { | ||
63 | return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE); | ||
64 | } | ||
65 | |||
66 | /* This will also vanish soon with removing sampling_rate_max */ | ||
54 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | 67 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) |
55 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 68 | #define LATENCY_MULTIPLIER (1000) |
56 | #define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) | 69 | #define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) |
57 | 70 | ||
58 | static void do_dbs_timer(struct work_struct *work); | 71 | static void do_dbs_timer(struct work_struct *work); |
@@ -65,14 +78,14 @@ struct cpu_dbs_info_s { | |||
65 | cputime64_t prev_cpu_wall; | 78 | cputime64_t prev_cpu_wall; |
66 | cputime64_t prev_cpu_nice; | 79 | cputime64_t prev_cpu_nice; |
67 | struct cpufreq_policy *cur_policy; | 80 | struct cpufreq_policy *cur_policy; |
68 | struct delayed_work work; | 81 | struct delayed_work work; |
69 | struct cpufreq_frequency_table *freq_table; | 82 | struct cpufreq_frequency_table *freq_table; |
70 | unsigned int freq_lo; | 83 | unsigned int freq_lo; |
71 | unsigned int freq_lo_jiffies; | 84 | unsigned int freq_lo_jiffies; |
72 | unsigned int freq_hi_jiffies; | 85 | unsigned int freq_hi_jiffies; |
73 | int cpu; | 86 | int cpu; |
74 | unsigned int enable:1, | 87 | unsigned int enable:1, |
75 | sample_type:1; | 88 | sample_type:1; |
76 | }; | 89 | }; |
77 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 90 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); |
78 | 91 | ||
@@ -203,12 +216,28 @@ static void ondemand_powersave_bias_init(void) | |||
203 | /************************** sysfs interface ************************/ | 216 | /************************** sysfs interface ************************/ |
204 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) | 217 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) |
205 | { | 218 | { |
206 | return sprintf (buf, "%u\n", MAX_SAMPLING_RATE); | 219 | static int print_once; |
220 | |||
221 | if (!print_once) { | ||
222 | printk(KERN_INFO "CPUFREQ: ondemand sampling_rate_max " | ||
223 | "sysfs file is deprecated - used by: %s\n", | ||
224 | current->comm); | ||
225 | print_once = 1; | ||
226 | } | ||
227 | return sprintf(buf, "%u\n", MAX_SAMPLING_RATE); | ||
207 | } | 228 | } |
208 | 229 | ||
209 | static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) | 230 | static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) |
210 | { | 231 | { |
211 | return sprintf (buf, "%u\n", MIN_SAMPLING_RATE); | 232 | static int print_once; |
233 | |||
234 | if (!print_once) { | ||
235 | printk(KERN_INFO "CPUFREQ: ondemand sampling_rate_min " | ||
236 | "sysfs file is deprecated - used by: %s\n", | ||
237 | current->comm); | ||
238 | print_once = 1; | ||
239 | } | ||
240 | return sprintf(buf, "%u\n", MIN_SAMPLING_RATE); | ||
212 | } | 241 | } |
213 | 242 | ||
214 | #define define_one_ro(_name) \ | 243 | #define define_one_ro(_name) \ |
@@ -238,13 +267,11 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | |||
238 | ret = sscanf(buf, "%u", &input); | 267 | ret = sscanf(buf, "%u", &input); |
239 | 268 | ||
240 | mutex_lock(&dbs_mutex); | 269 | mutex_lock(&dbs_mutex); |
241 | if (ret != 1 || input > MAX_SAMPLING_RATE | 270 | if (ret != 1) { |
242 | || input < MIN_SAMPLING_RATE) { | ||
243 | mutex_unlock(&dbs_mutex); | 271 | mutex_unlock(&dbs_mutex); |
244 | return -EINVAL; | 272 | return -EINVAL; |
245 | } | 273 | } |
246 | 274 | dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate()); | |
247 | dbs_tuners_ins.sampling_rate = input; | ||
248 | mutex_unlock(&dbs_mutex); | 275 | mutex_unlock(&dbs_mutex); |
249 | 276 | ||
250 | return count; | 277 | return count; |
@@ -279,14 +306,14 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
279 | unsigned int j; | 306 | unsigned int j; |
280 | 307 | ||
281 | ret = sscanf(buf, "%u", &input); | 308 | ret = sscanf(buf, "%u", &input); |
282 | if ( ret != 1 ) | 309 | if (ret != 1) |
283 | return -EINVAL; | 310 | return -EINVAL; |
284 | 311 | ||
285 | if ( input > 1 ) | 312 | if (input > 1) |
286 | input = 1; | 313 | input = 1; |
287 | 314 | ||
288 | mutex_lock(&dbs_mutex); | 315 | mutex_lock(&dbs_mutex); |
289 | if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ | 316 | if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */ |
290 | mutex_unlock(&dbs_mutex); | 317 | mutex_unlock(&dbs_mutex); |
291 | return count; | 318 | return count; |
292 | } | 319 | } |
@@ -337,7 +364,7 @@ define_one_rw(up_threshold); | |||
337 | define_one_rw(ignore_nice_load); | 364 | define_one_rw(ignore_nice_load); |
338 | define_one_rw(powersave_bias); | 365 | define_one_rw(powersave_bias); |
339 | 366 | ||
340 | static struct attribute * dbs_attributes[] = { | 367 | static struct attribute *dbs_attributes[] = { |
341 | &sampling_rate_max.attr, | 368 | &sampling_rate_max.attr, |
342 | &sampling_rate_min.attr, | 369 | &sampling_rate_min.attr, |
343 | &sampling_rate.attr, | 370 | &sampling_rate.attr, |
@@ -512,8 +539,7 @@ static void do_dbs_timer(struct work_struct *work) | |||
512 | } | 539 | } |
513 | } else { | 540 | } else { |
514 | __cpufreq_driver_target(dbs_info->cur_policy, | 541 | __cpufreq_driver_target(dbs_info->cur_policy, |
515 | dbs_info->freq_lo, | 542 | dbs_info->freq_lo, CPUFREQ_RELATION_H); |
516 | CPUFREQ_RELATION_H); | ||
517 | } | 543 | } |
518 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); | 544 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); |
519 | unlock_policy_rwsem_write(cpu); | 545 | unlock_policy_rwsem_write(cpu); |
@@ -530,7 +556,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
530 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; | 556 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; |
531 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); | 557 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); |
532 | queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, | 558 | queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, |
533 | delay); | 559 | delay); |
534 | } | 560 | } |
535 | 561 | ||
536 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) | 562 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) |
@@ -591,11 +617,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
591 | if (latency == 0) | 617 | if (latency == 0) |
592 | latency = 1; | 618 | latency = 1; |
593 | 619 | ||
594 | def_sampling_rate = latency * | 620 | def_sampling_rate = |
595 | DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; | 621 | max(latency * LATENCY_MULTIPLIER, |
596 | 622 | MIN_STAT_SAMPLING_RATE); | |
597 | if (def_sampling_rate < MIN_STAT_SAMPLING_RATE) | ||
598 | def_sampling_rate = MIN_STAT_SAMPLING_RATE; | ||
599 | 623 | ||
600 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | 624 | dbs_tuners_ins.sampling_rate = def_sampling_rate; |
601 | } | 625 | } |
@@ -617,12 +641,10 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
617 | mutex_lock(&dbs_mutex); | 641 | mutex_lock(&dbs_mutex); |
618 | if (policy->max < this_dbs_info->cur_policy->cur) | 642 | if (policy->max < this_dbs_info->cur_policy->cur) |
619 | __cpufreq_driver_target(this_dbs_info->cur_policy, | 643 | __cpufreq_driver_target(this_dbs_info->cur_policy, |
620 | policy->max, | 644 | policy->max, CPUFREQ_RELATION_H); |
621 | CPUFREQ_RELATION_H); | ||
622 | else if (policy->min > this_dbs_info->cur_policy->cur) | 645 | else if (policy->min > this_dbs_info->cur_policy->cur) |
623 | __cpufreq_driver_target(this_dbs_info->cur_policy, | 646 | __cpufreq_driver_target(this_dbs_info->cur_policy, |
624 | policy->min, | 647 | policy->min, CPUFREQ_RELATION_L); |
625 | CPUFREQ_RELATION_L); | ||
626 | mutex_unlock(&dbs_mutex); | 648 | mutex_unlock(&dbs_mutex); |
627 | break; | 649 | break; |
628 | } | 650 | } |
@@ -677,7 +699,7 @@ static void __exit cpufreq_gov_dbs_exit(void) | |||
677 | MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>"); | 699 | MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>"); |
678 | MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>"); | 700 | MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>"); |
679 | MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " | 701 | MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " |
680 | "Low Latency Frequency Transition capable processors"); | 702 | "Low Latency Frequency Transition capable processors"); |
681 | MODULE_LICENSE("GPL"); | 703 | MODULE_LICENSE("GPL"); |
682 | 704 | ||
683 | #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND | 705 | #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index c0ff97d375d7..5a62d678dd19 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * drivers/cpufreq/cpufreq_stats.c | 2 | * drivers/cpufreq/cpufreq_stats.c |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>. | 4 | * Copyright (C) 2003-2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>. |
5 | * (C) 2004 Zou Nan hai <nanhai.zou@intel.com>. | 5 | * (C) 2004 Zou Nan hai <nanhai.zou@intel.com>. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | static spinlock_t cpufreq_stats_lock; | 24 | static spinlock_t cpufreq_stats_lock; |
25 | 25 | ||
26 | #define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \ | 26 | #define CPUFREQ_STATDEVICE_ATTR(_name, _mode, _show) \ |
27 | static struct freq_attr _attr_##_name = {\ | 27 | static struct freq_attr _attr_##_name = {\ |
28 | .attr = {.name = __stringify(_name), .mode = _mode, }, \ | 28 | .attr = {.name = __stringify(_name), .mode = _mode, }, \ |
29 | .show = _show,\ | 29 | .show = _show,\ |
@@ -50,8 +50,7 @@ struct cpufreq_stats_attribute { | |||
50 | ssize_t(*show) (struct cpufreq_stats *, char *); | 50 | ssize_t(*show) (struct cpufreq_stats *, char *); |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static int | 53 | static int cpufreq_stats_update(unsigned int cpu) |
54 | cpufreq_stats_update (unsigned int cpu) | ||
55 | { | 54 | { |
56 | struct cpufreq_stats *stat; | 55 | struct cpufreq_stats *stat; |
57 | unsigned long long cur_time; | 56 | unsigned long long cur_time; |
@@ -68,8 +67,7 @@ cpufreq_stats_update (unsigned int cpu) | |||
68 | return 0; | 67 | return 0; |
69 | } | 68 | } |
70 | 69 | ||
71 | static ssize_t | 70 | static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) |
72 | show_total_trans(struct cpufreq_policy *policy, char *buf) | ||
73 | { | 71 | { |
74 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); | 72 | struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); |
75 | if (!stat) | 73 | if (!stat) |
@@ -78,8 +76,7 @@ show_total_trans(struct cpufreq_policy *policy, char *buf) | |||
78 | per_cpu(cpufreq_stats_table, stat->cpu)->total_trans); | 76 | per_cpu(cpufreq_stats_table, stat->cpu)->total_trans); |
79 | } | 77 | } |
80 | 78 | ||
81 | static ssize_t | 79 | static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) |
82 | show_time_in_state(struct cpufreq_policy *policy, char *buf) | ||
83 | { | 80 | { |
84 | ssize_t len = 0; | 81 | ssize_t len = 0; |
85 | int i; | 82 | int i; |
@@ -89,14 +86,14 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf) | |||
89 | cpufreq_stats_update(stat->cpu); | 86 | cpufreq_stats_update(stat->cpu); |
90 | for (i = 0; i < stat->state_num; i++) { | 87 | for (i = 0; i < stat->state_num; i++) { |
91 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], | 88 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], |
92 | (unsigned long long)cputime64_to_clock_t(stat->time_in_state[i])); | 89 | (unsigned long long) |
90 | cputime64_to_clock_t(stat->time_in_state[i])); | ||
93 | } | 91 | } |
94 | return len; | 92 | return len; |
95 | } | 93 | } |
96 | 94 | ||
97 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 95 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
98 | static ssize_t | 96 | static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) |
99 | show_trans_table(struct cpufreq_policy *policy, char *buf) | ||
100 | { | 97 | { |
101 | ssize_t len = 0; | 98 | ssize_t len = 0; |
102 | int i, j; | 99 | int i, j; |
@@ -139,11 +136,11 @@ show_trans_table(struct cpufreq_policy *policy, char *buf) | |||
139 | return PAGE_SIZE; | 136 | return PAGE_SIZE; |
140 | return len; | 137 | return len; |
141 | } | 138 | } |
142 | CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table); | 139 | CPUFREQ_STATDEVICE_ATTR(trans_table, 0444, show_trans_table); |
143 | #endif | 140 | #endif |
144 | 141 | ||
145 | CPUFREQ_STATDEVICE_ATTR(total_trans,0444,show_total_trans); | 142 | CPUFREQ_STATDEVICE_ATTR(total_trans, 0444, show_total_trans); |
146 | CPUFREQ_STATDEVICE_ATTR(time_in_state,0444,show_time_in_state); | 143 | CPUFREQ_STATDEVICE_ATTR(time_in_state, 0444, show_time_in_state); |
147 | 144 | ||
148 | static struct attribute *default_attrs[] = { | 145 | static struct attribute *default_attrs[] = { |
149 | &_attr_total_trans.attr, | 146 | &_attr_total_trans.attr, |
@@ -158,8 +155,7 @@ static struct attribute_group stats_attr_group = { | |||
158 | .name = "stats" | 155 | .name = "stats" |
159 | }; | 156 | }; |
160 | 157 | ||
161 | static int | 158 | static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) |
162 | freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) | ||
163 | { | 159 | { |
164 | int index; | 160 | int index; |
165 | for (index = 0; index < stat->max_state; index++) | 161 | for (index = 0; index < stat->max_state; index++) |
@@ -183,8 +179,7 @@ static void cpufreq_stats_free_table(unsigned int cpu) | |||
183 | cpufreq_cpu_put(policy); | 179 | cpufreq_cpu_put(policy); |
184 | } | 180 | } |
185 | 181 | ||
186 | static int | 182 | static int cpufreq_stats_create_table(struct cpufreq_policy *policy, |
187 | cpufreq_stats_create_table (struct cpufreq_policy *policy, | ||
188 | struct cpufreq_frequency_table *table) | 183 | struct cpufreq_frequency_table *table) |
189 | { | 184 | { |
190 | unsigned int i, j, count = 0, ret = 0; | 185 | unsigned int i, j, count = 0, ret = 0; |
@@ -194,7 +189,8 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy, | |||
194 | unsigned int cpu = policy->cpu; | 189 | unsigned int cpu = policy->cpu; |
195 | if (per_cpu(cpufreq_stats_table, cpu)) | 190 | if (per_cpu(cpufreq_stats_table, cpu)) |
196 | return -EBUSY; | 191 | return -EBUSY; |
197 | if ((stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL) | 192 | stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL); |
193 | if ((stat) == NULL) | ||
198 | return -ENOMEM; | 194 | return -ENOMEM; |
199 | 195 | ||
200 | data = cpufreq_cpu_get(cpu); | 196 | data = cpufreq_cpu_get(cpu); |
@@ -203,13 +199,14 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy, | |||
203 | goto error_get_fail; | 199 | goto error_get_fail; |
204 | } | 200 | } |
205 | 201 | ||
206 | if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group))) | 202 | ret = sysfs_create_group(&data->kobj, &stats_attr_group); |
203 | if (ret) | ||
207 | goto error_out; | 204 | goto error_out; |
208 | 205 | ||
209 | stat->cpu = cpu; | 206 | stat->cpu = cpu; |
210 | per_cpu(cpufreq_stats_table, cpu) = stat; | 207 | per_cpu(cpufreq_stats_table, cpu) = stat; |
211 | 208 | ||
212 | for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) { | 209 | for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { |
213 | unsigned int freq = table[i].frequency; | 210 | unsigned int freq = table[i].frequency; |
214 | if (freq == CPUFREQ_ENTRY_INVALID) | 211 | if (freq == CPUFREQ_ENTRY_INVALID) |
215 | continue; | 212 | continue; |
@@ -255,9 +252,8 @@ error_get_fail: | |||
255 | return ret; | 252 | return ret; |
256 | } | 253 | } |
257 | 254 | ||
258 | static int | 255 | static int cpufreq_stat_notifier_policy(struct notifier_block *nb, |
259 | cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val, | 256 | unsigned long val, void *data) |
260 | void *data) | ||
261 | { | 257 | { |
262 | int ret; | 258 | int ret; |
263 | struct cpufreq_policy *policy = data; | 259 | struct cpufreq_policy *policy = data; |
@@ -268,14 +264,14 @@ cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val, | |||
268 | table = cpufreq_frequency_get_table(cpu); | 264 | table = cpufreq_frequency_get_table(cpu); |
269 | if (!table) | 265 | if (!table) |
270 | return 0; | 266 | return 0; |
271 | if ((ret = cpufreq_stats_create_table(policy, table))) | 267 | ret = cpufreq_stats_create_table(policy, table); |
268 | if (ret) | ||
272 | return ret; | 269 | return ret; |
273 | return 0; | 270 | return 0; |
274 | } | 271 | } |
275 | 272 | ||
276 | static int | 273 | static int cpufreq_stat_notifier_trans(struct notifier_block *nb, |
277 | cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val, | 274 | unsigned long val, void *data) |
278 | void *data) | ||
279 | { | 275 | { |
280 | struct cpufreq_freqs *freq = data; | 276 | struct cpufreq_freqs *freq = data; |
281 | struct cpufreq_stats *stat; | 277 | struct cpufreq_stats *stat; |
@@ -340,19 +336,20 @@ static struct notifier_block notifier_trans_block = { | |||
340 | .notifier_call = cpufreq_stat_notifier_trans | 336 | .notifier_call = cpufreq_stat_notifier_trans |
341 | }; | 337 | }; |
342 | 338 | ||
343 | static int | 339 | static int __init cpufreq_stats_init(void) |
344 | __init cpufreq_stats_init(void) | ||
345 | { | 340 | { |
346 | int ret; | 341 | int ret; |
347 | unsigned int cpu; | 342 | unsigned int cpu; |
348 | 343 | ||
349 | spin_lock_init(&cpufreq_stats_lock); | 344 | spin_lock_init(&cpufreq_stats_lock); |
350 | if ((ret = cpufreq_register_notifier(¬ifier_policy_block, | 345 | ret = cpufreq_register_notifier(¬ifier_policy_block, |
351 | CPUFREQ_POLICY_NOTIFIER))) | 346 | CPUFREQ_POLICY_NOTIFIER); |
347 | if (ret) | ||
352 | return ret; | 348 | return ret; |
353 | 349 | ||
354 | if ((ret = cpufreq_register_notifier(¬ifier_trans_block, | 350 | ret = cpufreq_register_notifier(¬ifier_trans_block, |
355 | CPUFREQ_TRANSITION_NOTIFIER))) { | 351 | CPUFREQ_TRANSITION_NOTIFIER); |
352 | if (ret) { | ||
356 | cpufreq_unregister_notifier(¬ifier_policy_block, | 353 | cpufreq_unregister_notifier(¬ifier_policy_block, |
357 | CPUFREQ_POLICY_NOTIFIER); | 354 | CPUFREQ_POLICY_NOTIFIER); |
358 | return ret; | 355 | return ret; |
@@ -364,8 +361,7 @@ __init cpufreq_stats_init(void) | |||
364 | } | 361 | } |
365 | return 0; | 362 | return 0; |
366 | } | 363 | } |
367 | static void | 364 | static void __exit cpufreq_stats_exit(void) |
368 | __exit cpufreq_stats_exit(void) | ||
369 | { | 365 | { |
370 | unsigned int cpu; | 366 | unsigned int cpu; |
371 | 367 | ||
@@ -379,10 +375,10 @@ __exit cpufreq_stats_exit(void) | |||
379 | } | 375 | } |
380 | } | 376 | } |
381 | 377 | ||
382 | MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>"); | 378 | MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>"); |
383 | MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats " | 379 | MODULE_DESCRIPTION("'cpufreq_stats' - A driver to export cpufreq stats " |
384 | "through sysfs filesystem"); | 380 | "through sysfs filesystem"); |
385 | MODULE_LICENSE ("GPL"); | 381 | MODULE_LICENSE("GPL"); |
386 | 382 | ||
387 | module_init(cpufreq_stats_init); | 383 | module_init(cpufreq_stats_init); |
388 | module_exit(cpufreq_stats_exit); | 384 | module_exit(cpufreq_stats_exit); |
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 1442bbada053..66d2d1d6c80f 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c | |||
@@ -24,9 +24,6 @@ | |||
24 | #include <linux/sysfs.h> | 24 | #include <linux/sysfs.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | 26 | ||
27 | #include <asm/uaccess.h> | ||
28 | |||
29 | |||
30 | /** | 27 | /** |
31 | * A few values needed by the userspace governor | 28 | * A few values needed by the userspace governor |
32 | */ | 29 | */ |
@@ -37,7 +34,7 @@ static DEFINE_PER_CPU(unsigned int, cpu_set_freq); /* CPU freq desired by | |||
37 | userspace */ | 34 | userspace */ |
38 | static DEFINE_PER_CPU(unsigned int, cpu_is_managed); | 35 | static DEFINE_PER_CPU(unsigned int, cpu_is_managed); |
39 | 36 | ||
40 | static DEFINE_MUTEX (userspace_mutex); | 37 | static DEFINE_MUTEX(userspace_mutex); |
41 | static int cpus_using_userspace_governor; | 38 | static int cpus_using_userspace_governor; |
42 | 39 | ||
43 | #define dprintk(msg...) \ | 40 | #define dprintk(msg...) \ |
@@ -46,9 +43,9 @@ static int cpus_using_userspace_governor; | |||
46 | /* keep track of frequency transitions */ | 43 | /* keep track of frequency transitions */ |
47 | static int | 44 | static int |
48 | userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | 45 | userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val, |
49 | void *data) | 46 | void *data) |
50 | { | 47 | { |
51 | struct cpufreq_freqs *freq = data; | 48 | struct cpufreq_freqs *freq = data; |
52 | 49 | ||
53 | if (!per_cpu(cpu_is_managed, freq->cpu)) | 50 | if (!per_cpu(cpu_is_managed, freq->cpu)) |
54 | return 0; | 51 | return 0; |
@@ -57,11 +54,11 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
57 | freq->cpu, freq->new); | 54 | freq->cpu, freq->new); |
58 | per_cpu(cpu_cur_freq, freq->cpu) = freq->new; | 55 | per_cpu(cpu_cur_freq, freq->cpu) = freq->new; |
59 | 56 | ||
60 | return 0; | 57 | return 0; |
61 | } | 58 | } |
62 | 59 | ||
63 | static struct notifier_block userspace_cpufreq_notifier_block = { | 60 | static struct notifier_block userspace_cpufreq_notifier_block = { |
64 | .notifier_call = userspace_cpufreq_notifier | 61 | .notifier_call = userspace_cpufreq_notifier |
65 | }; | 62 | }; |
66 | 63 | ||
67 | 64 | ||
@@ -93,8 +90,11 @@ static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq) | |||
93 | * We're safe from concurrent calls to ->target() here | 90 | * We're safe from concurrent calls to ->target() here |
94 | * as we hold the userspace_mutex lock. If we were calling | 91 | * as we hold the userspace_mutex lock. If we were calling |
95 | * cpufreq_driver_target, a deadlock situation might occur: | 92 | * cpufreq_driver_target, a deadlock situation might occur: |
96 | * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock) | 93 | * A: cpufreq_set (lock userspace_mutex) -> |
97 | * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex) | 94 | * cpufreq_driver_target(lock policy->lock) |
95 | * B: cpufreq_set_policy(lock policy->lock) -> | ||
96 | * __cpufreq_governor -> | ||
97 | * cpufreq_governor_userspace (lock userspace_mutex) | ||
98 | */ | 98 | */ |
99 | ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); | 99 | ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); |
100 | 100 | ||
@@ -210,9 +210,10 @@ static void __exit cpufreq_gov_userspace_exit(void) | |||
210 | } | 210 | } |
211 | 211 | ||
212 | 212 | ||
213 | MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.org.uk>"); | 213 | MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, " |
214 | MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'"); | 214 | "Russell King <rmk@arm.linux.org.uk>"); |
215 | MODULE_LICENSE ("GPL"); | 215 | MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'"); |
216 | MODULE_LICENSE("GPL"); | ||
216 | 217 | ||
217 | #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE | 218 | #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE |
218 | fs_initcall(cpufreq_gov_userspace_init); | 219 | fs_initcall(cpufreq_gov_userspace_init); |
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 9071d80fbba2..a9bd3a05a684 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
@@ -28,7 +28,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, | |||
28 | unsigned int max_freq = 0; | 28 | unsigned int max_freq = 0; |
29 | unsigned int i; | 29 | unsigned int i; |
30 | 30 | ||
31 | for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 31 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
32 | unsigned int freq = table[i].frequency; | 32 | unsigned int freq = table[i].frequency; |
33 | if (freq == CPUFREQ_ENTRY_INVALID) { | 33 | if (freq == CPUFREQ_ENTRY_INVALID) { |
34 | dprintk("table entry %u is invalid, skipping\n", i); | 34 | dprintk("table entry %u is invalid, skipping\n", i); |
@@ -70,7 +70,7 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, | |||
70 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | 70 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, |
71 | policy->cpuinfo.max_freq); | 71 | policy->cpuinfo.max_freq); |
72 | 72 | ||
73 | for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 73 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
74 | unsigned int freq = table[i].frequency; | 74 | unsigned int freq = table[i].frequency; |
75 | if (freq == CPUFREQ_ENTRY_INVALID) | 75 | if (freq == CPUFREQ_ENTRY_INVALID) |
76 | continue; | 76 | continue; |
@@ -125,13 +125,13 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, | |||
125 | if (!cpu_online(policy->cpu)) | 125 | if (!cpu_online(policy->cpu)) |
126 | return -EINVAL; | 126 | return -EINVAL; |
127 | 127 | ||
128 | for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 128 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
129 | unsigned int freq = table[i].frequency; | 129 | unsigned int freq = table[i].frequency; |
130 | if (freq == CPUFREQ_ENTRY_INVALID) | 130 | if (freq == CPUFREQ_ENTRY_INVALID) |
131 | continue; | 131 | continue; |
132 | if ((freq < policy->min) || (freq > policy->max)) | 132 | if ((freq < policy->min) || (freq > policy->max)) |
133 | continue; | 133 | continue; |
134 | switch(relation) { | 134 | switch (relation) { |
135 | case CPUFREQ_RELATION_H: | 135 | case CPUFREQ_RELATION_H: |
136 | if (freq <= target_freq) { | 136 | if (freq <= target_freq) { |
137 | if (freq >= optimal.frequency) { | 137 | if (freq >= optimal.frequency) { |
@@ -178,7 +178,7 @@ static DEFINE_PER_CPU(struct cpufreq_frequency_table *, show_table); | |||
178 | /** | 178 | /** |
179 | * show_available_freqs - show available frequencies for the specified CPU | 179 | * show_available_freqs - show available frequencies for the specified CPU |
180 | */ | 180 | */ |
181 | static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf) | 181 | static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf) |
182 | { | 182 | { |
183 | unsigned int i = 0; | 183 | unsigned int i = 0; |
184 | unsigned int cpu = policy->cpu; | 184 | unsigned int cpu = policy->cpu; |
@@ -190,7 +190,7 @@ static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf) | |||
190 | 190 | ||
191 | table = per_cpu(show_table, cpu); | 191 | table = per_cpu(show_table, cpu); |
192 | 192 | ||
193 | for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 193 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { |
194 | if (table[i].frequency == CPUFREQ_ENTRY_INVALID) | 194 | if (table[i].frequency == CPUFREQ_ENTRY_INVALID) |
195 | continue; | 195 | continue; |
196 | count += sprintf(&buf[count], "%d ", table[i].frequency); | 196 | count += sprintf(&buf[count], "%d ", table[i].frequency); |
@@ -234,6 +234,6 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu) | |||
234 | } | 234 | } |
235 | EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); | 235 | EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); |
236 | 236 | ||
237 | MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>"); | 237 | MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>"); |
238 | MODULE_DESCRIPTION ("CPUfreq frequency table helpers"); | 238 | MODULE_DESCRIPTION("CPUfreq frequency table helpers"); |
239 | MODULE_LICENSE ("GPL"); | 239 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index e522144cba3a..01afd758072f 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig | |||
@@ -86,7 +86,7 @@ config ZCRYPT_MONOLITHIC | |||
86 | config CRYPTO_SHA1_S390 | 86 | config CRYPTO_SHA1_S390 |
87 | tristate "SHA1 digest algorithm" | 87 | tristate "SHA1 digest algorithm" |
88 | depends on S390 | 88 | depends on S390 |
89 | select CRYPTO_ALGAPI | 89 | select CRYPTO_HASH |
90 | help | 90 | help |
91 | This is the s390 hardware accelerated implementation of the | 91 | This is the s390 hardware accelerated implementation of the |
92 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). | 92 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). |
@@ -94,7 +94,7 @@ config CRYPTO_SHA1_S390 | |||
94 | config CRYPTO_SHA256_S390 | 94 | config CRYPTO_SHA256_S390 |
95 | tristate "SHA256 digest algorithm" | 95 | tristate "SHA256 digest algorithm" |
96 | depends on S390 | 96 | depends on S390 |
97 | select CRYPTO_ALGAPI | 97 | select CRYPTO_HASH |
98 | help | 98 | help |
99 | This is the s390 hardware accelerated implementation of the | 99 | This is the s390 hardware accelerated implementation of the |
100 | SHA256 secure hash standard (DFIPS 180-2). | 100 | SHA256 secure hash standard (DFIPS 180-2). |
@@ -105,7 +105,7 @@ config CRYPTO_SHA256_S390 | |||
105 | config CRYPTO_SHA512_S390 | 105 | config CRYPTO_SHA512_S390 |
106 | tristate "SHA384 and SHA512 digest algorithm" | 106 | tristate "SHA384 and SHA512 digest algorithm" |
107 | depends on S390 | 107 | depends on S390 |
108 | select CRYPTO_ALGAPI | 108 | select CRYPTO_HASH |
109 | help | 109 | help |
110 | This is the s390 hardware accelerated implementation of the | 110 | This is the s390 hardware accelerated implementation of the |
111 | SHA512 secure hash standard. | 111 | SHA512 secure hash standard. |
@@ -200,4 +200,13 @@ config CRYPTO_DEV_IXP4XX | |||
200 | help | 200 | help |
201 | Driver for the IXP4xx NPE crypto engine. | 201 | Driver for the IXP4xx NPE crypto engine. |
202 | 202 | ||
203 | config CRYPTO_DEV_PPC4XX | ||
204 | tristate "Driver AMCC PPC4xx crypto accelerator" | ||
205 | depends on PPC && 4xx | ||
206 | select CRYPTO_HASH | ||
207 | select CRYPTO_ALGAPI | ||
208 | select CRYPTO_BLKCIPHER | ||
209 | help | ||
210 | This option allows you to have support for AMCC crypto acceleration. | ||
211 | |||
203 | endif # CRYPTO_HW | 212 | endif # CRYPTO_HW |
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 73557b2968d3..9bf4a2bc8846 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile | |||
@@ -4,3 +4,4 @@ obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o | |||
4 | obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o | 4 | obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o |
5 | obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o | 5 | obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o |
6 | obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o | 6 | obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o |
7 | obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ | ||
diff --git a/drivers/crypto/amcc/Makefile b/drivers/crypto/amcc/Makefile new file mode 100644 index 000000000000..aa376e8d5ed5 --- /dev/null +++ b/drivers/crypto/amcc/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += crypto4xx.o | ||
2 | crypto4xx-objs := crypto4xx_core.o crypto4xx_alg.o crypto4xx_sa.o | ||
diff --git a/drivers/crypto/amcc/crypto4xx_alg.c b/drivers/crypto/amcc/crypto4xx_alg.c new file mode 100644 index 000000000000..61b6e1bec8c6 --- /dev/null +++ b/drivers/crypto/amcc/crypto4xx_alg.c | |||
@@ -0,0 +1,293 @@ | |||
1 | /** | ||
2 | * AMCC SoC PPC4xx Crypto Driver | ||
3 | * | ||
4 | * Copyright (c) 2008 Applied Micro Circuits Corporation. | ||
5 | * All rights reserved. James Hsiao <jhsiao@amcc.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * This file implements the Linux crypto algorithms. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/spinlock_types.h> | ||
23 | #include <linux/scatterlist.h> | ||
24 | #include <linux/crypto.h> | ||
25 | #include <linux/hash.h> | ||
26 | #include <crypto/internal/hash.h> | ||
27 | #include <linux/dma-mapping.h> | ||
28 | #include <crypto/algapi.h> | ||
29 | #include <crypto/aes.h> | ||
30 | #include <crypto/sha.h> | ||
31 | #include "crypto4xx_reg_def.h" | ||
32 | #include "crypto4xx_sa.h" | ||
33 | #include "crypto4xx_core.h" | ||
34 | |||
35 | void set_dynamic_sa_command_0(struct dynamic_sa_ctl *sa, u32 save_h, | ||
36 | u32 save_iv, u32 ld_h, u32 ld_iv, u32 hdr_proc, | ||
37 | u32 h, u32 c, u32 pad_type, u32 op_grp, u32 op, | ||
38 | u32 dir) | ||
39 | { | ||
40 | sa->sa_command_0.w = 0; | ||
41 | sa->sa_command_0.bf.save_hash_state = save_h; | ||
42 | sa->sa_command_0.bf.save_iv = save_iv; | ||
43 | sa->sa_command_0.bf.load_hash_state = ld_h; | ||
44 | sa->sa_command_0.bf.load_iv = ld_iv; | ||
45 | sa->sa_command_0.bf.hdr_proc = hdr_proc; | ||
46 | sa->sa_command_0.bf.hash_alg = h; | ||
47 | sa->sa_command_0.bf.cipher_alg = c; | ||
48 | sa->sa_command_0.bf.pad_type = pad_type & 3; | ||
49 | sa->sa_command_0.bf.extend_pad = pad_type >> 2; | ||
50 | sa->sa_command_0.bf.op_group = op_grp; | ||
51 | sa->sa_command_0.bf.opcode = op; | ||
52 | sa->sa_command_0.bf.dir = dir; | ||
53 | } | ||
54 | |||
55 | void set_dynamic_sa_command_1(struct dynamic_sa_ctl *sa, u32 cm, u32 hmac_mc, | ||
56 | u32 cfb, u32 esn, u32 sn_mask, u32 mute, | ||
57 | u32 cp_pad, u32 cp_pay, u32 cp_hdr) | ||
58 | { | ||
59 | sa->sa_command_1.w = 0; | ||
60 | sa->sa_command_1.bf.crypto_mode31 = (cm & 4) >> 2; | ||
61 | sa->sa_command_1.bf.crypto_mode9_8 = cm & 3; | ||
62 | sa->sa_command_1.bf.feedback_mode = cfb, | ||
63 | sa->sa_command_1.bf.sa_rev = 1; | ||
64 | sa->sa_command_1.bf.extended_seq_num = esn; | ||
65 | sa->sa_command_1.bf.seq_num_mask = sn_mask; | ||
66 | sa->sa_command_1.bf.mutable_bit_proc = mute; | ||
67 | sa->sa_command_1.bf.copy_pad = cp_pad; | ||
68 | sa->sa_command_1.bf.copy_payload = cp_pay; | ||
69 | sa->sa_command_1.bf.copy_hdr = cp_hdr; | ||
70 | } | ||
71 | |||
72 | int crypto4xx_encrypt(struct ablkcipher_request *req) | ||
73 | { | ||
74 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm); | ||
75 | |||
76 | ctx->direction = DIR_OUTBOUND; | ||
77 | ctx->hash_final = 0; | ||
78 | ctx->is_hash = 0; | ||
79 | ctx->pd_ctl = 0x1; | ||
80 | |||
81 | return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst, | ||
82 | req->nbytes, req->info, | ||
83 | get_dynamic_sa_iv_size(ctx)); | ||
84 | } | ||
85 | |||
86 | int crypto4xx_decrypt(struct ablkcipher_request *req) | ||
87 | { | ||
88 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm); | ||
89 | |||
90 | ctx->direction = DIR_INBOUND; | ||
91 | ctx->hash_final = 0; | ||
92 | ctx->is_hash = 0; | ||
93 | ctx->pd_ctl = 1; | ||
94 | |||
95 | return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst, | ||
96 | req->nbytes, req->info, | ||
97 | get_dynamic_sa_iv_size(ctx)); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * AES Functions | ||
102 | */ | ||
103 | static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher, | ||
104 | const u8 *key, | ||
105 | unsigned int keylen, | ||
106 | unsigned char cm, | ||
107 | u8 fb) | ||
108 | { | ||
109 | struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); | ||
110 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); | ||
111 | struct dynamic_sa_ctl *sa; | ||
112 | int rc; | ||
113 | |||
114 | if (keylen != AES_KEYSIZE_256 && | ||
115 | keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_128) { | ||
116 | crypto_ablkcipher_set_flags(cipher, | ||
117 | CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
118 | return -EINVAL; | ||
119 | } | ||
120 | |||
121 | /* Create SA */ | ||
122 | if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr) | ||
123 | crypto4xx_free_sa(ctx); | ||
124 | |||
125 | rc = crypto4xx_alloc_sa(ctx, SA_AES128_LEN + (keylen-16) / 4); | ||
126 | if (rc) | ||
127 | return rc; | ||
128 | |||
129 | if (ctx->state_record_dma_addr == 0) { | ||
130 | rc = crypto4xx_alloc_state_record(ctx); | ||
131 | if (rc) { | ||
132 | crypto4xx_free_sa(ctx); | ||
133 | return rc; | ||
134 | } | ||
135 | } | ||
136 | /* Setup SA */ | ||
137 | sa = (struct dynamic_sa_ctl *) ctx->sa_in; | ||
138 | ctx->hash_final = 0; | ||
139 | |||
140 | set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV, | ||
141 | SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE, | ||
142 | SA_NO_HEADER_PROC, SA_HASH_ALG_NULL, | ||
143 | SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO, | ||
144 | SA_OP_GROUP_BASIC, SA_OPCODE_DECRYPT, | ||
145 | DIR_INBOUND); | ||
146 | |||
147 | set_dynamic_sa_command_1(sa, cm, SA_HASH_MODE_HASH, | ||
148 | fb, SA_EXTENDED_SN_OFF, | ||
149 | SA_SEQ_MASK_OFF, SA_MC_ENABLE, | ||
150 | SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD, | ||
151 | SA_NOT_COPY_HDR); | ||
152 | crypto4xx_memcpy_le(ctx->sa_in + get_dynamic_sa_offset_key_field(ctx), | ||
153 | key, keylen); | ||
154 | sa->sa_contents = SA_AES_CONTENTS | (keylen << 2); | ||
155 | sa->sa_command_1.bf.key_len = keylen >> 3; | ||
156 | ctx->is_hash = 0; | ||
157 | ctx->direction = DIR_INBOUND; | ||
158 | memcpy(ctx->sa_in + get_dynamic_sa_offset_state_ptr_field(ctx), | ||
159 | (void *)&ctx->state_record_dma_addr, 4); | ||
160 | ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx); | ||
161 | |||
162 | memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4); | ||
163 | sa = (struct dynamic_sa_ctl *) ctx->sa_out; | ||
164 | sa->sa_command_0.bf.dir = DIR_OUTBOUND; | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher, | ||
170 | const u8 *key, unsigned int keylen) | ||
171 | { | ||
172 | return crypto4xx_setkey_aes(cipher, key, keylen, CRYPTO_MODE_CBC, | ||
173 | CRYPTO_FEEDBACK_MODE_NO_FB); | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * HASH SHA1 Functions | ||
178 | */ | ||
179 | static int crypto4xx_hash_alg_init(struct crypto_tfm *tfm, | ||
180 | unsigned int sa_len, | ||
181 | unsigned char ha, | ||
182 | unsigned char hm) | ||
183 | { | ||
184 | struct crypto_alg *alg = tfm->__crt_alg; | ||
185 | struct crypto4xx_alg *my_alg = crypto_alg_to_crypto4xx_alg(alg); | ||
186 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); | ||
187 | struct dynamic_sa_ctl *sa; | ||
188 | struct dynamic_sa_hash160 *sa_in; | ||
189 | int rc; | ||
190 | |||
191 | ctx->dev = my_alg->dev; | ||
192 | ctx->is_hash = 1; | ||
193 | ctx->hash_final = 0; | ||
194 | |||
195 | /* Create SA */ | ||
196 | if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr) | ||
197 | crypto4xx_free_sa(ctx); | ||
198 | |||
199 | rc = crypto4xx_alloc_sa(ctx, sa_len); | ||
200 | if (rc) | ||
201 | return rc; | ||
202 | |||
203 | if (ctx->state_record_dma_addr == 0) { | ||
204 | crypto4xx_alloc_state_record(ctx); | ||
205 | if (!ctx->state_record_dma_addr) { | ||
206 | crypto4xx_free_sa(ctx); | ||
207 | return -ENOMEM; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | tfm->crt_ahash.reqsize = sizeof(struct crypto4xx_ctx); | ||
212 | sa = (struct dynamic_sa_ctl *) ctx->sa_in; | ||
213 | set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV, | ||
214 | SA_NOT_LOAD_HASH, SA_LOAD_IV_FROM_SA, | ||
215 | SA_NO_HEADER_PROC, ha, SA_CIPHER_ALG_NULL, | ||
216 | SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC, | ||
217 | SA_OPCODE_HASH, DIR_INBOUND); | ||
218 | set_dynamic_sa_command_1(sa, 0, SA_HASH_MODE_HASH, | ||
219 | CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF, | ||
220 | SA_SEQ_MASK_OFF, SA_MC_ENABLE, | ||
221 | SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD, | ||
222 | SA_NOT_COPY_HDR); | ||
223 | ctx->direction = DIR_INBOUND; | ||
224 | sa->sa_contents = SA_HASH160_CONTENTS; | ||
225 | sa_in = (struct dynamic_sa_hash160 *) ctx->sa_in; | ||
226 | /* Need to zero hash digest in SA */ | ||
227 | memset(sa_in->inner_digest, 0, sizeof(sa_in->inner_digest)); | ||
228 | memset(sa_in->outer_digest, 0, sizeof(sa_in->outer_digest)); | ||
229 | sa_in->state_ptr = ctx->state_record_dma_addr; | ||
230 | ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | int crypto4xx_hash_init(struct ahash_request *req) | ||
236 | { | ||
237 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm); | ||
238 | int ds; | ||
239 | struct dynamic_sa_ctl *sa; | ||
240 | |||
241 | sa = (struct dynamic_sa_ctl *) ctx->sa_in; | ||
242 | ds = crypto_ahash_digestsize( | ||
243 | __crypto_ahash_cast(req->base.tfm)); | ||
244 | sa->sa_command_0.bf.digest_len = ds >> 2; | ||
245 | sa->sa_command_0.bf.load_hash_state = SA_LOAD_HASH_FROM_SA; | ||
246 | ctx->is_hash = 1; | ||
247 | ctx->direction = DIR_INBOUND; | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | int crypto4xx_hash_update(struct ahash_request *req) | ||
253 | { | ||
254 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm); | ||
255 | |||
256 | ctx->is_hash = 1; | ||
257 | ctx->hash_final = 0; | ||
258 | ctx->pd_ctl = 0x11; | ||
259 | ctx->direction = DIR_INBOUND; | ||
260 | |||
261 | return crypto4xx_build_pd(&req->base, ctx, req->src, | ||
262 | (struct scatterlist *) req->result, | ||
263 | req->nbytes, NULL, 0); | ||
264 | } | ||
265 | |||
266 | int crypto4xx_hash_final(struct ahash_request *req) | ||
267 | { | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | int crypto4xx_hash_digest(struct ahash_request *req) | ||
272 | { | ||
273 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm); | ||
274 | |||
275 | ctx->hash_final = 1; | ||
276 | ctx->pd_ctl = 0x11; | ||
277 | ctx->direction = DIR_INBOUND; | ||
278 | |||
279 | return crypto4xx_build_pd(&req->base, ctx, req->src, | ||
280 | (struct scatterlist *) req->result, | ||
281 | req->nbytes, NULL, 0); | ||
282 | } | ||
283 | |||
284 | /** | ||
285 | * SHA1 Algorithm | ||
286 | */ | ||
287 | int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm) | ||
288 | { | ||
289 | return crypto4xx_hash_alg_init(tfm, SA_HASH160_LEN, SA_HASH_ALG_SHA1, | ||
290 | SA_HASH_MODE_HASH); | ||
291 | } | ||
292 | |||
293 | |||
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c new file mode 100644 index 000000000000..4c0dfb2b872e --- /dev/null +++ b/drivers/crypto/amcc/crypto4xx_core.c | |||
@@ -0,0 +1,1310 @@ | |||
1 | /** | ||
2 | * AMCC SoC PPC4xx Crypto Driver | ||
3 | * | ||
4 | * Copyright (c) 2008 Applied Micro Circuits Corporation. | ||
5 | * All rights reserved. James Hsiao <jhsiao@amcc.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * This file implements AMCC crypto offload Linux device driver for use with | ||
18 | * Linux CryptoAPI. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/spinlock_types.h> | ||
24 | #include <linux/random.h> | ||
25 | #include <linux/scatterlist.h> | ||
26 | #include <linux/crypto.h> | ||
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/of_platform.h> | ||
31 | #include <asm/dcr.h> | ||
32 | #include <asm/dcr-regs.h> | ||
33 | #include <asm/cacheflush.h> | ||
34 | #include <crypto/internal/hash.h> | ||
35 | #include <crypto/algapi.h> | ||
36 | #include <crypto/aes.h> | ||
37 | #include <crypto/sha.h> | ||
38 | #include "crypto4xx_reg_def.h" | ||
39 | #include "crypto4xx_core.h" | ||
40 | #include "crypto4xx_sa.h" | ||
41 | |||
42 | #define PPC4XX_SEC_VERSION_STR "0.5" | ||
43 | |||
44 | /** | ||
45 | * PPC4xx Crypto Engine Initialization Routine | ||
46 | */ | ||
47 | static void crypto4xx_hw_init(struct crypto4xx_device *dev) | ||
48 | { | ||
49 | union ce_ring_size ring_size; | ||
50 | union ce_ring_contol ring_ctrl; | ||
51 | union ce_part_ring_size part_ring_size; | ||
52 | union ce_io_threshold io_threshold; | ||
53 | u32 rand_num; | ||
54 | union ce_pe_dma_cfg pe_dma_cfg; | ||
55 | |||
56 | writel(PPC4XX_BYTE_ORDER, dev->ce_base + CRYPTO4XX_BYTE_ORDER_CFG); | ||
57 | /* setup pe dma, include reset sg, pdr and pe, then release reset */ | ||
58 | pe_dma_cfg.w = 0; | ||
59 | pe_dma_cfg.bf.bo_sgpd_en = 1; | ||
60 | pe_dma_cfg.bf.bo_data_en = 0; | ||
61 | pe_dma_cfg.bf.bo_sa_en = 1; | ||
62 | pe_dma_cfg.bf.bo_pd_en = 1; | ||
63 | pe_dma_cfg.bf.dynamic_sa_en = 1; | ||
64 | pe_dma_cfg.bf.reset_sg = 1; | ||
65 | pe_dma_cfg.bf.reset_pdr = 1; | ||
66 | pe_dma_cfg.bf.reset_pe = 1; | ||
67 | writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG); | ||
68 | /* un reset pe,sg and pdr */ | ||
69 | pe_dma_cfg.bf.pe_mode = 0; | ||
70 | pe_dma_cfg.bf.reset_sg = 0; | ||
71 | pe_dma_cfg.bf.reset_pdr = 0; | ||
72 | pe_dma_cfg.bf.reset_pe = 0; | ||
73 | pe_dma_cfg.bf.bo_td_en = 0; | ||
74 | writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG); | ||
75 | writel(dev->pdr_pa, dev->ce_base + CRYPTO4XX_PDR_BASE); | ||
76 | writel(dev->pdr_pa, dev->ce_base + CRYPTO4XX_RDR_BASE); | ||
77 | writel(PPC4XX_PRNG_CTRL_AUTO_EN, dev->ce_base + CRYPTO4XX_PRNG_CTRL); | ||
78 | get_random_bytes(&rand_num, sizeof(rand_num)); | ||
79 | writel(rand_num, dev->ce_base + CRYPTO4XX_PRNG_SEED_L); | ||
80 | get_random_bytes(&rand_num, sizeof(rand_num)); | ||
81 | writel(rand_num, dev->ce_base + CRYPTO4XX_PRNG_SEED_H); | ||
82 | ring_size.w = 0; | ||
83 | ring_size.bf.ring_offset = PPC4XX_PD_SIZE; | ||
84 | ring_size.bf.ring_size = PPC4XX_NUM_PD; | ||
85 | writel(ring_size.w, dev->ce_base + CRYPTO4XX_RING_SIZE); | ||
86 | ring_ctrl.w = 0; | ||
87 | writel(ring_ctrl.w, dev->ce_base + CRYPTO4XX_RING_CTRL); | ||
88 | writel(PPC4XX_DC_3DES_EN, dev->ce_base + CRYPTO4XX_DEVICE_CTRL); | ||
89 | writel(dev->gdr_pa, dev->ce_base + CRYPTO4XX_GATH_RING_BASE); | ||
90 | writel(dev->sdr_pa, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE); | ||
91 | part_ring_size.w = 0; | ||
92 | part_ring_size.bf.sdr_size = PPC4XX_SDR_SIZE; | ||
93 | part_ring_size.bf.gdr_size = PPC4XX_GDR_SIZE; | ||
94 | writel(part_ring_size.w, dev->ce_base + CRYPTO4XX_PART_RING_SIZE); | ||
95 | writel(PPC4XX_SD_BUFFER_SIZE, dev->ce_base + CRYPTO4XX_PART_RING_CFG); | ||
96 | io_threshold.w = 0; | ||
97 | io_threshold.bf.output_threshold = PPC4XX_OUTPUT_THRESHOLD; | ||
98 | io_threshold.bf.input_threshold = PPC4XX_INPUT_THRESHOLD; | ||
99 | writel(io_threshold.w, dev->ce_base + CRYPTO4XX_IO_THRESHOLD); | ||
100 | writel(0, dev->ce_base + CRYPTO4XX_PDR_BASE_UADDR); | ||
101 | writel(0, dev->ce_base + CRYPTO4XX_RDR_BASE_UADDR); | ||
102 | writel(0, dev->ce_base + CRYPTO4XX_PKT_SRC_UADDR); | ||
103 | writel(0, dev->ce_base + CRYPTO4XX_PKT_DEST_UADDR); | ||
104 | writel(0, dev->ce_base + CRYPTO4XX_SA_UADDR); | ||
105 | writel(0, dev->ce_base + CRYPTO4XX_GATH_RING_BASE_UADDR); | ||
106 | writel(0, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE_UADDR); | ||
107 | /* un reset pe,sg and pdr */ | ||
108 | pe_dma_cfg.bf.pe_mode = 1; | ||
109 | pe_dma_cfg.bf.reset_sg = 0; | ||
110 | pe_dma_cfg.bf.reset_pdr = 0; | ||
111 | pe_dma_cfg.bf.reset_pe = 0; | ||
112 | pe_dma_cfg.bf.bo_td_en = 0; | ||
113 | writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG); | ||
114 | /*clear all pending interrupt*/ | ||
115 | writel(PPC4XX_INTERRUPT_CLR, dev->ce_base + CRYPTO4XX_INT_CLR); | ||
116 | writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT); | ||
117 | writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT); | ||
118 | writel(PPC4XX_INT_CFG, dev->ce_base + CRYPTO4XX_INT_CFG); | ||
119 | writel(PPC4XX_PD_DONE_INT, dev->ce_base + CRYPTO4XX_INT_EN); | ||
120 | } | ||
121 | |||
122 | int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size) | ||
123 | { | ||
124 | ctx->sa_in = dma_alloc_coherent(ctx->dev->core_dev->device, size * 4, | ||
125 | &ctx->sa_in_dma_addr, GFP_ATOMIC); | ||
126 | if (ctx->sa_in == NULL) | ||
127 | return -ENOMEM; | ||
128 | |||
129 | ctx->sa_out = dma_alloc_coherent(ctx->dev->core_dev->device, size * 4, | ||
130 | &ctx->sa_out_dma_addr, GFP_ATOMIC); | ||
131 | if (ctx->sa_out == NULL) { | ||
132 | dma_free_coherent(ctx->dev->core_dev->device, | ||
133 | ctx->sa_len * 4, | ||
134 | ctx->sa_in, ctx->sa_in_dma_addr); | ||
135 | return -ENOMEM; | ||
136 | } | ||
137 | |||
138 | memset(ctx->sa_in, 0, size * 4); | ||
139 | memset(ctx->sa_out, 0, size * 4); | ||
140 | ctx->sa_len = size; | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | void crypto4xx_free_sa(struct crypto4xx_ctx *ctx) | ||
146 | { | ||
147 | if (ctx->sa_in != NULL) | ||
148 | dma_free_coherent(ctx->dev->core_dev->device, ctx->sa_len * 4, | ||
149 | ctx->sa_in, ctx->sa_in_dma_addr); | ||
150 | if (ctx->sa_out != NULL) | ||
151 | dma_free_coherent(ctx->dev->core_dev->device, ctx->sa_len * 4, | ||
152 | ctx->sa_out, ctx->sa_out_dma_addr); | ||
153 | |||
154 | ctx->sa_in_dma_addr = 0; | ||
155 | ctx->sa_out_dma_addr = 0; | ||
156 | ctx->sa_len = 0; | ||
157 | } | ||
158 | |||
159 | u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx) | ||
160 | { | ||
161 | ctx->state_record = dma_alloc_coherent(ctx->dev->core_dev->device, | ||
162 | sizeof(struct sa_state_record), | ||
163 | &ctx->state_record_dma_addr, GFP_ATOMIC); | ||
164 | if (!ctx->state_record_dma_addr) | ||
165 | return -ENOMEM; | ||
166 | memset(ctx->state_record, 0, sizeof(struct sa_state_record)); | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | void crypto4xx_free_state_record(struct crypto4xx_ctx *ctx) | ||
172 | { | ||
173 | if (ctx->state_record != NULL) | ||
174 | dma_free_coherent(ctx->dev->core_dev->device, | ||
175 | sizeof(struct sa_state_record), | ||
176 | ctx->state_record, | ||
177 | ctx->state_record_dma_addr); | ||
178 | ctx->state_record_dma_addr = 0; | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * alloc memory for the gather ring | ||
183 | * no need to alloc buf for the ring | ||
184 | * gdr_tail, gdr_head and gdr_count are initialized by this function | ||
185 | */ | ||
186 | static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev) | ||
187 | { | ||
188 | int i; | ||
189 | struct pd_uinfo *pd_uinfo; | ||
190 | dev->pdr = dma_alloc_coherent(dev->core_dev->device, | ||
191 | sizeof(struct ce_pd) * PPC4XX_NUM_PD, | ||
192 | &dev->pdr_pa, GFP_ATOMIC); | ||
193 | if (!dev->pdr) | ||
194 | return -ENOMEM; | ||
195 | |||
196 | dev->pdr_uinfo = kzalloc(sizeof(struct pd_uinfo) * PPC4XX_NUM_PD, | ||
197 | GFP_KERNEL); | ||
198 | if (!dev->pdr_uinfo) { | ||
199 | dma_free_coherent(dev->core_dev->device, | ||
200 | sizeof(struct ce_pd) * PPC4XX_NUM_PD, | ||
201 | dev->pdr, | ||
202 | dev->pdr_pa); | ||
203 | return -ENOMEM; | ||
204 | } | ||
205 | memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD); | ||
206 | dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device, | ||
207 | 256 * PPC4XX_NUM_PD, | ||
208 | &dev->shadow_sa_pool_pa, | ||
209 | GFP_ATOMIC); | ||
210 | if (!dev->shadow_sa_pool) | ||
211 | return -ENOMEM; | ||
212 | |||
213 | dev->shadow_sr_pool = dma_alloc_coherent(dev->core_dev->device, | ||
214 | sizeof(struct sa_state_record) * PPC4XX_NUM_PD, | ||
215 | &dev->shadow_sr_pool_pa, GFP_ATOMIC); | ||
216 | if (!dev->shadow_sr_pool) | ||
217 | return -ENOMEM; | ||
218 | for (i = 0; i < PPC4XX_NUM_PD; i++) { | ||
219 | pd_uinfo = (struct pd_uinfo *) (dev->pdr_uinfo + | ||
220 | sizeof(struct pd_uinfo) * i); | ||
221 | |||
222 | /* alloc 256 bytes which is enough for any kind of dynamic sa */ | ||
223 | pd_uinfo->sa_va = dev->shadow_sa_pool + 256 * i; | ||
224 | pd_uinfo->sa_pa = dev->shadow_sa_pool_pa + 256 * i; | ||
225 | |||
226 | /* alloc state record */ | ||
227 | pd_uinfo->sr_va = dev->shadow_sr_pool + | ||
228 | sizeof(struct sa_state_record) * i; | ||
229 | pd_uinfo->sr_pa = dev->shadow_sr_pool_pa + | ||
230 | sizeof(struct sa_state_record) * i; | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static void crypto4xx_destroy_pdr(struct crypto4xx_device *dev) | ||
237 | { | ||
238 | if (dev->pdr != NULL) | ||
239 | dma_free_coherent(dev->core_dev->device, | ||
240 | sizeof(struct ce_pd) * PPC4XX_NUM_PD, | ||
241 | dev->pdr, dev->pdr_pa); | ||
242 | if (dev->shadow_sa_pool) | ||
243 | dma_free_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD, | ||
244 | dev->shadow_sa_pool, dev->shadow_sa_pool_pa); | ||
245 | if (dev->shadow_sr_pool) | ||
246 | dma_free_coherent(dev->core_dev->device, | ||
247 | sizeof(struct sa_state_record) * PPC4XX_NUM_PD, | ||
248 | dev->shadow_sr_pool, dev->shadow_sr_pool_pa); | ||
249 | |||
250 | kfree(dev->pdr_uinfo); | ||
251 | } | ||
252 | |||
253 | static u32 crypto4xx_get_pd_from_pdr_nolock(struct crypto4xx_device *dev) | ||
254 | { | ||
255 | u32 retval; | ||
256 | u32 tmp; | ||
257 | |||
258 | retval = dev->pdr_head; | ||
259 | tmp = (dev->pdr_head + 1) % PPC4XX_NUM_PD; | ||
260 | |||
261 | if (tmp == dev->pdr_tail) | ||
262 | return ERING_WAS_FULL; | ||
263 | |||
264 | dev->pdr_head = tmp; | ||
265 | |||
266 | return retval; | ||
267 | } | ||
268 | |||
269 | static u32 crypto4xx_put_pd_to_pdr(struct crypto4xx_device *dev, u32 idx) | ||
270 | { | ||
271 | struct pd_uinfo *pd_uinfo; | ||
272 | unsigned long flags; | ||
273 | |||
274 | pd_uinfo = (struct pd_uinfo *)(dev->pdr_uinfo + | ||
275 | sizeof(struct pd_uinfo) * idx); | ||
276 | spin_lock_irqsave(&dev->core_dev->lock, flags); | ||
277 | if (dev->pdr_tail != PPC4XX_LAST_PD) | ||
278 | dev->pdr_tail++; | ||
279 | else | ||
280 | dev->pdr_tail = 0; | ||
281 | pd_uinfo->state = PD_ENTRY_FREE; | ||
282 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static struct ce_pd *crypto4xx_get_pdp(struct crypto4xx_device *dev, | ||
288 | dma_addr_t *pd_dma, u32 idx) | ||
289 | { | ||
290 | *pd_dma = dev->pdr_pa + sizeof(struct ce_pd) * idx; | ||
291 | |||
292 | return dev->pdr + sizeof(struct ce_pd) * idx; | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * alloc memory for the gather ring | ||
297 | * no need to alloc buf for the ring | ||
298 | * gdr_tail, gdr_head and gdr_count are initialized by this function | ||
299 | */ | ||
300 | static u32 crypto4xx_build_gdr(struct crypto4xx_device *dev) | ||
301 | { | ||
302 | dev->gdr = dma_alloc_coherent(dev->core_dev->device, | ||
303 | sizeof(struct ce_gd) * PPC4XX_NUM_GD, | ||
304 | &dev->gdr_pa, GFP_ATOMIC); | ||
305 | if (!dev->gdr) | ||
306 | return -ENOMEM; | ||
307 | |||
308 | memset(dev->gdr, 0, sizeof(struct ce_gd) * PPC4XX_NUM_GD); | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static inline void crypto4xx_destroy_gdr(struct crypto4xx_device *dev) | ||
314 | { | ||
315 | dma_free_coherent(dev->core_dev->device, | ||
316 | sizeof(struct ce_gd) * PPC4XX_NUM_GD, | ||
317 | dev->gdr, dev->gdr_pa); | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * when this function is called. | ||
322 | * preemption or interrupt must be disabled | ||
323 | */ | ||
324 | u32 crypto4xx_get_n_gd(struct crypto4xx_device *dev, int n) | ||
325 | { | ||
326 | u32 retval; | ||
327 | u32 tmp; | ||
328 | if (n >= PPC4XX_NUM_GD) | ||
329 | return ERING_WAS_FULL; | ||
330 | |||
331 | retval = dev->gdr_head; | ||
332 | tmp = (dev->gdr_head + n) % PPC4XX_NUM_GD; | ||
333 | if (dev->gdr_head > dev->gdr_tail) { | ||
334 | if (tmp < dev->gdr_head && tmp >= dev->gdr_tail) | ||
335 | return ERING_WAS_FULL; | ||
336 | } else if (dev->gdr_head < dev->gdr_tail) { | ||
337 | if (tmp < dev->gdr_head || tmp >= dev->gdr_tail) | ||
338 | return ERING_WAS_FULL; | ||
339 | } | ||
340 | dev->gdr_head = tmp; | ||
341 | |||
342 | return retval; | ||
343 | } | ||
344 | |||
345 | static u32 crypto4xx_put_gd_to_gdr(struct crypto4xx_device *dev) | ||
346 | { | ||
347 | unsigned long flags; | ||
348 | |||
349 | spin_lock_irqsave(&dev->core_dev->lock, flags); | ||
350 | if (dev->gdr_tail == dev->gdr_head) { | ||
351 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | if (dev->gdr_tail != PPC4XX_LAST_GD) | ||
356 | dev->gdr_tail++; | ||
357 | else | ||
358 | dev->gdr_tail = 0; | ||
359 | |||
360 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
361 | |||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static inline struct ce_gd *crypto4xx_get_gdp(struct crypto4xx_device *dev, | ||
366 | dma_addr_t *gd_dma, u32 idx) | ||
367 | { | ||
368 | *gd_dma = dev->gdr_pa + sizeof(struct ce_gd) * idx; | ||
369 | |||
370 | return (struct ce_gd *) (dev->gdr + sizeof(struct ce_gd) * idx); | ||
371 | } | ||
372 | |||
373 | /** | ||
374 | * alloc memory for the scatter ring | ||
375 | * need to alloc buf for the ring | ||
376 | * sdr_tail, sdr_head and sdr_count are initialized by this function | ||
377 | */ | ||
378 | static u32 crypto4xx_build_sdr(struct crypto4xx_device *dev) | ||
379 | { | ||
380 | int i; | ||
381 | struct ce_sd *sd_array; | ||
382 | |||
383 | /* alloc memory for scatter descriptor ring */ | ||
384 | dev->sdr = dma_alloc_coherent(dev->core_dev->device, | ||
385 | sizeof(struct ce_sd) * PPC4XX_NUM_SD, | ||
386 | &dev->sdr_pa, GFP_ATOMIC); | ||
387 | if (!dev->sdr) | ||
388 | return -ENOMEM; | ||
389 | |||
390 | dev->scatter_buffer_size = PPC4XX_SD_BUFFER_SIZE; | ||
391 | dev->scatter_buffer_va = | ||
392 | dma_alloc_coherent(dev->core_dev->device, | ||
393 | dev->scatter_buffer_size * PPC4XX_NUM_SD, | ||
394 | &dev->scatter_buffer_pa, GFP_ATOMIC); | ||
395 | if (!dev->scatter_buffer_va) { | ||
396 | dma_free_coherent(dev->core_dev->device, | ||
397 | sizeof(struct ce_sd) * PPC4XX_NUM_SD, | ||
398 | dev->sdr, dev->sdr_pa); | ||
399 | return -ENOMEM; | ||
400 | } | ||
401 | |||
402 | sd_array = dev->sdr; | ||
403 | |||
404 | for (i = 0; i < PPC4XX_NUM_SD; i++) { | ||
405 | sd_array[i].ptr = dev->scatter_buffer_pa + | ||
406 | dev->scatter_buffer_size * i; | ||
407 | } | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | static void crypto4xx_destroy_sdr(struct crypto4xx_device *dev) | ||
413 | { | ||
414 | if (dev->sdr != NULL) | ||
415 | dma_free_coherent(dev->core_dev->device, | ||
416 | sizeof(struct ce_sd) * PPC4XX_NUM_SD, | ||
417 | dev->sdr, dev->sdr_pa); | ||
418 | |||
419 | if (dev->scatter_buffer_va != NULL) | ||
420 | dma_free_coherent(dev->core_dev->device, | ||
421 | dev->scatter_buffer_size * PPC4XX_NUM_SD, | ||
422 | dev->scatter_buffer_va, | ||
423 | dev->scatter_buffer_pa); | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * when this function is called. | ||
428 | * preemption or interrupt must be disabled | ||
429 | */ | ||
430 | static u32 crypto4xx_get_n_sd(struct crypto4xx_device *dev, int n) | ||
431 | { | ||
432 | u32 retval; | ||
433 | u32 tmp; | ||
434 | |||
435 | if (n >= PPC4XX_NUM_SD) | ||
436 | return ERING_WAS_FULL; | ||
437 | |||
438 | retval = dev->sdr_head; | ||
439 | tmp = (dev->sdr_head + n) % PPC4XX_NUM_SD; | ||
440 | if (dev->sdr_head > dev->gdr_tail) { | ||
441 | if (tmp < dev->sdr_head && tmp >= dev->sdr_tail) | ||
442 | return ERING_WAS_FULL; | ||
443 | } else if (dev->sdr_head < dev->sdr_tail) { | ||
444 | if (tmp < dev->sdr_head || tmp >= dev->sdr_tail) | ||
445 | return ERING_WAS_FULL; | ||
446 | } /* the head = tail, or empty case is already take cared */ | ||
447 | dev->sdr_head = tmp; | ||
448 | |||
449 | return retval; | ||
450 | } | ||
451 | |||
452 | static u32 crypto4xx_put_sd_to_sdr(struct crypto4xx_device *dev) | ||
453 | { | ||
454 | unsigned long flags; | ||
455 | |||
456 | spin_lock_irqsave(&dev->core_dev->lock, flags); | ||
457 | if (dev->sdr_tail == dev->sdr_head) { | ||
458 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
459 | return 0; | ||
460 | } | ||
461 | if (dev->sdr_tail != PPC4XX_LAST_SD) | ||
462 | dev->sdr_tail++; | ||
463 | else | ||
464 | dev->sdr_tail = 0; | ||
465 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
466 | |||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | static inline struct ce_sd *crypto4xx_get_sdp(struct crypto4xx_device *dev, | ||
471 | dma_addr_t *sd_dma, u32 idx) | ||
472 | { | ||
473 | *sd_dma = dev->sdr_pa + sizeof(struct ce_sd) * idx; | ||
474 | |||
475 | return (struct ce_sd *)(dev->sdr + sizeof(struct ce_sd) * idx); | ||
476 | } | ||
477 | |||
478 | static u32 crypto4xx_fill_one_page(struct crypto4xx_device *dev, | ||
479 | dma_addr_t *addr, u32 *length, | ||
480 | u32 *idx, u32 *offset, u32 *nbytes) | ||
481 | { | ||
482 | u32 len; | ||
483 | |||
484 | if (*length > dev->scatter_buffer_size) { | ||
485 | memcpy(phys_to_virt(*addr), | ||
486 | dev->scatter_buffer_va + | ||
487 | *idx * dev->scatter_buffer_size + *offset, | ||
488 | dev->scatter_buffer_size); | ||
489 | *offset = 0; | ||
490 | *length -= dev->scatter_buffer_size; | ||
491 | *nbytes -= dev->scatter_buffer_size; | ||
492 | if (*idx == PPC4XX_LAST_SD) | ||
493 | *idx = 0; | ||
494 | else | ||
495 | (*idx)++; | ||
496 | *addr = *addr + dev->scatter_buffer_size; | ||
497 | return 1; | ||
498 | } else if (*length < dev->scatter_buffer_size) { | ||
499 | memcpy(phys_to_virt(*addr), | ||
500 | dev->scatter_buffer_va + | ||
501 | *idx * dev->scatter_buffer_size + *offset, *length); | ||
502 | if ((*offset + *length) == dev->scatter_buffer_size) { | ||
503 | if (*idx == PPC4XX_LAST_SD) | ||
504 | *idx = 0; | ||
505 | else | ||
506 | (*idx)++; | ||
507 | *nbytes -= *length; | ||
508 | *offset = 0; | ||
509 | } else { | ||
510 | *nbytes -= *length; | ||
511 | *offset += *length; | ||
512 | } | ||
513 | |||
514 | return 0; | ||
515 | } else { | ||
516 | len = (*nbytes <= dev->scatter_buffer_size) ? | ||
517 | (*nbytes) : dev->scatter_buffer_size; | ||
518 | memcpy(phys_to_virt(*addr), | ||
519 | dev->scatter_buffer_va + | ||
520 | *idx * dev->scatter_buffer_size + *offset, | ||
521 | len); | ||
522 | *offset = 0; | ||
523 | *nbytes -= len; | ||
524 | |||
525 | if (*idx == PPC4XX_LAST_SD) | ||
526 | *idx = 0; | ||
527 | else | ||
528 | (*idx)++; | ||
529 | |||
530 | return 0; | ||
531 | } | ||
532 | } | ||
533 | |||
534 | static void crypto4xx_copy_pkt_to_dst(struct crypto4xx_device *dev, | ||
535 | struct ce_pd *pd, | ||
536 | struct pd_uinfo *pd_uinfo, | ||
537 | u32 nbytes, | ||
538 | struct scatterlist *dst) | ||
539 | { | ||
540 | dma_addr_t addr; | ||
541 | u32 this_sd; | ||
542 | u32 offset; | ||
543 | u32 len; | ||
544 | u32 i; | ||
545 | u32 sg_len; | ||
546 | struct scatterlist *sg; | ||
547 | |||
548 | this_sd = pd_uinfo->first_sd; | ||
549 | offset = 0; | ||
550 | i = 0; | ||
551 | |||
552 | while (nbytes) { | ||
553 | sg = &dst[i]; | ||
554 | sg_len = sg->length; | ||
555 | addr = dma_map_page(dev->core_dev->device, sg_page(sg), | ||
556 | sg->offset, sg->length, DMA_TO_DEVICE); | ||
557 | |||
558 | if (offset == 0) { | ||
559 | len = (nbytes <= sg->length) ? nbytes : sg->length; | ||
560 | while (crypto4xx_fill_one_page(dev, &addr, &len, | ||
561 | &this_sd, &offset, &nbytes)) | ||
562 | ; | ||
563 | if (!nbytes) | ||
564 | return; | ||
565 | i++; | ||
566 | } else { | ||
567 | len = (nbytes <= (dev->scatter_buffer_size - offset)) ? | ||
568 | nbytes : (dev->scatter_buffer_size - offset); | ||
569 | len = (sg->length < len) ? sg->length : len; | ||
570 | while (crypto4xx_fill_one_page(dev, &addr, &len, | ||
571 | &this_sd, &offset, &nbytes)) | ||
572 | ; | ||
573 | if (!nbytes) | ||
574 | return; | ||
575 | sg_len -= len; | ||
576 | if (sg_len) { | ||
577 | addr += len; | ||
578 | while (crypto4xx_fill_one_page(dev, &addr, | ||
579 | &sg_len, &this_sd, &offset, &nbytes)) | ||
580 | ; | ||
581 | } | ||
582 | i++; | ||
583 | } | ||
584 | } | ||
585 | } | ||
586 | |||
587 | static u32 crypto4xx_copy_digest_to_dst(struct pd_uinfo *pd_uinfo, | ||
588 | struct crypto4xx_ctx *ctx) | ||
589 | { | ||
590 | struct dynamic_sa_ctl *sa = (struct dynamic_sa_ctl *) ctx->sa_in; | ||
591 | struct sa_state_record *state_record = | ||
592 | (struct sa_state_record *) pd_uinfo->sr_va; | ||
593 | |||
594 | if (sa->sa_command_0.bf.hash_alg == SA_HASH_ALG_SHA1) { | ||
595 | memcpy((void *) pd_uinfo->dest_va, state_record->save_digest, | ||
596 | SA_HASH_ALG_SHA1_DIGEST_SIZE); | ||
597 | } | ||
598 | |||
599 | return 0; | ||
600 | } | ||
601 | |||
602 | static void crypto4xx_ret_sg_desc(struct crypto4xx_device *dev, | ||
603 | struct pd_uinfo *pd_uinfo) | ||
604 | { | ||
605 | int i; | ||
606 | if (pd_uinfo->num_gd) { | ||
607 | for (i = 0; i < pd_uinfo->num_gd; i++) | ||
608 | crypto4xx_put_gd_to_gdr(dev); | ||
609 | pd_uinfo->first_gd = 0xffffffff; | ||
610 | pd_uinfo->num_gd = 0; | ||
611 | } | ||
612 | if (pd_uinfo->num_sd) { | ||
613 | for (i = 0; i < pd_uinfo->num_sd; i++) | ||
614 | crypto4xx_put_sd_to_sdr(dev); | ||
615 | |||
616 | pd_uinfo->first_sd = 0xffffffff; | ||
617 | pd_uinfo->num_sd = 0; | ||
618 | } | ||
619 | } | ||
620 | |||
621 | static u32 crypto4xx_ablkcipher_done(struct crypto4xx_device *dev, | ||
622 | struct pd_uinfo *pd_uinfo, | ||
623 | struct ce_pd *pd) | ||
624 | { | ||
625 | struct crypto4xx_ctx *ctx; | ||
626 | struct ablkcipher_request *ablk_req; | ||
627 | struct scatterlist *dst; | ||
628 | dma_addr_t addr; | ||
629 | |||
630 | ablk_req = ablkcipher_request_cast(pd_uinfo->async_req); | ||
631 | ctx = crypto_tfm_ctx(ablk_req->base.tfm); | ||
632 | |||
633 | if (pd_uinfo->using_sd) { | ||
634 | crypto4xx_copy_pkt_to_dst(dev, pd, pd_uinfo, ablk_req->nbytes, | ||
635 | ablk_req->dst); | ||
636 | } else { | ||
637 | dst = pd_uinfo->dest_va; | ||
638 | addr = dma_map_page(dev->core_dev->device, sg_page(dst), | ||
639 | dst->offset, dst->length, DMA_FROM_DEVICE); | ||
640 | } | ||
641 | crypto4xx_ret_sg_desc(dev, pd_uinfo); | ||
642 | if (ablk_req->base.complete != NULL) | ||
643 | ablk_req->base.complete(&ablk_req->base, 0); | ||
644 | |||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | static u32 crypto4xx_ahash_done(struct crypto4xx_device *dev, | ||
649 | struct pd_uinfo *pd_uinfo) | ||
650 | { | ||
651 | struct crypto4xx_ctx *ctx; | ||
652 | struct ahash_request *ahash_req; | ||
653 | |||
654 | ahash_req = ahash_request_cast(pd_uinfo->async_req); | ||
655 | ctx = crypto_tfm_ctx(ahash_req->base.tfm); | ||
656 | |||
657 | crypto4xx_copy_digest_to_dst(pd_uinfo, | ||
658 | crypto_tfm_ctx(ahash_req->base.tfm)); | ||
659 | crypto4xx_ret_sg_desc(dev, pd_uinfo); | ||
660 | /* call user provided callback function x */ | ||
661 | if (ahash_req->base.complete != NULL) | ||
662 | ahash_req->base.complete(&ahash_req->base, 0); | ||
663 | |||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static u32 crypto4xx_pd_done(struct crypto4xx_device *dev, u32 idx) | ||
668 | { | ||
669 | struct ce_pd *pd; | ||
670 | struct pd_uinfo *pd_uinfo; | ||
671 | |||
672 | pd = dev->pdr + sizeof(struct ce_pd)*idx; | ||
673 | pd_uinfo = dev->pdr_uinfo + sizeof(struct pd_uinfo)*idx; | ||
674 | if (crypto_tfm_alg_type(pd_uinfo->async_req->tfm) == | ||
675 | CRYPTO_ALG_TYPE_ABLKCIPHER) | ||
676 | return crypto4xx_ablkcipher_done(dev, pd_uinfo, pd); | ||
677 | else | ||
678 | return crypto4xx_ahash_done(dev, pd_uinfo); | ||
679 | } | ||
680 | |||
681 | /** | ||
682 | * Note: Only use this function to copy items that is word aligned. | ||
683 | */ | ||
684 | void crypto4xx_memcpy_le(unsigned int *dst, | ||
685 | const unsigned char *buf, | ||
686 | int len) | ||
687 | { | ||
688 | u8 *tmp; | ||
689 | for (; len >= 4; buf += 4, len -= 4) | ||
690 | *dst++ = cpu_to_le32(*(unsigned int *) buf); | ||
691 | |||
692 | tmp = (u8 *)dst; | ||
693 | switch (len) { | ||
694 | case 3: | ||
695 | *tmp++ = 0; | ||
696 | *tmp++ = *(buf+2); | ||
697 | *tmp++ = *(buf+1); | ||
698 | *tmp++ = *buf; | ||
699 | break; | ||
700 | case 2: | ||
701 | *tmp++ = 0; | ||
702 | *tmp++ = 0; | ||
703 | *tmp++ = *(buf+1); | ||
704 | *tmp++ = *buf; | ||
705 | break; | ||
706 | case 1: | ||
707 | *tmp++ = 0; | ||
708 | *tmp++ = 0; | ||
709 | *tmp++ = 0; | ||
710 | *tmp++ = *buf; | ||
711 | break; | ||
712 | default: | ||
713 | break; | ||
714 | } | ||
715 | } | ||
716 | |||
717 | static void crypto4xx_stop_all(struct crypto4xx_core_device *core_dev) | ||
718 | { | ||
719 | crypto4xx_destroy_pdr(core_dev->dev); | ||
720 | crypto4xx_destroy_gdr(core_dev->dev); | ||
721 | crypto4xx_destroy_sdr(core_dev->dev); | ||
722 | dev_set_drvdata(core_dev->device, NULL); | ||
723 | iounmap(core_dev->dev->ce_base); | ||
724 | kfree(core_dev->dev); | ||
725 | kfree(core_dev); | ||
726 | } | ||
727 | |||
728 | void crypto4xx_return_pd(struct crypto4xx_device *dev, | ||
729 | u32 pd_entry, struct ce_pd *pd, | ||
730 | struct pd_uinfo *pd_uinfo) | ||
731 | { | ||
732 | /* irq should be already disabled */ | ||
733 | dev->pdr_head = pd_entry; | ||
734 | pd->pd_ctl.w = 0; | ||
735 | pd->pd_ctl_len.w = 0; | ||
736 | pd_uinfo->state = PD_ENTRY_FREE; | ||
737 | } | ||
738 | |||
739 | /* | ||
740 | * derive number of elements in scatterlist | ||
741 | * Shamlessly copy from talitos.c | ||
742 | */ | ||
743 | static int get_sg_count(struct scatterlist *sg_list, int nbytes) | ||
744 | { | ||
745 | struct scatterlist *sg = sg_list; | ||
746 | int sg_nents = 0; | ||
747 | |||
748 | while (nbytes) { | ||
749 | sg_nents++; | ||
750 | if (sg->length > nbytes) | ||
751 | break; | ||
752 | nbytes -= sg->length; | ||
753 | sg = sg_next(sg); | ||
754 | } | ||
755 | |||
756 | return sg_nents; | ||
757 | } | ||
758 | |||
759 | static u32 get_next_gd(u32 current) | ||
760 | { | ||
761 | if (current != PPC4XX_LAST_GD) | ||
762 | return current + 1; | ||
763 | else | ||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | static u32 get_next_sd(u32 current) | ||
768 | { | ||
769 | if (current != PPC4XX_LAST_SD) | ||
770 | return current + 1; | ||
771 | else | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | u32 crypto4xx_build_pd(struct crypto_async_request *req, | ||
776 | struct crypto4xx_ctx *ctx, | ||
777 | struct scatterlist *src, | ||
778 | struct scatterlist *dst, | ||
779 | unsigned int datalen, | ||
780 | void *iv, u32 iv_len) | ||
781 | { | ||
782 | struct crypto4xx_device *dev = ctx->dev; | ||
783 | dma_addr_t addr, pd_dma, sd_dma, gd_dma; | ||
784 | struct dynamic_sa_ctl *sa; | ||
785 | struct scatterlist *sg; | ||
786 | struct ce_gd *gd; | ||
787 | struct ce_pd *pd; | ||
788 | u32 num_gd, num_sd; | ||
789 | u32 fst_gd = 0xffffffff; | ||
790 | u32 fst_sd = 0xffffffff; | ||
791 | u32 pd_entry; | ||
792 | unsigned long flags; | ||
793 | struct pd_uinfo *pd_uinfo = NULL; | ||
794 | unsigned int nbytes = datalen, idx; | ||
795 | unsigned int ivlen = 0; | ||
796 | u32 gd_idx = 0; | ||
797 | |||
798 | /* figure how many gd is needed */ | ||
799 | num_gd = get_sg_count(src, datalen); | ||
800 | if (num_gd == 1) | ||
801 | num_gd = 0; | ||
802 | |||
803 | /* figure how many sd is needed */ | ||
804 | if (sg_is_last(dst) || ctx->is_hash) { | ||
805 | num_sd = 0; | ||
806 | } else { | ||
807 | if (datalen > PPC4XX_SD_BUFFER_SIZE) { | ||
808 | num_sd = datalen / PPC4XX_SD_BUFFER_SIZE; | ||
809 | if (datalen % PPC4XX_SD_BUFFER_SIZE) | ||
810 | num_sd++; | ||
811 | } else { | ||
812 | num_sd = 1; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | /* | ||
817 | * The follow section of code needs to be protected | ||
818 | * The gather ring and scatter ring needs to be consecutive | ||
819 | * In case of run out of any kind of descriptor, the descriptor | ||
820 | * already got must be return the original place. | ||
821 | */ | ||
822 | spin_lock_irqsave(&dev->core_dev->lock, flags); | ||
823 | if (num_gd) { | ||
824 | fst_gd = crypto4xx_get_n_gd(dev, num_gd); | ||
825 | if (fst_gd == ERING_WAS_FULL) { | ||
826 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
827 | return -EAGAIN; | ||
828 | } | ||
829 | } | ||
830 | if (num_sd) { | ||
831 | fst_sd = crypto4xx_get_n_sd(dev, num_sd); | ||
832 | if (fst_sd == ERING_WAS_FULL) { | ||
833 | if (num_gd) | ||
834 | dev->gdr_head = fst_gd; | ||
835 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
836 | return -EAGAIN; | ||
837 | } | ||
838 | } | ||
839 | pd_entry = crypto4xx_get_pd_from_pdr_nolock(dev); | ||
840 | if (pd_entry == ERING_WAS_FULL) { | ||
841 | if (num_gd) | ||
842 | dev->gdr_head = fst_gd; | ||
843 | if (num_sd) | ||
844 | dev->sdr_head = fst_sd; | ||
845 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
846 | return -EAGAIN; | ||
847 | } | ||
848 | spin_unlock_irqrestore(&dev->core_dev->lock, flags); | ||
849 | |||
850 | pd_uinfo = (struct pd_uinfo *)(dev->pdr_uinfo + | ||
851 | sizeof(struct pd_uinfo) * pd_entry); | ||
852 | pd = crypto4xx_get_pdp(dev, &pd_dma, pd_entry); | ||
853 | pd_uinfo->async_req = req; | ||
854 | pd_uinfo->num_gd = num_gd; | ||
855 | pd_uinfo->num_sd = num_sd; | ||
856 | |||
857 | if (iv_len || ctx->is_hash) { | ||
858 | ivlen = iv_len; | ||
859 | pd->sa = pd_uinfo->sa_pa; | ||
860 | sa = (struct dynamic_sa_ctl *) pd_uinfo->sa_va; | ||
861 | if (ctx->direction == DIR_INBOUND) | ||
862 | memcpy(sa, ctx->sa_in, ctx->sa_len * 4); | ||
863 | else | ||
864 | memcpy(sa, ctx->sa_out, ctx->sa_len * 4); | ||
865 | |||
866 | memcpy((void *) sa + ctx->offset_to_sr_ptr, | ||
867 | &pd_uinfo->sr_pa, 4); | ||
868 | |||
869 | if (iv_len) | ||
870 | crypto4xx_memcpy_le(pd_uinfo->sr_va, iv, iv_len); | ||
871 | } else { | ||
872 | if (ctx->direction == DIR_INBOUND) { | ||
873 | pd->sa = ctx->sa_in_dma_addr; | ||
874 | sa = (struct dynamic_sa_ctl *) ctx->sa_in; | ||
875 | } else { | ||
876 | pd->sa = ctx->sa_out_dma_addr; | ||
877 | sa = (struct dynamic_sa_ctl *) ctx->sa_out; | ||
878 | } | ||
879 | } | ||
880 | pd->sa_len = ctx->sa_len; | ||
881 | if (num_gd) { | ||
882 | /* get first gd we are going to use */ | ||
883 | gd_idx = fst_gd; | ||
884 | pd_uinfo->first_gd = fst_gd; | ||
885 | pd_uinfo->num_gd = num_gd; | ||
886 | gd = crypto4xx_get_gdp(dev, &gd_dma, gd_idx); | ||
887 | pd->src = gd_dma; | ||
888 | /* enable gather */ | ||
889 | sa->sa_command_0.bf.gather = 1; | ||
890 | idx = 0; | ||
891 | src = &src[0]; | ||
892 | /* walk the sg, and setup gather array */ | ||
893 | while (nbytes) { | ||
894 | sg = &src[idx]; | ||
895 | addr = dma_map_page(dev->core_dev->device, sg_page(sg), | ||
896 | sg->offset, sg->length, DMA_TO_DEVICE); | ||
897 | gd->ptr = addr; | ||
898 | gd->ctl_len.len = sg->length; | ||
899 | gd->ctl_len.done = 0; | ||
900 | gd->ctl_len.ready = 1; | ||
901 | if (sg->length >= nbytes) | ||
902 | break; | ||
903 | nbytes -= sg->length; | ||
904 | gd_idx = get_next_gd(gd_idx); | ||
905 | gd = crypto4xx_get_gdp(dev, &gd_dma, gd_idx); | ||
906 | idx++; | ||
907 | } | ||
908 | } else { | ||
909 | pd->src = (u32)dma_map_page(dev->core_dev->device, sg_page(src), | ||
910 | src->offset, src->length, DMA_TO_DEVICE); | ||
911 | /* | ||
912 | * Disable gather in sa command | ||
913 | */ | ||
914 | sa->sa_command_0.bf.gather = 0; | ||
915 | /* | ||
916 | * Indicate gather array is not used | ||
917 | */ | ||
918 | pd_uinfo->first_gd = 0xffffffff; | ||
919 | pd_uinfo->num_gd = 0; | ||
920 | } | ||
921 | if (ctx->is_hash || sg_is_last(dst)) { | ||
922 | /* | ||
923 | * we know application give us dst a whole piece of memory | ||
924 | * no need to use scatter ring. | ||
925 | * In case of is_hash, the icv is always at end of src data. | ||
926 | */ | ||
927 | pd_uinfo->using_sd = 0; | ||
928 | pd_uinfo->first_sd = 0xffffffff; | ||
929 | pd_uinfo->num_sd = 0; | ||
930 | pd_uinfo->dest_va = dst; | ||
931 | sa->sa_command_0.bf.scatter = 0; | ||
932 | if (ctx->is_hash) | ||
933 | pd->dest = virt_to_phys((void *)dst); | ||
934 | else | ||
935 | pd->dest = (u32)dma_map_page(dev->core_dev->device, | ||
936 | sg_page(dst), dst->offset, | ||
937 | dst->length, DMA_TO_DEVICE); | ||
938 | } else { | ||
939 | struct ce_sd *sd = NULL; | ||
940 | u32 sd_idx = fst_sd; | ||
941 | nbytes = datalen; | ||
942 | sa->sa_command_0.bf.scatter = 1; | ||
943 | pd_uinfo->using_sd = 1; | ||
944 | pd_uinfo->dest_va = dst; | ||
945 | pd_uinfo->first_sd = fst_sd; | ||
946 | pd_uinfo->num_sd = num_sd; | ||
947 | sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx); | ||
948 | pd->dest = sd_dma; | ||
949 | /* setup scatter descriptor */ | ||
950 | sd->ctl.done = 0; | ||
951 | sd->ctl.rdy = 1; | ||
952 | /* sd->ptr should be setup by sd_init routine*/ | ||
953 | idx = 0; | ||
954 | if (nbytes >= PPC4XX_SD_BUFFER_SIZE) | ||
955 | nbytes -= PPC4XX_SD_BUFFER_SIZE; | ||
956 | else | ||
957 | nbytes = 0; | ||
958 | while (nbytes) { | ||
959 | sd_idx = get_next_sd(sd_idx); | ||
960 | sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx); | ||
961 | /* setup scatter descriptor */ | ||
962 | sd->ctl.done = 0; | ||
963 | sd->ctl.rdy = 1; | ||
964 | if (nbytes >= PPC4XX_SD_BUFFER_SIZE) | ||
965 | nbytes -= PPC4XX_SD_BUFFER_SIZE; | ||
966 | else | ||
967 | /* | ||
968 | * SD entry can hold PPC4XX_SD_BUFFER_SIZE, | ||
969 | * which is more than nbytes, so done. | ||
970 | */ | ||
971 | nbytes = 0; | ||
972 | } | ||
973 | } | ||
974 | |||
975 | sa->sa_command_1.bf.hash_crypto_offset = 0; | ||
976 | pd->pd_ctl.w = ctx->pd_ctl; | ||
977 | pd->pd_ctl_len.w = 0x00400000 | (ctx->bypass << 24) | datalen; | ||
978 | pd_uinfo->state = PD_ENTRY_INUSE; | ||
979 | wmb(); | ||
980 | /* write any value to push engine to read a pd */ | ||
981 | writel(1, dev->ce_base + CRYPTO4XX_INT_DESCR_RD); | ||
982 | return -EINPROGRESS; | ||
983 | } | ||
984 | |||
985 | /** | ||
986 | * Algorithm Registration Functions | ||
987 | */ | ||
988 | static int crypto4xx_alg_init(struct crypto_tfm *tfm) | ||
989 | { | ||
990 | struct crypto_alg *alg = tfm->__crt_alg; | ||
991 | struct crypto4xx_alg *amcc_alg = crypto_alg_to_crypto4xx_alg(alg); | ||
992 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); | ||
993 | |||
994 | ctx->dev = amcc_alg->dev; | ||
995 | ctx->sa_in = NULL; | ||
996 | ctx->sa_out = NULL; | ||
997 | ctx->sa_in_dma_addr = 0; | ||
998 | ctx->sa_out_dma_addr = 0; | ||
999 | ctx->sa_len = 0; | ||
1000 | |||
1001 | if (alg->cra_type == &crypto_ablkcipher_type) | ||
1002 | tfm->crt_ablkcipher.reqsize = sizeof(struct crypto4xx_ctx); | ||
1003 | else if (alg->cra_type == &crypto_ahash_type) | ||
1004 | tfm->crt_ahash.reqsize = sizeof(struct crypto4xx_ctx); | ||
1005 | |||
1006 | return 0; | ||
1007 | } | ||
1008 | |||
1009 | static void crypto4xx_alg_exit(struct crypto_tfm *tfm) | ||
1010 | { | ||
1011 | struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm); | ||
1012 | |||
1013 | crypto4xx_free_sa(ctx); | ||
1014 | crypto4xx_free_state_record(ctx); | ||
1015 | } | ||
1016 | |||
1017 | int crypto4xx_register_alg(struct crypto4xx_device *sec_dev, | ||
1018 | struct crypto_alg *crypto_alg, int array_size) | ||
1019 | { | ||
1020 | struct crypto4xx_alg *alg; | ||
1021 | int i; | ||
1022 | int rc = 0; | ||
1023 | |||
1024 | for (i = 0; i < array_size; i++) { | ||
1025 | alg = kzalloc(sizeof(struct crypto4xx_alg), GFP_KERNEL); | ||
1026 | if (!alg) | ||
1027 | return -ENOMEM; | ||
1028 | |||
1029 | alg->alg = crypto_alg[i]; | ||
1030 | INIT_LIST_HEAD(&alg->alg.cra_list); | ||
1031 | if (alg->alg.cra_init == NULL) | ||
1032 | alg->alg.cra_init = crypto4xx_alg_init; | ||
1033 | if (alg->alg.cra_exit == NULL) | ||
1034 | alg->alg.cra_exit = crypto4xx_alg_exit; | ||
1035 | alg->dev = sec_dev; | ||
1036 | rc = crypto_register_alg(&alg->alg); | ||
1037 | if (rc) { | ||
1038 | list_del(&alg->entry); | ||
1039 | kfree(alg); | ||
1040 | } else { | ||
1041 | list_add_tail(&alg->entry, &sec_dev->alg_list); | ||
1042 | } | ||
1043 | } | ||
1044 | |||
1045 | return 0; | ||
1046 | } | ||
1047 | |||
1048 | static void crypto4xx_unregister_alg(struct crypto4xx_device *sec_dev) | ||
1049 | { | ||
1050 | struct crypto4xx_alg *alg, *tmp; | ||
1051 | |||
1052 | list_for_each_entry_safe(alg, tmp, &sec_dev->alg_list, entry) { | ||
1053 | list_del(&alg->entry); | ||
1054 | crypto_unregister_alg(&alg->alg); | ||
1055 | kfree(alg); | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | static void crypto4xx_bh_tasklet_cb(unsigned long data) | ||
1060 | { | ||
1061 | struct device *dev = (struct device *)data; | ||
1062 | struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev); | ||
1063 | struct pd_uinfo *pd_uinfo; | ||
1064 | struct ce_pd *pd; | ||
1065 | u32 tail; | ||
1066 | |||
1067 | while (core_dev->dev->pdr_head != core_dev->dev->pdr_tail) { | ||
1068 | tail = core_dev->dev->pdr_tail; | ||
1069 | pd_uinfo = core_dev->dev->pdr_uinfo + | ||
1070 | sizeof(struct pd_uinfo)*tail; | ||
1071 | pd = core_dev->dev->pdr + sizeof(struct ce_pd) * tail; | ||
1072 | if ((pd_uinfo->state == PD_ENTRY_INUSE) && | ||
1073 | pd->pd_ctl.bf.pe_done && | ||
1074 | !pd->pd_ctl.bf.host_ready) { | ||
1075 | pd->pd_ctl.bf.pe_done = 0; | ||
1076 | crypto4xx_pd_done(core_dev->dev, tail); | ||
1077 | crypto4xx_put_pd_to_pdr(core_dev->dev, tail); | ||
1078 | pd_uinfo->state = PD_ENTRY_FREE; | ||
1079 | } else { | ||
1080 | /* if tail not done, break */ | ||
1081 | break; | ||
1082 | } | ||
1083 | } | ||
1084 | } | ||
1085 | |||
1086 | /** | ||
1087 | * Top Half of isr. | ||
1088 | */ | ||
1089 | static irqreturn_t crypto4xx_ce_interrupt_handler(int irq, void *data) | ||
1090 | { | ||
1091 | struct device *dev = (struct device *)data; | ||
1092 | struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev); | ||
1093 | |||
1094 | if (core_dev->dev->ce_base == 0) | ||
1095 | return 0; | ||
1096 | |||
1097 | writel(PPC4XX_INTERRUPT_CLR, | ||
1098 | core_dev->dev->ce_base + CRYPTO4XX_INT_CLR); | ||
1099 | tasklet_schedule(&core_dev->tasklet); | ||
1100 | |||
1101 | return IRQ_HANDLED; | ||
1102 | } | ||
1103 | |||
1104 | /** | ||
1105 | * Supported Crypto Algorithms | ||
1106 | */ | ||
1107 | struct crypto_alg crypto4xx_alg[] = { | ||
1108 | /* Crypto AES modes */ | ||
1109 | { | ||
1110 | .cra_name = "cbc(aes)", | ||
1111 | .cra_driver_name = "cbc-aes-ppc4xx", | ||
1112 | .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY, | ||
1113 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, | ||
1114 | .cra_blocksize = AES_BLOCK_SIZE, | ||
1115 | .cra_ctxsize = sizeof(struct crypto4xx_ctx), | ||
1116 | .cra_alignmask = 0, | ||
1117 | .cra_type = &crypto_ablkcipher_type, | ||
1118 | .cra_module = THIS_MODULE, | ||
1119 | .cra_u = { | ||
1120 | .ablkcipher = { | ||
1121 | .min_keysize = AES_MIN_KEY_SIZE, | ||
1122 | .max_keysize = AES_MAX_KEY_SIZE, | ||
1123 | .ivsize = AES_IV_SIZE, | ||
1124 | .setkey = crypto4xx_setkey_aes_cbc, | ||
1125 | .encrypt = crypto4xx_encrypt, | ||
1126 | .decrypt = crypto4xx_decrypt, | ||
1127 | } | ||
1128 | } | ||
1129 | }, | ||
1130 | /* Hash SHA1 */ | ||
1131 | { | ||
1132 | .cra_name = "sha1", | ||
1133 | .cra_driver_name = "sha1-ppc4xx", | ||
1134 | .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY, | ||
1135 | .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC, | ||
1136 | .cra_blocksize = SHA1_BLOCK_SIZE, | ||
1137 | .cra_ctxsize = sizeof(struct crypto4xx_ctx), | ||
1138 | .cra_alignmask = 0, | ||
1139 | .cra_type = &crypto_ahash_type, | ||
1140 | .cra_init = crypto4xx_sha1_alg_init, | ||
1141 | .cra_module = THIS_MODULE, | ||
1142 | .cra_u = { | ||
1143 | .ahash = { | ||
1144 | .digestsize = SHA1_DIGEST_SIZE, | ||
1145 | .init = crypto4xx_hash_init, | ||
1146 | .update = crypto4xx_hash_update, | ||
1147 | .final = crypto4xx_hash_final, | ||
1148 | .digest = crypto4xx_hash_digest, | ||
1149 | } | ||
1150 | } | ||
1151 | }, | ||
1152 | }; | ||
1153 | |||
1154 | /** | ||
1155 | * Module Initialization Routine | ||
1156 | */ | ||
1157 | static int __init crypto4xx_probe(struct of_device *ofdev, | ||
1158 | const struct of_device_id *match) | ||
1159 | { | ||
1160 | int rc; | ||
1161 | struct resource res; | ||
1162 | struct device *dev = &ofdev->dev; | ||
1163 | struct crypto4xx_core_device *core_dev; | ||
1164 | |||
1165 | rc = of_address_to_resource(ofdev->node, 0, &res); | ||
1166 | if (rc) | ||
1167 | return -ENODEV; | ||
1168 | |||
1169 | if (of_find_compatible_node(NULL, NULL, "amcc,ppc460ex-crypto")) { | ||
1170 | mtdcri(SDR0, PPC460EX_SDR0_SRST, | ||
1171 | mfdcri(SDR0, PPC460EX_SDR0_SRST) | PPC460EX_CE_RESET); | ||
1172 | mtdcri(SDR0, PPC460EX_SDR0_SRST, | ||
1173 | mfdcri(SDR0, PPC460EX_SDR0_SRST) & ~PPC460EX_CE_RESET); | ||
1174 | } else if (of_find_compatible_node(NULL, NULL, | ||
1175 | "amcc,ppc405ex-crypto")) { | ||
1176 | mtdcri(SDR0, PPC405EX_SDR0_SRST, | ||
1177 | mfdcri(SDR0, PPC405EX_SDR0_SRST) | PPC405EX_CE_RESET); | ||
1178 | mtdcri(SDR0, PPC405EX_SDR0_SRST, | ||
1179 | mfdcri(SDR0, PPC405EX_SDR0_SRST) & ~PPC405EX_CE_RESET); | ||
1180 | } else if (of_find_compatible_node(NULL, NULL, | ||
1181 | "amcc,ppc460sx-crypto")) { | ||
1182 | mtdcri(SDR0, PPC460SX_SDR0_SRST, | ||
1183 | mfdcri(SDR0, PPC460SX_SDR0_SRST) | PPC460SX_CE_RESET); | ||
1184 | mtdcri(SDR0, PPC460SX_SDR0_SRST, | ||
1185 | mfdcri(SDR0, PPC460SX_SDR0_SRST) & ~PPC460SX_CE_RESET); | ||
1186 | } else { | ||
1187 | printk(KERN_ERR "Crypto Function Not supported!\n"); | ||
1188 | return -EINVAL; | ||
1189 | } | ||
1190 | |||
1191 | core_dev = kzalloc(sizeof(struct crypto4xx_core_device), GFP_KERNEL); | ||
1192 | if (!core_dev) | ||
1193 | return -ENOMEM; | ||
1194 | |||
1195 | dev_set_drvdata(dev, core_dev); | ||
1196 | core_dev->ofdev = ofdev; | ||
1197 | core_dev->dev = kzalloc(sizeof(struct crypto4xx_device), GFP_KERNEL); | ||
1198 | if (!core_dev->dev) | ||
1199 | goto err_alloc_dev; | ||
1200 | |||
1201 | core_dev->dev->core_dev = core_dev; | ||
1202 | core_dev->device = dev; | ||
1203 | spin_lock_init(&core_dev->lock); | ||
1204 | INIT_LIST_HEAD(&core_dev->dev->alg_list); | ||
1205 | rc = crypto4xx_build_pdr(core_dev->dev); | ||
1206 | if (rc) | ||
1207 | goto err_build_pdr; | ||
1208 | |||
1209 | rc = crypto4xx_build_gdr(core_dev->dev); | ||
1210 | if (rc) | ||
1211 | goto err_build_gdr; | ||
1212 | |||
1213 | rc = crypto4xx_build_sdr(core_dev->dev); | ||
1214 | if (rc) | ||
1215 | goto err_build_sdr; | ||
1216 | |||
1217 | /* Init tasklet for bottom half processing */ | ||
1218 | tasklet_init(&core_dev->tasklet, crypto4xx_bh_tasklet_cb, | ||
1219 | (unsigned long) dev); | ||
1220 | |||
1221 | /* Register for Crypto isr, Crypto Engine IRQ */ | ||
1222 | core_dev->irq = irq_of_parse_and_map(ofdev->node, 0); | ||
1223 | rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0, | ||
1224 | core_dev->dev->name, dev); | ||
1225 | if (rc) | ||
1226 | goto err_request_irq; | ||
1227 | |||
1228 | core_dev->dev->ce_base = of_iomap(ofdev->node, 0); | ||
1229 | if (!core_dev->dev->ce_base) { | ||
1230 | dev_err(dev, "failed to of_iomap\n"); | ||
1231 | goto err_iomap; | ||
1232 | } | ||
1233 | |||
1234 | /* need to setup pdr, rdr, gdr and sdr before this */ | ||
1235 | crypto4xx_hw_init(core_dev->dev); | ||
1236 | |||
1237 | /* Register security algorithms with Linux CryptoAPI */ | ||
1238 | rc = crypto4xx_register_alg(core_dev->dev, crypto4xx_alg, | ||
1239 | ARRAY_SIZE(crypto4xx_alg)); | ||
1240 | if (rc) | ||
1241 | goto err_start_dev; | ||
1242 | |||
1243 | return 0; | ||
1244 | |||
1245 | err_start_dev: | ||
1246 | iounmap(core_dev->dev->ce_base); | ||
1247 | err_iomap: | ||
1248 | free_irq(core_dev->irq, dev); | ||
1249 | irq_dispose_mapping(core_dev->irq); | ||
1250 | tasklet_kill(&core_dev->tasklet); | ||
1251 | err_request_irq: | ||
1252 | crypto4xx_destroy_sdr(core_dev->dev); | ||
1253 | err_build_sdr: | ||
1254 | crypto4xx_destroy_gdr(core_dev->dev); | ||
1255 | err_build_gdr: | ||
1256 | crypto4xx_destroy_pdr(core_dev->dev); | ||
1257 | err_build_pdr: | ||
1258 | kfree(core_dev->dev); | ||
1259 | err_alloc_dev: | ||
1260 | kfree(core_dev); | ||
1261 | |||
1262 | return rc; | ||
1263 | } | ||
1264 | |||
1265 | static int __exit crypto4xx_remove(struct of_device *ofdev) | ||
1266 | { | ||
1267 | struct device *dev = &ofdev->dev; | ||
1268 | struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev); | ||
1269 | |||
1270 | free_irq(core_dev->irq, dev); | ||
1271 | irq_dispose_mapping(core_dev->irq); | ||
1272 | |||
1273 | tasklet_kill(&core_dev->tasklet); | ||
1274 | /* Un-register with Linux CryptoAPI */ | ||
1275 | crypto4xx_unregister_alg(core_dev->dev); | ||
1276 | /* Free all allocated memory */ | ||
1277 | crypto4xx_stop_all(core_dev); | ||
1278 | |||
1279 | return 0; | ||
1280 | } | ||
1281 | |||
1282 | static struct of_device_id crypto4xx_match[] = { | ||
1283 | { .compatible = "amcc,ppc4xx-crypto",}, | ||
1284 | { }, | ||
1285 | }; | ||
1286 | |||
1287 | static struct of_platform_driver crypto4xx_driver = { | ||
1288 | .name = "crypto4xx", | ||
1289 | .match_table = crypto4xx_match, | ||
1290 | .probe = crypto4xx_probe, | ||
1291 | .remove = crypto4xx_remove, | ||
1292 | }; | ||
1293 | |||
1294 | static int __init crypto4xx_init(void) | ||
1295 | { | ||
1296 | return of_register_platform_driver(&crypto4xx_driver); | ||
1297 | } | ||
1298 | |||
1299 | static void __exit crypto4xx_exit(void) | ||
1300 | { | ||
1301 | of_unregister_platform_driver(&crypto4xx_driver); | ||
1302 | } | ||
1303 | |||
1304 | module_init(crypto4xx_init); | ||
1305 | module_exit(crypto4xx_exit); | ||
1306 | |||
1307 | MODULE_LICENSE("GPL"); | ||
1308 | MODULE_AUTHOR("James Hsiao <jhsiao@amcc.com>"); | ||
1309 | MODULE_DESCRIPTION("Driver for AMCC PPC4xx crypto accelerator"); | ||
1310 | |||
diff --git a/drivers/crypto/amcc/crypto4xx_core.h b/drivers/crypto/amcc/crypto4xx_core.h new file mode 100644 index 000000000000..1ef103449364 --- /dev/null +++ b/drivers/crypto/amcc/crypto4xx_core.h | |||
@@ -0,0 +1,177 @@ | |||
1 | /** | ||
2 | * AMCC SoC PPC4xx Crypto Driver | ||
3 | * | ||
4 | * Copyright (c) 2008 Applied Micro Circuits Corporation. | ||
5 | * All rights reserved. James Hsiao <jhsiao@amcc.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * This is the header file for AMCC Crypto offload Linux device driver for | ||
18 | * use with Linux CryptoAPI. | ||
19 | |||
20 | */ | ||
21 | |||
22 | #ifndef __CRYPTO4XX_CORE_H__ | ||
23 | #define __CRYPTO4XX_CORE_H__ | ||
24 | |||
25 | #define PPC460SX_SDR0_SRST 0x201 | ||
26 | #define PPC405EX_SDR0_SRST 0x200 | ||
27 | #define PPC460EX_SDR0_SRST 0x201 | ||
28 | #define PPC460EX_CE_RESET 0x08000000 | ||
29 | #define PPC460SX_CE_RESET 0x20000000 | ||
30 | #define PPC405EX_CE_RESET 0x00000008 | ||
31 | |||
32 | #define CRYPTO4XX_CRYPTO_PRIORITY 300 | ||
33 | #define PPC4XX_LAST_PD 63 | ||
34 | #define PPC4XX_NUM_PD 64 | ||
35 | #define PPC4XX_LAST_GD 1023 | ||
36 | #define PPC4XX_NUM_GD 1024 | ||
37 | #define PPC4XX_LAST_SD 63 | ||
38 | #define PPC4XX_NUM_SD 64 | ||
39 | #define PPC4XX_SD_BUFFER_SIZE 2048 | ||
40 | |||
41 | #define PD_ENTRY_INUSE 1 | ||
42 | #define PD_ENTRY_FREE 0 | ||
43 | #define ERING_WAS_FULL 0xffffffff | ||
44 | |||
45 | struct crypto4xx_device; | ||
46 | |||
47 | struct pd_uinfo { | ||
48 | struct crypto4xx_device *dev; | ||
49 | u32 state; | ||
50 | u32 using_sd; | ||
51 | u32 first_gd; /* first gather discriptor | ||
52 | used by this packet */ | ||
53 | u32 num_gd; /* number of gather discriptor | ||
54 | used by this packet */ | ||
55 | u32 first_sd; /* first scatter discriptor | ||
56 | used by this packet */ | ||
57 | u32 num_sd; /* number of scatter discriptors | ||
58 | used by this packet */ | ||
59 | void *sa_va; /* shadow sa, when using cp from ctx->sa */ | ||
60 | u32 sa_pa; | ||
61 | void *sr_va; /* state record for shadow sa */ | ||
62 | u32 sr_pa; | ||
63 | struct scatterlist *dest_va; | ||
64 | struct crypto_async_request *async_req; /* base crypto request | ||
65 | for this packet */ | ||
66 | }; | ||
67 | |||
68 | struct crypto4xx_device { | ||
69 | struct crypto4xx_core_device *core_dev; | ||
70 | char *name; | ||
71 | u64 ce_phy_address; | ||
72 | void __iomem *ce_base; | ||
73 | |||
74 | void *pdr; /* base address of packet | ||
75 | descriptor ring */ | ||
76 | dma_addr_t pdr_pa; /* physical address used to | ||
77 | program ce pdr_base_register */ | ||
78 | void *gdr; /* gather descriptor ring */ | ||
79 | dma_addr_t gdr_pa; /* physical address used to | ||
80 | program ce gdr_base_register */ | ||
81 | void *sdr; /* scatter descriptor ring */ | ||
82 | dma_addr_t sdr_pa; /* physical address used to | ||
83 | program ce sdr_base_register */ | ||
84 | void *scatter_buffer_va; | ||
85 | dma_addr_t scatter_buffer_pa; | ||
86 | u32 scatter_buffer_size; | ||
87 | |||
88 | void *shadow_sa_pool; /* pool of memory for sa in pd_uinfo */ | ||
89 | dma_addr_t shadow_sa_pool_pa; | ||
90 | void *shadow_sr_pool; /* pool of memory for sr in pd_uinfo */ | ||
91 | dma_addr_t shadow_sr_pool_pa; | ||
92 | u32 pdr_tail; | ||
93 | u32 pdr_head; | ||
94 | u32 gdr_tail; | ||
95 | u32 gdr_head; | ||
96 | u32 sdr_tail; | ||
97 | u32 sdr_head; | ||
98 | void *pdr_uinfo; | ||
99 | struct list_head alg_list; /* List of algorithm supported | ||
100 | by this device */ | ||
101 | }; | ||
102 | |||
103 | struct crypto4xx_core_device { | ||
104 | struct device *device; | ||
105 | struct of_device *ofdev; | ||
106 | struct crypto4xx_device *dev; | ||
107 | u32 int_status; | ||
108 | u32 irq; | ||
109 | struct tasklet_struct tasklet; | ||
110 | spinlock_t lock; | ||
111 | }; | ||
112 | |||
113 | struct crypto4xx_ctx { | ||
114 | struct crypto4xx_device *dev; | ||
115 | void *sa_in; | ||
116 | dma_addr_t sa_in_dma_addr; | ||
117 | void *sa_out; | ||
118 | dma_addr_t sa_out_dma_addr; | ||
119 | void *state_record; | ||
120 | dma_addr_t state_record_dma_addr; | ||
121 | u32 sa_len; | ||
122 | u32 offset_to_sr_ptr; /* offset to state ptr, in dynamic sa */ | ||
123 | u32 direction; | ||
124 | u32 next_hdr; | ||
125 | u32 save_iv; | ||
126 | u32 pd_ctl_len; | ||
127 | u32 pd_ctl; | ||
128 | u32 bypass; | ||
129 | u32 is_hash; | ||
130 | u32 hash_final; | ||
131 | }; | ||
132 | |||
133 | struct crypto4xx_req_ctx { | ||
134 | struct crypto4xx_device *dev; /* Device in which | ||
135 | operation to send to */ | ||
136 | void *sa; | ||
137 | u32 sa_dma_addr; | ||
138 | u16 sa_len; | ||
139 | }; | ||
140 | |||
141 | struct crypto4xx_alg { | ||
142 | struct list_head entry; | ||
143 | struct crypto_alg alg; | ||
144 | struct crypto4xx_device *dev; | ||
145 | }; | ||
146 | |||
147 | #define crypto_alg_to_crypto4xx_alg(x) \ | ||
148 | container_of(x, struct crypto4xx_alg, alg) | ||
149 | |||
150 | extern int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size); | ||
151 | extern void crypto4xx_free_sa(struct crypto4xx_ctx *ctx); | ||
152 | extern u32 crypto4xx_alloc_sa_rctx(struct crypto4xx_ctx *ctx, | ||
153 | struct crypto4xx_ctx *rctx); | ||
154 | extern void crypto4xx_free_sa_rctx(struct crypto4xx_ctx *rctx); | ||
155 | extern void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx); | ||
156 | extern u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx); | ||
157 | extern u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx); | ||
158 | extern u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx); | ||
159 | extern u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx); | ||
160 | extern void crypto4xx_memcpy_le(unsigned int *dst, | ||
161 | const unsigned char *buf, int len); | ||
162 | extern u32 crypto4xx_build_pd(struct crypto_async_request *req, | ||
163 | struct crypto4xx_ctx *ctx, | ||
164 | struct scatterlist *src, | ||
165 | struct scatterlist *dst, | ||
166 | unsigned int datalen, | ||
167 | void *iv, u32 iv_len); | ||
168 | extern int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher, | ||
169 | const u8 *key, unsigned int keylen); | ||
170 | extern int crypto4xx_encrypt(struct ablkcipher_request *req); | ||
171 | extern int crypto4xx_decrypt(struct ablkcipher_request *req); | ||
172 | extern int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm); | ||
173 | extern int crypto4xx_hash_digest(struct ahash_request *req); | ||
174 | extern int crypto4xx_hash_final(struct ahash_request *req); | ||
175 | extern int crypto4xx_hash_update(struct ahash_request *req); | ||
176 | extern int crypto4xx_hash_init(struct ahash_request *req); | ||
177 | #endif | ||
diff --git a/drivers/crypto/amcc/crypto4xx_reg_def.h b/drivers/crypto/amcc/crypto4xx_reg_def.h new file mode 100644 index 000000000000..7d4edb002619 --- /dev/null +++ b/drivers/crypto/amcc/crypto4xx_reg_def.h | |||
@@ -0,0 +1,284 @@ | |||
1 | /** | ||
2 | * AMCC SoC PPC4xx Crypto Driver | ||
3 | * | ||
4 | * Copyright (c) 2008 Applied Micro Circuits Corporation. | ||
5 | * All rights reserved. James Hsiao <jhsiao@amcc.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * This filr defines the register set for Security Subsystem | ||
18 | */ | ||
19 | |||
20 | #ifndef __CRYPTO4XX_REG_DEF_H__ | ||
21 | #define __CRYPTO4XX_REG_DEF_H__ | ||
22 | |||
23 | /* CRYPTO4XX Register offset */ | ||
24 | #define CRYPTO4XX_DESCRIPTOR 0x00000000 | ||
25 | #define CRYPTO4XX_CTRL_STAT 0x00000000 | ||
26 | #define CRYPTO4XX_SOURCE 0x00000004 | ||
27 | #define CRYPTO4XX_DEST 0x00000008 | ||
28 | #define CRYPTO4XX_SA 0x0000000C | ||
29 | #define CRYPTO4XX_SA_LENGTH 0x00000010 | ||
30 | #define CRYPTO4XX_LENGTH 0x00000014 | ||
31 | |||
32 | #define CRYPTO4XX_PE_DMA_CFG 0x00000040 | ||
33 | #define CRYPTO4XX_PE_DMA_STAT 0x00000044 | ||
34 | #define CRYPTO4XX_PDR_BASE 0x00000048 | ||
35 | #define CRYPTO4XX_RDR_BASE 0x0000004c | ||
36 | #define CRYPTO4XX_RING_SIZE 0x00000050 | ||
37 | #define CRYPTO4XX_RING_CTRL 0x00000054 | ||
38 | #define CRYPTO4XX_INT_RING_STAT 0x00000058 | ||
39 | #define CRYPTO4XX_EXT_RING_STAT 0x0000005c | ||
40 | #define CRYPTO4XX_IO_THRESHOLD 0x00000060 | ||
41 | #define CRYPTO4XX_GATH_RING_BASE 0x00000064 | ||
42 | #define CRYPTO4XX_SCAT_RING_BASE 0x00000068 | ||
43 | #define CRYPTO4XX_PART_RING_SIZE 0x0000006c | ||
44 | #define CRYPTO4XX_PART_RING_CFG 0x00000070 | ||
45 | |||
46 | #define CRYPTO4XX_PDR_BASE_UADDR 0x00000080 | ||
47 | #define CRYPTO4XX_RDR_BASE_UADDR 0x00000084 | ||
48 | #define CRYPTO4XX_PKT_SRC_UADDR 0x00000088 | ||
49 | #define CRYPTO4XX_PKT_DEST_UADDR 0x0000008c | ||
50 | #define CRYPTO4XX_SA_UADDR 0x00000090 | ||
51 | #define CRYPTO4XX_GATH_RING_BASE_UADDR 0x000000A0 | ||
52 | #define CRYPTO4XX_SCAT_RING_BASE_UADDR 0x000000A4 | ||
53 | |||
54 | #define CRYPTO4XX_SEQ_RD 0x00000408 | ||
55 | #define CRYPTO4XX_SEQ_MASK_RD 0x0000040C | ||
56 | |||
57 | #define CRYPTO4XX_SA_CMD_0 0x00010600 | ||
58 | #define CRYPTO4XX_SA_CMD_1 0x00010604 | ||
59 | |||
60 | #define CRYPTO4XX_STATE_PTR 0x000106dc | ||
61 | #define CRYPTO4XX_STATE_IV 0x00010700 | ||
62 | #define CRYPTO4XX_STATE_HASH_BYTE_CNT_0 0x00010710 | ||
63 | #define CRYPTO4XX_STATE_HASH_BYTE_CNT_1 0x00010714 | ||
64 | |||
65 | #define CRYPTO4XX_STATE_IDIGEST_0 0x00010718 | ||
66 | #define CRYPTO4XX_STATE_IDIGEST_1 0x0001071c | ||
67 | |||
68 | #define CRYPTO4XX_DATA_IN 0x00018000 | ||
69 | #define CRYPTO4XX_DATA_OUT 0x0001c000 | ||
70 | |||
71 | #define CRYPTO4XX_INT_UNMASK_STAT 0x000500a0 | ||
72 | #define CRYPTO4XX_INT_MASK_STAT 0x000500a4 | ||
73 | #define CRYPTO4XX_INT_CLR 0x000500a4 | ||
74 | #define CRYPTO4XX_INT_EN 0x000500a8 | ||
75 | |||
76 | #define CRYPTO4XX_INT_PKA 0x00000002 | ||
77 | #define CRYPTO4XX_INT_PDR_DONE 0x00008000 | ||
78 | #define CRYPTO4XX_INT_MA_WR_ERR 0x00020000 | ||
79 | #define CRYPTO4XX_INT_MA_RD_ERR 0x00010000 | ||
80 | #define CRYPTO4XX_INT_PE_ERR 0x00000200 | ||
81 | #define CRYPTO4XX_INT_USER_DMA_ERR 0x00000040 | ||
82 | #define CRYPTO4XX_INT_SLAVE_ERR 0x00000010 | ||
83 | #define CRYPTO4XX_INT_MASTER_ERR 0x00000008 | ||
84 | #define CRYPTO4XX_INT_ERROR 0x00030258 | ||
85 | |||
86 | #define CRYPTO4XX_INT_CFG 0x000500ac | ||
87 | #define CRYPTO4XX_INT_DESCR_RD 0x000500b0 | ||
88 | #define CRYPTO4XX_INT_DESCR_CNT 0x000500b4 | ||
89 | #define CRYPTO4XX_INT_TIMEOUT_CNT 0x000500b8 | ||
90 | |||
91 | #define CRYPTO4XX_DEVICE_CTRL 0x00060080 | ||
92 | #define CRYPTO4XX_DEVICE_ID 0x00060084 | ||
93 | #define CRYPTO4XX_DEVICE_INFO 0x00060088 | ||
94 | #define CRYPTO4XX_DMA_USER_SRC 0x00060094 | ||
95 | #define CRYPTO4XX_DMA_USER_DEST 0x00060098 | ||
96 | #define CRYPTO4XX_DMA_USER_CMD 0x0006009C | ||
97 | |||
98 | #define CRYPTO4XX_DMA_CFG 0x000600d4 | ||
99 | #define CRYPTO4XX_BYTE_ORDER_CFG 0x000600d8 | ||
100 | #define CRYPTO4XX_ENDIAN_CFG 0x000600d8 | ||
101 | |||
102 | #define CRYPTO4XX_PRNG_STAT 0x00070000 | ||
103 | #define CRYPTO4XX_PRNG_CTRL 0x00070004 | ||
104 | #define CRYPTO4XX_PRNG_SEED_L 0x00070008 | ||
105 | #define CRYPTO4XX_PRNG_SEED_H 0x0007000c | ||
106 | |||
107 | #define CRYPTO4XX_PRNG_RES_0 0x00070020 | ||
108 | #define CRYPTO4XX_PRNG_RES_1 0x00070024 | ||
109 | #define CRYPTO4XX_PRNG_RES_2 0x00070028 | ||
110 | #define CRYPTO4XX_PRNG_RES_3 0x0007002C | ||
111 | |||
112 | #define CRYPTO4XX_PRNG_LFSR_L 0x00070030 | ||
113 | #define CRYPTO4XX_PRNG_LFSR_H 0x00070034 | ||
114 | |||
115 | /** | ||
116 | * Initilize CRYPTO ENGINE registers, and memory bases. | ||
117 | */ | ||
118 | #define PPC4XX_PDR_POLL 0x3ff | ||
119 | #define PPC4XX_OUTPUT_THRESHOLD 2 | ||
120 | #define PPC4XX_INPUT_THRESHOLD 2 | ||
121 | #define PPC4XX_PD_SIZE 6 | ||
122 | #define PPC4XX_CTX_DONE_INT 0x2000 | ||
123 | #define PPC4XX_PD_DONE_INT 0x8000 | ||
124 | #define PPC4XX_BYTE_ORDER 0x22222 | ||
125 | #define PPC4XX_INTERRUPT_CLR 0x3ffff | ||
126 | #define PPC4XX_PRNG_CTRL_AUTO_EN 0x3 | ||
127 | #define PPC4XX_DC_3DES_EN 1 | ||
128 | #define PPC4XX_INT_DESCR_CNT 4 | ||
129 | #define PPC4XX_INT_TIMEOUT_CNT 0 | ||
130 | #define PPC4XX_INT_CFG 1 | ||
131 | /** | ||
132 | * all follow define are ad hoc | ||
133 | */ | ||
134 | #define PPC4XX_RING_RETRY 100 | ||
135 | #define PPC4XX_RING_POLL 100 | ||
136 | #define PPC4XX_SDR_SIZE PPC4XX_NUM_SD | ||
137 | #define PPC4XX_GDR_SIZE PPC4XX_NUM_GD | ||
138 | |||
139 | /** | ||
140 | * Generic Security Association (SA) with all possible fields. These will | ||
141 | * never likely used except for reference purpose. These structure format | ||
142 | * can be not changed as the hardware expects them to be layout as defined. | ||
143 | * Field can be removed or reduced but ordering can not be changed. | ||
144 | */ | ||
145 | #define CRYPTO4XX_DMA_CFG_OFFSET 0x40 | ||
146 | union ce_pe_dma_cfg { | ||
147 | struct { | ||
148 | u32 rsv:7; | ||
149 | u32 dir_host:1; | ||
150 | u32 rsv1:2; | ||
151 | u32 bo_td_en:1; | ||
152 | u32 dis_pdr_upd:1; | ||
153 | u32 bo_sgpd_en:1; | ||
154 | u32 bo_data_en:1; | ||
155 | u32 bo_sa_en:1; | ||
156 | u32 bo_pd_en:1; | ||
157 | u32 rsv2:4; | ||
158 | u32 dynamic_sa_en:1; | ||
159 | u32 pdr_mode:2; | ||
160 | u32 pe_mode:1; | ||
161 | u32 rsv3:5; | ||
162 | u32 reset_sg:1; | ||
163 | u32 reset_pdr:1; | ||
164 | u32 reset_pe:1; | ||
165 | } bf; | ||
166 | u32 w; | ||
167 | } __attribute__((packed)); | ||
168 | |||
169 | #define CRYPTO4XX_PDR_BASE_OFFSET 0x48 | ||
170 | #define CRYPTO4XX_RDR_BASE_OFFSET 0x4c | ||
171 | #define CRYPTO4XX_RING_SIZE_OFFSET 0x50 | ||
172 | union ce_ring_size { | ||
173 | struct { | ||
174 | u32 ring_offset:16; | ||
175 | u32 rsv:6; | ||
176 | u32 ring_size:10; | ||
177 | } bf; | ||
178 | u32 w; | ||
179 | } __attribute__((packed)); | ||
180 | |||
181 | #define CRYPTO4XX_RING_CONTROL_OFFSET 0x54 | ||
182 | union ce_ring_contol { | ||
183 | struct { | ||
184 | u32 continuous:1; | ||
185 | u32 rsv:5; | ||
186 | u32 ring_retry_divisor:10; | ||
187 | u32 rsv1:4; | ||
188 | u32 ring_poll_divisor:10; | ||
189 | } bf; | ||
190 | u32 w; | ||
191 | } __attribute__((packed)); | ||
192 | |||
193 | #define CRYPTO4XX_IO_THRESHOLD_OFFSET 0x60 | ||
194 | union ce_io_threshold { | ||
195 | struct { | ||
196 | u32 rsv:6; | ||
197 | u32 output_threshold:10; | ||
198 | u32 rsv1:6; | ||
199 | u32 input_threshold:10; | ||
200 | } bf; | ||
201 | u32 w; | ||
202 | } __attribute__((packed)); | ||
203 | |||
204 | #define CRYPTO4XX_GATHER_RING_BASE_OFFSET 0x64 | ||
205 | #define CRYPTO4XX_SCATTER_RING_BASE_OFFSET 0x68 | ||
206 | |||
207 | union ce_part_ring_size { | ||
208 | struct { | ||
209 | u32 sdr_size:16; | ||
210 | u32 gdr_size:16; | ||
211 | } bf; | ||
212 | u32 w; | ||
213 | } __attribute__((packed)); | ||
214 | |||
215 | #define MAX_BURST_SIZE_32 0 | ||
216 | #define MAX_BURST_SIZE_64 1 | ||
217 | #define MAX_BURST_SIZE_128 2 | ||
218 | #define MAX_BURST_SIZE_256 3 | ||
219 | |||
220 | /* gather descriptor control length */ | ||
221 | struct gd_ctl_len { | ||
222 | u32 len:16; | ||
223 | u32 rsv:14; | ||
224 | u32 done:1; | ||
225 | u32 ready:1; | ||
226 | } __attribute__((packed)); | ||
227 | |||
228 | struct ce_gd { | ||
229 | u32 ptr; | ||
230 | struct gd_ctl_len ctl_len; | ||
231 | } __attribute__((packed)); | ||
232 | |||
233 | struct sd_ctl { | ||
234 | u32 ctl:30; | ||
235 | u32 done:1; | ||
236 | u32 rdy:1; | ||
237 | } __attribute__((packed)); | ||
238 | |||
239 | struct ce_sd { | ||
240 | u32 ptr; | ||
241 | struct sd_ctl ctl; | ||
242 | } __attribute__((packed)); | ||
243 | |||
244 | #define PD_PAD_CTL_32 0x10 | ||
245 | #define PD_PAD_CTL_64 0x20 | ||
246 | #define PD_PAD_CTL_128 0x40 | ||
247 | #define PD_PAD_CTL_256 0x80 | ||
248 | union ce_pd_ctl { | ||
249 | struct { | ||
250 | u32 pd_pad_ctl:8; | ||
251 | u32 status:8; | ||
252 | u32 next_hdr:8; | ||
253 | u32 rsv:2; | ||
254 | u32 cached_sa:1; | ||
255 | u32 hash_final:1; | ||
256 | u32 init_arc4:1; | ||
257 | u32 rsv1:1; | ||
258 | u32 pe_done:1; | ||
259 | u32 host_ready:1; | ||
260 | } bf; | ||
261 | u32 w; | ||
262 | } __attribute__((packed)); | ||
263 | |||
264 | union ce_pd_ctl_len { | ||
265 | struct { | ||
266 | u32 bypass:8; | ||
267 | u32 pe_done:1; | ||
268 | u32 host_ready:1; | ||
269 | u32 rsv:2; | ||
270 | u32 pkt_len:20; | ||
271 | } bf; | ||
272 | u32 w; | ||
273 | } __attribute__((packed)); | ||
274 | |||
275 | struct ce_pd { | ||
276 | union ce_pd_ctl pd_ctl; | ||
277 | u32 src; | ||
278 | u32 dest; | ||
279 | u32 sa; /* get from ctx->sa_dma_addr */ | ||
280 | u32 sa_len; /* only if dynamic sa is used */ | ||
281 | union ce_pd_ctl_len pd_ctl_len; | ||
282 | |||
283 | } __attribute__((packed)); | ||
284 | #endif | ||
diff --git a/drivers/crypto/amcc/crypto4xx_sa.c b/drivers/crypto/amcc/crypto4xx_sa.c new file mode 100644 index 000000000000..466fd94cd4a3 --- /dev/null +++ b/drivers/crypto/amcc/crypto4xx_sa.c | |||
@@ -0,0 +1,108 @@ | |||
1 | /** | ||
2 | * AMCC SoC PPC4xx Crypto Driver | ||
3 | * | ||
4 | * Copyright (c) 2008 Applied Micro Circuits Corporation. | ||
5 | * All rights reserved. James Hsiao <jhsiao@amcc.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * @file crypto4xx_sa.c | ||
18 | * | ||
19 | * This file implements the security context | ||
20 | * assoicate format. | ||
21 | */ | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/moduleparam.h> | ||
25 | #include <linux/mod_devicetable.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/spinlock_types.h> | ||
28 | #include <linux/highmem.h> | ||
29 | #include <linux/scatterlist.h> | ||
30 | #include <linux/crypto.h> | ||
31 | #include <crypto/algapi.h> | ||
32 | #include <crypto/des.h> | ||
33 | #include "crypto4xx_reg_def.h" | ||
34 | #include "crypto4xx_sa.h" | ||
35 | #include "crypto4xx_core.h" | ||
36 | |||
37 | u32 get_dynamic_sa_offset_iv_field(struct crypto4xx_ctx *ctx) | ||
38 | { | ||
39 | u32 offset; | ||
40 | union dynamic_sa_contents cts; | ||
41 | |||
42 | if (ctx->direction == DIR_INBOUND) | ||
43 | cts.w = ((struct dynamic_sa_ctl *)(ctx->sa_in))->sa_contents; | ||
44 | else | ||
45 | cts.w = ((struct dynamic_sa_ctl *)(ctx->sa_out))->sa_contents; | ||
46 | offset = cts.bf.key_size | ||
47 | + cts.bf.inner_size | ||
48 | + cts.bf.outer_size | ||
49 | + cts.bf.spi | ||
50 | + cts.bf.seq_num0 | ||
51 | + cts.bf.seq_num1 | ||
52 | + cts.bf.seq_num_mask0 | ||
53 | + cts.bf.seq_num_mask1 | ||
54 | + cts.bf.seq_num_mask2 | ||
55 | + cts.bf.seq_num_mask3; | ||
56 | |||
57 | return sizeof(struct dynamic_sa_ctl) + offset * 4; | ||
58 | } | ||
59 | |||
60 | u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx) | ||
61 | { | ||
62 | u32 offset; | ||
63 | union dynamic_sa_contents cts; | ||
64 | |||
65 | if (ctx->direction == DIR_INBOUND) | ||
66 | cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents; | ||
67 | else | ||
68 | cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents; | ||
69 | offset = cts.bf.key_size | ||
70 | + cts.bf.inner_size | ||
71 | + cts.bf.outer_size | ||
72 | + cts.bf.spi | ||
73 | + cts.bf.seq_num0 | ||
74 | + cts.bf.seq_num1 | ||
75 | + cts.bf.seq_num_mask0 | ||
76 | + cts.bf.seq_num_mask1 | ||
77 | + cts.bf.seq_num_mask2 | ||
78 | + cts.bf.seq_num_mask3 | ||
79 | + cts.bf.iv0 | ||
80 | + cts.bf.iv1 | ||
81 | + cts.bf.iv2 | ||
82 | + cts.bf.iv3; | ||
83 | |||
84 | return sizeof(struct dynamic_sa_ctl) + offset * 4; | ||
85 | } | ||
86 | |||
87 | u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx) | ||
88 | { | ||
89 | union dynamic_sa_contents cts; | ||
90 | |||
91 | if (ctx->direction == DIR_INBOUND) | ||
92 | cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents; | ||
93 | else | ||
94 | cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents; | ||
95 | return (cts.bf.iv0 + cts.bf.iv1 + cts.bf.iv2 + cts.bf.iv3) * 4; | ||
96 | } | ||
97 | |||
98 | u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx) | ||
99 | { | ||
100 | union dynamic_sa_contents cts; | ||
101 | |||
102 | if (ctx->direction == DIR_INBOUND) | ||
103 | cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents; | ||
104 | else | ||
105 | cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents; | ||
106 | |||
107 | return sizeof(struct dynamic_sa_ctl); | ||
108 | } | ||
diff --git a/drivers/crypto/amcc/crypto4xx_sa.h b/drivers/crypto/amcc/crypto4xx_sa.h new file mode 100644 index 000000000000..4b83ed7e5570 --- /dev/null +++ b/drivers/crypto/amcc/crypto4xx_sa.h | |||
@@ -0,0 +1,243 @@ | |||
1 | /** | ||
2 | * AMCC SoC PPC4xx Crypto Driver | ||
3 | * | ||
4 | * Copyright (c) 2008 Applied Micro Circuits Corporation. | ||
5 | * All rights reserved. James Hsiao <jhsiao@amcc.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * This file defines the security context | ||
18 | * assoicate format. | ||
19 | */ | ||
20 | |||
21 | #ifndef __CRYPTO4XX_SA_H__ | ||
22 | #define __CRYPTO4XX_SA_H__ | ||
23 | |||
24 | #define AES_IV_SIZE 16 | ||
25 | |||
26 | /** | ||
27 | * Contents of Dynamic Security Association (SA) with all possible fields | ||
28 | */ | ||
29 | union dynamic_sa_contents { | ||
30 | struct { | ||
31 | u32 arc4_state_ptr:1; | ||
32 | u32 arc4_ij_ptr:1; | ||
33 | u32 state_ptr:1; | ||
34 | u32 iv3:1; | ||
35 | u32 iv2:1; | ||
36 | u32 iv1:1; | ||
37 | u32 iv0:1; | ||
38 | u32 seq_num_mask3:1; | ||
39 | u32 seq_num_mask2:1; | ||
40 | u32 seq_num_mask1:1; | ||
41 | u32 seq_num_mask0:1; | ||
42 | u32 seq_num1:1; | ||
43 | u32 seq_num0:1; | ||
44 | u32 spi:1; | ||
45 | u32 outer_size:5; | ||
46 | u32 inner_size:5; | ||
47 | u32 key_size:4; | ||
48 | u32 cmd_size:4; | ||
49 | } bf; | ||
50 | u32 w; | ||
51 | } __attribute__((packed)); | ||
52 | |||
53 | #define DIR_OUTBOUND 0 | ||
54 | #define DIR_INBOUND 1 | ||
55 | #define SA_OP_GROUP_BASIC 0 | ||
56 | #define SA_OPCODE_ENCRYPT 0 | ||
57 | #define SA_OPCODE_DECRYPT 0 | ||
58 | #define SA_OPCODE_HASH 3 | ||
59 | #define SA_CIPHER_ALG_DES 0 | ||
60 | #define SA_CIPHER_ALG_3DES 1 | ||
61 | #define SA_CIPHER_ALG_ARC4 2 | ||
62 | #define SA_CIPHER_ALG_AES 3 | ||
63 | #define SA_CIPHER_ALG_KASUMI 4 | ||
64 | #define SA_CIPHER_ALG_NULL 15 | ||
65 | |||
66 | #define SA_HASH_ALG_MD5 0 | ||
67 | #define SA_HASH_ALG_SHA1 1 | ||
68 | #define SA_HASH_ALG_NULL 15 | ||
69 | #define SA_HASH_ALG_SHA1_DIGEST_SIZE 20 | ||
70 | |||
71 | #define SA_LOAD_HASH_FROM_SA 0 | ||
72 | #define SA_LOAD_HASH_FROM_STATE 2 | ||
73 | #define SA_NOT_LOAD_HASH 3 | ||
74 | #define SA_LOAD_IV_FROM_SA 0 | ||
75 | #define SA_LOAD_IV_FROM_INPUT 1 | ||
76 | #define SA_LOAD_IV_FROM_STATE 2 | ||
77 | #define SA_LOAD_IV_GEN_IV 3 | ||
78 | |||
79 | #define SA_PAD_TYPE_CONSTANT 2 | ||
80 | #define SA_PAD_TYPE_ZERO 3 | ||
81 | #define SA_PAD_TYPE_TLS 5 | ||
82 | #define SA_PAD_TYPE_DTLS 5 | ||
83 | #define SA_NOT_SAVE_HASH 0 | ||
84 | #define SA_SAVE_HASH 1 | ||
85 | #define SA_NOT_SAVE_IV 0 | ||
86 | #define SA_SAVE_IV 1 | ||
87 | #define SA_HEADER_PROC 1 | ||
88 | #define SA_NO_HEADER_PROC 0 | ||
89 | |||
90 | union sa_command_0 { | ||
91 | struct { | ||
92 | u32 scatter:1; | ||
93 | u32 gather:1; | ||
94 | u32 save_hash_state:1; | ||
95 | u32 save_iv:1; | ||
96 | u32 load_hash_state:2; | ||
97 | u32 load_iv:2; | ||
98 | u32 digest_len:4; | ||
99 | u32 hdr_proc:1; | ||
100 | u32 extend_pad:1; | ||
101 | u32 stream_cipher_pad:1; | ||
102 | u32 rsv:1; | ||
103 | u32 hash_alg:4; | ||
104 | u32 cipher_alg:4; | ||
105 | u32 pad_type:2; | ||
106 | u32 op_group:2; | ||
107 | u32 dir:1; | ||
108 | u32 opcode:3; | ||
109 | } bf; | ||
110 | u32 w; | ||
111 | } __attribute__((packed)); | ||
112 | |||
113 | #define CRYPTO_MODE_ECB 0 | ||
114 | #define CRYPTO_MODE_CBC 1 | ||
115 | |||
116 | #define CRYPTO_FEEDBACK_MODE_NO_FB 0 | ||
117 | #define CRYPTO_FEEDBACK_MODE_64BIT_OFB 0 | ||
118 | #define CRYPTO_FEEDBACK_MODE_8BIT_CFB 1 | ||
119 | #define CRYPTO_FEEDBACK_MODE_1BIT_CFB 2 | ||
120 | #define CRYPTO_FEEDBACK_MODE_128BIT_CFB 3 | ||
121 | |||
122 | #define SA_AES_KEY_LEN_128 2 | ||
123 | #define SA_AES_KEY_LEN_192 3 | ||
124 | #define SA_AES_KEY_LEN_256 4 | ||
125 | |||
126 | #define SA_REV2 1 | ||
127 | /** | ||
128 | * The follow defines bits sa_command_1 | ||
129 | * In Basic hash mode this bit define simple hash or hmac. | ||
130 | * In IPsec mode, this bit define muting control. | ||
131 | */ | ||
132 | #define SA_HASH_MODE_HASH 0 | ||
133 | #define SA_HASH_MODE_HMAC 1 | ||
134 | #define SA_MC_ENABLE 0 | ||
135 | #define SA_MC_DISABLE 1 | ||
136 | #define SA_NOT_COPY_HDR 0 | ||
137 | #define SA_COPY_HDR 1 | ||
138 | #define SA_NOT_COPY_PAD 0 | ||
139 | #define SA_COPY_PAD 1 | ||
140 | #define SA_NOT_COPY_PAYLOAD 0 | ||
141 | #define SA_COPY_PAYLOAD 1 | ||
142 | #define SA_EXTENDED_SN_OFF 0 | ||
143 | #define SA_EXTENDED_SN_ON 1 | ||
144 | #define SA_SEQ_MASK_OFF 0 | ||
145 | #define SA_SEQ_MASK_ON 1 | ||
146 | |||
147 | union sa_command_1 { | ||
148 | struct { | ||
149 | u32 crypto_mode31:1; | ||
150 | u32 save_arc4_state:1; | ||
151 | u32 arc4_stateful:1; | ||
152 | u32 key_len:5; | ||
153 | u32 hash_crypto_offset:8; | ||
154 | u32 sa_rev:2; | ||
155 | u32 byte_offset:1; | ||
156 | u32 hmac_muting:1; | ||
157 | u32 feedback_mode:2; | ||
158 | u32 crypto_mode9_8:2; | ||
159 | u32 extended_seq_num:1; | ||
160 | u32 seq_num_mask:1; | ||
161 | u32 mutable_bit_proc:1; | ||
162 | u32 ip_version:1; | ||
163 | u32 copy_pad:1; | ||
164 | u32 copy_payload:1; | ||
165 | u32 copy_hdr:1; | ||
166 | u32 rsv1:1; | ||
167 | } bf; | ||
168 | u32 w; | ||
169 | } __attribute__((packed)); | ||
170 | |||
171 | struct dynamic_sa_ctl { | ||
172 | u32 sa_contents; | ||
173 | union sa_command_0 sa_command_0; | ||
174 | union sa_command_1 sa_command_1; | ||
175 | } __attribute__((packed)); | ||
176 | |||
177 | /** | ||
178 | * State Record for Security Association (SA) | ||
179 | */ | ||
180 | struct sa_state_record { | ||
181 | u32 save_iv[4]; | ||
182 | u32 save_hash_byte_cnt[2]; | ||
183 | u32 save_digest[16]; | ||
184 | } __attribute__((packed)); | ||
185 | |||
186 | /** | ||
187 | * Security Association (SA) for AES128 | ||
188 | * | ||
189 | */ | ||
190 | struct dynamic_sa_aes128 { | ||
191 | struct dynamic_sa_ctl ctrl; | ||
192 | u32 key[4]; | ||
193 | u32 iv[4]; /* for CBC, OFC, and CFB mode */ | ||
194 | u32 state_ptr; | ||
195 | u32 reserved; | ||
196 | } __attribute__((packed)); | ||
197 | |||
198 | #define SA_AES128_LEN (sizeof(struct dynamic_sa_aes128)/4) | ||
199 | #define SA_AES128_CONTENTS 0x3e000042 | ||
200 | |||
201 | /* | ||
202 | * Security Association (SA) for AES192 | ||
203 | */ | ||
204 | struct dynamic_sa_aes192 { | ||
205 | struct dynamic_sa_ctl ctrl; | ||
206 | u32 key[6]; | ||
207 | u32 iv[4]; /* for CBC, OFC, and CFB mode */ | ||
208 | u32 state_ptr; | ||
209 | u32 reserved; | ||
210 | } __attribute__((packed)); | ||
211 | |||
212 | #define SA_AES192_LEN (sizeof(struct dynamic_sa_aes192)/4) | ||
213 | #define SA_AES192_CONTENTS 0x3e000062 | ||
214 | |||
215 | /** | ||
216 | * Security Association (SA) for AES256 | ||
217 | */ | ||
218 | struct dynamic_sa_aes256 { | ||
219 | struct dynamic_sa_ctl ctrl; | ||
220 | u32 key[8]; | ||
221 | u32 iv[4]; /* for CBC, OFC, and CFB mode */ | ||
222 | u32 state_ptr; | ||
223 | u32 reserved; | ||
224 | } __attribute__((packed)); | ||
225 | |||
226 | #define SA_AES256_LEN (sizeof(struct dynamic_sa_aes256)/4) | ||
227 | #define SA_AES256_CONTENTS 0x3e000082 | ||
228 | #define SA_AES_CONTENTS 0x3e000002 | ||
229 | |||
230 | /** | ||
231 | * Security Association (SA) for HASH160: HMAC-SHA1 | ||
232 | */ | ||
233 | struct dynamic_sa_hash160 { | ||
234 | struct dynamic_sa_ctl ctrl; | ||
235 | u32 inner_digest[5]; | ||
236 | u32 outer_digest[5]; | ||
237 | u32 state_ptr; | ||
238 | u32 reserved; | ||
239 | } __attribute__((packed)); | ||
240 | #define SA_HASH160_LEN (sizeof(struct dynamic_sa_hash160)/4) | ||
241 | #define SA_HASH160_CONTENTS 0x2000a502 | ||
242 | |||
243 | #endif | ||
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c index 10c3c498358c..55dd88d82d6d 100644 --- a/drivers/dio/dio.c +++ b/drivers/dio/dio.c | |||
@@ -182,7 +182,7 @@ static int __init dio_init(void) | |||
182 | 182 | ||
183 | /* Initialize the DIO bus */ | 183 | /* Initialize the DIO bus */ |
184 | INIT_LIST_HEAD(&dio_bus.devices); | 184 | INIT_LIST_HEAD(&dio_bus.devices); |
185 | strcpy(dio_bus.dev.bus_id, "dio"); | 185 | dev_set_name(&dio_bus.dev, "dio"); |
186 | error = device_register(&dio_bus.dev); | 186 | error = device_register(&dio_bus.dev); |
187 | if (error) { | 187 | if (error) { |
188 | pr_err("DIO: Error registering dio_bus\n"); | 188 | pr_err("DIO: Error registering dio_bus\n"); |
@@ -237,7 +237,7 @@ static int __init dio_init(void) | |||
237 | dev->scode = scode; | 237 | dev->scode = scode; |
238 | dev->resource.start = pa; | 238 | dev->resource.start = pa; |
239 | dev->resource.end = pa + DIO_SIZE(scode, va); | 239 | dev->resource.end = pa + DIO_SIZE(scode, va); |
240 | sprintf(dev->dev.bus_id,"%02x", scode); | 240 | dev_set_name(&dev->dev, "%02x", scode); |
241 | 241 | ||
242 | /* read the ID byte(s) and encode if necessary. */ | 242 | /* read the ID byte(s) and encode if necessary. */ |
243 | prid = DIO_ID(va); | 243 | prid = DIO_ID(va); |
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index a97c07eef7ec..20ad3d26bec2 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -1011,7 +1011,7 @@ static int __init dw_probe(struct platform_device *pdev) | |||
1011 | dma_writel(dw, CFG, DW_CFG_DMA_EN); | 1011 | dma_writel(dw, CFG, DW_CFG_DMA_EN); |
1012 | 1012 | ||
1013 | printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n", | 1013 | printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n", |
1014 | pdev->dev.bus_id, dw->dma.chancnt); | 1014 | dev_name(&pdev->dev), dw->dma.chancnt); |
1015 | 1015 | ||
1016 | dma_async_device_register(&dw->dma); | 1016 | dma_async_device_register(&dw->dma); |
1017 | 1017 | ||
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c index 24f3ca851523..cb0f639f049d 100644 --- a/drivers/edac/cell_edac.c +++ b/drivers/edac/cell_edac.c | |||
@@ -198,7 +198,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev) | |||
198 | mci->edac_cap = EDAC_FLAG_EC | EDAC_FLAG_SECDED; | 198 | mci->edac_cap = EDAC_FLAG_EC | EDAC_FLAG_SECDED; |
199 | mci->mod_name = "cell_edac"; | 199 | mci->mod_name = "cell_edac"; |
200 | mci->ctl_name = "MIC"; | 200 | mci->ctl_name = "MIC"; |
201 | mci->dev_name = pdev->dev.bus_id; | 201 | mci->dev_name = dev_name(&pdev->dev); |
202 | mci->edac_check = cell_edac_check; | 202 | mci->edac_check = cell_edac_check; |
203 | cell_edac_init_csrows(mci); | 203 | cell_edac_init_csrows(mci); |
204 | 204 | ||
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 853ef37ec006..4637a4a757df 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -218,7 +218,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op, | |||
218 | pci->dev = &op->dev; | 218 | pci->dev = &op->dev; |
219 | pci->mod_name = EDAC_MOD_STR; | 219 | pci->mod_name = EDAC_MOD_STR; |
220 | pci->ctl_name = pdata->name; | 220 | pci->ctl_name = pdata->name; |
221 | pci->dev_name = op->dev.bus_id; | 221 | pci->dev_name = dev_name(&op->dev); |
222 | 222 | ||
223 | if (edac_op_state == EDAC_OPSTATE_POLL) | 223 | if (edac_op_state == EDAC_OPSTATE_POLL) |
224 | pci->edac_check = mpc85xx_pci_check; | 224 | pci->edac_check = mpc85xx_pci_check; |
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c index 083ce8d0c63d..5131aaae8e03 100644 --- a/drivers/edac/mv64x60_edac.c +++ b/drivers/edac/mv64x60_edac.c | |||
@@ -121,7 +121,7 @@ static int __devinit mv64x60_pci_err_probe(struct platform_device *pdev) | |||
121 | pdata->irq = NO_IRQ; | 121 | pdata->irq = NO_IRQ; |
122 | platform_set_drvdata(pdev, pci); | 122 | platform_set_drvdata(pdev, pci); |
123 | pci->dev = &pdev->dev; | 123 | pci->dev = &pdev->dev; |
124 | pci->dev_name = pdev->dev.bus_id; | 124 | pci->dev_name = dev_name(&pdev->dev); |
125 | pci->mod_name = EDAC_MOD_STR; | 125 | pci->mod_name = EDAC_MOD_STR; |
126 | pci->ctl_name = pdata->name; | 126 | pci->ctl_name = pdata->name; |
127 | 127 | ||
@@ -294,7 +294,7 @@ static int __devinit mv64x60_sram_err_probe(struct platform_device *pdev) | |||
294 | pdata->irq = NO_IRQ; | 294 | pdata->irq = NO_IRQ; |
295 | edac_dev->dev = &pdev->dev; | 295 | edac_dev->dev = &pdev->dev; |
296 | platform_set_drvdata(pdev, edac_dev); | 296 | platform_set_drvdata(pdev, edac_dev); |
297 | edac_dev->dev_name = pdev->dev.bus_id; | 297 | edac_dev->dev_name = dev_name(&pdev->dev); |
298 | 298 | ||
299 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 299 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
300 | if (!r) { | 300 | if (!r) { |
@@ -462,7 +462,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev) | |||
462 | pdata->irq = NO_IRQ; | 462 | pdata->irq = NO_IRQ; |
463 | edac_dev->dev = &pdev->dev; | 463 | edac_dev->dev = &pdev->dev; |
464 | platform_set_drvdata(pdev, edac_dev); | 464 | platform_set_drvdata(pdev, edac_dev); |
465 | edac_dev->dev_name = pdev->dev.bus_id; | 465 | edac_dev->dev_name = dev_name(&pdev->dev); |
466 | 466 | ||
467 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 467 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
468 | if (!r) { | 468 | if (!r) { |
@@ -713,7 +713,7 @@ static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev) | |||
713 | platform_set_drvdata(pdev, mci); | 713 | platform_set_drvdata(pdev, mci); |
714 | pdata->name = "mv64x60_mc_err"; | 714 | pdata->name = "mv64x60_mc_err"; |
715 | pdata->irq = NO_IRQ; | 715 | pdata->irq = NO_IRQ; |
716 | mci->dev_name = pdev->dev.bus_id; | 716 | mci->dev_name = dev_name(&pdev->dev); |
717 | pdata->edac_idx = edac_mc_idx++; | 717 | pdata->edac_idx = edac_mc_idx++; |
718 | 718 | ||
719 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 719 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c index c950bf8606d9..66958b3f10b4 100644 --- a/drivers/eisa/eisa-bus.c +++ b/drivers/eisa/eisa-bus.c | |||
@@ -200,7 +200,7 @@ static int __init eisa_init_device (struct eisa_root_device *root, | |||
200 | edev->dev.bus = &eisa_bus_type; | 200 | edev->dev.bus = &eisa_bus_type; |
201 | edev->dev.dma_mask = &edev->dma_mask; | 201 | edev->dev.dma_mask = &edev->dma_mask; |
202 | edev->dev.coherent_dma_mask = edev->dma_mask; | 202 | edev->dev.coherent_dma_mask = edev->dma_mask; |
203 | sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot); | 203 | dev_set_name(&edev->dev, "%02X:%02X", root->bus_nr, slot); |
204 | 204 | ||
205 | for (i = 0; i < EISA_MAX_RESOURCES; i++) { | 205 | for (i = 0; i < EISA_MAX_RESOURCES; i++) { |
206 | #ifdef CONFIG_EISA_NAMES | 206 | #ifdef CONFIG_EISA_NAMES |
@@ -301,7 +301,7 @@ static int __init eisa_probe (struct eisa_root_device *root) | |||
301 | struct eisa_device *edev; | 301 | struct eisa_device *edev; |
302 | 302 | ||
303 | printk (KERN_INFO "EISA: Probing bus %d at %s\n", | 303 | printk (KERN_INFO "EISA: Probing bus %d at %s\n", |
304 | root->bus_nr, root->dev->bus_id); | 304 | root->bus_nr, dev_name(root->dev)); |
305 | 305 | ||
306 | /* First try to get hold of slot 0. If there is no device | 306 | /* First try to get hold of slot 0. If there is no device |
307 | * here, simply fail, unless root->force_probe is set. */ | 307 | * here, simply fail, unless root->force_probe is set. */ |
diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/bt8xxgpio.c index 7a1168249dd5..984b587f0f96 100644 --- a/drivers/gpio/bt8xxgpio.c +++ b/drivers/gpio/bt8xxgpio.c | |||
@@ -160,7 +160,7 @@ static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg) | |||
160 | { | 160 | { |
161 | struct gpio_chip *c = &bg->gpio; | 161 | struct gpio_chip *c = &bg->gpio; |
162 | 162 | ||
163 | c->label = bg->pdev->dev.bus_id; | 163 | c->label = dev_name(&bg->pdev->dev); |
164 | c->owner = THIS_MODULE; | 164 | c->owner = THIS_MODULE; |
165 | c->direction_input = bt8xxgpio_gpio_direction_input; | 165 | c->direction_input = bt8xxgpio_gpio_direction_input; |
166 | c->get = bt8xxgpio_gpio_get; | 166 | c->get = bt8xxgpio_gpio_get; |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 5aa6780652aa..186d08159d48 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -359,8 +359,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector) | |||
359 | DRM_DEBUG("adding \"%s\" to sysfs\n", | 359 | DRM_DEBUG("adding \"%s\" to sysfs\n", |
360 | drm_get_connector_name(connector)); | 360 | drm_get_connector_name(connector)); |
361 | 361 | ||
362 | snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s", | 362 | dev_set_name(&connector->kdev, "card%d-%s", |
363 | dev->primary->index, drm_get_connector_name(connector)); | 363 | dev->primary->index, drm_get_connector_name(connector)); |
364 | ret = device_register(&connector->kdev); | 364 | ret = device_register(&connector->kdev); |
365 | 365 | ||
366 | if (ret) { | 366 | if (ret) { |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e7d984866de0..fbb9030b68a5 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -841,7 +841,7 @@ int i2c_attach_client(struct i2c_client *client) | |||
841 | 841 | ||
842 | if (client->driver && !is_newstyle_driver(client->driver)) { | 842 | if (client->driver && !is_newstyle_driver(client->driver)) { |
843 | client->dev.release = i2c_client_release; | 843 | client->dev.release = i2c_client_release; |
844 | client->dev.uevent_suppress = 1; | 844 | dev_set_uevent_suppress(&client->dev, 1); |
845 | } else | 845 | } else |
846 | client->dev.release = i2c_client_dev_release; | 846 | client->dev.release = i2c_client_dev_release; |
847 | 847 | ||
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 5ea3bfad172a..640c99207242 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -56,8 +56,12 @@ if IDE | |||
56 | 56 | ||
57 | comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" | 57 | comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" |
58 | 58 | ||
59 | config IDE_XFER_MODE | ||
60 | bool | ||
61 | |||
59 | config IDE_TIMINGS | 62 | config IDE_TIMINGS |
60 | bool | 63 | bool |
64 | select IDE_XFER_MODE | ||
61 | 65 | ||
62 | config IDE_ATAPI | 66 | config IDE_ATAPI |
63 | bool | 67 | bool |
@@ -698,6 +702,7 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST | |||
698 | config BLK_DEV_IDE_AU1XXX | 702 | config BLK_DEV_IDE_AU1XXX |
699 | bool "IDE for AMD Alchemy Au1200" | 703 | bool "IDE for AMD Alchemy Au1200" |
700 | depends on SOC_AU1200 | 704 | depends on SOC_AU1200 |
705 | select IDE_XFER_MODE | ||
701 | choice | 706 | choice |
702 | prompt "IDE Mode for AMD Alchemy Au1200" | 707 | prompt "IDE Mode for AMD Alchemy Au1200" |
703 | default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA | 708 | default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA |
@@ -871,6 +876,7 @@ config BLK_DEV_ALI14XX | |||
871 | 876 | ||
872 | config BLK_DEV_DTC2278 | 877 | config BLK_DEV_DTC2278 |
873 | tristate "DTC-2278 support" | 878 | tristate "DTC-2278 support" |
879 | select IDE_XFER_MODE | ||
874 | select IDE_LEGACY | 880 | select IDE_LEGACY |
875 | help | 881 | help |
876 | This driver is enabled at runtime using the "dtc2278.probe" kernel | 882 | This driver is enabled at runtime using the "dtc2278.probe" kernel |
@@ -902,6 +908,7 @@ config BLK_DEV_QD65XX | |||
902 | 908 | ||
903 | config BLK_DEV_UMC8672 | 909 | config BLK_DEV_UMC8672 |
904 | tristate "UMC-8672 support" | 910 | tristate "UMC-8672 support" |
911 | select IDE_XFER_MODE | ||
905 | select IDE_LEGACY | 912 | select IDE_LEGACY |
906 | help | 913 | help |
907 | This driver is enabled at runtime using the "umc8672.probe" kernel | 914 | This driver is enabled at runtime using the "umc8672.probe" kernel |
@@ -915,5 +922,6 @@ endif | |||
915 | config BLK_DEV_IDEDMA | 922 | config BLK_DEV_IDEDMA |
916 | def_bool BLK_DEV_IDEDMA_SFF || \ | 923 | def_bool BLK_DEV_IDEDMA_SFF || \ |
917 | BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA | 924 | BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA |
925 | select IDE_XFER_MODE | ||
918 | 926 | ||
919 | endif # IDE | 927 | endif # IDE |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 1c326d94aa6d..9b4bbe1cdc1a 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
@@ -5,9 +5,11 @@ | |||
5 | EXTRA_CFLAGS += -Idrivers/ide | 5 | EXTRA_CFLAGS += -Idrivers/ide |
6 | 6 | ||
7 | ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ | 7 | ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ |
8 | ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o | 8 | ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \ |
9 | ide-io-std.o ide-eh.o | ||
9 | 10 | ||
10 | # core IDE code | 11 | # core IDE code |
12 | ide-core-$(CONFIG_IDE_XFER_MODE) += ide-pio-blacklist.o ide-xfer-mode.o | ||
11 | ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o | 13 | ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o |
12 | ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o | 14 | ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o |
13 | ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o | 15 | ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o |
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c index 4485b9c6f0e6..878f8ec6dbe1 100644 --- a/drivers/ide/aec62xx.c +++ b/drivers/ide/aec62xx.c | |||
@@ -139,7 +139,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
139 | drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0); | 139 | drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0); |
140 | } | 140 | } |
141 | 141 | ||
142 | static unsigned int init_chipset_aec62xx(struct pci_dev *dev) | 142 | static int init_chipset_aec62xx(struct pci_dev *dev) |
143 | { | 143 | { |
144 | /* These are necessary to get AEC6280 Macintosh cards to work */ | 144 | /* These are necessary to get AEC6280 Macintosh cards to work */ |
145 | if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) || | 145 | if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) || |
@@ -156,7 +156,7 @@ static unsigned int init_chipset_aec62xx(struct pci_dev *dev) | |||
156 | pci_write_config_byte(dev, 0x4a, reg4ah | 0x80); | 156 | pci_write_config_byte(dev, 0x4a, reg4ah | 0x80); |
157 | } | 157 | } |
158 | 158 | ||
159 | return dev->irq; | 159 | return 0; |
160 | } | 160 | } |
161 | 161 | ||
162 | static u8 atp86x_cable_detect(ide_hwif_t *hwif) | 162 | static u8 atp86x_cable_detect(ide_hwif_t *hwif) |
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 66f43083408b..d3513b6b8530 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c | |||
@@ -212,7 +212,7 @@ static int ali15x3_dma_setup(ide_drive_t *drive) | |||
212 | * appropriate also sets up the 1533 southbridge. | 212 | * appropriate also sets up the 1533 southbridge. |
213 | */ | 213 | */ |
214 | 214 | ||
215 | static unsigned int init_chipset_ali15x3(struct pci_dev *dev) | 215 | static int init_chipset_ali15x3(struct pci_dev *dev) |
216 | { | 216 | { |
217 | unsigned long flags; | 217 | unsigned long flags; |
218 | u8 tmpbyte; | 218 | u8 tmpbyte; |
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index 77267c859965..628cd2e5fed8 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c | |||
@@ -140,7 +140,7 @@ static void amd7411_cable_detect(struct pci_dev *dev) | |||
140 | * The initialization callback. Initialize drive independent registers. | 140 | * The initialization callback. Initialize drive independent registers. |
141 | */ | 141 | */ |
142 | 142 | ||
143 | static unsigned int init_chipset_amd74xx(struct pci_dev *dev) | 143 | static int init_chipset_amd74xx(struct pci_dev *dev) |
144 | { | 144 | { |
145 | u8 t = 0, offset = amd_offset(dev); | 145 | u8 t = 0, offset = amd_offset(dev); |
146 | 146 | ||
@@ -172,7 +172,7 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev) | |||
172 | t |= 0xf0; | 172 | t |= 0xf0; |
173 | pci_write_config_byte(dev, AMD_IDE_CONFIG + offset, t); | 173 | pci_write_config_byte(dev, AMD_IDE_CONFIG + offset, t); |
174 | 174 | ||
175 | return dev->irq; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | static u8 amd_cable_detect(ide_hwif_t *hwif) | 178 | static u8 amd_cable_detect(ide_hwif_t *hwif) |
@@ -183,14 +183,6 @@ static u8 amd_cable_detect(ide_hwif_t *hwif) | |||
183 | return ATA_CBL_PATA40; | 183 | return ATA_CBL_PATA40; |
184 | } | 184 | } |
185 | 185 | ||
186 | static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) | ||
187 | { | ||
188 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
189 | |||
190 | if (hwif->irq == 0) /* 0 is bogus but will do for now */ | ||
191 | hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel); | ||
192 | } | ||
193 | |||
194 | static const struct ide_port_ops amd_port_ops = { | 186 | static const struct ide_port_ops amd_port_ops = { |
195 | .set_pio_mode = amd_set_pio_mode, | 187 | .set_pio_mode = amd_set_pio_mode, |
196 | .set_dma_mode = amd_set_drive, | 188 | .set_dma_mode = amd_set_drive, |
@@ -207,7 +199,6 @@ static const struct ide_port_ops amd_port_ops = { | |||
207 | { \ | 199 | { \ |
208 | .name = DRV_NAME, \ | 200 | .name = DRV_NAME, \ |
209 | .init_chipset = init_chipset_amd74xx, \ | 201 | .init_chipset = init_chipset_amd74xx, \ |
210 | .init_hwif = init_hwif_amd74xx, \ | ||
211 | .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ | 202 | .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ |
212 | .port_ops = &amd_port_ops, \ | 203 | .port_ops = &amd_port_ops, \ |
213 | .host_flags = IDE_HFLAGS_AMD, \ | 204 | .host_flags = IDE_HFLAGS_AMD, \ |
@@ -221,7 +212,6 @@ static const struct ide_port_ops amd_port_ops = { | |||
221 | { \ | 212 | { \ |
222 | .name = DRV_NAME, \ | 213 | .name = DRV_NAME, \ |
223 | .init_chipset = init_chipset_amd74xx, \ | 214 | .init_chipset = init_chipset_amd74xx, \ |
224 | .init_hwif = init_hwif_amd74xx, \ | ||
225 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \ | 215 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \ |
226 | .port_ops = &amd_port_ops, \ | 216 | .port_ops = &amd_port_ops, \ |
227 | .host_flags = IDE_HFLAGS_AMD, \ | 217 | .host_flags = IDE_HFLAGS_AMD, \ |
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c index ecd1e62ca91a..923cbfe259d3 100644 --- a/drivers/ide/atiixp.c +++ b/drivers/ide/atiixp.c | |||
@@ -142,7 +142,6 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = { | |||
142 | .name = DRV_NAME, | 142 | .name = DRV_NAME, |
143 | .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, | 143 | .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, |
144 | .port_ops = &atiixp_port_ops, | 144 | .port_ops = &atiixp_port_ops, |
145 | .host_flags = IDE_HFLAG_LEGACY_IRQS, | ||
146 | .pio_mask = ATA_PIO4, | 145 | .pio_mask = ATA_PIO4, |
147 | .mwdma_mask = ATA_MWDMA2, | 146 | .mwdma_mask = ATA_MWDMA2, |
148 | .udma_mask = ATA_UDMA5, | 147 | .udma_mask = ATA_UDMA5, |
@@ -151,7 +150,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = { | |||
151 | .name = DRV_NAME, | 150 | .name = DRV_NAME, |
152 | .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, | 151 | .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, |
153 | .port_ops = &atiixp_port_ops, | 152 | .port_ops = &atiixp_port_ops, |
154 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS, | 153 | .host_flags = IDE_HFLAG_SINGLE, |
155 | .pio_mask = ATA_PIO4, | 154 | .pio_mask = ATA_PIO4, |
156 | .mwdma_mask = ATA_MWDMA2, | 155 | .mwdma_mask = ATA_MWDMA2, |
157 | .udma_mask = ATA_UDMA5, | 156 | .udma_mask = ATA_UDMA5, |
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c index 79a2dfed8eb7..154ec2cf734f 100644 --- a/drivers/ide/au1xxx-ide.c +++ b/drivers/ide/au1xxx-ide.c | |||
@@ -536,9 +536,8 @@ static const struct ide_port_info au1xxx_port_info = { | |||
536 | #endif | 536 | #endif |
537 | }; | 537 | }; |
538 | 538 | ||
539 | static int au_ide_probe(struct device *dev) | 539 | static int au_ide_probe(struct platform_device *dev) |
540 | { | 540 | { |
541 | struct platform_device *pdev = to_platform_device(dev); | ||
542 | _auide_hwif *ahwif = &auide_hwif; | 541 | _auide_hwif *ahwif = &auide_hwif; |
543 | struct resource *res; | 542 | struct resource *res; |
544 | struct ide_host *host; | 543 | struct ide_host *host; |
@@ -552,23 +551,23 @@ static int au_ide_probe(struct device *dev) | |||
552 | #endif | 551 | #endif |
553 | 552 | ||
554 | memset(&auide_hwif, 0, sizeof(_auide_hwif)); | 553 | memset(&auide_hwif, 0, sizeof(_auide_hwif)); |
555 | ahwif->irq = platform_get_irq(pdev, 0); | 554 | ahwif->irq = platform_get_irq(dev, 0); |
556 | 555 | ||
557 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 556 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
558 | 557 | ||
559 | if (res == NULL) { | 558 | if (res == NULL) { |
560 | pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id); | 559 | pr_debug("%s %d: no base address\n", DRV_NAME, dev->id); |
561 | ret = -ENODEV; | 560 | ret = -ENODEV; |
562 | goto out; | 561 | goto out; |
563 | } | 562 | } |
564 | if (ahwif->irq < 0) { | 563 | if (ahwif->irq < 0) { |
565 | pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id); | 564 | pr_debug("%s %d: no IRQ\n", DRV_NAME, dev->id); |
566 | ret = -ENODEV; | 565 | ret = -ENODEV; |
567 | goto out; | 566 | goto out; |
568 | } | 567 | } |
569 | 568 | ||
570 | if (!request_mem_region(res->start, res->end - res->start + 1, | 569 | if (!request_mem_region(res->start, res->end - res->start + 1, |
571 | pdev->name)) { | 570 | dev->name)) { |
572 | pr_debug("%s: request_mem_region failed\n", DRV_NAME); | 571 | pr_debug("%s: request_mem_region failed\n", DRV_NAME); |
573 | ret = -EBUSY; | 572 | ret = -EBUSY; |
574 | goto out; | 573 | goto out; |
@@ -583,7 +582,7 @@ static int au_ide_probe(struct device *dev) | |||
583 | memset(&hw, 0, sizeof(hw)); | 582 | memset(&hw, 0, sizeof(hw)); |
584 | auide_setup_ports(&hw, ahwif); | 583 | auide_setup_ports(&hw, ahwif); |
585 | hw.irq = ahwif->irq; | 584 | hw.irq = ahwif->irq; |
586 | hw.dev = dev; | 585 | hw.dev = &dev->dev; |
587 | hw.chipset = ide_au1xxx; | 586 | hw.chipset = ide_au1xxx; |
588 | 587 | ||
589 | ret = ide_host_add(&au1xxx_port_info, hws, &host); | 588 | ret = ide_host_add(&au1xxx_port_info, hws, &host); |
@@ -592,7 +591,7 @@ static int au_ide_probe(struct device *dev) | |||
592 | 591 | ||
593 | auide_hwif.hwif = host->ports[0]; | 592 | auide_hwif.hwif = host->ports[0]; |
594 | 593 | ||
595 | dev_set_drvdata(dev, host); | 594 | platform_set_drvdata(dev, host); |
596 | 595 | ||
597 | printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); | 596 | printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); |
598 | 597 | ||
@@ -600,38 +599,39 @@ static int au_ide_probe(struct device *dev) | |||
600 | return ret; | 599 | return ret; |
601 | } | 600 | } |
602 | 601 | ||
603 | static int au_ide_remove(struct device *dev) | 602 | static int au_ide_remove(struct platform_device *dev) |
604 | { | 603 | { |
605 | struct platform_device *pdev = to_platform_device(dev); | ||
606 | struct resource *res; | 604 | struct resource *res; |
607 | struct ide_host *host = dev_get_drvdata(dev); | 605 | struct ide_host *host = platform_get_drvdata(dev); |
608 | _auide_hwif *ahwif = &auide_hwif; | 606 | _auide_hwif *ahwif = &auide_hwif; |
609 | 607 | ||
610 | ide_host_remove(host); | 608 | ide_host_remove(host); |
611 | 609 | ||
612 | iounmap((void *)ahwif->regbase); | 610 | iounmap((void *)ahwif->regbase); |
613 | 611 | ||
614 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 612 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
615 | release_mem_region(res->start, res->end - res->start + 1); | 613 | release_mem_region(res->start, res->end - res->start + 1); |
616 | 614 | ||
617 | return 0; | 615 | return 0; |
618 | } | 616 | } |
619 | 617 | ||
620 | static struct device_driver au1200_ide_driver = { | 618 | static struct platform_driver au1200_ide_driver = { |
621 | .name = "au1200-ide", | 619 | .driver = { |
622 | .bus = &platform_bus_type, | 620 | .name = "au1200-ide", |
621 | .owner = THIS_MODULE, | ||
622 | }, | ||
623 | .probe = au_ide_probe, | 623 | .probe = au_ide_probe, |
624 | .remove = au_ide_remove, | 624 | .remove = au_ide_remove, |
625 | }; | 625 | }; |
626 | 626 | ||
627 | static int __init au_ide_init(void) | 627 | static int __init au_ide_init(void) |
628 | { | 628 | { |
629 | return driver_register(&au1200_ide_driver); | 629 | return platform_driver_register(&au1200_ide_driver); |
630 | } | 630 | } |
631 | 631 | ||
632 | static void __exit au_ide_exit(void) | 632 | static void __exit au_ide_exit(void) |
633 | { | 633 | { |
634 | driver_unregister(&au1200_ide_driver); | 634 | platform_driver_unregister(&au1200_ide_driver); |
635 | } | 635 | } |
636 | 636 | ||
637 | MODULE_LICENSE("GPL"); | 637 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 2f9688d87ecd..aeee036b1503 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c | |||
@@ -333,7 +333,7 @@ static int cmd646_1_dma_end(ide_drive_t *drive) | |||
333 | return (dma_stat & 7) != 4; | 333 | return (dma_stat & 7) != 4; |
334 | } | 334 | } |
335 | 335 | ||
336 | static unsigned int init_chipset_cmd64x(struct pci_dev *dev) | 336 | static int init_chipset_cmd64x(struct pci_dev *dev) |
337 | { | 337 | { |
338 | u8 mrdmode = 0; | 338 | u8 mrdmode = 0; |
339 | 339 | ||
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c index d003bec56ff9..58fb90e5b763 100644 --- a/drivers/ide/cs5520.c +++ b/drivers/ide/cs5520.c | |||
@@ -133,7 +133,8 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic | |||
133 | * do all the device setup for us | 133 | * do all the device setup for us |
134 | */ | 134 | */ |
135 | 135 | ||
136 | ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]); | 136 | ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); |
137 | hw[0].irq = 14; | ||
137 | 138 | ||
138 | return ide_host_add(d, hws, NULL); | 139 | return ide_host_add(d, hws, NULL); |
139 | } | 140 | } |
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c index d8ede85fe17f..8e8b35a89901 100644 --- a/drivers/ide/cs5530.c +++ b/drivers/ide/cs5530.c | |||
@@ -135,7 +135,7 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
135 | * Initialize the cs5530 bridge for reliable IDE DMA operation. | 135 | * Initialize the cs5530 bridge for reliable IDE DMA operation. |
136 | */ | 136 | */ |
137 | 137 | ||
138 | static unsigned int init_chipset_cs5530(struct pci_dev *dev) | 138 | static int init_chipset_cs5530(struct pci_dev *dev) |
139 | { | 139 | { |
140 | struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; | 140 | struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; |
141 | 141 | ||
diff --git a/drivers/ide/delkin_cb.c b/drivers/ide/delkin_cb.c index 8f1b2d9f0513..bacb1194c9c9 100644 --- a/drivers/ide/delkin_cb.c +++ b/drivers/ide/delkin_cb.c | |||
@@ -46,7 +46,7 @@ static const struct ide_port_ops delkin_cb_port_ops = { | |||
46 | .quirkproc = ide_undecoded_slave, | 46 | .quirkproc = ide_undecoded_slave, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static unsigned int delkin_cb_init_chipset(struct pci_dev *dev) | 49 | static int delkin_cb_init_chipset(struct pci_dev *dev) |
50 | { | 50 | { |
51 | unsigned long base = pci_resource_start(dev, 0); | 51 | unsigned long base = pci_resource_start(dev, 0); |
52 | int i; | 52 | int i; |
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index 3eb9b5c63a0f..d3b3e824f445 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c | |||
@@ -995,7 +995,7 @@ static void hpt3xx_disable_fast_irq(struct pci_dev *dev, u8 mcr_addr) | |||
995 | pci_write_config_byte(dev, mcr_addr + 1, new_mcr); | 995 | pci_write_config_byte(dev, mcr_addr + 1, new_mcr); |
996 | } | 996 | } |
997 | 997 | ||
998 | static unsigned int init_chipset_hpt366(struct pci_dev *dev) | 998 | static int init_chipset_hpt366(struct pci_dev *dev) |
999 | { | 999 | { |
1000 | unsigned long io_base = pci_resource_start(dev, 4); | 1000 | unsigned long io_base = pci_resource_start(dev, 4); |
1001 | struct hpt_info *info = hpt3xx_get_info(&dev->dev); | 1001 | struct hpt_info *info = hpt3xx_get_info(&dev->dev); |
@@ -1237,7 +1237,7 @@ static unsigned int init_chipset_hpt366(struct pci_dev *dev) | |||
1237 | hpt3xx_disable_fast_irq(dev, 0x50); | 1237 | hpt3xx_disable_fast_irq(dev, 0x50); |
1238 | hpt3xx_disable_fast_irq(dev, 0x54); | 1238 | hpt3xx_disable_fast_irq(dev, 0x54); |
1239 | 1239 | ||
1240 | return dev->irq; | 1240 | return 0; |
1241 | } | 1241 | } |
1242 | 1242 | ||
1243 | static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) | 1243 | static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) |
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index ec7d07fa570a..5b704f1ea90c 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
@@ -20,9 +20,6 @@ | |||
20 | #include <acpi/acpi_bus.h> | 20 | #include <acpi/acpi_bus.h> |
21 | 21 | ||
22 | #define REGS_PER_GTF 7 | 22 | #define REGS_PER_GTF 7 |
23 | struct taskfile_array { | ||
24 | u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ | ||
25 | }; | ||
26 | 23 | ||
27 | struct GTM_buffer { | 24 | struct GTM_buffer { |
28 | u32 PIO_speed0; | 25 | u32 PIO_speed0; |
@@ -89,12 +86,8 @@ static const struct dmi_system_id ide_acpi_dmi_table[] = { | |||
89 | { } /* terminate list */ | 86 | { } /* terminate list */ |
90 | }; | 87 | }; |
91 | 88 | ||
92 | static int ide_acpi_blacklist(void) | 89 | int ide_acpi_init(void) |
93 | { | 90 | { |
94 | static int done; | ||
95 | if (done) | ||
96 | return 0; | ||
97 | done = 1; | ||
98 | dmi_check_system(ide_acpi_dmi_table); | 91 | dmi_check_system(ide_acpi_dmi_table); |
99 | return 0; | 92 | return 0; |
100 | } | 93 | } |
@@ -202,40 +195,6 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) | |||
202 | } | 195 | } |
203 | 196 | ||
204 | /** | 197 | /** |
205 | * ide_acpi_drive_get_handle - Get ACPI object handle for a given drive | ||
206 | * @drive: device to locate | ||
207 | * | ||
208 | * Retrieves the object handle of a given drive. According to the ACPI | ||
209 | * spec the drive is a child of the hwif. | ||
210 | * | ||
211 | * Returns handle on success, 0 on error. | ||
212 | */ | ||
213 | static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive) | ||
214 | { | ||
215 | ide_hwif_t *hwif = drive->hwif; | ||
216 | int port; | ||
217 | acpi_handle drive_handle; | ||
218 | |||
219 | if (!hwif->acpidata) | ||
220 | return NULL; | ||
221 | |||
222 | if (!hwif->acpidata->obj_handle) | ||
223 | return NULL; | ||
224 | |||
225 | port = hwif->channel ? drive->dn - 2: drive->dn; | ||
226 | |||
227 | DEBPRINT("ENTER: %s at channel#: %d port#: %d\n", | ||
228 | drive->name, hwif->channel, port); | ||
229 | |||
230 | |||
231 | /* TBD: could also check ACPI object VALID bits */ | ||
232 | drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port); | ||
233 | DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle); | ||
234 | |||
235 | return drive_handle; | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * do_drive_get_GTF - get the drive bootup default taskfile settings | 198 | * do_drive_get_GTF - get the drive bootup default taskfile settings |
240 | * @drive: the drive for which the taskfile settings should be retrieved | 199 | * @drive: the drive for which the taskfile settings should be retrieved |
241 | * @gtf_length: number of bytes of _GTF data returned at @gtf_address | 200 | * @gtf_length: number of bytes of _GTF data returned at @gtf_address |
@@ -257,47 +216,15 @@ static int do_drive_get_GTF(ide_drive_t *drive, | |||
257 | acpi_status status; | 216 | acpi_status status; |
258 | struct acpi_buffer output; | 217 | struct acpi_buffer output; |
259 | union acpi_object *out_obj; | 218 | union acpi_object *out_obj; |
260 | ide_hwif_t *hwif = drive->hwif; | ||
261 | struct device *dev = hwif->gendev.parent; | ||
262 | int err = -ENODEV; | 219 | int err = -ENODEV; |
263 | int port; | ||
264 | 220 | ||
265 | *gtf_length = 0; | 221 | *gtf_length = 0; |
266 | *gtf_address = 0UL; | 222 | *gtf_address = 0UL; |
267 | *obj_loc = 0UL; | 223 | *obj_loc = 0UL; |
268 | 224 | ||
269 | if (ide_noacpi) | ||
270 | return 0; | ||
271 | |||
272 | if (!dev) { | ||
273 | DEBPRINT("no PCI device for %s\n", hwif->name); | ||
274 | goto out; | ||
275 | } | ||
276 | |||
277 | if (!hwif->acpidata) { | ||
278 | DEBPRINT("no ACPI data for %s\n", hwif->name); | ||
279 | goto out; | ||
280 | } | ||
281 | |||
282 | port = hwif->channel ? drive->dn - 2: drive->dn; | ||
283 | |||
284 | DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n", | ||
285 | hwif->name, dev_name(dev), port, hwif->channel); | ||
286 | |||
287 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) { | ||
288 | DEBPRINT("%s drive %d:%d not present\n", | ||
289 | hwif->name, hwif->channel, port); | ||
290 | goto out; | ||
291 | } | ||
292 | |||
293 | /* Get this drive's _ADR info. if not already known. */ | ||
294 | if (!drive->acpidata->obj_handle) { | 225 | if (!drive->acpidata->obj_handle) { |
295 | drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); | 226 | DEBPRINT("No ACPI object found for %s\n", drive->name); |
296 | if (!drive->acpidata->obj_handle) { | 227 | goto out; |
297 | DEBPRINT("No ACPI object found for %s\n", | ||
298 | drive->name); | ||
299 | goto out; | ||
300 | } | ||
301 | } | 228 | } |
302 | 229 | ||
303 | /* Setting up output buffer */ | 230 | /* Setting up output buffer */ |
@@ -355,43 +282,6 @@ out: | |||
355 | } | 282 | } |
356 | 283 | ||
357 | /** | 284 | /** |
358 | * taskfile_load_raw - send taskfile registers to drive | ||
359 | * @drive: drive to which output is sent | ||
360 | * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) | ||
361 | * | ||
362 | * Outputs IDE taskfile to the drive. | ||
363 | */ | ||
364 | static int taskfile_load_raw(ide_drive_t *drive, | ||
365 | const struct taskfile_array *gtf) | ||
366 | { | ||
367 | ide_task_t args; | ||
368 | int err = 0; | ||
369 | |||
370 | DEBPRINT("(0x1f1-1f7): hex: " | ||
371 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
372 | gtf->tfa[0], gtf->tfa[1], gtf->tfa[2], | ||
373 | gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]); | ||
374 | |||
375 | memset(&args, 0, sizeof(ide_task_t)); | ||
376 | |||
377 | /* convert gtf to IDE Taskfile */ | ||
378 | memcpy(&args.tf_array[7], >f->tfa, 7); | ||
379 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | ||
380 | |||
381 | if (!ide_acpigtf) { | ||
382 | DEBPRINT("_GTF execution disabled\n"); | ||
383 | return err; | ||
384 | } | ||
385 | |||
386 | err = ide_no_data_taskfile(drive, &args); | ||
387 | if (err) | ||
388 | printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n", | ||
389 | __func__, err); | ||
390 | |||
391 | return err; | ||
392 | } | ||
393 | |||
394 | /** | ||
395 | * do_drive_set_taskfiles - write the drive taskfile settings from _GTF | 285 | * do_drive_set_taskfiles - write the drive taskfile settings from _GTF |
396 | * @drive: the drive to which the taskfile command should be sent | 286 | * @drive: the drive to which the taskfile command should be sent |
397 | * @gtf_length: total number of bytes of _GTF taskfiles | 287 | * @gtf_length: total number of bytes of _GTF taskfiles |
@@ -404,43 +294,41 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, | |||
404 | unsigned int gtf_length, | 294 | unsigned int gtf_length, |
405 | unsigned long gtf_address) | 295 | unsigned long gtf_address) |
406 | { | 296 | { |
407 | int rc = -ENODEV, err; | 297 | int rc = 0, err; |
408 | int gtf_count = gtf_length / REGS_PER_GTF; | 298 | int gtf_count = gtf_length / REGS_PER_GTF; |
409 | int ix; | 299 | int ix; |
410 | struct taskfile_array *gtf; | ||
411 | |||
412 | if (ide_noacpi) | ||
413 | return 0; | ||
414 | |||
415 | DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn); | ||
416 | |||
417 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | ||
418 | goto out; | ||
419 | |||
420 | if (!gtf_count) /* shouldn't be here */ | ||
421 | goto out; | ||
422 | 300 | ||
423 | DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n", | 301 | DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n", |
424 | gtf_length, gtf_length, gtf_count, gtf_address); | 302 | gtf_length, gtf_length, gtf_count, gtf_address); |
425 | 303 | ||
426 | if (gtf_length % REGS_PER_GTF) { | 304 | /* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */ |
427 | printk(KERN_ERR "%s: unexpected GTF length (%d)\n", | ||
428 | __func__, gtf_length); | ||
429 | goto out; | ||
430 | } | ||
431 | |||
432 | rc = 0; | ||
433 | for (ix = 0; ix < gtf_count; ix++) { | 305 | for (ix = 0; ix < gtf_count; ix++) { |
434 | gtf = (struct taskfile_array *) | 306 | u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF); |
435 | (gtf_address + ix * REGS_PER_GTF); | 307 | ide_task_t task; |
436 | 308 | ||
437 | /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ | 309 | DEBPRINT("(0x1f1-1f7): " |
438 | err = taskfile_load_raw(drive, gtf); | 310 | "hex: %02x %02x %02x %02x %02x %02x %02x\n", |
439 | if (err) | 311 | gtf[0], gtf[1], gtf[2], |
312 | gtf[3], gtf[4], gtf[5], gtf[6]); | ||
313 | |||
314 | if (!ide_acpigtf) { | ||
315 | DEBPRINT("_GTF execution disabled\n"); | ||
316 | continue; | ||
317 | } | ||
318 | |||
319 | /* convert GTF to taskfile */ | ||
320 | memset(&task, 0, sizeof(ide_task_t)); | ||
321 | memcpy(&task.tf_array[7], gtf, REGS_PER_GTF); | ||
322 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | ||
323 | |||
324 | err = ide_no_data_taskfile(drive, &task); | ||
325 | if (err) { | ||
326 | printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n", | ||
327 | __func__, err); | ||
440 | rc = err; | 328 | rc = err; |
329 | } | ||
441 | } | 330 | } |
442 | 331 | ||
443 | out: | ||
444 | return rc; | 332 | return rc; |
445 | } | 333 | } |
446 | 334 | ||
@@ -647,26 +535,23 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) | |||
647 | DEBPRINT("no ACPI data for %s\n", hwif->name); | 535 | DEBPRINT("no ACPI data for %s\n", hwif->name); |
648 | return; | 536 | return; |
649 | } | 537 | } |
538 | |||
650 | /* channel first and then drives for power on and verse versa for power off */ | 539 | /* channel first and then drives for power on and verse versa for power off */ |
651 | if (on) | 540 | if (on) |
652 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); | 541 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); |
653 | 542 | ||
654 | ide_port_for_each_dev(i, drive, hwif) { | 543 | ide_port_for_each_present_dev(i, drive, hwif) { |
655 | if (!drive->acpidata->obj_handle) | 544 | if (drive->acpidata->obj_handle) |
656 | drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); | ||
657 | |||
658 | if (drive->acpidata->obj_handle && | ||
659 | (drive->dev_flags & IDE_DFLAG_PRESENT)) { | ||
660 | acpi_bus_set_power(drive->acpidata->obj_handle, | 545 | acpi_bus_set_power(drive->acpidata->obj_handle, |
661 | on? ACPI_STATE_D0: ACPI_STATE_D3); | 546 | on ? ACPI_STATE_D0 : ACPI_STATE_D3); |
662 | } | ||
663 | } | 547 | } |
548 | |||
664 | if (!on) | 549 | if (!on) |
665 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3); | 550 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3); |
666 | } | 551 | } |
667 | 552 | ||
668 | /** | 553 | /** |
669 | * ide_acpi_init - initialize the ACPI link for an IDE interface | 554 | * ide_acpi_init_port - initialize the ACPI link for an IDE interface |
670 | * @hwif: target IDE interface (channel) | 555 | * @hwif: target IDE interface (channel) |
671 | * | 556 | * |
672 | * The ACPI spec is not quite clear when the drive identify buffer | 557 | * The ACPI spec is not quite clear when the drive identify buffer |
@@ -676,10 +561,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) | |||
676 | * So we get the information during startup; but this means that | 561 | * So we get the information during startup; but this means that |
677 | * any changes during run-time will be lost after resume. | 562 | * any changes during run-time will be lost after resume. |
678 | */ | 563 | */ |
679 | void ide_acpi_init(ide_hwif_t *hwif) | 564 | void ide_acpi_init_port(ide_hwif_t *hwif) |
680 | { | 565 | { |
681 | ide_acpi_blacklist(); | ||
682 | |||
683 | hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL); | 566 | hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL); |
684 | if (!hwif->acpidata) | 567 | if (!hwif->acpidata) |
685 | return; | 568 | return; |
@@ -708,15 +591,24 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) | |||
708 | hwif->devices[0]->acpidata = &hwif->acpidata->master; | 591 | hwif->devices[0]->acpidata = &hwif->acpidata->master; |
709 | hwif->devices[1]->acpidata = &hwif->acpidata->slave; | 592 | hwif->devices[1]->acpidata = &hwif->acpidata->slave; |
710 | 593 | ||
711 | /* | 594 | /* get _ADR info for each device */ |
712 | * Send IDENTIFY for each drive | 595 | ide_port_for_each_present_dev(i, drive, hwif) { |
713 | */ | 596 | acpi_handle dev_handle; |
714 | ide_port_for_each_dev(i, drive, hwif) { | ||
715 | memset(drive->acpidata, 0, sizeof(*drive->acpidata)); | ||
716 | 597 | ||
717 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | 598 | DEBPRINT("ENTER: %s at channel#: %d port#: %d\n", |
718 | continue; | 599 | drive->name, hwif->channel, drive->dn & 1); |
600 | |||
601 | /* TBD: could also check ACPI object VALID bits */ | ||
602 | dev_handle = acpi_get_child(hwif->acpidata->obj_handle, | ||
603 | drive->dn & 1); | ||
604 | |||
605 | DEBPRINT("drive %s handle 0x%p\n", drive->name, dev_handle); | ||
606 | |||
607 | drive->acpidata->obj_handle = dev_handle; | ||
608 | } | ||
719 | 609 | ||
610 | /* send IDENTIFY for each device */ | ||
611 | ide_port_for_each_present_dev(i, drive, hwif) { | ||
720 | err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff); | 612 | err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff); |
721 | if (err) | 613 | if (err) |
722 | DEBPRINT("identify device %s failed (%d)\n", | 614 | DEBPRINT("identify device %s failed (%d)\n", |
@@ -736,9 +628,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) | |||
736 | ide_acpi_get_timing(hwif); | 628 | ide_acpi_get_timing(hwif); |
737 | ide_acpi_push_timing(hwif); | 629 | ide_acpi_push_timing(hwif); |
738 | 630 | ||
739 | ide_port_for_each_dev(i, drive, hwif) { | 631 | ide_port_for_each_present_dev(i, drive, hwif) { |
740 | if (drive->dev_flags & IDE_DFLAG_PRESENT) | 632 | ide_acpi_exec_tfs(drive); |
741 | /* Execute ACPI startup code */ | ||
742 | ide_acpi_exec_tfs(drive); | ||
743 | } | 633 | } |
744 | } | 634 | } |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index e9d042dba0e0..6adc5b4a4406 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
@@ -149,7 +149,10 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, | |||
149 | memcpy(rq->cmd, pc->c, 12); | 149 | memcpy(rq->cmd, pc->c, 12); |
150 | if (drive->media == ide_tape) | 150 | if (drive->media == ide_tape) |
151 | rq->cmd[13] = REQ_IDETAPE_PC1; | 151 | rq->cmd[13] = REQ_IDETAPE_PC1; |
152 | ide_do_drive_cmd(drive, rq); | 152 | |
153 | drive->hwif->rq = NULL; | ||
154 | |||
155 | elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); | ||
153 | } | 156 | } |
154 | 157 | ||
155 | /* | 158 | /* |
@@ -297,6 +300,21 @@ int ide_cd_get_xferlen(struct request *rq) | |||
297 | } | 300 | } |
298 | EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); | 301 | EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); |
299 | 302 | ||
303 | void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) | ||
304 | { | ||
305 | ide_task_t task; | ||
306 | |||
307 | memset(&task, 0, sizeof(task)); | ||
308 | task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | | ||
309 | IDE_TFLAG_IN_NSECT; | ||
310 | |||
311 | drive->hwif->tp_ops->tf_read(drive, &task); | ||
312 | |||
313 | *bcount = (task.tf.lbah << 8) | task.tf.lbam; | ||
314 | *ireason = task.tf.nsect & 3; | ||
315 | } | ||
316 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); | ||
317 | |||
300 | /* | 318 | /* |
301 | * This is the usual interrupt handler which will be called during a packet | 319 | * This is the usual interrupt handler which will be called during a packet |
302 | * command. We will transfer some of the data (as requested by the drive) | 320 | * command. We will transfer some of the data (as requested by the drive) |
@@ -456,6 +474,25 @@ next_irq: | |||
456 | return ide_started; | 474 | return ide_started; |
457 | } | 475 | } |
458 | 476 | ||
477 | static void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount) | ||
478 | { | ||
479 | ide_hwif_t *hwif = drive->hwif; | ||
480 | ide_task_t task; | ||
481 | u8 dma = drive->dma; | ||
482 | |||
483 | memset(&task, 0, sizeof(task)); | ||
484 | task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | | ||
485 | IDE_TFLAG_OUT_FEATURE | tf_flags; | ||
486 | task.tf.feature = dma; /* Use PIO/DMA */ | ||
487 | task.tf.lbam = bcount & 0xff; | ||
488 | task.tf.lbah = (bcount >> 8) & 0xff; | ||
489 | |||
490 | ide_tf_dump(drive->name, &task.tf); | ||
491 | hwif->tp_ops->set_irq(hwif, 1); | ||
492 | SELECT_MASK(drive, 0); | ||
493 | hwif->tp_ops->tf_load(drive, &task); | ||
494 | } | ||
495 | |||
459 | static u8 ide_read_ireason(ide_drive_t *drive) | 496 | static u8 ide_read_ireason(ide_drive_t *drive) |
460 | { | 497 | { |
461 | ide_task_t task; | 498 | ide_task_t task; |
@@ -629,7 +666,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive) | |||
629 | : WAIT_TAPE_CMD; | 666 | : WAIT_TAPE_CMD; |
630 | } | 667 | } |
631 | 668 | ||
632 | ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); | 669 | ide_pktcmd_tf_load(drive, tf_flags, bcount); |
633 | 670 | ||
634 | /* Issue the packet command */ | 671 | /* Issue the packet command */ |
635 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { | 672 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ddfbea41d296..2177cd11664c 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -242,7 +242,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, | |||
242 | ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", | 242 | ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", |
243 | failed_command->cmd[0]); | 243 | failed_command->cmd[0]); |
244 | 244 | ||
245 | ide_do_drive_cmd(drive, rq); | 245 | drive->hwif->rq = NULL; |
246 | |||
247 | elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); | ||
246 | } | 248 | } |
247 | 249 | ||
248 | static void cdrom_end_request(ide_drive_t *drive, int uptodate) | 250 | static void cdrom_end_request(ide_drive_t *drive, int uptodate) |
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c new file mode 100644 index 000000000000..7c3953414d47 --- /dev/null +++ b/drivers/ide/ide-devsets.c | |||
@@ -0,0 +1,190 @@ | |||
1 | |||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/ide.h> | ||
4 | |||
5 | DEFINE_MUTEX(ide_setting_mtx); | ||
6 | |||
7 | ide_devset_get(io_32bit, io_32bit); | ||
8 | |||
9 | static int set_io_32bit(ide_drive_t *drive, int arg) | ||
10 | { | ||
11 | if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) | ||
12 | return -EPERM; | ||
13 | |||
14 | if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) | ||
15 | return -EINVAL; | ||
16 | |||
17 | drive->io_32bit = arg; | ||
18 | |||
19 | return 0; | ||
20 | } | ||
21 | |||
22 | ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS); | ||
23 | |||
24 | static int set_ksettings(ide_drive_t *drive, int arg) | ||
25 | { | ||
26 | if (arg < 0 || arg > 1) | ||
27 | return -EINVAL; | ||
28 | |||
29 | if (arg) | ||
30 | drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS; | ||
31 | else | ||
32 | drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS; | ||
33 | |||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA); | ||
38 | |||
39 | static int set_using_dma(ide_drive_t *drive, int arg) | ||
40 | { | ||
41 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
42 | int err = -EPERM; | ||
43 | |||
44 | if (arg < 0 || arg > 1) | ||
45 | return -EINVAL; | ||
46 | |||
47 | if (ata_id_has_dma(drive->id) == 0) | ||
48 | goto out; | ||
49 | |||
50 | if (drive->hwif->dma_ops == NULL) | ||
51 | goto out; | ||
52 | |||
53 | err = 0; | ||
54 | |||
55 | if (arg) { | ||
56 | if (ide_set_dma(drive)) | ||
57 | err = -EIO; | ||
58 | } else | ||
59 | ide_dma_off(drive); | ||
60 | |||
61 | out: | ||
62 | return err; | ||
63 | #else | ||
64 | if (arg < 0 || arg > 1) | ||
65 | return -EINVAL; | ||
66 | |||
67 | return -EPERM; | ||
68 | #endif | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away | ||
73 | */ | ||
74 | static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) | ||
75 | { | ||
76 | switch (req_pio) { | ||
77 | case 202: | ||
78 | case 201: | ||
79 | case 200: | ||
80 | case 102: | ||
81 | case 101: | ||
82 | case 100: | ||
83 | return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; | ||
84 | case 9: | ||
85 | case 8: | ||
86 | return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; | ||
87 | case 7: | ||
88 | case 6: | ||
89 | return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; | ||
90 | default: | ||
91 | return 0; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static int set_pio_mode(ide_drive_t *drive, int arg) | ||
96 | { | ||
97 | ide_hwif_t *hwif = drive->hwif; | ||
98 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
99 | |||
100 | if (arg < 0 || arg > 255) | ||
101 | return -EINVAL; | ||
102 | |||
103 | if (port_ops == NULL || port_ops->set_pio_mode == NULL || | ||
104 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
105 | return -ENOSYS; | ||
106 | |||
107 | if (set_pio_mode_abuse(drive->hwif, arg)) { | ||
108 | if (arg == 8 || arg == 9) { | ||
109 | unsigned long flags; | ||
110 | |||
111 | /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ | ||
112 | spin_lock_irqsave(&hwif->lock, flags); | ||
113 | port_ops->set_pio_mode(drive, arg); | ||
114 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
115 | } else | ||
116 | port_ops->set_pio_mode(drive, arg); | ||
117 | } else { | ||
118 | int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | ||
119 | |||
120 | ide_set_pio(drive, arg); | ||
121 | |||
122 | if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { | ||
123 | if (keep_dma) | ||
124 | ide_dma_on(drive); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK); | ||
132 | |||
133 | static int set_unmaskirq(ide_drive_t *drive, int arg) | ||
134 | { | ||
135 | if (drive->dev_flags & IDE_DFLAG_NO_UNMASK) | ||
136 | return -EPERM; | ||
137 | |||
138 | if (arg < 0 || arg > 1) | ||
139 | return -EINVAL; | ||
140 | |||
141 | if (arg) | ||
142 | drive->dev_flags |= IDE_DFLAG_UNMASK; | ||
143 | else | ||
144 | drive->dev_flags &= ~IDE_DFLAG_UNMASK; | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | ide_ext_devset_rw_sync(io_32bit, io_32bit); | ||
150 | ide_ext_devset_rw_sync(keepsettings, ksettings); | ||
151 | ide_ext_devset_rw_sync(unmaskirq, unmaskirq); | ||
152 | ide_ext_devset_rw_sync(using_dma, using_dma); | ||
153 | __IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode); | ||
154 | |||
155 | int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting, | ||
156 | int arg) | ||
157 | { | ||
158 | struct request_queue *q = drive->queue; | ||
159 | struct request *rq; | ||
160 | int ret = 0; | ||
161 | |||
162 | if (!(setting->flags & DS_SYNC)) | ||
163 | return setting->set(drive, arg); | ||
164 | |||
165 | rq = blk_get_request(q, READ, __GFP_WAIT); | ||
166 | rq->cmd_type = REQ_TYPE_SPECIAL; | ||
167 | rq->cmd_len = 5; | ||
168 | rq->cmd[0] = REQ_DEVSET_EXEC; | ||
169 | *(int *)&rq->cmd[1] = arg; | ||
170 | rq->special = setting->set; | ||
171 | |||
172 | if (blk_execute_rq(q, NULL, rq, 0)) | ||
173 | ret = rq->errors; | ||
174 | blk_put_request(rq); | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq) | ||
180 | { | ||
181 | int err, (*setfunc)(ide_drive_t *, int) = rq->special; | ||
182 | |||
183 | err = setfunc(drive, *(int *)&rq->cmd[1]); | ||
184 | if (err) | ||
185 | rq->errors = err; | ||
186 | else | ||
187 | err = 1; | ||
188 | ide_end_request(drive, err, 0); | ||
189 | return ide_stopped; | ||
190 | } | ||
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 059c90bb5ad2..a878f4734f81 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -470,6 +470,63 @@ void ide_dma_timeout(ide_drive_t *drive) | |||
470 | } | 470 | } |
471 | EXPORT_SYMBOL_GPL(ide_dma_timeout); | 471 | EXPORT_SYMBOL_GPL(ide_dma_timeout); |
472 | 472 | ||
473 | /* | ||
474 | * un-busy the port etc, and clear any pending DMA status. we want to | ||
475 | * retry the current request in pio mode instead of risking tossing it | ||
476 | * all away | ||
477 | */ | ||
478 | ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | ||
479 | { | ||
480 | ide_hwif_t *hwif = drive->hwif; | ||
481 | struct request *rq; | ||
482 | ide_startstop_t ret = ide_stopped; | ||
483 | |||
484 | /* | ||
485 | * end current dma transaction | ||
486 | */ | ||
487 | |||
488 | if (error < 0) { | ||
489 | printk(KERN_WARNING "%s: DMA timeout error\n", drive->name); | ||
490 | (void)hwif->dma_ops->dma_end(drive); | ||
491 | ret = ide_error(drive, "dma timeout error", | ||
492 | hwif->tp_ops->read_status(hwif)); | ||
493 | } else { | ||
494 | printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name); | ||
495 | hwif->dma_ops->dma_timeout(drive); | ||
496 | } | ||
497 | |||
498 | /* | ||
499 | * disable dma for now, but remember that we did so because of | ||
500 | * a timeout -- we'll reenable after we finish this next request | ||
501 | * (or rather the first chunk of it) in pio. | ||
502 | */ | ||
503 | drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY; | ||
504 | drive->retry_pio++; | ||
505 | ide_dma_off_quietly(drive); | ||
506 | |||
507 | /* | ||
508 | * un-busy drive etc and make sure request is sane | ||
509 | */ | ||
510 | |||
511 | rq = hwif->rq; | ||
512 | if (!rq) | ||
513 | goto out; | ||
514 | |||
515 | hwif->rq = NULL; | ||
516 | |||
517 | rq->errors = 0; | ||
518 | |||
519 | if (!rq->bio) | ||
520 | goto out; | ||
521 | |||
522 | rq->sector = rq->bio->bi_sector; | ||
523 | rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; | ||
524 | rq->hard_cur_sectors = rq->current_nr_sectors; | ||
525 | rq->buffer = bio_data(rq->bio); | ||
526 | out: | ||
527 | return ret; | ||
528 | } | ||
529 | |||
473 | void ide_release_dma_engine(ide_hwif_t *hwif) | 530 | void ide_release_dma_engine(ide_hwif_t *hwif) |
474 | { | 531 | { |
475 | if (hwif->dmatable_cpu) { | 532 | if (hwif->dmatable_cpu) { |
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c new file mode 100644 index 000000000000..1231b5e486f2 --- /dev/null +++ b/drivers/ide/ide-eh.c | |||
@@ -0,0 +1,428 @@ | |||
1 | |||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/ide.h> | ||
4 | #include <linux/delay.h> | ||
5 | |||
6 | static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, | ||
7 | u8 stat, u8 err) | ||
8 | { | ||
9 | ide_hwif_t *hwif = drive->hwif; | ||
10 | |||
11 | if ((stat & ATA_BUSY) || | ||
12 | ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { | ||
13 | /* other bits are useless when BUSY */ | ||
14 | rq->errors |= ERROR_RESET; | ||
15 | } else if (stat & ATA_ERR) { | ||
16 | /* err has different meaning on cdrom and tape */ | ||
17 | if (err == ATA_ABORTED) { | ||
18 | if ((drive->dev_flags & IDE_DFLAG_LBA) && | ||
19 | /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */ | ||
20 | hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS) | ||
21 | return ide_stopped; | ||
22 | } else if ((err & BAD_CRC) == BAD_CRC) { | ||
23 | /* UDMA crc error, just retry the operation */ | ||
24 | drive->crc_count++; | ||
25 | } else if (err & (ATA_BBK | ATA_UNC)) { | ||
26 | /* retries won't help these */ | ||
27 | rq->errors = ERROR_MAX; | ||
28 | } else if (err & ATA_TRK0NF) { | ||
29 | /* help it find track zero */ | ||
30 | rq->errors |= ERROR_RECAL; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ && | ||
35 | (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) { | ||
36 | int nsect = drive->mult_count ? drive->mult_count : 1; | ||
37 | |||
38 | ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE); | ||
39 | } | ||
40 | |||
41 | if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) { | ||
42 | ide_kill_rq(drive, rq); | ||
43 | return ide_stopped; | ||
44 | } | ||
45 | |||
46 | if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) | ||
47 | rq->errors |= ERROR_RESET; | ||
48 | |||
49 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | ||
50 | ++rq->errors; | ||
51 | return ide_do_reset(drive); | ||
52 | } | ||
53 | |||
54 | if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) | ||
55 | drive->special.b.recalibrate = 1; | ||
56 | |||
57 | ++rq->errors; | ||
58 | |||
59 | return ide_stopped; | ||
60 | } | ||
61 | |||
62 | static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, | ||
63 | u8 stat, u8 err) | ||
64 | { | ||
65 | ide_hwif_t *hwif = drive->hwif; | ||
66 | |||
67 | if ((stat & ATA_BUSY) || | ||
68 | ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { | ||
69 | /* other bits are useless when BUSY */ | ||
70 | rq->errors |= ERROR_RESET; | ||
71 | } else { | ||
72 | /* add decoding error stuff */ | ||
73 | } | ||
74 | |||
75 | if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) | ||
76 | /* force an abort */ | ||
77 | hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE); | ||
78 | |||
79 | if (rq->errors >= ERROR_MAX) { | ||
80 | ide_kill_rq(drive, rq); | ||
81 | } else { | ||
82 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | ||
83 | ++rq->errors; | ||
84 | return ide_do_reset(drive); | ||
85 | } | ||
86 | ++rq->errors; | ||
87 | } | ||
88 | |||
89 | return ide_stopped; | ||
90 | } | ||
91 | |||
92 | static ide_startstop_t __ide_error(ide_drive_t *drive, struct request *rq, | ||
93 | u8 stat, u8 err) | ||
94 | { | ||
95 | if (drive->media == ide_disk) | ||
96 | return ide_ata_error(drive, rq, stat, err); | ||
97 | return ide_atapi_error(drive, rq, stat, err); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * ide_error - handle an error on the IDE | ||
102 | * @drive: drive the error occurred on | ||
103 | * @msg: message to report | ||
104 | * @stat: status bits | ||
105 | * | ||
106 | * ide_error() takes action based on the error returned by the drive. | ||
107 | * For normal I/O that may well include retries. We deal with | ||
108 | * both new-style (taskfile) and old style command handling here. | ||
109 | * In the case of taskfile command handling there is work left to | ||
110 | * do | ||
111 | */ | ||
112 | |||
113 | ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat) | ||
114 | { | ||
115 | struct request *rq; | ||
116 | u8 err; | ||
117 | |||
118 | err = ide_dump_status(drive, msg, stat); | ||
119 | |||
120 | rq = drive->hwif->rq; | ||
121 | if (rq == NULL) | ||
122 | return ide_stopped; | ||
123 | |||
124 | /* retry only "normal" I/O: */ | ||
125 | if (!blk_fs_request(rq)) { | ||
126 | rq->errors = 1; | ||
127 | ide_end_drive_cmd(drive, stat, err); | ||
128 | return ide_stopped; | ||
129 | } | ||
130 | |||
131 | return __ide_error(drive, rq, stat, err); | ||
132 | } | ||
133 | EXPORT_SYMBOL_GPL(ide_error); | ||
134 | |||
135 | static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) | ||
136 | { | ||
137 | struct request *rq = drive->hwif->rq; | ||
138 | |||
139 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) | ||
140 | ide_end_request(drive, err ? err : 1, 0); | ||
141 | } | ||
142 | |||
143 | /* needed below */ | ||
144 | static ide_startstop_t do_reset1(ide_drive_t *, int); | ||
145 | |||
146 | /* | ||
147 | * atapi_reset_pollfunc() gets invoked to poll the interface for completion | ||
148 | * every 50ms during an atapi drive reset operation. If the drive has not yet | ||
149 | * responded, and we have not yet hit our maximum waiting time, then the timer | ||
150 | * is restarted for another 50ms. | ||
151 | */ | ||
152 | static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive) | ||
153 | { | ||
154 | ide_hwif_t *hwif = drive->hwif; | ||
155 | u8 stat; | ||
156 | |||
157 | SELECT_DRIVE(drive); | ||
158 | udelay(10); | ||
159 | stat = hwif->tp_ops->read_status(hwif); | ||
160 | |||
161 | if (OK_STAT(stat, 0, ATA_BUSY)) | ||
162 | printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name); | ||
163 | else { | ||
164 | if (time_before(jiffies, hwif->poll_timeout)) { | ||
165 | ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, | ||
166 | NULL); | ||
167 | /* continue polling */ | ||
168 | return ide_started; | ||
169 | } | ||
170 | /* end of polling */ | ||
171 | hwif->polling = 0; | ||
172 | printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n", | ||
173 | drive->name, stat); | ||
174 | /* do it the old fashioned way */ | ||
175 | return do_reset1(drive, 1); | ||
176 | } | ||
177 | /* done polling */ | ||
178 | hwif->polling = 0; | ||
179 | ide_complete_drive_reset(drive, 0); | ||
180 | return ide_stopped; | ||
181 | } | ||
182 | |||
183 | static void ide_reset_report_error(ide_hwif_t *hwif, u8 err) | ||
184 | { | ||
185 | static const char *err_master_vals[] = | ||
186 | { NULL, "passed", "formatter device error", | ||
187 | "sector buffer error", "ECC circuitry error", | ||
188 | "controlling MPU error" }; | ||
189 | |||
190 | u8 err_master = err & 0x7f; | ||
191 | |||
192 | printk(KERN_ERR "%s: reset: master: ", hwif->name); | ||
193 | if (err_master && err_master < 6) | ||
194 | printk(KERN_CONT "%s", err_master_vals[err_master]); | ||
195 | else | ||
196 | printk(KERN_CONT "error (0x%02x?)", err); | ||
197 | if (err & 0x80) | ||
198 | printk(KERN_CONT "; slave: failed"); | ||
199 | printk(KERN_CONT "\n"); | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * reset_pollfunc() gets invoked to poll the interface for completion every 50ms | ||
204 | * during an ide reset operation. If the drives have not yet responded, | ||
205 | * and we have not yet hit our maximum waiting time, then the timer is restarted | ||
206 | * for another 50ms. | ||
207 | */ | ||
208 | static ide_startstop_t reset_pollfunc(ide_drive_t *drive) | ||
209 | { | ||
210 | ide_hwif_t *hwif = drive->hwif; | ||
211 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
212 | u8 tmp; | ||
213 | int err = 0; | ||
214 | |||
215 | if (port_ops && port_ops->reset_poll) { | ||
216 | err = port_ops->reset_poll(drive); | ||
217 | if (err) { | ||
218 | printk(KERN_ERR "%s: host reset_poll failure for %s.\n", | ||
219 | hwif->name, drive->name); | ||
220 | goto out; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | tmp = hwif->tp_ops->read_status(hwif); | ||
225 | |||
226 | if (!OK_STAT(tmp, 0, ATA_BUSY)) { | ||
227 | if (time_before(jiffies, hwif->poll_timeout)) { | ||
228 | ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); | ||
229 | /* continue polling */ | ||
230 | return ide_started; | ||
231 | } | ||
232 | printk(KERN_ERR "%s: reset timed-out, status=0x%02x\n", | ||
233 | hwif->name, tmp); | ||
234 | drive->failures++; | ||
235 | err = -EIO; | ||
236 | } else { | ||
237 | tmp = ide_read_error(drive); | ||
238 | |||
239 | if (tmp == 1) { | ||
240 | printk(KERN_INFO "%s: reset: success\n", hwif->name); | ||
241 | drive->failures = 0; | ||
242 | } else { | ||
243 | ide_reset_report_error(hwif, tmp); | ||
244 | drive->failures++; | ||
245 | err = -EIO; | ||
246 | } | ||
247 | } | ||
248 | out: | ||
249 | hwif->polling = 0; /* done polling */ | ||
250 | ide_complete_drive_reset(drive, err); | ||
251 | return ide_stopped; | ||
252 | } | ||
253 | |||
254 | static void ide_disk_pre_reset(ide_drive_t *drive) | ||
255 | { | ||
256 | int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1; | ||
257 | |||
258 | drive->special.all = 0; | ||
259 | drive->special.b.set_geometry = legacy; | ||
260 | drive->special.b.recalibrate = legacy; | ||
261 | |||
262 | drive->mult_count = 0; | ||
263 | drive->dev_flags &= ~IDE_DFLAG_PARKED; | ||
264 | |||
265 | if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 && | ||
266 | (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) | ||
267 | drive->mult_req = 0; | ||
268 | |||
269 | if (drive->mult_req != drive->mult_count) | ||
270 | drive->special.b.set_multmode = 1; | ||
271 | } | ||
272 | |||
273 | static void pre_reset(ide_drive_t *drive) | ||
274 | { | ||
275 | const struct ide_port_ops *port_ops = drive->hwif->port_ops; | ||
276 | |||
277 | if (drive->media == ide_disk) | ||
278 | ide_disk_pre_reset(drive); | ||
279 | else | ||
280 | drive->dev_flags |= IDE_DFLAG_POST_RESET; | ||
281 | |||
282 | if (drive->dev_flags & IDE_DFLAG_USING_DMA) { | ||
283 | if (drive->crc_count) | ||
284 | ide_check_dma_crc(drive); | ||
285 | else | ||
286 | ide_dma_off(drive); | ||
287 | } | ||
288 | |||
289 | if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) { | ||
290 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) { | ||
291 | drive->dev_flags &= ~IDE_DFLAG_UNMASK; | ||
292 | drive->io_32bit = 0; | ||
293 | } | ||
294 | return; | ||
295 | } | ||
296 | |||
297 | if (port_ops && port_ops->pre_reset) | ||
298 | port_ops->pre_reset(drive); | ||
299 | |||
300 | if (drive->current_speed != 0xff) | ||
301 | drive->desired_speed = drive->current_speed; | ||
302 | drive->current_speed = 0xff; | ||
303 | } | ||
304 | |||
305 | /* | ||
306 | * do_reset1() attempts to recover a confused drive by resetting it. | ||
307 | * Unfortunately, resetting a disk drive actually resets all devices on | ||
308 | * the same interface, so it can really be thought of as resetting the | ||
309 | * interface rather than resetting the drive. | ||
310 | * | ||
311 | * ATAPI devices have their own reset mechanism which allows them to be | ||
312 | * individually reset without clobbering other devices on the same interface. | ||
313 | * | ||
314 | * Unfortunately, the IDE interface does not generate an interrupt to let | ||
315 | * us know when the reset operation has finished, so we must poll for this. | ||
316 | * Equally poor, though, is the fact that this may a very long time to complete, | ||
317 | * (up to 30 seconds worstcase). So, instead of busy-waiting here for it, | ||
318 | * we set a timer to poll at 50ms intervals. | ||
319 | */ | ||
320 | static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi) | ||
321 | { | ||
322 | ide_hwif_t *hwif = drive->hwif; | ||
323 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
324 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
325 | const struct ide_port_ops *port_ops; | ||
326 | ide_drive_t *tdrive; | ||
327 | unsigned long flags, timeout; | ||
328 | int i; | ||
329 | DEFINE_WAIT(wait); | ||
330 | |||
331 | spin_lock_irqsave(&hwif->lock, flags); | ||
332 | |||
333 | /* We must not reset with running handlers */ | ||
334 | BUG_ON(hwif->handler != NULL); | ||
335 | |||
336 | /* For an ATAPI device, first try an ATAPI SRST. */ | ||
337 | if (drive->media != ide_disk && !do_not_try_atapi) { | ||
338 | pre_reset(drive); | ||
339 | SELECT_DRIVE(drive); | ||
340 | udelay(20); | ||
341 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); | ||
342 | ndelay(400); | ||
343 | hwif->poll_timeout = jiffies + WAIT_WORSTCASE; | ||
344 | hwif->polling = 1; | ||
345 | __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); | ||
346 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
347 | return ide_started; | ||
348 | } | ||
349 | |||
350 | /* We must not disturb devices in the IDE_DFLAG_PARKED state. */ | ||
351 | do { | ||
352 | unsigned long now; | ||
353 | |||
354 | prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE); | ||
355 | timeout = jiffies; | ||
356 | ide_port_for_each_present_dev(i, tdrive, hwif) { | ||
357 | if ((tdrive->dev_flags & IDE_DFLAG_PARKED) && | ||
358 | time_after(tdrive->sleep, timeout)) | ||
359 | timeout = tdrive->sleep; | ||
360 | } | ||
361 | |||
362 | now = jiffies; | ||
363 | if (time_before_eq(timeout, now)) | ||
364 | break; | ||
365 | |||
366 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
367 | timeout = schedule_timeout_uninterruptible(timeout - now); | ||
368 | spin_lock_irqsave(&hwif->lock, flags); | ||
369 | } while (timeout); | ||
370 | finish_wait(&ide_park_wq, &wait); | ||
371 | |||
372 | /* | ||
373 | * First, reset any device state data we were maintaining | ||
374 | * for any of the drives on this interface. | ||
375 | */ | ||
376 | ide_port_for_each_dev(i, tdrive, hwif) | ||
377 | pre_reset(tdrive); | ||
378 | |||
379 | if (io_ports->ctl_addr == 0) { | ||
380 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
381 | ide_complete_drive_reset(drive, -ENXIO); | ||
382 | return ide_stopped; | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * Note that we also set nIEN while resetting the device, | ||
387 | * to mask unwanted interrupts from the interface during the reset. | ||
388 | * However, due to the design of PC hardware, this will cause an | ||
389 | * immediate interrupt due to the edge transition it produces. | ||
390 | * This single interrupt gives us a "fast poll" for drives that | ||
391 | * recover from reset very quickly, saving us the first 50ms wait time. | ||
392 | * | ||
393 | * TODO: add ->softreset method and stop abusing ->set_irq | ||
394 | */ | ||
395 | /* set SRST and nIEN */ | ||
396 | tp_ops->set_irq(hwif, 4); | ||
397 | /* more than enough time */ | ||
398 | udelay(10); | ||
399 | /* clear SRST, leave nIEN (unless device is on the quirk list) */ | ||
400 | tp_ops->set_irq(hwif, drive->quirk_list == 2); | ||
401 | /* more than enough time */ | ||
402 | udelay(10); | ||
403 | hwif->poll_timeout = jiffies + WAIT_WORSTCASE; | ||
404 | hwif->polling = 1; | ||
405 | __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); | ||
406 | |||
407 | /* | ||
408 | * Some weird controller like resetting themselves to a strange | ||
409 | * state when the disks are reset this way. At least, the Winbond | ||
410 | * 553 documentation says that | ||
411 | */ | ||
412 | port_ops = hwif->port_ops; | ||
413 | if (port_ops && port_ops->resetproc) | ||
414 | port_ops->resetproc(drive); | ||
415 | |||
416 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
417 | return ide_started; | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * ide_do_reset() is the entry point to the drive/interface reset code. | ||
422 | */ | ||
423 | |||
424 | ide_startstop_t ide_do_reset(ide_drive_t *drive) | ||
425 | { | ||
426 | return do_reset1(drive, 0); | ||
427 | } | ||
428 | EXPORT_SYMBOL(ide_do_reset); | ||
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c new file mode 100644 index 000000000000..45b43dd49cda --- /dev/null +++ b/drivers/ide/ide-io-std.c | |||
@@ -0,0 +1,316 @@ | |||
1 | |||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/ide.h> | ||
4 | |||
5 | /* | ||
6 | * Conventional PIO operations for ATA devices | ||
7 | */ | ||
8 | |||
9 | static u8 ide_inb(unsigned long port) | ||
10 | { | ||
11 | return (u8) inb(port); | ||
12 | } | ||
13 | |||
14 | static void ide_outb(u8 val, unsigned long port) | ||
15 | { | ||
16 | outb(val, port); | ||
17 | } | ||
18 | |||
19 | /* | ||
20 | * MMIO operations, typically used for SATA controllers | ||
21 | */ | ||
22 | |||
23 | static u8 ide_mm_inb(unsigned long port) | ||
24 | { | ||
25 | return (u8) readb((void __iomem *) port); | ||
26 | } | ||
27 | |||
28 | static void ide_mm_outb(u8 value, unsigned long port) | ||
29 | { | ||
30 | writeb(value, (void __iomem *) port); | ||
31 | } | ||
32 | |||
33 | void ide_exec_command(ide_hwif_t *hwif, u8 cmd) | ||
34 | { | ||
35 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
36 | writeb(cmd, (void __iomem *)hwif->io_ports.command_addr); | ||
37 | else | ||
38 | outb(cmd, hwif->io_ports.command_addr); | ||
39 | } | ||
40 | EXPORT_SYMBOL_GPL(ide_exec_command); | ||
41 | |||
42 | u8 ide_read_status(ide_hwif_t *hwif) | ||
43 | { | ||
44 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
45 | return readb((void __iomem *)hwif->io_ports.status_addr); | ||
46 | else | ||
47 | return inb(hwif->io_ports.status_addr); | ||
48 | } | ||
49 | EXPORT_SYMBOL_GPL(ide_read_status); | ||
50 | |||
51 | u8 ide_read_altstatus(ide_hwif_t *hwif) | ||
52 | { | ||
53 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
54 | return readb((void __iomem *)hwif->io_ports.ctl_addr); | ||
55 | else | ||
56 | return inb(hwif->io_ports.ctl_addr); | ||
57 | } | ||
58 | EXPORT_SYMBOL_GPL(ide_read_altstatus); | ||
59 | |||
60 | void ide_set_irq(ide_hwif_t *hwif, int on) | ||
61 | { | ||
62 | u8 ctl = ATA_DEVCTL_OBS; | ||
63 | |||
64 | if (on == 4) { /* hack for SRST */ | ||
65 | ctl |= 4; | ||
66 | on &= ~4; | ||
67 | } | ||
68 | |||
69 | ctl |= on ? 0 : 2; | ||
70 | |||
71 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
72 | writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); | ||
73 | else | ||
74 | outb(ctl, hwif->io_ports.ctl_addr); | ||
75 | } | ||
76 | EXPORT_SYMBOL_GPL(ide_set_irq); | ||
77 | |||
78 | void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | ||
79 | { | ||
80 | ide_hwif_t *hwif = drive->hwif; | ||
81 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
82 | struct ide_taskfile *tf = &task->tf; | ||
83 | void (*tf_outb)(u8 addr, unsigned long port); | ||
84 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
85 | u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | ||
86 | |||
87 | if (mmio) | ||
88 | tf_outb = ide_mm_outb; | ||
89 | else | ||
90 | tf_outb = ide_outb; | ||
91 | |||
92 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | ||
93 | HIHI = 0xFF; | ||
94 | |||
95 | if (task->tf_flags & IDE_TFLAG_OUT_DATA) { | ||
96 | u16 data = (tf->hob_data << 8) | tf->data; | ||
97 | |||
98 | if (mmio) | ||
99 | writew(data, (void __iomem *)io_ports->data_addr); | ||
100 | else | ||
101 | outw(data, io_ports->data_addr); | ||
102 | } | ||
103 | |||
104 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
105 | tf_outb(tf->hob_feature, io_ports->feature_addr); | ||
106 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
107 | tf_outb(tf->hob_nsect, io_ports->nsect_addr); | ||
108 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
109 | tf_outb(tf->hob_lbal, io_ports->lbal_addr); | ||
110 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
111 | tf_outb(tf->hob_lbam, io_ports->lbam_addr); | ||
112 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
113 | tf_outb(tf->hob_lbah, io_ports->lbah_addr); | ||
114 | |||
115 | if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
116 | tf_outb(tf->feature, io_ports->feature_addr); | ||
117 | if (task->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
118 | tf_outb(tf->nsect, io_ports->nsect_addr); | ||
119 | if (task->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
120 | tf_outb(tf->lbal, io_ports->lbal_addr); | ||
121 | if (task->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
122 | tf_outb(tf->lbam, io_ports->lbam_addr); | ||
123 | if (task->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
124 | tf_outb(tf->lbah, io_ports->lbah_addr); | ||
125 | |||
126 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
127 | tf_outb((tf->device & HIHI) | drive->select, | ||
128 | io_ports->device_addr); | ||
129 | } | ||
130 | EXPORT_SYMBOL_GPL(ide_tf_load); | ||
131 | |||
132 | void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | ||
133 | { | ||
134 | ide_hwif_t *hwif = drive->hwif; | ||
135 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
136 | struct ide_taskfile *tf = &task->tf; | ||
137 | void (*tf_outb)(u8 addr, unsigned long port); | ||
138 | u8 (*tf_inb)(unsigned long port); | ||
139 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
140 | |||
141 | if (mmio) { | ||
142 | tf_outb = ide_mm_outb; | ||
143 | tf_inb = ide_mm_inb; | ||
144 | } else { | ||
145 | tf_outb = ide_outb; | ||
146 | tf_inb = ide_inb; | ||
147 | } | ||
148 | |||
149 | if (task->tf_flags & IDE_TFLAG_IN_DATA) { | ||
150 | u16 data; | ||
151 | |||
152 | if (mmio) | ||
153 | data = readw((void __iomem *)io_ports->data_addr); | ||
154 | else | ||
155 | data = inw(io_ports->data_addr); | ||
156 | |||
157 | tf->data = data & 0xff; | ||
158 | tf->hob_data = (data >> 8) & 0xff; | ||
159 | } | ||
160 | |||
161 | /* be sure we're looking at the low order bits */ | ||
162 | tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); | ||
163 | |||
164 | if (task->tf_flags & IDE_TFLAG_IN_FEATURE) | ||
165 | tf->feature = tf_inb(io_ports->feature_addr); | ||
166 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | ||
167 | tf->nsect = tf_inb(io_ports->nsect_addr); | ||
168 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | ||
169 | tf->lbal = tf_inb(io_ports->lbal_addr); | ||
170 | if (task->tf_flags & IDE_TFLAG_IN_LBAM) | ||
171 | tf->lbam = tf_inb(io_ports->lbam_addr); | ||
172 | if (task->tf_flags & IDE_TFLAG_IN_LBAH) | ||
173 | tf->lbah = tf_inb(io_ports->lbah_addr); | ||
174 | if (task->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
175 | tf->device = tf_inb(io_ports->device_addr); | ||
176 | |||
177 | if (task->tf_flags & IDE_TFLAG_LBA48) { | ||
178 | tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); | ||
179 | |||
180 | if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) | ||
181 | tf->hob_feature = tf_inb(io_ports->feature_addr); | ||
182 | if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
183 | tf->hob_nsect = tf_inb(io_ports->nsect_addr); | ||
184 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
185 | tf->hob_lbal = tf_inb(io_ports->lbal_addr); | ||
186 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
187 | tf->hob_lbam = tf_inb(io_ports->lbam_addr); | ||
188 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
189 | tf->hob_lbah = tf_inb(io_ports->lbah_addr); | ||
190 | } | ||
191 | } | ||
192 | EXPORT_SYMBOL_GPL(ide_tf_read); | ||
193 | |||
194 | /* | ||
195 | * Some localbus EIDE interfaces require a special access sequence | ||
196 | * when using 32-bit I/O instructions to transfer data. We call this | ||
197 | * the "vlb_sync" sequence, which consists of three successive reads | ||
198 | * of the sector count register location, with interrupts disabled | ||
199 | * to ensure that the reads all happen together. | ||
200 | */ | ||
201 | static void ata_vlb_sync(unsigned long port) | ||
202 | { | ||
203 | (void)inb(port); | ||
204 | (void)inb(port); | ||
205 | (void)inb(port); | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * This is used for most PIO data transfers *from* the IDE interface | ||
210 | * | ||
211 | * These routines will round up any request for an odd number of bytes, | ||
212 | * so if an odd len is specified, be sure that there's at least one | ||
213 | * extra byte allocated for the buffer. | ||
214 | */ | ||
215 | void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, | ||
216 | unsigned int len) | ||
217 | { | ||
218 | ide_hwif_t *hwif = drive->hwif; | ||
219 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
220 | unsigned long data_addr = io_ports->data_addr; | ||
221 | u8 io_32bit = drive->io_32bit; | ||
222 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
223 | |||
224 | len++; | ||
225 | |||
226 | if (io_32bit) { | ||
227 | unsigned long uninitialized_var(flags); | ||
228 | |||
229 | if ((io_32bit & 2) && !mmio) { | ||
230 | local_irq_save(flags); | ||
231 | ata_vlb_sync(io_ports->nsect_addr); | ||
232 | } | ||
233 | |||
234 | if (mmio) | ||
235 | __ide_mm_insl((void __iomem *)data_addr, buf, len / 4); | ||
236 | else | ||
237 | insl(data_addr, buf, len / 4); | ||
238 | |||
239 | if ((io_32bit & 2) && !mmio) | ||
240 | local_irq_restore(flags); | ||
241 | |||
242 | if ((len & 3) >= 2) { | ||
243 | if (mmio) | ||
244 | __ide_mm_insw((void __iomem *)data_addr, | ||
245 | (u8 *)buf + (len & ~3), 1); | ||
246 | else | ||
247 | insw(data_addr, (u8 *)buf + (len & ~3), 1); | ||
248 | } | ||
249 | } else { | ||
250 | if (mmio) | ||
251 | __ide_mm_insw((void __iomem *)data_addr, buf, len / 2); | ||
252 | else | ||
253 | insw(data_addr, buf, len / 2); | ||
254 | } | ||
255 | } | ||
256 | EXPORT_SYMBOL_GPL(ide_input_data); | ||
257 | |||
258 | /* | ||
259 | * This is used for most PIO data transfers *to* the IDE interface | ||
260 | */ | ||
261 | void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, | ||
262 | unsigned int len) | ||
263 | { | ||
264 | ide_hwif_t *hwif = drive->hwif; | ||
265 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
266 | unsigned long data_addr = io_ports->data_addr; | ||
267 | u8 io_32bit = drive->io_32bit; | ||
268 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
269 | |||
270 | len++; | ||
271 | |||
272 | if (io_32bit) { | ||
273 | unsigned long uninitialized_var(flags); | ||
274 | |||
275 | if ((io_32bit & 2) && !mmio) { | ||
276 | local_irq_save(flags); | ||
277 | ata_vlb_sync(io_ports->nsect_addr); | ||
278 | } | ||
279 | |||
280 | if (mmio) | ||
281 | __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4); | ||
282 | else | ||
283 | outsl(data_addr, buf, len / 4); | ||
284 | |||
285 | if ((io_32bit & 2) && !mmio) | ||
286 | local_irq_restore(flags); | ||
287 | |||
288 | if ((len & 3) >= 2) { | ||
289 | if (mmio) | ||
290 | __ide_mm_outsw((void __iomem *)data_addr, | ||
291 | (u8 *)buf + (len & ~3), 1); | ||
292 | else | ||
293 | outsw(data_addr, (u8 *)buf + (len & ~3), 1); | ||
294 | } | ||
295 | } else { | ||
296 | if (mmio) | ||
297 | __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2); | ||
298 | else | ||
299 | outsw(data_addr, buf, len / 2); | ||
300 | } | ||
301 | } | ||
302 | EXPORT_SYMBOL_GPL(ide_output_data); | ||
303 | |||
304 | const struct ide_tp_ops default_tp_ops = { | ||
305 | .exec_command = ide_exec_command, | ||
306 | .read_status = ide_read_status, | ||
307 | .read_altstatus = ide_read_altstatus, | ||
308 | |||
309 | .set_irq = ide_set_irq, | ||
310 | |||
311 | .tf_load = ide_tf_load, | ||
312 | .tf_read = ide_tf_read, | ||
313 | |||
314 | .input_data = ide_input_data, | ||
315 | .output_data = ide_output_data, | ||
316 | }; | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index a9a6c208288a..2e92497b58aa 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -196,7 +196,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
196 | } | 196 | } |
197 | EXPORT_SYMBOL(ide_end_drive_cmd); | 197 | EXPORT_SYMBOL(ide_end_drive_cmd); |
198 | 198 | ||
199 | static void ide_kill_rq(ide_drive_t *drive, struct request *rq) | 199 | void ide_kill_rq(ide_drive_t *drive, struct request *rq) |
200 | { | 200 | { |
201 | if (rq->rq_disk) { | 201 | if (rq->rq_disk) { |
202 | struct ide_driver *drv; | 202 | struct ide_driver *drv; |
@@ -207,133 +207,6 @@ static void ide_kill_rq(ide_drive_t *drive, struct request *rq) | |||
207 | ide_end_request(drive, 0, 0); | 207 | ide_end_request(drive, 0, 0); |
208 | } | 208 | } |
209 | 209 | ||
210 | static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | ||
211 | { | ||
212 | ide_hwif_t *hwif = drive->hwif; | ||
213 | |||
214 | if ((stat & ATA_BUSY) || | ||
215 | ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { | ||
216 | /* other bits are useless when BUSY */ | ||
217 | rq->errors |= ERROR_RESET; | ||
218 | } else if (stat & ATA_ERR) { | ||
219 | /* err has different meaning on cdrom and tape */ | ||
220 | if (err == ATA_ABORTED) { | ||
221 | if ((drive->dev_flags & IDE_DFLAG_LBA) && | ||
222 | /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */ | ||
223 | hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS) | ||
224 | return ide_stopped; | ||
225 | } else if ((err & BAD_CRC) == BAD_CRC) { | ||
226 | /* UDMA crc error, just retry the operation */ | ||
227 | drive->crc_count++; | ||
228 | } else if (err & (ATA_BBK | ATA_UNC)) { | ||
229 | /* retries won't help these */ | ||
230 | rq->errors = ERROR_MAX; | ||
231 | } else if (err & ATA_TRK0NF) { | ||
232 | /* help it find track zero */ | ||
233 | rq->errors |= ERROR_RECAL; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ && | ||
238 | (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) { | ||
239 | int nsect = drive->mult_count ? drive->mult_count : 1; | ||
240 | |||
241 | ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE); | ||
242 | } | ||
243 | |||
244 | if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) { | ||
245 | ide_kill_rq(drive, rq); | ||
246 | return ide_stopped; | ||
247 | } | ||
248 | |||
249 | if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) | ||
250 | rq->errors |= ERROR_RESET; | ||
251 | |||
252 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | ||
253 | ++rq->errors; | ||
254 | return ide_do_reset(drive); | ||
255 | } | ||
256 | |||
257 | if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) | ||
258 | drive->special.b.recalibrate = 1; | ||
259 | |||
260 | ++rq->errors; | ||
261 | |||
262 | return ide_stopped; | ||
263 | } | ||
264 | |||
265 | static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | ||
266 | { | ||
267 | ide_hwif_t *hwif = drive->hwif; | ||
268 | |||
269 | if ((stat & ATA_BUSY) || | ||
270 | ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) { | ||
271 | /* other bits are useless when BUSY */ | ||
272 | rq->errors |= ERROR_RESET; | ||
273 | } else { | ||
274 | /* add decoding error stuff */ | ||
275 | } | ||
276 | |||
277 | if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) | ||
278 | /* force an abort */ | ||
279 | hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE); | ||
280 | |||
281 | if (rq->errors >= ERROR_MAX) { | ||
282 | ide_kill_rq(drive, rq); | ||
283 | } else { | ||
284 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | ||
285 | ++rq->errors; | ||
286 | return ide_do_reset(drive); | ||
287 | } | ||
288 | ++rq->errors; | ||
289 | } | ||
290 | |||
291 | return ide_stopped; | ||
292 | } | ||
293 | |||
294 | static ide_startstop_t | ||
295 | __ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | ||
296 | { | ||
297 | if (drive->media == ide_disk) | ||
298 | return ide_ata_error(drive, rq, stat, err); | ||
299 | return ide_atapi_error(drive, rq, stat, err); | ||
300 | } | ||
301 | |||
302 | /** | ||
303 | * ide_error - handle an error on the IDE | ||
304 | * @drive: drive the error occurred on | ||
305 | * @msg: message to report | ||
306 | * @stat: status bits | ||
307 | * | ||
308 | * ide_error() takes action based on the error returned by the drive. | ||
309 | * For normal I/O that may well include retries. We deal with | ||
310 | * both new-style (taskfile) and old style command handling here. | ||
311 | * In the case of taskfile command handling there is work left to | ||
312 | * do | ||
313 | */ | ||
314 | |||
315 | ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat) | ||
316 | { | ||
317 | struct request *rq; | ||
318 | u8 err; | ||
319 | |||
320 | err = ide_dump_status(drive, msg, stat); | ||
321 | |||
322 | rq = drive->hwif->rq; | ||
323 | if (rq == NULL) | ||
324 | return ide_stopped; | ||
325 | |||
326 | /* retry only "normal" I/O: */ | ||
327 | if (!blk_fs_request(rq)) { | ||
328 | rq->errors = 1; | ||
329 | ide_end_drive_cmd(drive, stat, err); | ||
330 | return ide_stopped; | ||
331 | } | ||
332 | |||
333 | return __ide_error(drive, rq, stat, err); | ||
334 | } | ||
335 | EXPORT_SYMBOL_GPL(ide_error); | ||
336 | |||
337 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 210 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
338 | { | 211 | { |
339 | tf->nsect = drive->sect; | 212 | tf->nsect = drive->sect; |
@@ -490,71 +363,16 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
490 | return ide_stopped; | 363 | return ide_stopped; |
491 | } | 364 | } |
492 | 365 | ||
493 | int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting, | ||
494 | int arg) | ||
495 | { | ||
496 | struct request_queue *q = drive->queue; | ||
497 | struct request *rq; | ||
498 | int ret = 0; | ||
499 | |||
500 | if (!(setting->flags & DS_SYNC)) | ||
501 | return setting->set(drive, arg); | ||
502 | |||
503 | rq = blk_get_request(q, READ, __GFP_WAIT); | ||
504 | rq->cmd_type = REQ_TYPE_SPECIAL; | ||
505 | rq->cmd_len = 5; | ||
506 | rq->cmd[0] = REQ_DEVSET_EXEC; | ||
507 | *(int *)&rq->cmd[1] = arg; | ||
508 | rq->special = setting->set; | ||
509 | |||
510 | if (blk_execute_rq(q, NULL, rq, 0)) | ||
511 | ret = rq->errors; | ||
512 | blk_put_request(rq); | ||
513 | |||
514 | return ret; | ||
515 | } | ||
516 | EXPORT_SYMBOL_GPL(ide_devset_execute); | ||
517 | |||
518 | static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) | 366 | static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) |
519 | { | 367 | { |
520 | u8 cmd = rq->cmd[0]; | 368 | u8 cmd = rq->cmd[0]; |
521 | 369 | ||
522 | if (cmd == REQ_PARK_HEADS || cmd == REQ_UNPARK_HEADS) { | ||
523 | ide_task_t task; | ||
524 | struct ide_taskfile *tf = &task.tf; | ||
525 | |||
526 | memset(&task, 0, sizeof(task)); | ||
527 | if (cmd == REQ_PARK_HEADS) { | ||
528 | drive->sleep = *(unsigned long *)rq->special; | ||
529 | drive->dev_flags |= IDE_DFLAG_SLEEPING; | ||
530 | tf->command = ATA_CMD_IDLEIMMEDIATE; | ||
531 | tf->feature = 0x44; | ||
532 | tf->lbal = 0x4c; | ||
533 | tf->lbam = 0x4e; | ||
534 | tf->lbah = 0x55; | ||
535 | task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER; | ||
536 | } else /* cmd == REQ_UNPARK_HEADS */ | ||
537 | tf->command = ATA_CMD_CHK_POWER; | ||
538 | |||
539 | task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | ||
540 | task.rq = rq; | ||
541 | drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA; | ||
542 | return do_rw_taskfile(drive, &task); | ||
543 | } | ||
544 | |||
545 | switch (cmd) { | 370 | switch (cmd) { |
371 | case REQ_PARK_HEADS: | ||
372 | case REQ_UNPARK_HEADS: | ||
373 | return ide_do_park_unpark(drive, rq); | ||
546 | case REQ_DEVSET_EXEC: | 374 | case REQ_DEVSET_EXEC: |
547 | { | 375 | return ide_do_devset(drive, rq); |
548 | int err, (*setfunc)(ide_drive_t *, int) = rq->special; | ||
549 | |||
550 | err = setfunc(drive, *(int *)&rq->cmd[1]); | ||
551 | if (err) | ||
552 | rq->errors = err; | ||
553 | else | ||
554 | err = 1; | ||
555 | ide_end_request(drive, err, 0); | ||
556 | return ide_stopped; | ||
557 | } | ||
558 | case REQ_DRIVE_RESET: | 376 | case REQ_DRIVE_RESET: |
559 | return ide_do_reset(drive); | 377 | return ide_do_reset(drive); |
560 | default: | 378 | default: |
@@ -820,63 +638,6 @@ plug_device_2: | |||
820 | blk_plug_device(q); | 638 | blk_plug_device(q); |
821 | } | 639 | } |
822 | 640 | ||
823 | /* | ||
824 | * un-busy the port etc, and clear any pending DMA status. we want to | ||
825 | * retry the current request in pio mode instead of risking tossing it | ||
826 | * all away | ||
827 | */ | ||
828 | static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | ||
829 | { | ||
830 | ide_hwif_t *hwif = drive->hwif; | ||
831 | struct request *rq; | ||
832 | ide_startstop_t ret = ide_stopped; | ||
833 | |||
834 | /* | ||
835 | * end current dma transaction | ||
836 | */ | ||
837 | |||
838 | if (error < 0) { | ||
839 | printk(KERN_WARNING "%s: DMA timeout error\n", drive->name); | ||
840 | (void)hwif->dma_ops->dma_end(drive); | ||
841 | ret = ide_error(drive, "dma timeout error", | ||
842 | hwif->tp_ops->read_status(hwif)); | ||
843 | } else { | ||
844 | printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name); | ||
845 | hwif->dma_ops->dma_timeout(drive); | ||
846 | } | ||
847 | |||
848 | /* | ||
849 | * disable dma for now, but remember that we did so because of | ||
850 | * a timeout -- we'll reenable after we finish this next request | ||
851 | * (or rather the first chunk of it) in pio. | ||
852 | */ | ||
853 | drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY; | ||
854 | drive->retry_pio++; | ||
855 | ide_dma_off_quietly(drive); | ||
856 | |||
857 | /* | ||
858 | * un-busy drive etc and make sure request is sane | ||
859 | */ | ||
860 | |||
861 | rq = hwif->rq; | ||
862 | if (!rq) | ||
863 | goto out; | ||
864 | |||
865 | hwif->rq = NULL; | ||
866 | |||
867 | rq->errors = 0; | ||
868 | |||
869 | if (!rq->bio) | ||
870 | goto out; | ||
871 | |||
872 | rq->sector = rq->bio->bi_sector; | ||
873 | rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; | ||
874 | rq->hard_cur_sectors = rq->current_nr_sectors; | ||
875 | rq->buffer = bio_data(rq->bio); | ||
876 | out: | ||
877 | return ret; | ||
878 | } | ||
879 | |||
880 | static void ide_plug_device(ide_drive_t *drive) | 641 | static void ide_plug_device(ide_drive_t *drive) |
881 | { | 642 | { |
882 | struct request_queue *q = drive->queue; | 643 | struct request_queue *q = drive->queue; |
@@ -888,6 +649,29 @@ static void ide_plug_device(ide_drive_t *drive) | |||
888 | spin_unlock_irqrestore(q->queue_lock, flags); | 649 | spin_unlock_irqrestore(q->queue_lock, flags); |
889 | } | 650 | } |
890 | 651 | ||
652 | static int drive_is_ready(ide_drive_t *drive) | ||
653 | { | ||
654 | ide_hwif_t *hwif = drive->hwif; | ||
655 | u8 stat = 0; | ||
656 | |||
657 | if (drive->waiting_for_dma) | ||
658 | return hwif->dma_ops->dma_test_irq(drive); | ||
659 | |||
660 | if (hwif->io_ports.ctl_addr && | ||
661 | (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) | ||
662 | stat = hwif->tp_ops->read_altstatus(hwif); | ||
663 | else | ||
664 | /* Note: this may clear a pending IRQ!! */ | ||
665 | stat = hwif->tp_ops->read_status(hwif); | ||
666 | |||
667 | if (stat & ATA_BUSY) | ||
668 | /* drive busy: definitely not interrupting */ | ||
669 | return 0; | ||
670 | |||
671 | /* drive ready: *might* be interrupting */ | ||
672 | return 1; | ||
673 | } | ||
674 | |||
891 | /** | 675 | /** |
892 | * ide_timer_expiry - handle lack of an IDE interrupt | 676 | * ide_timer_expiry - handle lack of an IDE interrupt |
893 | * @data: timer callback magic (hwif) | 677 | * @data: timer callback magic (hwif) |
@@ -1164,54 +948,6 @@ out_early: | |||
1164 | } | 948 | } |
1165 | EXPORT_SYMBOL_GPL(ide_intr); | 949 | EXPORT_SYMBOL_GPL(ide_intr); |
1166 | 950 | ||
1167 | /** | ||
1168 | * ide_do_drive_cmd - issue IDE special command | ||
1169 | * @drive: device to issue command | ||
1170 | * @rq: request to issue | ||
1171 | * | ||
1172 | * This function issues a special IDE device request | ||
1173 | * onto the request queue. | ||
1174 | * | ||
1175 | * the rq is queued at the head of the request queue, displacing | ||
1176 | * the currently-being-processed request and this function | ||
1177 | * returns immediately without waiting for the new rq to be | ||
1178 | * completed. This is VERY DANGEROUS, and is intended for | ||
1179 | * careful use by the ATAPI tape/cdrom driver code. | ||
1180 | */ | ||
1181 | |||
1182 | void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) | ||
1183 | { | ||
1184 | struct request_queue *q = drive->queue; | ||
1185 | unsigned long flags; | ||
1186 | |||
1187 | drive->hwif->rq = NULL; | ||
1188 | |||
1189 | spin_lock_irqsave(q->queue_lock, flags); | ||
1190 | __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); | ||
1191 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
1192 | } | ||
1193 | EXPORT_SYMBOL(ide_do_drive_cmd); | ||
1194 | |||
1195 | void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) | ||
1196 | { | ||
1197 | ide_hwif_t *hwif = drive->hwif; | ||
1198 | ide_task_t task; | ||
1199 | |||
1200 | memset(&task, 0, sizeof(task)); | ||
1201 | task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | | ||
1202 | IDE_TFLAG_OUT_FEATURE | tf_flags; | ||
1203 | task.tf.feature = dma; /* Use PIO/DMA */ | ||
1204 | task.tf.lbam = bcount & 0xff; | ||
1205 | task.tf.lbah = (bcount >> 8) & 0xff; | ||
1206 | |||
1207 | ide_tf_dump(drive->name, &task.tf); | ||
1208 | hwif->tp_ops->set_irq(hwif, 1); | ||
1209 | SELECT_MASK(drive, 0); | ||
1210 | hwif->tp_ops->tf_load(drive, &task); | ||
1211 | } | ||
1212 | |||
1213 | EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load); | ||
1214 | |||
1215 | void ide_pad_transfer(ide_drive_t *drive, int write, int len) | 951 | void ide_pad_transfer(ide_drive_t *drive, int write, int len) |
1216 | { | 952 | { |
1217 | ide_hwif_t *hwif = drive->hwif; | 953 | ide_hwif_t *hwif = drive->hwif; |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index b1892bd95c6f..317c5dadd7c0 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -27,35 +27,7 @@ | |||
27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
28 | #include <asm/io.h> | 28 | #include <asm/io.h> |
29 | 29 | ||
30 | /* | 30 | void SELECT_DRIVE(ide_drive_t *drive) |
31 | * Conventional PIO operations for ATA devices | ||
32 | */ | ||
33 | |||
34 | static u8 ide_inb (unsigned long port) | ||
35 | { | ||
36 | return (u8) inb(port); | ||
37 | } | ||
38 | |||
39 | static void ide_outb (u8 val, unsigned long port) | ||
40 | { | ||
41 | outb(val, port); | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * MMIO operations, typically used for SATA controllers | ||
46 | */ | ||
47 | |||
48 | static u8 ide_mm_inb (unsigned long port) | ||
49 | { | ||
50 | return (u8) readb((void __iomem *) port); | ||
51 | } | ||
52 | |||
53 | static void ide_mm_outb (u8 value, unsigned long port) | ||
54 | { | ||
55 | writeb(value, (void __iomem *) port); | ||
56 | } | ||
57 | |||
58 | void SELECT_DRIVE (ide_drive_t *drive) | ||
59 | { | 31 | { |
60 | ide_hwif_t *hwif = drive->hwif; | 32 | ide_hwif_t *hwif = drive->hwif; |
61 | const struct ide_port_ops *port_ops = hwif->port_ops; | 33 | const struct ide_port_ops *port_ops = hwif->port_ops; |
@@ -78,277 +50,6 @@ void SELECT_MASK(ide_drive_t *drive, int mask) | |||
78 | port_ops->maskproc(drive, mask); | 50 | port_ops->maskproc(drive, mask); |
79 | } | 51 | } |
80 | 52 | ||
81 | void ide_exec_command(ide_hwif_t *hwif, u8 cmd) | ||
82 | { | ||
83 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
84 | writeb(cmd, (void __iomem *)hwif->io_ports.command_addr); | ||
85 | else | ||
86 | outb(cmd, hwif->io_ports.command_addr); | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(ide_exec_command); | ||
89 | |||
90 | u8 ide_read_status(ide_hwif_t *hwif) | ||
91 | { | ||
92 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
93 | return readb((void __iomem *)hwif->io_ports.status_addr); | ||
94 | else | ||
95 | return inb(hwif->io_ports.status_addr); | ||
96 | } | ||
97 | EXPORT_SYMBOL_GPL(ide_read_status); | ||
98 | |||
99 | u8 ide_read_altstatus(ide_hwif_t *hwif) | ||
100 | { | ||
101 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
102 | return readb((void __iomem *)hwif->io_ports.ctl_addr); | ||
103 | else | ||
104 | return inb(hwif->io_ports.ctl_addr); | ||
105 | } | ||
106 | EXPORT_SYMBOL_GPL(ide_read_altstatus); | ||
107 | |||
108 | void ide_set_irq(ide_hwif_t *hwif, int on) | ||
109 | { | ||
110 | u8 ctl = ATA_DEVCTL_OBS; | ||
111 | |||
112 | if (on == 4) { /* hack for SRST */ | ||
113 | ctl |= 4; | ||
114 | on &= ~4; | ||
115 | } | ||
116 | |||
117 | ctl |= on ? 0 : 2; | ||
118 | |||
119 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
120 | writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); | ||
121 | else | ||
122 | outb(ctl, hwif->io_ports.ctl_addr); | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(ide_set_irq); | ||
125 | |||
126 | void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | ||
127 | { | ||
128 | ide_hwif_t *hwif = drive->hwif; | ||
129 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
130 | struct ide_taskfile *tf = &task->tf; | ||
131 | void (*tf_outb)(u8 addr, unsigned long port); | ||
132 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
133 | u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | ||
134 | |||
135 | if (mmio) | ||
136 | tf_outb = ide_mm_outb; | ||
137 | else | ||
138 | tf_outb = ide_outb; | ||
139 | |||
140 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | ||
141 | HIHI = 0xFF; | ||
142 | |||
143 | if (task->tf_flags & IDE_TFLAG_OUT_DATA) { | ||
144 | u16 data = (tf->hob_data << 8) | tf->data; | ||
145 | |||
146 | if (mmio) | ||
147 | writew(data, (void __iomem *)io_ports->data_addr); | ||
148 | else | ||
149 | outw(data, io_ports->data_addr); | ||
150 | } | ||
151 | |||
152 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
153 | tf_outb(tf->hob_feature, io_ports->feature_addr); | ||
154 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
155 | tf_outb(tf->hob_nsect, io_ports->nsect_addr); | ||
156 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
157 | tf_outb(tf->hob_lbal, io_ports->lbal_addr); | ||
158 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
159 | tf_outb(tf->hob_lbam, io_ports->lbam_addr); | ||
160 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
161 | tf_outb(tf->hob_lbah, io_ports->lbah_addr); | ||
162 | |||
163 | if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
164 | tf_outb(tf->feature, io_ports->feature_addr); | ||
165 | if (task->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
166 | tf_outb(tf->nsect, io_ports->nsect_addr); | ||
167 | if (task->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
168 | tf_outb(tf->lbal, io_ports->lbal_addr); | ||
169 | if (task->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
170 | tf_outb(tf->lbam, io_ports->lbam_addr); | ||
171 | if (task->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
172 | tf_outb(tf->lbah, io_ports->lbah_addr); | ||
173 | |||
174 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
175 | tf_outb((tf->device & HIHI) | drive->select, | ||
176 | io_ports->device_addr); | ||
177 | } | ||
178 | EXPORT_SYMBOL_GPL(ide_tf_load); | ||
179 | |||
180 | void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | ||
181 | { | ||
182 | ide_hwif_t *hwif = drive->hwif; | ||
183 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
184 | struct ide_taskfile *tf = &task->tf; | ||
185 | void (*tf_outb)(u8 addr, unsigned long port); | ||
186 | u8 (*tf_inb)(unsigned long port); | ||
187 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
188 | |||
189 | if (mmio) { | ||
190 | tf_outb = ide_mm_outb; | ||
191 | tf_inb = ide_mm_inb; | ||
192 | } else { | ||
193 | tf_outb = ide_outb; | ||
194 | tf_inb = ide_inb; | ||
195 | } | ||
196 | |||
197 | if (task->tf_flags & IDE_TFLAG_IN_DATA) { | ||
198 | u16 data; | ||
199 | |||
200 | if (mmio) | ||
201 | data = readw((void __iomem *)io_ports->data_addr); | ||
202 | else | ||
203 | data = inw(io_ports->data_addr); | ||
204 | |||
205 | tf->data = data & 0xff; | ||
206 | tf->hob_data = (data >> 8) & 0xff; | ||
207 | } | ||
208 | |||
209 | /* be sure we're looking at the low order bits */ | ||
210 | tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); | ||
211 | |||
212 | if (task->tf_flags & IDE_TFLAG_IN_FEATURE) | ||
213 | tf->feature = tf_inb(io_ports->feature_addr); | ||
214 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | ||
215 | tf->nsect = tf_inb(io_ports->nsect_addr); | ||
216 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | ||
217 | tf->lbal = tf_inb(io_ports->lbal_addr); | ||
218 | if (task->tf_flags & IDE_TFLAG_IN_LBAM) | ||
219 | tf->lbam = tf_inb(io_ports->lbam_addr); | ||
220 | if (task->tf_flags & IDE_TFLAG_IN_LBAH) | ||
221 | tf->lbah = tf_inb(io_ports->lbah_addr); | ||
222 | if (task->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
223 | tf->device = tf_inb(io_ports->device_addr); | ||
224 | |||
225 | if (task->tf_flags & IDE_TFLAG_LBA48) { | ||
226 | tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); | ||
227 | |||
228 | if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) | ||
229 | tf->hob_feature = tf_inb(io_ports->feature_addr); | ||
230 | if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
231 | tf->hob_nsect = tf_inb(io_ports->nsect_addr); | ||
232 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
233 | tf->hob_lbal = tf_inb(io_ports->lbal_addr); | ||
234 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
235 | tf->hob_lbam = tf_inb(io_ports->lbam_addr); | ||
236 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
237 | tf->hob_lbah = tf_inb(io_ports->lbah_addr); | ||
238 | } | ||
239 | } | ||
240 | EXPORT_SYMBOL_GPL(ide_tf_read); | ||
241 | |||
242 | /* | ||
243 | * Some localbus EIDE interfaces require a special access sequence | ||
244 | * when using 32-bit I/O instructions to transfer data. We call this | ||
245 | * the "vlb_sync" sequence, which consists of three successive reads | ||
246 | * of the sector count register location, with interrupts disabled | ||
247 | * to ensure that the reads all happen together. | ||
248 | */ | ||
249 | static void ata_vlb_sync(unsigned long port) | ||
250 | { | ||
251 | (void)inb(port); | ||
252 | (void)inb(port); | ||
253 | (void)inb(port); | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * This is used for most PIO data transfers *from* the IDE interface | ||
258 | * | ||
259 | * These routines will round up any request for an odd number of bytes, | ||
260 | * so if an odd len is specified, be sure that there's at least one | ||
261 | * extra byte allocated for the buffer. | ||
262 | */ | ||
263 | void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, | ||
264 | unsigned int len) | ||
265 | { | ||
266 | ide_hwif_t *hwif = drive->hwif; | ||
267 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
268 | unsigned long data_addr = io_ports->data_addr; | ||
269 | u8 io_32bit = drive->io_32bit; | ||
270 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
271 | |||
272 | len++; | ||
273 | |||
274 | if (io_32bit) { | ||
275 | unsigned long uninitialized_var(flags); | ||
276 | |||
277 | if ((io_32bit & 2) && !mmio) { | ||
278 | local_irq_save(flags); | ||
279 | ata_vlb_sync(io_ports->nsect_addr); | ||
280 | } | ||
281 | |||
282 | if (mmio) | ||
283 | __ide_mm_insl((void __iomem *)data_addr, buf, len / 4); | ||
284 | else | ||
285 | insl(data_addr, buf, len / 4); | ||
286 | |||
287 | if ((io_32bit & 2) && !mmio) | ||
288 | local_irq_restore(flags); | ||
289 | |||
290 | if ((len & 3) >= 2) { | ||
291 | if (mmio) | ||
292 | __ide_mm_insw((void __iomem *)data_addr, | ||
293 | (u8 *)buf + (len & ~3), 1); | ||
294 | else | ||
295 | insw(data_addr, (u8 *)buf + (len & ~3), 1); | ||
296 | } | ||
297 | } else { | ||
298 | if (mmio) | ||
299 | __ide_mm_insw((void __iomem *)data_addr, buf, len / 2); | ||
300 | else | ||
301 | insw(data_addr, buf, len / 2); | ||
302 | } | ||
303 | } | ||
304 | EXPORT_SYMBOL_GPL(ide_input_data); | ||
305 | |||
306 | /* | ||
307 | * This is used for most PIO data transfers *to* the IDE interface | ||
308 | */ | ||
309 | void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, | ||
310 | unsigned int len) | ||
311 | { | ||
312 | ide_hwif_t *hwif = drive->hwif; | ||
313 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
314 | unsigned long data_addr = io_ports->data_addr; | ||
315 | u8 io_32bit = drive->io_32bit; | ||
316 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
317 | |||
318 | len++; | ||
319 | |||
320 | if (io_32bit) { | ||
321 | unsigned long uninitialized_var(flags); | ||
322 | |||
323 | if ((io_32bit & 2) && !mmio) { | ||
324 | local_irq_save(flags); | ||
325 | ata_vlb_sync(io_ports->nsect_addr); | ||
326 | } | ||
327 | |||
328 | if (mmio) | ||
329 | __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4); | ||
330 | else | ||
331 | outsl(data_addr, buf, len / 4); | ||
332 | |||
333 | if ((io_32bit & 2) && !mmio) | ||
334 | local_irq_restore(flags); | ||
335 | |||
336 | if ((len & 3) >= 2) { | ||
337 | if (mmio) | ||
338 | __ide_mm_outsw((void __iomem *)data_addr, | ||
339 | (u8 *)buf + (len & ~3), 1); | ||
340 | else | ||
341 | outsw(data_addr, (u8 *)buf + (len & ~3), 1); | ||
342 | } | ||
343 | } else { | ||
344 | if (mmio) | ||
345 | __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2); | ||
346 | else | ||
347 | outsw(data_addr, buf, len / 2); | ||
348 | } | ||
349 | } | ||
350 | EXPORT_SYMBOL_GPL(ide_output_data); | ||
351 | |||
352 | u8 ide_read_error(ide_drive_t *drive) | 53 | u8 ide_read_error(ide_drive_t *drive) |
353 | { | 54 | { |
354 | ide_task_t task; | 55 | ide_task_t task; |
@@ -362,35 +63,6 @@ u8 ide_read_error(ide_drive_t *drive) | |||
362 | } | 63 | } |
363 | EXPORT_SYMBOL_GPL(ide_read_error); | 64 | EXPORT_SYMBOL_GPL(ide_read_error); |
364 | 65 | ||
365 | void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) | ||
366 | { | ||
367 | ide_task_t task; | ||
368 | |||
369 | memset(&task, 0, sizeof(task)); | ||
370 | task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | | ||
371 | IDE_TFLAG_IN_NSECT; | ||
372 | |||
373 | drive->hwif->tp_ops->tf_read(drive, &task); | ||
374 | |||
375 | *bcount = (task.tf.lbah << 8) | task.tf.lbam; | ||
376 | *ireason = task.tf.nsect & 3; | ||
377 | } | ||
378 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); | ||
379 | |||
380 | const struct ide_tp_ops default_tp_ops = { | ||
381 | .exec_command = ide_exec_command, | ||
382 | .read_status = ide_read_status, | ||
383 | .read_altstatus = ide_read_altstatus, | ||
384 | |||
385 | .set_irq = ide_set_irq, | ||
386 | |||
387 | .tf_load = ide_tf_load, | ||
388 | .tf_read = ide_tf_read, | ||
389 | |||
390 | .input_data = ide_input_data, | ||
391 | .output_data = ide_output_data, | ||
392 | }; | ||
393 | |||
394 | void ide_fix_driveid(u16 *id) | 66 | void ide_fix_driveid(u16 *id) |
395 | { | 67 | { |
396 | #ifndef __LITTLE_ENDIAN | 68 | #ifndef __LITTLE_ENDIAN |
@@ -412,7 +84,7 @@ void ide_fix_driveid(u16 *id) | |||
412 | * returned by the ATA_CMD_ID_ATA[PI] commands. | 84 | * returned by the ATA_CMD_ID_ATA[PI] commands. |
413 | */ | 85 | */ |
414 | 86 | ||
415 | void ide_fixstring (u8 *s, const int bytecount, const int byteswap) | 87 | void ide_fixstring(u8 *s, const int bytecount, const int byteswap) |
416 | { | 88 | { |
417 | u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */ | 89 | u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */ |
418 | 90 | ||
@@ -435,44 +107,9 @@ void ide_fixstring (u8 *s, const int bytecount, const int byteswap) | |||
435 | while (p != end) | 107 | while (p != end) |
436 | *p++ = '\0'; | 108 | *p++ = '\0'; |
437 | } | 109 | } |
438 | |||
439 | EXPORT_SYMBOL(ide_fixstring); | 110 | EXPORT_SYMBOL(ide_fixstring); |
440 | 111 | ||
441 | /* | 112 | /* |
442 | * Needed for PCI irq sharing | ||
443 | */ | ||
444 | int drive_is_ready (ide_drive_t *drive) | ||
445 | { | ||
446 | ide_hwif_t *hwif = drive->hwif; | ||
447 | u8 stat = 0; | ||
448 | |||
449 | if (drive->waiting_for_dma) | ||
450 | return hwif->dma_ops->dma_test_irq(drive); | ||
451 | |||
452 | /* | ||
453 | * We do a passive status test under shared PCI interrupts on | ||
454 | * cards that truly share the ATA side interrupt, but may also share | ||
455 | * an interrupt with another pci card/device. We make no assumptions | ||
456 | * about possible isa-pnp and pci-pnp issues yet. | ||
457 | */ | ||
458 | if (hwif->io_ports.ctl_addr && | ||
459 | (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) | ||
460 | stat = hwif->tp_ops->read_altstatus(hwif); | ||
461 | else | ||
462 | /* Note: this may clear a pending IRQ!! */ | ||
463 | stat = hwif->tp_ops->read_status(hwif); | ||
464 | |||
465 | if (stat & ATA_BUSY) | ||
466 | /* drive busy: definitely not interrupting */ | ||
467 | return 0; | ||
468 | |||
469 | /* drive ready: *might* be interrupting */ | ||
470 | return 1; | ||
471 | } | ||
472 | |||
473 | EXPORT_SYMBOL(drive_is_ready); | ||
474 | |||
475 | /* | ||
476 | * This routine busy-waits for the drive status to be not "busy". | 113 | * This routine busy-waits for the drive status to be not "busy". |
477 | * It then checks the status for all of the "good" bits and none | 114 | * It then checks the status for all of the "good" bits and none |
478 | * of the "bad" bits, and if all is okay it returns 0. All other | 115 | * of the "bad" bits, and if all is okay it returns 0. All other |
@@ -483,7 +120,8 @@ EXPORT_SYMBOL(drive_is_ready); | |||
483 | * setting a timer to wake up at half second intervals thereafter, | 120 | * setting a timer to wake up at half second intervals thereafter, |
484 | * until timeout is achieved, before timing out. | 121 | * until timeout is achieved, before timing out. |
485 | */ | 122 | */ |
486 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) | 123 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, |
124 | unsigned long timeout, u8 *rstat) | ||
487 | { | 125 | { |
488 | ide_hwif_t *hwif = drive->hwif; | 126 | ide_hwif_t *hwif = drive->hwif; |
489 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 127 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
@@ -541,7 +179,8 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti | |||
541 | * The caller should return the updated value of "startstop" in this case, | 179 | * The caller should return the updated value of "startstop" in this case, |
542 | * "startstop" is unchanged when the function returns 0. | 180 | * "startstop" is unchanged when the function returns 0. |
543 | */ | 181 | */ |
544 | int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout) | 182 | int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, |
183 | u8 bad, unsigned long timeout) | ||
545 | { | 184 | { |
546 | int err; | 185 | int err; |
547 | u8 stat; | 186 | u8 stat; |
@@ -561,7 +200,6 @@ int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 ba | |||
561 | 200 | ||
562 | return err; | 201 | return err; |
563 | } | 202 | } |
564 | |||
565 | EXPORT_SYMBOL(ide_wait_stat); | 203 | EXPORT_SYMBOL(ide_wait_stat); |
566 | 204 | ||
567 | /** | 205 | /** |
@@ -582,7 +220,6 @@ int ide_in_drive_list(u16 *id, const struct drive_list_entry *table) | |||
582 | return 1; | 220 | return 1; |
583 | return 0; | 221 | return 0; |
584 | } | 222 | } |
585 | |||
586 | EXPORT_SYMBOL_GPL(ide_in_drive_list); | 223 | EXPORT_SYMBOL_GPL(ide_in_drive_list); |
587 | 224 | ||
588 | /* | 225 | /* |
@@ -607,7 +244,7 @@ static const struct drive_list_entry ivb_list[] = { | |||
607 | * All hosts that use the 80c ribbon must use! | 244 | * All hosts that use the 80c ribbon must use! |
608 | * The name is derived from upper byte of word 93 and the 80c ribbon. | 245 | * The name is derived from upper byte of word 93 and the 80c ribbon. |
609 | */ | 246 | */ |
610 | u8 eighty_ninty_three (ide_drive_t *drive) | 247 | u8 eighty_ninty_three(ide_drive_t *drive) |
611 | { | 248 | { |
612 | ide_hwif_t *hwif = drive->hwif; | 249 | ide_hwif_t *hwif = drive->hwif; |
613 | u16 *id = drive->id; | 250 | u16 *id = drive->id; |
@@ -652,47 +289,19 @@ no_80w: | |||
652 | 289 | ||
653 | int ide_driveid_update(ide_drive_t *drive) | 290 | int ide_driveid_update(ide_drive_t *drive) |
654 | { | 291 | { |
655 | ide_hwif_t *hwif = drive->hwif; | ||
656 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
657 | u16 *id; | 292 | u16 *id; |
658 | unsigned long flags; | 293 | int rc; |
659 | u8 stat; | ||
660 | |||
661 | /* | ||
662 | * Re-read drive->id for possible DMA mode | ||
663 | * change (copied from ide-probe.c) | ||
664 | */ | ||
665 | |||
666 | SELECT_MASK(drive, 1); | ||
667 | tp_ops->set_irq(hwif, 0); | ||
668 | msleep(50); | ||
669 | tp_ops->exec_command(hwif, ATA_CMD_ID_ATA); | ||
670 | 294 | ||
671 | if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) { | 295 | id = kmalloc(SECTOR_SIZE, GFP_ATOMIC); |
672 | SELECT_MASK(drive, 0); | 296 | if (id == NULL) |
673 | return 0; | 297 | return 0; |
674 | } | ||
675 | |||
676 | msleep(50); /* wait for IRQ and ATA_DRQ */ | ||
677 | stat = tp_ops->read_status(hwif); | ||
678 | 298 | ||
679 | if (!OK_STAT(stat, ATA_DRQ, BAD_R_STAT)) { | 299 | SELECT_MASK(drive, 1); |
680 | SELECT_MASK(drive, 0); | 300 | rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id); |
681 | printk("%s: CHECK for good STATUS\n", drive->name); | ||
682 | return 0; | ||
683 | } | ||
684 | local_irq_save(flags); | ||
685 | SELECT_MASK(drive, 0); | 301 | SELECT_MASK(drive, 0); |
686 | id = kmalloc(SECTOR_SIZE, GFP_ATOMIC); | 302 | |
687 | if (!id) { | 303 | if (rc) |
688 | local_irq_restore(flags); | 304 | goto out_err; |
689 | return 0; | ||
690 | } | ||
691 | tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); | ||
692 | (void)tp_ops->read_status(hwif); /* clear drive IRQ */ | ||
693 | local_irq_enable(); | ||
694 | local_irq_restore(flags); | ||
695 | ide_fix_driveid(id); | ||
696 | 305 | ||
697 | drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES]; | 306 | drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES]; |
698 | drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES]; | 307 | drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES]; |
@@ -705,6 +314,12 @@ int ide_driveid_update(ide_drive_t *drive) | |||
705 | ide_dma_off(drive); | 314 | ide_dma_off(drive); |
706 | 315 | ||
707 | return 1; | 316 | return 1; |
317 | out_err: | ||
318 | SELECT_MASK(drive, 0); | ||
319 | if (rc == 2) | ||
320 | printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__); | ||
321 | kfree(id); | ||
322 | return 0; | ||
708 | } | 323 | } |
709 | 324 | ||
710 | int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | 325 | int ide_config_drive_speed(ide_drive_t *drive, u8 speed) |
@@ -731,18 +346,15 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
731 | * but for some reason these don't work at | 346 | * but for some reason these don't work at |
732 | * this point (lost interrupt). | 347 | * this point (lost interrupt). |
733 | */ | 348 | */ |
734 | /* | 349 | |
735 | * Select the drive, and issue the SETFEATURES command | ||
736 | */ | ||
737 | disable_irq_nosync(hwif->irq); | ||
738 | |||
739 | /* | 350 | /* |
740 | * FIXME: we race against the running IRQ here if | 351 | * FIXME: we race against the running IRQ here if |
741 | * this is called from non IRQ context. If we use | 352 | * this is called from non IRQ context. If we use |
742 | * disable_irq() we hang on the error path. Work | 353 | * disable_irq() we hang on the error path. Work |
743 | * is needed. | 354 | * is needed. |
744 | */ | 355 | */ |
745 | 356 | disable_irq_nosync(hwif->irq); | |
357 | |||
746 | udelay(1); | 358 | udelay(1); |
747 | SELECT_DRIVE(drive); | 359 | SELECT_DRIVE(drive); |
748 | SELECT_MASK(drive, 1); | 360 | SELECT_MASK(drive, 1); |
@@ -812,8 +424,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
812 | * | 424 | * |
813 | * See also ide_execute_command | 425 | * See also ide_execute_command |
814 | */ | 426 | */ |
815 | static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, | 427 | void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, |
816 | unsigned int timeout, ide_expiry_t *expiry) | 428 | unsigned int timeout, ide_expiry_t *expiry) |
817 | { | 429 | { |
818 | ide_hwif_t *hwif = drive->hwif; | 430 | ide_hwif_t *hwif = drive->hwif; |
819 | 431 | ||
@@ -835,9 +447,8 @@ void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, | |||
835 | __ide_set_handler(drive, handler, timeout, expiry); | 447 | __ide_set_handler(drive, handler, timeout, expiry); |
836 | spin_unlock_irqrestore(&hwif->lock, flags); | 448 | spin_unlock_irqrestore(&hwif->lock, flags); |
837 | } | 449 | } |
838 | |||
839 | EXPORT_SYMBOL(ide_set_handler); | 450 | EXPORT_SYMBOL(ide_set_handler); |
840 | 451 | ||
841 | /** | 452 | /** |
842 | * ide_execute_command - execute an IDE command | 453 | * ide_execute_command - execute an IDE command |
843 | * @drive: IDE drive to issue the command against | 454 | * @drive: IDE drive to issue the command against |
@@ -847,7 +458,7 @@ EXPORT_SYMBOL(ide_set_handler); | |||
847 | * @expiry: handler to run on timeout | 458 | * @expiry: handler to run on timeout |
848 | * | 459 | * |
849 | * Helper function to issue an IDE command. This handles the | 460 | * Helper function to issue an IDE command. This handles the |
850 | * atomicity requirements, command timing and ensures that the | 461 | * atomicity requirements, command timing and ensures that the |
851 | * handler and IRQ setup do not race. All IDE command kick off | 462 | * handler and IRQ setup do not race. All IDE command kick off |
852 | * should go via this function or do equivalent locking. | 463 | * should go via this function or do equivalent locking. |
853 | */ | 464 | */ |
@@ -884,301 +495,6 @@ void ide_execute_pkt_cmd(ide_drive_t *drive) | |||
884 | } | 495 | } |
885 | EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); | 496 | EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); |
886 | 497 | ||
887 | static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) | ||
888 | { | ||
889 | struct request *rq = drive->hwif->rq; | ||
890 | |||
891 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) | ||
892 | ide_end_request(drive, err ? err : 1, 0); | ||
893 | } | ||
894 | |||
895 | /* needed below */ | ||
896 | static ide_startstop_t do_reset1 (ide_drive_t *, int); | ||
897 | |||
898 | /* | ||
899 | * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms | ||
900 | * during an atapi drive reset operation. If the drive has not yet responded, | ||
901 | * and we have not yet hit our maximum waiting time, then the timer is restarted | ||
902 | * for another 50ms. | ||
903 | */ | ||
904 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | ||
905 | { | ||
906 | ide_hwif_t *hwif = drive->hwif; | ||
907 | u8 stat; | ||
908 | |||
909 | SELECT_DRIVE(drive); | ||
910 | udelay (10); | ||
911 | stat = hwif->tp_ops->read_status(hwif); | ||
912 | |||
913 | if (OK_STAT(stat, 0, ATA_BUSY)) | ||
914 | printk("%s: ATAPI reset complete\n", drive->name); | ||
915 | else { | ||
916 | if (time_before(jiffies, hwif->poll_timeout)) { | ||
917 | ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); | ||
918 | /* continue polling */ | ||
919 | return ide_started; | ||
920 | } | ||
921 | /* end of polling */ | ||
922 | hwif->polling = 0; | ||
923 | printk("%s: ATAPI reset timed-out, status=0x%02x\n", | ||
924 | drive->name, stat); | ||
925 | /* do it the old fashioned way */ | ||
926 | return do_reset1(drive, 1); | ||
927 | } | ||
928 | /* done polling */ | ||
929 | hwif->polling = 0; | ||
930 | ide_complete_drive_reset(drive, 0); | ||
931 | return ide_stopped; | ||
932 | } | ||
933 | |||
934 | static void ide_reset_report_error(ide_hwif_t *hwif, u8 err) | ||
935 | { | ||
936 | static const char *err_master_vals[] = | ||
937 | { NULL, "passed", "formatter device error", | ||
938 | "sector buffer error", "ECC circuitry error", | ||
939 | "controlling MPU error" }; | ||
940 | |||
941 | u8 err_master = err & 0x7f; | ||
942 | |||
943 | printk(KERN_ERR "%s: reset: master: ", hwif->name); | ||
944 | if (err_master && err_master < 6) | ||
945 | printk(KERN_CONT "%s", err_master_vals[err_master]); | ||
946 | else | ||
947 | printk(KERN_CONT "error (0x%02x?)", err); | ||
948 | if (err & 0x80) | ||
949 | printk(KERN_CONT "; slave: failed"); | ||
950 | printk(KERN_CONT "\n"); | ||
951 | } | ||
952 | |||
953 | /* | ||
954 | * reset_pollfunc() gets invoked to poll the interface for completion every 50ms | ||
955 | * during an ide reset operation. If the drives have not yet responded, | ||
956 | * and we have not yet hit our maximum waiting time, then the timer is restarted | ||
957 | * for another 50ms. | ||
958 | */ | ||
959 | static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | ||
960 | { | ||
961 | ide_hwif_t *hwif = drive->hwif; | ||
962 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
963 | u8 tmp; | ||
964 | int err = 0; | ||
965 | |||
966 | if (port_ops && port_ops->reset_poll) { | ||
967 | err = port_ops->reset_poll(drive); | ||
968 | if (err) { | ||
969 | printk(KERN_ERR "%s: host reset_poll failure for %s.\n", | ||
970 | hwif->name, drive->name); | ||
971 | goto out; | ||
972 | } | ||
973 | } | ||
974 | |||
975 | tmp = hwif->tp_ops->read_status(hwif); | ||
976 | |||
977 | if (!OK_STAT(tmp, 0, ATA_BUSY)) { | ||
978 | if (time_before(jiffies, hwif->poll_timeout)) { | ||
979 | ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); | ||
980 | /* continue polling */ | ||
981 | return ide_started; | ||
982 | } | ||
983 | printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp); | ||
984 | drive->failures++; | ||
985 | err = -EIO; | ||
986 | } else { | ||
987 | tmp = ide_read_error(drive); | ||
988 | |||
989 | if (tmp == 1) { | ||
990 | printk(KERN_INFO "%s: reset: success\n", hwif->name); | ||
991 | drive->failures = 0; | ||
992 | } else { | ||
993 | ide_reset_report_error(hwif, tmp); | ||
994 | drive->failures++; | ||
995 | err = -EIO; | ||
996 | } | ||
997 | } | ||
998 | out: | ||
999 | hwif->polling = 0; /* done polling */ | ||
1000 | ide_complete_drive_reset(drive, err); | ||
1001 | return ide_stopped; | ||
1002 | } | ||
1003 | |||
1004 | static void ide_disk_pre_reset(ide_drive_t *drive) | ||
1005 | { | ||
1006 | int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1; | ||
1007 | |||
1008 | drive->special.all = 0; | ||
1009 | drive->special.b.set_geometry = legacy; | ||
1010 | drive->special.b.recalibrate = legacy; | ||
1011 | |||
1012 | drive->mult_count = 0; | ||
1013 | drive->dev_flags &= ~IDE_DFLAG_PARKED; | ||
1014 | |||
1015 | if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 && | ||
1016 | (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) | ||
1017 | drive->mult_req = 0; | ||
1018 | |||
1019 | if (drive->mult_req != drive->mult_count) | ||
1020 | drive->special.b.set_multmode = 1; | ||
1021 | } | ||
1022 | |||
1023 | static void pre_reset(ide_drive_t *drive) | ||
1024 | { | ||
1025 | const struct ide_port_ops *port_ops = drive->hwif->port_ops; | ||
1026 | |||
1027 | if (drive->media == ide_disk) | ||
1028 | ide_disk_pre_reset(drive); | ||
1029 | else | ||
1030 | drive->dev_flags |= IDE_DFLAG_POST_RESET; | ||
1031 | |||
1032 | if (drive->dev_flags & IDE_DFLAG_USING_DMA) { | ||
1033 | if (drive->crc_count) | ||
1034 | ide_check_dma_crc(drive); | ||
1035 | else | ||
1036 | ide_dma_off(drive); | ||
1037 | } | ||
1038 | |||
1039 | if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) { | ||
1040 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) { | ||
1041 | drive->dev_flags &= ~IDE_DFLAG_UNMASK; | ||
1042 | drive->io_32bit = 0; | ||
1043 | } | ||
1044 | return; | ||
1045 | } | ||
1046 | |||
1047 | if (port_ops && port_ops->pre_reset) | ||
1048 | port_ops->pre_reset(drive); | ||
1049 | |||
1050 | if (drive->current_speed != 0xff) | ||
1051 | drive->desired_speed = drive->current_speed; | ||
1052 | drive->current_speed = 0xff; | ||
1053 | } | ||
1054 | |||
1055 | /* | ||
1056 | * do_reset1() attempts to recover a confused drive by resetting it. | ||
1057 | * Unfortunately, resetting a disk drive actually resets all devices on | ||
1058 | * the same interface, so it can really be thought of as resetting the | ||
1059 | * interface rather than resetting the drive. | ||
1060 | * | ||
1061 | * ATAPI devices have their own reset mechanism which allows them to be | ||
1062 | * individually reset without clobbering other devices on the same interface. | ||
1063 | * | ||
1064 | * Unfortunately, the IDE interface does not generate an interrupt to let | ||
1065 | * us know when the reset operation has finished, so we must poll for this. | ||
1066 | * Equally poor, though, is the fact that this may a very long time to complete, | ||
1067 | * (up to 30 seconds worstcase). So, instead of busy-waiting here for it, | ||
1068 | * we set a timer to poll at 50ms intervals. | ||
1069 | */ | ||
1070 | static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | ||
1071 | { | ||
1072 | ide_hwif_t *hwif = drive->hwif; | ||
1073 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
1074 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
1075 | const struct ide_port_ops *port_ops; | ||
1076 | ide_drive_t *tdrive; | ||
1077 | unsigned long flags, timeout; | ||
1078 | int i; | ||
1079 | DEFINE_WAIT(wait); | ||
1080 | |||
1081 | spin_lock_irqsave(&hwif->lock, flags); | ||
1082 | |||
1083 | /* We must not reset with running handlers */ | ||
1084 | BUG_ON(hwif->handler != NULL); | ||
1085 | |||
1086 | /* For an ATAPI device, first try an ATAPI SRST. */ | ||
1087 | if (drive->media != ide_disk && !do_not_try_atapi) { | ||
1088 | pre_reset(drive); | ||
1089 | SELECT_DRIVE(drive); | ||
1090 | udelay (20); | ||
1091 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); | ||
1092 | ndelay(400); | ||
1093 | hwif->poll_timeout = jiffies + WAIT_WORSTCASE; | ||
1094 | hwif->polling = 1; | ||
1095 | __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); | ||
1096 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
1097 | return ide_started; | ||
1098 | } | ||
1099 | |||
1100 | /* We must not disturb devices in the IDE_DFLAG_PARKED state. */ | ||
1101 | do { | ||
1102 | unsigned long now; | ||
1103 | |||
1104 | prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE); | ||
1105 | timeout = jiffies; | ||
1106 | ide_port_for_each_dev(i, tdrive, hwif) { | ||
1107 | if (tdrive->dev_flags & IDE_DFLAG_PRESENT && | ||
1108 | tdrive->dev_flags & IDE_DFLAG_PARKED && | ||
1109 | time_after(tdrive->sleep, timeout)) | ||
1110 | timeout = tdrive->sleep; | ||
1111 | } | ||
1112 | |||
1113 | now = jiffies; | ||
1114 | if (time_before_eq(timeout, now)) | ||
1115 | break; | ||
1116 | |||
1117 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
1118 | timeout = schedule_timeout_uninterruptible(timeout - now); | ||
1119 | spin_lock_irqsave(&hwif->lock, flags); | ||
1120 | } while (timeout); | ||
1121 | finish_wait(&ide_park_wq, &wait); | ||
1122 | |||
1123 | /* | ||
1124 | * First, reset any device state data we were maintaining | ||
1125 | * for any of the drives on this interface. | ||
1126 | */ | ||
1127 | ide_port_for_each_dev(i, tdrive, hwif) | ||
1128 | pre_reset(tdrive); | ||
1129 | |||
1130 | if (io_ports->ctl_addr == 0) { | ||
1131 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
1132 | ide_complete_drive_reset(drive, -ENXIO); | ||
1133 | return ide_stopped; | ||
1134 | } | ||
1135 | |||
1136 | /* | ||
1137 | * Note that we also set nIEN while resetting the device, | ||
1138 | * to mask unwanted interrupts from the interface during the reset. | ||
1139 | * However, due to the design of PC hardware, this will cause an | ||
1140 | * immediate interrupt due to the edge transition it produces. | ||
1141 | * This single interrupt gives us a "fast poll" for drives that | ||
1142 | * recover from reset very quickly, saving us the first 50ms wait time. | ||
1143 | * | ||
1144 | * TODO: add ->softreset method and stop abusing ->set_irq | ||
1145 | */ | ||
1146 | /* set SRST and nIEN */ | ||
1147 | tp_ops->set_irq(hwif, 4); | ||
1148 | /* more than enough time */ | ||
1149 | udelay(10); | ||
1150 | /* clear SRST, leave nIEN (unless device is on the quirk list) */ | ||
1151 | tp_ops->set_irq(hwif, drive->quirk_list == 2); | ||
1152 | /* more than enough time */ | ||
1153 | udelay(10); | ||
1154 | hwif->poll_timeout = jiffies + WAIT_WORSTCASE; | ||
1155 | hwif->polling = 1; | ||
1156 | __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); | ||
1157 | |||
1158 | /* | ||
1159 | * Some weird controller like resetting themselves to a strange | ||
1160 | * state when the disks are reset this way. At least, the Winbond | ||
1161 | * 553 documentation says that | ||
1162 | */ | ||
1163 | port_ops = hwif->port_ops; | ||
1164 | if (port_ops && port_ops->resetproc) | ||
1165 | port_ops->resetproc(drive); | ||
1166 | |||
1167 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
1168 | return ide_started; | ||
1169 | } | ||
1170 | |||
1171 | /* | ||
1172 | * ide_do_reset() is the entry point to the drive/interface reset code. | ||
1173 | */ | ||
1174 | |||
1175 | ide_startstop_t ide_do_reset (ide_drive_t *drive) | ||
1176 | { | ||
1177 | return do_reset1(drive, 0); | ||
1178 | } | ||
1179 | |||
1180 | EXPORT_SYMBOL(ide_do_reset); | ||
1181 | |||
1182 | /* | 498 | /* |
1183 | * ide_wait_not_busy() waits for the currently selected device on the hwif | 499 | * ide_wait_not_busy() waits for the currently selected device on the hwif |
1184 | * to report a non-busy status, see comments in ide_probe_port(). | 500 | * to report a non-busy status, see comments in ide_probe_port(). |
@@ -1187,7 +503,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) | |||
1187 | { | 503 | { |
1188 | u8 stat = 0; | 504 | u8 stat = 0; |
1189 | 505 | ||
1190 | while(timeout--) { | 506 | while (timeout--) { |
1191 | /* | 507 | /* |
1192 | * Turn this into a schedule() sleep once I'm sure | 508 | * Turn this into a schedule() sleep once I'm sure |
1193 | * about locking issues (2.5 work ?). | 509 | * about locking issues (2.5 work ?). |
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 09526a0de734..f6c683dd2987 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -5,163 +5,6 @@ | |||
5 | #include <linux/ide.h> | 5 | #include <linux/ide.h> |
6 | #include <linux/bitops.h> | 6 | #include <linux/bitops.h> |
7 | 7 | ||
8 | static const char *udma_str[] = | ||
9 | { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44", | ||
10 | "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" }; | ||
11 | static const char *mwdma_str[] = | ||
12 | { "MWDMA0", "MWDMA1", "MWDMA2" }; | ||
13 | static const char *swdma_str[] = | ||
14 | { "SWDMA0", "SWDMA1", "SWDMA2" }; | ||
15 | static const char *pio_str[] = | ||
16 | { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" }; | ||
17 | |||
18 | /** | ||
19 | * ide_xfer_verbose - return IDE mode names | ||
20 | * @mode: transfer mode | ||
21 | * | ||
22 | * Returns a constant string giving the name of the mode | ||
23 | * requested. | ||
24 | */ | ||
25 | |||
26 | const char *ide_xfer_verbose(u8 mode) | ||
27 | { | ||
28 | const char *s; | ||
29 | u8 i = mode & 0xf; | ||
30 | |||
31 | if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7) | ||
32 | s = udma_str[i]; | ||
33 | else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2) | ||
34 | s = mwdma_str[i]; | ||
35 | else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2) | ||
36 | s = swdma_str[i]; | ||
37 | else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5) | ||
38 | s = pio_str[i & 0x7]; | ||
39 | else if (mode == XFER_PIO_SLOW) | ||
40 | s = "PIO SLOW"; | ||
41 | else | ||
42 | s = "XFER ERROR"; | ||
43 | |||
44 | return s; | ||
45 | } | ||
46 | EXPORT_SYMBOL(ide_xfer_verbose); | ||
47 | |||
48 | /** | ||
49 | * ide_rate_filter - filter transfer mode | ||
50 | * @drive: IDE device | ||
51 | * @speed: desired speed | ||
52 | * | ||
53 | * Given the available transfer modes this function returns | ||
54 | * the best available speed at or below the speed requested. | ||
55 | * | ||
56 | * TODO: check device PIO capabilities | ||
57 | */ | ||
58 | |||
59 | static u8 ide_rate_filter(ide_drive_t *drive, u8 speed) | ||
60 | { | ||
61 | ide_hwif_t *hwif = drive->hwif; | ||
62 | u8 mode = ide_find_dma_mode(drive, speed); | ||
63 | |||
64 | if (mode == 0) { | ||
65 | if (hwif->pio_mask) | ||
66 | mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0; | ||
67 | else | ||
68 | mode = XFER_PIO_4; | ||
69 | } | ||
70 | |||
71 | /* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */ | ||
72 | |||
73 | return min(speed, mode); | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * ide_get_best_pio_mode - get PIO mode from drive | ||
78 | * @drive: drive to consider | ||
79 | * @mode_wanted: preferred mode | ||
80 | * @max_mode: highest allowed mode | ||
81 | * | ||
82 | * This routine returns the recommended PIO settings for a given drive, | ||
83 | * based on the drive->id information and the ide_pio_blacklist[]. | ||
84 | * | ||
85 | * Drive PIO mode is auto-selected if 255 is passed as mode_wanted. | ||
86 | * This is used by most chipset support modules when "auto-tuning". | ||
87 | */ | ||
88 | |||
89 | u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) | ||
90 | { | ||
91 | u16 *id = drive->id; | ||
92 | int pio_mode = -1, overridden = 0; | ||
93 | |||
94 | if (mode_wanted != 255) | ||
95 | return min_t(u8, mode_wanted, max_mode); | ||
96 | |||
97 | if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0) | ||
98 | pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]); | ||
99 | |||
100 | if (pio_mode != -1) { | ||
101 | printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name); | ||
102 | } else { | ||
103 | pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8; | ||
104 | if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */ | ||
105 | pio_mode = 2; | ||
106 | overridden = 1; | ||
107 | } | ||
108 | |||
109 | if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */ | ||
110 | if (ata_id_has_iordy(id)) { | ||
111 | if (id[ATA_ID_PIO_MODES] & 7) { | ||
112 | overridden = 0; | ||
113 | if (id[ATA_ID_PIO_MODES] & 4) | ||
114 | pio_mode = 5; | ||
115 | else if (id[ATA_ID_PIO_MODES] & 2) | ||
116 | pio_mode = 4; | ||
117 | else | ||
118 | pio_mode = 3; | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | |||
123 | if (overridden) | ||
124 | printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n", | ||
125 | drive->name); | ||
126 | } | ||
127 | |||
128 | if (pio_mode > max_mode) | ||
129 | pio_mode = max_mode; | ||
130 | |||
131 | return pio_mode; | ||
132 | } | ||
133 | EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); | ||
134 | |||
135 | /* req_pio == "255" for auto-tune */ | ||
136 | void ide_set_pio(ide_drive_t *drive, u8 req_pio) | ||
137 | { | ||
138 | ide_hwif_t *hwif = drive->hwif; | ||
139 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
140 | u8 host_pio, pio; | ||
141 | |||
142 | if (port_ops == NULL || port_ops->set_pio_mode == NULL || | ||
143 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
144 | return; | ||
145 | |||
146 | BUG_ON(hwif->pio_mask == 0x00); | ||
147 | |||
148 | host_pio = fls(hwif->pio_mask) - 1; | ||
149 | |||
150 | pio = ide_get_best_pio_mode(drive, req_pio, host_pio); | ||
151 | |||
152 | /* | ||
153 | * TODO: | ||
154 | * - report device max PIO mode | ||
155 | * - check req_pio != 255 against device max PIO mode | ||
156 | */ | ||
157 | printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n", | ||
158 | drive->name, host_pio, req_pio, | ||
159 | req_pio == 255 ? "(auto-tune)" : "", pio); | ||
160 | |||
161 | (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio); | ||
162 | } | ||
163 | EXPORT_SYMBOL_GPL(ide_set_pio); | ||
164 | |||
165 | /** | 8 | /** |
166 | * ide_toggle_bounce - handle bounce buffering | 9 | * ide_toggle_bounce - handle bounce buffering |
167 | * @drive: drive to update | 10 | * @drive: drive to update |
@@ -188,89 +31,6 @@ void ide_toggle_bounce(ide_drive_t *drive, int on) | |||
188 | blk_queue_bounce_limit(drive->queue, addr); | 31 | blk_queue_bounce_limit(drive->queue, addr); |
189 | } | 32 | } |
190 | 33 | ||
191 | int ide_set_pio_mode(ide_drive_t *drive, const u8 mode) | ||
192 | { | ||
193 | ide_hwif_t *hwif = drive->hwif; | ||
194 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
195 | |||
196 | if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) | ||
197 | return 0; | ||
198 | |||
199 | if (port_ops == NULL || port_ops->set_pio_mode == NULL) | ||
200 | return -1; | ||
201 | |||
202 | /* | ||
203 | * TODO: temporary hack for some legacy host drivers that didn't | ||
204 | * set transfer mode on the device in ->set_pio_mode method... | ||
205 | */ | ||
206 | if (port_ops->set_dma_mode == NULL) { | ||
207 | port_ops->set_pio_mode(drive, mode - XFER_PIO_0); | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { | ||
212 | if (ide_config_drive_speed(drive, mode)) | ||
213 | return -1; | ||
214 | port_ops->set_pio_mode(drive, mode - XFER_PIO_0); | ||
215 | return 0; | ||
216 | } else { | ||
217 | port_ops->set_pio_mode(drive, mode - XFER_PIO_0); | ||
218 | return ide_config_drive_speed(drive, mode); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | int ide_set_dma_mode(ide_drive_t *drive, const u8 mode) | ||
223 | { | ||
224 | ide_hwif_t *hwif = drive->hwif; | ||
225 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
226 | |||
227 | if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) | ||
228 | return 0; | ||
229 | |||
230 | if (port_ops == NULL || port_ops->set_dma_mode == NULL) | ||
231 | return -1; | ||
232 | |||
233 | if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { | ||
234 | if (ide_config_drive_speed(drive, mode)) | ||
235 | return -1; | ||
236 | port_ops->set_dma_mode(drive, mode); | ||
237 | return 0; | ||
238 | } else { | ||
239 | port_ops->set_dma_mode(drive, mode); | ||
240 | return ide_config_drive_speed(drive, mode); | ||
241 | } | ||
242 | } | ||
243 | EXPORT_SYMBOL_GPL(ide_set_dma_mode); | ||
244 | |||
245 | /** | ||
246 | * ide_set_xfer_rate - set transfer rate | ||
247 | * @drive: drive to set | ||
248 | * @rate: speed to attempt to set | ||
249 | * | ||
250 | * General helper for setting the speed of an IDE device. This | ||
251 | * function knows about user enforced limits from the configuration | ||
252 | * which ->set_pio_mode/->set_dma_mode does not. | ||
253 | */ | ||
254 | |||
255 | int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | ||
256 | { | ||
257 | ide_hwif_t *hwif = drive->hwif; | ||
258 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
259 | |||
260 | if (port_ops == NULL || port_ops->set_dma_mode == NULL || | ||
261 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
262 | return -1; | ||
263 | |||
264 | rate = ide_rate_filter(drive, rate); | ||
265 | |||
266 | BUG_ON(rate < XFER_PIO_0); | ||
267 | |||
268 | if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) | ||
269 | return ide_set_pio_mode(drive, rate); | ||
270 | |||
271 | return ide_set_dma_mode(drive, rate); | ||
272 | } | ||
273 | |||
274 | static void ide_dump_opcode(ide_drive_t *drive) | 34 | static void ide_dump_opcode(ide_drive_t *drive) |
275 | { | 35 | { |
276 | struct request *rq = drive->hwif->rq; | 36 | struct request *rq = drive->hwif->rq; |
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index c875a957596c..f30e52152fcb 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
2 | #include <linux/ide.h> | 2 | #include <linux/ide.h> |
3 | #include <linux/hdreg.h> | ||
3 | #include <linux/jiffies.h> | 4 | #include <linux/jiffies.h> |
4 | #include <linux/blkdev.h> | 5 | #include <linux/blkdev.h> |
5 | 6 | ||
@@ -60,6 +61,30 @@ out: | |||
60 | return; | 61 | return; |
61 | } | 62 | } |
62 | 63 | ||
64 | ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq) | ||
65 | { | ||
66 | ide_task_t task; | ||
67 | struct ide_taskfile *tf = &task.tf; | ||
68 | |||
69 | memset(&task, 0, sizeof(task)); | ||
70 | if (rq->cmd[0] == REQ_PARK_HEADS) { | ||
71 | drive->sleep = *(unsigned long *)rq->special; | ||
72 | drive->dev_flags |= IDE_DFLAG_SLEEPING; | ||
73 | tf->command = ATA_CMD_IDLEIMMEDIATE; | ||
74 | tf->feature = 0x44; | ||
75 | tf->lbal = 0x4c; | ||
76 | tf->lbam = 0x4e; | ||
77 | tf->lbah = 0x55; | ||
78 | task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER; | ||
79 | } else /* cmd == REQ_UNPARK_HEADS */ | ||
80 | tf->command = ATA_CMD_CHK_POWER; | ||
81 | |||
82 | task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | ||
83 | task.rq = rq; | ||
84 | drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA; | ||
85 | return do_rw_taskfile(drive, &task); | ||
86 | } | ||
87 | |||
63 | ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, | 88 | ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, |
64 | char *buf) | 89 | char *buf) |
65 | { | 90 | { |
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c index bddae2b329a0..61111fd27130 100644 --- a/drivers/ide/ide-pci-generic.c +++ b/drivers/ide/ide-pci-generic.c | |||
@@ -33,8 +33,6 @@ static int ide_generic_all; /* Set to claim all devices */ | |||
33 | module_param_named(all_generic_ide, ide_generic_all, bool, 0444); | 33 | module_param_named(all_generic_ide, ide_generic_all, bool, 0444); |
34 | MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); | 34 | MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); |
35 | 35 | ||
36 | #define IDE_HFLAGS_UMC (IDE_HFLAG_NO_DMA | IDE_HFLAG_FORCE_LEGACY_IRQS) | ||
37 | |||
38 | #define DECLARE_GENERIC_PCI_DEV(extra_flags) \ | 36 | #define DECLARE_GENERIC_PCI_DEV(extra_flags) \ |
39 | { \ | 37 | { \ |
40 | .name = DRV_NAME, \ | 38 | .name = DRV_NAME, \ |
@@ -61,7 +59,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = { | |||
61 | /* 2: SAMURAI / HT6565 / HINT_IDE */ | 59 | /* 2: SAMURAI / HT6565 / HINT_IDE */ |
62 | DECLARE_GENERIC_PCI_DEV(0), | 60 | DECLARE_GENERIC_PCI_DEV(0), |
63 | /* 3: UM8673F / UM8886A / UM8886BF */ | 61 | /* 3: UM8673F / UM8886A / UM8886BF */ |
64 | DECLARE_GENERIC_PCI_DEV(IDE_HFLAGS_UMC), | 62 | DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_DMA), |
65 | /* 4: VIA_IDE / OPTI621V / Piccolo010{2,3,5} */ | 63 | /* 4: VIA_IDE / OPTI621V / Piccolo010{2,3,5} */ |
66 | DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_AUTODMA), | 64 | DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_AUTODMA), |
67 | 65 | ||
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index ee8e3e7cad51..974067043fba 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -181,16 +181,16 @@ static void ide_classify_atapi_dev(ide_drive_t *drive) | |||
181 | * do_identify - identify a drive | 181 | * do_identify - identify a drive |
182 | * @drive: drive to identify | 182 | * @drive: drive to identify |
183 | * @cmd: command used | 183 | * @cmd: command used |
184 | * @id: buffer for IDENTIFY data | ||
184 | * | 185 | * |
185 | * Called when we have issued a drive identify command to | 186 | * Called when we have issued a drive identify command to |
186 | * read and parse the results. This function is run with | 187 | * read and parse the results. This function is run with |
187 | * interrupts disabled. | 188 | * interrupts disabled. |
188 | */ | 189 | */ |
189 | 190 | ||
190 | static void do_identify(ide_drive_t *drive, u8 cmd) | 191 | static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) |
191 | { | 192 | { |
192 | ide_hwif_t *hwif = drive->hwif; | 193 | ide_hwif_t *hwif = drive->hwif; |
193 | u16 *id = drive->id; | ||
194 | char *m = (char *)&id[ATA_ID_PROD]; | 194 | char *m = (char *)&id[ATA_ID_PROD]; |
195 | unsigned long flags; | 195 | unsigned long flags; |
196 | int bswap = 1; | 196 | int bswap = 1; |
@@ -233,16 +233,6 @@ static void do_identify(ide_drive_t *drive, u8 cmd) | |||
233 | drive->dev_flags |= IDE_DFLAG_PRESENT; | 233 | drive->dev_flags |= IDE_DFLAG_PRESENT; |
234 | drive->dev_flags &= ~IDE_DFLAG_DEAD; | 234 | drive->dev_flags &= ~IDE_DFLAG_DEAD; |
235 | 235 | ||
236 | /* | ||
237 | * Check for an ATAPI device | ||
238 | */ | ||
239 | if (cmd == ATA_CMD_ID_ATAPI) | ||
240 | ide_classify_atapi_dev(drive); | ||
241 | else | ||
242 | /* | ||
243 | * Not an ATAPI device: looks like a "regular" hard disk | ||
244 | */ | ||
245 | ide_classify_ata_dev(drive); | ||
246 | return; | 236 | return; |
247 | err_misc: | 237 | err_misc: |
248 | kfree(id); | 238 | kfree(id); |
@@ -250,21 +240,19 @@ err_misc: | |||
250 | } | 240 | } |
251 | 241 | ||
252 | /** | 242 | /** |
253 | * actual_try_to_identify - send ata/atapi identify | 243 | * ide_dev_read_id - send ATA/ATAPI IDENTIFY command |
254 | * @drive: drive to identify | 244 | * @drive: drive to identify |
255 | * @cmd: command to use | 245 | * @cmd: command to use |
246 | * @id: buffer for IDENTIFY data | ||
256 | * | 247 | * |
257 | * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive | 248 | * Sends an ATA(PI) IDENTIFY request to a drive and waits for a response. |
258 | * and waits for a response. It also monitors irqs while this is | ||
259 | * happening, in hope of automatically determining which one is | ||
260 | * being used by the interface. | ||
261 | * | 249 | * |
262 | * Returns: 0 device was identified | 250 | * Returns: 0 device was identified |
263 | * 1 device timed-out (no response to identify request) | 251 | * 1 device timed-out (no response to identify request) |
264 | * 2 device aborted the command (refused to identify itself) | 252 | * 2 device aborted the command (refused to identify itself) |
265 | */ | 253 | */ |
266 | 254 | ||
267 | static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | 255 | int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) |
268 | { | 256 | { |
269 | ide_hwif_t *hwif = drive->hwif; | 257 | ide_hwif_t *hwif = drive->hwif; |
270 | struct ide_io_ports *io_ports = &hwif->io_ports; | 258 | struct ide_io_ports *io_ports = &hwif->io_ports; |
@@ -273,6 +261,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
273 | unsigned long timeout; | 261 | unsigned long timeout; |
274 | u8 s = 0, a = 0; | 262 | u8 s = 0, a = 0; |
275 | 263 | ||
264 | /* | ||
265 | * Disable device IRQ. Otherwise we'll get spurious interrupts | ||
266 | * during the identify phase that the IRQ handler isn't expecting. | ||
267 | */ | ||
268 | if (io_ports->ctl_addr) | ||
269 | tp_ops->set_irq(hwif, 0); | ||
270 | |||
276 | /* take a deep breath */ | 271 | /* take a deep breath */ |
277 | msleep(50); | 272 | msleep(50); |
278 | 273 | ||
@@ -317,7 +312,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
317 | 312 | ||
318 | if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) { | 313 | if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) { |
319 | /* drive returned ID */ | 314 | /* drive returned ID */ |
320 | do_identify(drive, cmd); | 315 | do_identify(drive, cmd, id); |
321 | /* drive responded with ID */ | 316 | /* drive responded with ID */ |
322 | rc = 0; | 317 | rc = 0; |
323 | /* clear drive IRQ */ | 318 | /* clear drive IRQ */ |
@@ -329,63 +324,6 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
329 | return rc; | 324 | return rc; |
330 | } | 325 | } |
331 | 326 | ||
332 | /** | ||
333 | * try_to_identify - try to identify a drive | ||
334 | * @drive: drive to probe | ||
335 | * @cmd: command to use | ||
336 | * | ||
337 | * Issue the identify command and then do IRQ probing to | ||
338 | * complete the identification when needed by finding the | ||
339 | * IRQ the drive is attached to | ||
340 | */ | ||
341 | |||
342 | static int try_to_identify (ide_drive_t *drive, u8 cmd) | ||
343 | { | ||
344 | ide_hwif_t *hwif = drive->hwif; | ||
345 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
346 | int retval; | ||
347 | int autoprobe = 0; | ||
348 | unsigned long cookie = 0; | ||
349 | |||
350 | /* | ||
351 | * Disable device irq unless we need to | ||
352 | * probe for it. Otherwise we'll get spurious | ||
353 | * interrupts during the identify-phase that | ||
354 | * the irq handler isn't expecting. | ||
355 | */ | ||
356 | if (hwif->io_ports.ctl_addr) { | ||
357 | if (!hwif->irq) { | ||
358 | autoprobe = 1; | ||
359 | cookie = probe_irq_on(); | ||
360 | } | ||
361 | tp_ops->set_irq(hwif, autoprobe); | ||
362 | } | ||
363 | |||
364 | retval = actual_try_to_identify(drive, cmd); | ||
365 | |||
366 | if (autoprobe) { | ||
367 | int irq; | ||
368 | |||
369 | tp_ops->set_irq(hwif, 0); | ||
370 | /* clear drive IRQ */ | ||
371 | (void)tp_ops->read_status(hwif); | ||
372 | udelay(5); | ||
373 | irq = probe_irq_off(cookie); | ||
374 | if (!hwif->irq) { | ||
375 | if (irq > 0) { | ||
376 | hwif->irq = irq; | ||
377 | } else { | ||
378 | /* Mmmm.. multiple IRQs.. | ||
379 | * don't know which was ours | ||
380 | */ | ||
381 | printk(KERN_ERR "%s: IRQ probe failed (0x%lx)\n", | ||
382 | drive->name, cookie); | ||
383 | } | ||
384 | } | ||
385 | } | ||
386 | return retval; | ||
387 | } | ||
388 | |||
389 | int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus) | 327 | int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus) |
390 | { | 328 | { |
391 | u8 stat; | 329 | u8 stat; |
@@ -440,6 +378,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
440 | { | 378 | { |
441 | ide_hwif_t *hwif = drive->hwif; | 379 | ide_hwif_t *hwif = drive->hwif; |
442 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 380 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
381 | u16 *id = drive->id; | ||
443 | int rc; | 382 | int rc; |
444 | u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat; | 383 | u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat; |
445 | 384 | ||
@@ -475,11 +414,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
475 | 414 | ||
476 | if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || | 415 | if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || |
477 | present || cmd == ATA_CMD_ID_ATAPI) { | 416 | present || cmd == ATA_CMD_ID_ATAPI) { |
478 | /* send cmd and wait */ | 417 | rc = ide_dev_read_id(drive, cmd, id); |
479 | if ((rc = try_to_identify(drive, cmd))) { | 418 | if (rc) |
480 | /* failed: try again */ | 419 | /* failed: try again */ |
481 | rc = try_to_identify(drive,cmd); | 420 | rc = ide_dev_read_id(drive, cmd, id); |
482 | } | ||
483 | 421 | ||
484 | stat = tp_ops->read_status(hwif); | 422 | stat = tp_ops->read_status(hwif); |
485 | 423 | ||
@@ -494,7 +432,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
494 | msleep(50); | 432 | msleep(50); |
495 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); | 433 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); |
496 | (void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0); | 434 | (void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0); |
497 | rc = try_to_identify(drive, cmd); | 435 | rc = ide_dev_read_id(drive, cmd, id); |
498 | } | 436 | } |
499 | 437 | ||
500 | /* ensure drive IRQ is clear */ | 438 | /* ensure drive IRQ is clear */ |
@@ -517,37 +455,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
517 | return rc; | 455 | return rc; |
518 | } | 456 | } |
519 | 457 | ||
520 | /* | ||
521 | * | ||
522 | */ | ||
523 | static void enable_nest (ide_drive_t *drive) | ||
524 | { | ||
525 | ide_hwif_t *hwif = drive->hwif; | ||
526 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
527 | u8 stat; | ||
528 | |||
529 | printk(KERN_INFO "%s: enabling %s -- ", | ||
530 | hwif->name, (char *)&drive->id[ATA_ID_PROD]); | ||
531 | |||
532 | SELECT_DRIVE(drive); | ||
533 | msleep(50); | ||
534 | tp_ops->exec_command(hwif, ATA_EXABYTE_ENABLE_NEST); | ||
535 | |||
536 | if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 0)) { | ||
537 | printk(KERN_CONT "failed (timeout)\n"); | ||
538 | return; | ||
539 | } | ||
540 | |||
541 | msleep(50); | ||
542 | |||
543 | stat = tp_ops->read_status(hwif); | ||
544 | |||
545 | if (!OK_STAT(stat, 0, BAD_STAT)) | ||
546 | printk(KERN_CONT "failed (status = 0x%02x)\n", stat); | ||
547 | else | ||
548 | printk(KERN_CONT "success\n"); | ||
549 | } | ||
550 | |||
551 | /** | 458 | /** |
552 | * probe_for_drives - upper level drive probe | 459 | * probe_for_drives - upper level drive probe |
553 | * @drive: drive to probe for | 460 | * @drive: drive to probe for |
@@ -563,6 +470,8 @@ static void enable_nest (ide_drive_t *drive) | |||
563 | static u8 probe_for_drive(ide_drive_t *drive) | 470 | static u8 probe_for_drive(ide_drive_t *drive) |
564 | { | 471 | { |
565 | char *m; | 472 | char *m; |
473 | int rc; | ||
474 | u8 cmd; | ||
566 | 475 | ||
567 | /* | 476 | /* |
568 | * In order to keep things simple we have an id | 477 | * In order to keep things simple we have an id |
@@ -586,21 +495,19 @@ static u8 probe_for_drive(ide_drive_t *drive) | |||
586 | 495 | ||
587 | /* skip probing? */ | 496 | /* skip probing? */ |
588 | if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) { | 497 | if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) { |
589 | retry: | ||
590 | /* if !(success||timed-out) */ | 498 | /* if !(success||timed-out) */ |
591 | if (do_probe(drive, ATA_CMD_ID_ATA) >= 2) | 499 | cmd = ATA_CMD_ID_ATA; |
500 | rc = do_probe(drive, cmd); | ||
501 | if (rc >= 2) { | ||
592 | /* look for ATAPI device */ | 502 | /* look for ATAPI device */ |
593 | (void)do_probe(drive, ATA_CMD_ID_ATAPI); | 503 | cmd = ATA_CMD_ID_ATAPI; |
504 | rc = do_probe(drive, cmd); | ||
505 | } | ||
594 | 506 | ||
595 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | 507 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
596 | /* drive not found */ | 508 | /* drive not found */ |
597 | return 0; | 509 | return 0; |
598 | 510 | ||
599 | if (strstr(m, "E X A B Y T E N E S T")) { | ||
600 | enable_nest(drive); | ||
601 | goto retry; | ||
602 | } | ||
603 | |||
604 | /* identification failed? */ | 511 | /* identification failed? */ |
605 | if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { | 512 | if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) { |
606 | if (drive->media == ide_disk) { | 513 | if (drive->media == ide_disk) { |
@@ -614,8 +521,12 @@ retry: | |||
614 | printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name); | 521 | printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name); |
615 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; | 522 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; |
616 | } | 523 | } |
524 | } else { | ||
525 | if (cmd == ATA_CMD_ID_ATAPI) | ||
526 | ide_classify_atapi_dev(drive); | ||
527 | else | ||
528 | ide_classify_ata_dev(drive); | ||
617 | } | 529 | } |
618 | /* drive was found */ | ||
619 | } | 530 | } |
620 | 531 | ||
621 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | 532 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
@@ -779,7 +690,6 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave); | |||
779 | static int ide_probe_port(ide_hwif_t *hwif) | 690 | static int ide_probe_port(ide_hwif_t *hwif) |
780 | { | 691 | { |
781 | ide_drive_t *drive; | 692 | ide_drive_t *drive; |
782 | unsigned long flags; | ||
783 | unsigned int irqd; | 693 | unsigned int irqd; |
784 | int i, rc = -ENODEV; | 694 | int i, rc = -ENODEV; |
785 | 695 | ||
@@ -797,9 +707,6 @@ static int ide_probe_port(ide_hwif_t *hwif) | |||
797 | if (irqd) | 707 | if (irqd) |
798 | disable_irq(hwif->irq); | 708 | disable_irq(hwif->irq); |
799 | 709 | ||
800 | local_save_flags(flags); | ||
801 | local_irq_enable_in_hardirq(); | ||
802 | |||
803 | if (ide_port_wait_ready(hwif) == -EBUSY) | 710 | if (ide_port_wait_ready(hwif) == -EBUSY) |
804 | printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name); | 711 | printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name); |
805 | 712 | ||
@@ -813,8 +720,6 @@ static int ide_probe_port(ide_hwif_t *hwif) | |||
813 | rc = 0; | 720 | rc = 0; |
814 | } | 721 | } |
815 | 722 | ||
816 | local_irq_restore(flags); | ||
817 | |||
818 | /* | 723 | /* |
819 | * Use cached IRQ number. It might be (and is...) changed by probe | 724 | * Use cached IRQ number. It might be (and is...) changed by probe |
820 | * code above | 725 | * code above |
@@ -831,29 +736,18 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) | |||
831 | ide_drive_t *drive; | 736 | ide_drive_t *drive; |
832 | int i; | 737 | int i; |
833 | 738 | ||
834 | ide_port_for_each_dev(i, drive, hwif) { | 739 | ide_port_for_each_present_dev(i, drive, hwif) { |
835 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | 740 | if (port_ops && port_ops->quirkproc) |
836 | if (port_ops && port_ops->quirkproc) | 741 | port_ops->quirkproc(drive); |
837 | port_ops->quirkproc(drive); | ||
838 | } | ||
839 | } | 742 | } |
840 | 743 | ||
841 | ide_port_for_each_dev(i, drive, hwif) { | 744 | ide_port_for_each_present_dev(i, drive, hwif) { |
842 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | 745 | ide_set_max_pio(drive); |
843 | ide_set_max_pio(drive); | ||
844 | 746 | ||
845 | drive->dev_flags |= IDE_DFLAG_NICE1; | 747 | drive->dev_flags |= IDE_DFLAG_NICE1; |
846 | |||
847 | if (hwif->dma_ops) | ||
848 | ide_set_dma(drive); | ||
849 | } | ||
850 | } | ||
851 | 748 | ||
852 | ide_port_for_each_dev(i, drive, hwif) { | 749 | if (hwif->dma_ops) |
853 | if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) | 750 | ide_set_dma(drive); |
854 | drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; | ||
855 | else | ||
856 | drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT; | ||
857 | } | 751 | } |
858 | } | 752 | } |
859 | 753 | ||
@@ -924,10 +818,7 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) | |||
924 | int i, j = 0; | 818 | int i, j = 0; |
925 | 819 | ||
926 | mutex_lock(&ide_cfg_mtx); | 820 | mutex_lock(&ide_cfg_mtx); |
927 | ide_port_for_each_dev(i, drive, hwif) { | 821 | ide_port_for_each_present_dev(i, drive, hwif) { |
928 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | ||
929 | continue; | ||
930 | |||
931 | if (ide_init_queue(drive)) { | 822 | if (ide_init_queue(drive)) { |
932 | printk(KERN_ERR "ide: failed to init %s\n", | 823 | printk(KERN_ERR "ide: failed to init %s\n", |
933 | drive->name); | 824 | drive->name); |
@@ -953,13 +844,6 @@ static int init_irq (ide_hwif_t *hwif) | |||
953 | irq_handler_t irq_handler; | 844 | irq_handler_t irq_handler; |
954 | int sa = 0; | 845 | int sa = 0; |
955 | 846 | ||
956 | mutex_lock(&ide_cfg_mtx); | ||
957 | spin_lock_init(&hwif->lock); | ||
958 | |||
959 | init_timer(&hwif->timer); | ||
960 | hwif->timer.function = &ide_timer_expiry; | ||
961 | hwif->timer.data = (unsigned long)hwif; | ||
962 | |||
963 | irq_handler = hwif->host->irq_handler; | 847 | irq_handler = hwif->host->irq_handler; |
964 | if (irq_handler == NULL) | 848 | if (irq_handler == NULL) |
965 | irq_handler = ide_intr; | 849 | irq_handler = ide_intr; |
@@ -997,10 +881,8 @@ static int init_irq (ide_hwif_t *hwif) | |||
997 | printk(KERN_CONT " (serialized)"); | 881 | printk(KERN_CONT " (serialized)"); |
998 | printk(KERN_CONT "\n"); | 882 | printk(KERN_CONT "\n"); |
999 | 883 | ||
1000 | mutex_unlock(&ide_cfg_mtx); | ||
1001 | return 0; | 884 | return 0; |
1002 | out_up: | 885 | out_up: |
1003 | mutex_unlock(&ide_cfg_mtx); | ||
1004 | return 1; | 886 | return 1; |
1005 | } | 887 | } |
1006 | 888 | ||
@@ -1099,14 +981,9 @@ static void drive_release_dev (struct device *dev) | |||
1099 | 981 | ||
1100 | static int hwif_init(ide_hwif_t *hwif) | 982 | static int hwif_init(ide_hwif_t *hwif) |
1101 | { | 983 | { |
1102 | int old_irq; | ||
1103 | |||
1104 | if (!hwif->irq) { | 984 | if (!hwif->irq) { |
1105 | hwif->irq = __ide_default_irq(hwif->io_ports.data_addr); | 985 | printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name); |
1106 | if (!hwif->irq) { | 986 | return 0; |
1107 | printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name); | ||
1108 | return 0; | ||
1109 | } | ||
1110 | } | 987 | } |
1111 | 988 | ||
1112 | if (register_blkdev(hwif->major, hwif->name)) | 989 | if (register_blkdev(hwif->major, hwif->name)) |
@@ -1124,29 +1001,12 @@ static int hwif_init(ide_hwif_t *hwif) | |||
1124 | 1001 | ||
1125 | sg_init_table(hwif->sg_table, hwif->sg_max_nents); | 1002 | sg_init_table(hwif->sg_table, hwif->sg_max_nents); |
1126 | 1003 | ||
1127 | if (init_irq(hwif) == 0) | ||
1128 | goto done; | ||
1129 | |||
1130 | old_irq = hwif->irq; | ||
1131 | /* | ||
1132 | * It failed to initialise. Find the default IRQ for | ||
1133 | * this port and try that. | ||
1134 | */ | ||
1135 | hwif->irq = __ide_default_irq(hwif->io_ports.data_addr); | ||
1136 | if (!hwif->irq) { | ||
1137 | printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n", | ||
1138 | hwif->name, old_irq); | ||
1139 | goto out; | ||
1140 | } | ||
1141 | if (init_irq(hwif)) { | 1004 | if (init_irq(hwif)) { |
1142 | printk(KERN_ERR "%s: probed IRQ %d and default IRQ %d failed\n", | 1005 | printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n", |
1143 | hwif->name, old_irq, hwif->irq); | 1006 | hwif->name, hwif->irq); |
1144 | goto out; | 1007 | goto out; |
1145 | } | 1008 | } |
1146 | printk(KERN_WARNING "%s: probed IRQ %d failed, using default\n", | ||
1147 | hwif->name, hwif->irq); | ||
1148 | 1009 | ||
1149 | done: | ||
1150 | blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS, | 1010 | blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS, |
1151 | THIS_MODULE, ata_probe, ata_lock, hwif); | 1011 | THIS_MODULE, ata_probe, ata_lock, hwif); |
1152 | return 1; | 1012 | return 1; |
@@ -1161,13 +1021,10 @@ static void hwif_register_devices(ide_hwif_t *hwif) | |||
1161 | ide_drive_t *drive; | 1021 | ide_drive_t *drive; |
1162 | unsigned int i; | 1022 | unsigned int i; |
1163 | 1023 | ||
1164 | ide_port_for_each_dev(i, drive, hwif) { | 1024 | ide_port_for_each_present_dev(i, drive, hwif) { |
1165 | struct device *dev = &drive->gendev; | 1025 | struct device *dev = &drive->gendev; |
1166 | int ret; | 1026 | int ret; |
1167 | 1027 | ||
1168 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | ||
1169 | continue; | ||
1170 | |||
1171 | dev_set_name(dev, "%u.%u", hwif->index, i); | 1028 | dev_set_name(dev, "%u.%u", hwif->index, i); |
1172 | dev->parent = &hwif->gendev; | 1029 | dev->parent = &hwif->gendev; |
1173 | dev->bus = &ide_bus_type; | 1030 | dev->bus = &ide_bus_type; |
@@ -1192,6 +1049,8 @@ static void ide_port_init_devices(ide_hwif_t *hwif) | |||
1192 | 1049 | ||
1193 | if (hwif->host_flags & IDE_HFLAG_IO_32BIT) | 1050 | if (hwif->host_flags & IDE_HFLAG_IO_32BIT) |
1194 | drive->io_32bit = 1; | 1051 | drive->io_32bit = 1; |
1052 | if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) | ||
1053 | drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; | ||
1195 | if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS) | 1054 | if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS) |
1196 | drive->dev_flags |= IDE_DFLAG_UNMASK; | 1055 | drive->dev_flags |= IDE_DFLAG_UNMASK; |
1197 | if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) | 1056 | if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS) |
@@ -1213,10 +1072,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | |||
1213 | if (d->init_iops) | 1072 | if (d->init_iops) |
1214 | d->init_iops(hwif); | 1073 | d->init_iops(hwif); |
1215 | 1074 | ||
1216 | if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) || | ||
1217 | (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) | ||
1218 | hwif->irq = port ? 15 : 14; | ||
1219 | |||
1220 | /* ->host_flags may be set by ->init_iops (or even earlier...) */ | 1075 | /* ->host_flags may be set by ->init_iops (or even earlier...) */ |
1221 | hwif->host_flags |= d->host_flags; | 1076 | hwif->host_flags |= d->host_flags; |
1222 | hwif->pio_mask = d->pio_mask; | 1077 | hwif->pio_mask = d->pio_mask; |
@@ -1317,6 +1172,12 @@ static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) | |||
1317 | hwif->name[2] = 'e'; | 1172 | hwif->name[2] = 'e'; |
1318 | hwif->name[3] = '0' + index; | 1173 | hwif->name[3] = '0' + index; |
1319 | 1174 | ||
1175 | spin_lock_init(&hwif->lock); | ||
1176 | |||
1177 | init_timer(&hwif->timer); | ||
1178 | hwif->timer.function = &ide_timer_expiry; | ||
1179 | hwif->timer.data = (unsigned long)hwif; | ||
1180 | |||
1320 | init_completion(&hwif->gendev_rel_comp); | 1181 | init_completion(&hwif->gendev_rel_comp); |
1321 | 1182 | ||
1322 | hwif->tp_ops = &default_tp_ops; | 1183 | hwif->tp_ops = &default_tp_ops; |
@@ -1567,7 +1428,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1567 | 1428 | ||
1568 | j++; | 1429 | j++; |
1569 | 1430 | ||
1570 | ide_acpi_init(hwif); | 1431 | ide_acpi_init_port(hwif); |
1571 | 1432 | ||
1572 | if (hwif->present) | 1433 | if (hwif->present) |
1573 | ide_acpi_port_init_devices(hwif); | 1434 | ide_acpi_port_init_devices(hwif); |
@@ -1624,11 +1485,9 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif) | |||
1624 | ide_drive_t *drive; | 1485 | ide_drive_t *drive; |
1625 | int i; | 1486 | int i; |
1626 | 1487 | ||
1627 | ide_port_for_each_dev(i, drive, hwif) { | 1488 | ide_port_for_each_present_dev(i, drive, hwif) { |
1628 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | 1489 | device_unregister(&drive->gendev); |
1629 | device_unregister(&drive->gendev); | 1490 | wait_for_completion(&drive->gendev_rel_comp); |
1630 | wait_for_completion(&drive->gendev_rel_comp); | ||
1631 | } | ||
1632 | } | 1491 | } |
1633 | } | 1492 | } |
1634 | 1493 | ||
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index a7b9287ee0d4..417cde56eafd 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -600,7 +600,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif) | |||
600 | int i; | 600 | int i; |
601 | 601 | ||
602 | ide_port_for_each_dev(i, drive, hwif) { | 602 | ide_port_for_each_dev(i, drive, hwif) { |
603 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc) | 603 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
604 | continue; | 604 | continue; |
605 | 605 | ||
606 | drive->proc = proc_mkdir(drive->name, parent); | 606 | drive->proc = proc_mkdir(drive->name, parent); |
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c new file mode 100644 index 000000000000..6910f6a257e8 --- /dev/null +++ b/drivers/ide/ide-xfer-mode.c | |||
@@ -0,0 +1,246 @@ | |||
1 | #include <linux/types.h> | ||
2 | #include <linux/string.h> | ||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/interrupt.h> | ||
5 | #include <linux/ide.h> | ||
6 | #include <linux/bitops.h> | ||
7 | |||
8 | static const char *udma_str[] = | ||
9 | { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44", | ||
10 | "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" }; | ||
11 | static const char *mwdma_str[] = | ||
12 | { "MWDMA0", "MWDMA1", "MWDMA2" }; | ||
13 | static const char *swdma_str[] = | ||
14 | { "SWDMA0", "SWDMA1", "SWDMA2" }; | ||
15 | static const char *pio_str[] = | ||
16 | { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" }; | ||
17 | |||
18 | /** | ||
19 | * ide_xfer_verbose - return IDE mode names | ||
20 | * @mode: transfer mode | ||
21 | * | ||
22 | * Returns a constant string giving the name of the mode | ||
23 | * requested. | ||
24 | */ | ||
25 | |||
26 | const char *ide_xfer_verbose(u8 mode) | ||
27 | { | ||
28 | const char *s; | ||
29 | u8 i = mode & 0xf; | ||
30 | |||
31 | if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7) | ||
32 | s = udma_str[i]; | ||
33 | else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2) | ||
34 | s = mwdma_str[i]; | ||
35 | else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2) | ||
36 | s = swdma_str[i]; | ||
37 | else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5) | ||
38 | s = pio_str[i & 0x7]; | ||
39 | else if (mode == XFER_PIO_SLOW) | ||
40 | s = "PIO SLOW"; | ||
41 | else | ||
42 | s = "XFER ERROR"; | ||
43 | |||
44 | return s; | ||
45 | } | ||
46 | EXPORT_SYMBOL(ide_xfer_verbose); | ||
47 | |||
48 | /** | ||
49 | * ide_get_best_pio_mode - get PIO mode from drive | ||
50 | * @drive: drive to consider | ||
51 | * @mode_wanted: preferred mode | ||
52 | * @max_mode: highest allowed mode | ||
53 | * | ||
54 | * This routine returns the recommended PIO settings for a given drive, | ||
55 | * based on the drive->id information and the ide_pio_blacklist[]. | ||
56 | * | ||
57 | * Drive PIO mode is auto-selected if 255 is passed as mode_wanted. | ||
58 | * This is used by most chipset support modules when "auto-tuning". | ||
59 | */ | ||
60 | |||
61 | u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) | ||
62 | { | ||
63 | u16 *id = drive->id; | ||
64 | int pio_mode = -1, overridden = 0; | ||
65 | |||
66 | if (mode_wanted != 255) | ||
67 | return min_t(u8, mode_wanted, max_mode); | ||
68 | |||
69 | if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0) | ||
70 | pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]); | ||
71 | |||
72 | if (pio_mode != -1) { | ||
73 | printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name); | ||
74 | } else { | ||
75 | pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8; | ||
76 | if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */ | ||
77 | pio_mode = 2; | ||
78 | overridden = 1; | ||
79 | } | ||
80 | |||
81 | if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */ | ||
82 | if (ata_id_has_iordy(id)) { | ||
83 | if (id[ATA_ID_PIO_MODES] & 7) { | ||
84 | overridden = 0; | ||
85 | if (id[ATA_ID_PIO_MODES] & 4) | ||
86 | pio_mode = 5; | ||
87 | else if (id[ATA_ID_PIO_MODES] & 2) | ||
88 | pio_mode = 4; | ||
89 | else | ||
90 | pio_mode = 3; | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | if (overridden) | ||
96 | printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n", | ||
97 | drive->name); | ||
98 | } | ||
99 | |||
100 | if (pio_mode > max_mode) | ||
101 | pio_mode = max_mode; | ||
102 | |||
103 | return pio_mode; | ||
104 | } | ||
105 | EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); | ||
106 | |||
107 | int ide_set_pio_mode(ide_drive_t *drive, const u8 mode) | ||
108 | { | ||
109 | ide_hwif_t *hwif = drive->hwif; | ||
110 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
111 | |||
112 | if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) | ||
113 | return 0; | ||
114 | |||
115 | if (port_ops == NULL || port_ops->set_pio_mode == NULL) | ||
116 | return -1; | ||
117 | |||
118 | /* | ||
119 | * TODO: temporary hack for some legacy host drivers that didn't | ||
120 | * set transfer mode on the device in ->set_pio_mode method... | ||
121 | */ | ||
122 | if (port_ops->set_dma_mode == NULL) { | ||
123 | port_ops->set_pio_mode(drive, mode - XFER_PIO_0); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { | ||
128 | if (ide_config_drive_speed(drive, mode)) | ||
129 | return -1; | ||
130 | port_ops->set_pio_mode(drive, mode - XFER_PIO_0); | ||
131 | return 0; | ||
132 | } else { | ||
133 | port_ops->set_pio_mode(drive, mode - XFER_PIO_0); | ||
134 | return ide_config_drive_speed(drive, mode); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | int ide_set_dma_mode(ide_drive_t *drive, const u8 mode) | ||
139 | { | ||
140 | ide_hwif_t *hwif = drive->hwif; | ||
141 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
142 | |||
143 | if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) | ||
144 | return 0; | ||
145 | |||
146 | if (port_ops == NULL || port_ops->set_dma_mode == NULL) | ||
147 | return -1; | ||
148 | |||
149 | if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { | ||
150 | if (ide_config_drive_speed(drive, mode)) | ||
151 | return -1; | ||
152 | port_ops->set_dma_mode(drive, mode); | ||
153 | return 0; | ||
154 | } else { | ||
155 | port_ops->set_dma_mode(drive, mode); | ||
156 | return ide_config_drive_speed(drive, mode); | ||
157 | } | ||
158 | } | ||
159 | EXPORT_SYMBOL_GPL(ide_set_dma_mode); | ||
160 | |||
161 | /* req_pio == "255" for auto-tune */ | ||
162 | void ide_set_pio(ide_drive_t *drive, u8 req_pio) | ||
163 | { | ||
164 | ide_hwif_t *hwif = drive->hwif; | ||
165 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
166 | u8 host_pio, pio; | ||
167 | |||
168 | if (port_ops == NULL || port_ops->set_pio_mode == NULL || | ||
169 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
170 | return; | ||
171 | |||
172 | BUG_ON(hwif->pio_mask == 0x00); | ||
173 | |||
174 | host_pio = fls(hwif->pio_mask) - 1; | ||
175 | |||
176 | pio = ide_get_best_pio_mode(drive, req_pio, host_pio); | ||
177 | |||
178 | /* | ||
179 | * TODO: | ||
180 | * - report device max PIO mode | ||
181 | * - check req_pio != 255 against device max PIO mode | ||
182 | */ | ||
183 | printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n", | ||
184 | drive->name, host_pio, req_pio, | ||
185 | req_pio == 255 ? "(auto-tune)" : "", pio); | ||
186 | |||
187 | (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio); | ||
188 | } | ||
189 | EXPORT_SYMBOL_GPL(ide_set_pio); | ||
190 | |||
191 | /** | ||
192 | * ide_rate_filter - filter transfer mode | ||
193 | * @drive: IDE device | ||
194 | * @speed: desired speed | ||
195 | * | ||
196 | * Given the available transfer modes this function returns | ||
197 | * the best available speed at or below the speed requested. | ||
198 | * | ||
199 | * TODO: check device PIO capabilities | ||
200 | */ | ||
201 | |||
202 | static u8 ide_rate_filter(ide_drive_t *drive, u8 speed) | ||
203 | { | ||
204 | ide_hwif_t *hwif = drive->hwif; | ||
205 | u8 mode = ide_find_dma_mode(drive, speed); | ||
206 | |||
207 | if (mode == 0) { | ||
208 | if (hwif->pio_mask) | ||
209 | mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0; | ||
210 | else | ||
211 | mode = XFER_PIO_4; | ||
212 | } | ||
213 | |||
214 | /* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */ | ||
215 | |||
216 | return min(speed, mode); | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * ide_set_xfer_rate - set transfer rate | ||
221 | * @drive: drive to set | ||
222 | * @rate: speed to attempt to set | ||
223 | * | ||
224 | * General helper for setting the speed of an IDE device. This | ||
225 | * function knows about user enforced limits from the configuration | ||
226 | * which ->set_pio_mode/->set_dma_mode does not. | ||
227 | */ | ||
228 | |||
229 | int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | ||
230 | { | ||
231 | ide_hwif_t *hwif = drive->hwif; | ||
232 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
233 | |||
234 | if (port_ops == NULL || port_ops->set_dma_mode == NULL || | ||
235 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
236 | return -1; | ||
237 | |||
238 | rate = ide_rate_filter(drive, rate); | ||
239 | |||
240 | BUG_ON(rate < XFER_PIO_0); | ||
241 | |||
242 | if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) | ||
243 | return ide_set_pio_mode(drive, rate); | ||
244 | |||
245 | return ide_set_dma_mode(drive, rate); | ||
246 | } | ||
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 0920e3b0c962..92c9b90931e7 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -62,160 +62,6 @@ | |||
62 | 62 | ||
63 | struct class *ide_port_class; | 63 | struct class *ide_port_class; |
64 | 64 | ||
65 | /* | ||
66 | * Locks for IDE setting functionality | ||
67 | */ | ||
68 | |||
69 | DEFINE_MUTEX(ide_setting_mtx); | ||
70 | |||
71 | ide_devset_get(io_32bit, io_32bit); | ||
72 | |||
73 | static int set_io_32bit(ide_drive_t *drive, int arg) | ||
74 | { | ||
75 | if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) | ||
76 | return -EPERM; | ||
77 | |||
78 | if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) | ||
79 | return -EINVAL; | ||
80 | |||
81 | drive->io_32bit = arg; | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS); | ||
87 | |||
88 | static int set_ksettings(ide_drive_t *drive, int arg) | ||
89 | { | ||
90 | if (arg < 0 || arg > 1) | ||
91 | return -EINVAL; | ||
92 | |||
93 | if (arg) | ||
94 | drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS; | ||
95 | else | ||
96 | drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS; | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA); | ||
102 | |||
103 | static int set_using_dma(ide_drive_t *drive, int arg) | ||
104 | { | ||
105 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
106 | int err = -EPERM; | ||
107 | |||
108 | if (arg < 0 || arg > 1) | ||
109 | return -EINVAL; | ||
110 | |||
111 | if (ata_id_has_dma(drive->id) == 0) | ||
112 | goto out; | ||
113 | |||
114 | if (drive->hwif->dma_ops == NULL) | ||
115 | goto out; | ||
116 | |||
117 | err = 0; | ||
118 | |||
119 | if (arg) { | ||
120 | if (ide_set_dma(drive)) | ||
121 | err = -EIO; | ||
122 | } else | ||
123 | ide_dma_off(drive); | ||
124 | |||
125 | out: | ||
126 | return err; | ||
127 | #else | ||
128 | if (arg < 0 || arg > 1) | ||
129 | return -EINVAL; | ||
130 | |||
131 | return -EPERM; | ||
132 | #endif | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away | ||
137 | */ | ||
138 | static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) | ||
139 | { | ||
140 | switch (req_pio) { | ||
141 | case 202: | ||
142 | case 201: | ||
143 | case 200: | ||
144 | case 102: | ||
145 | case 101: | ||
146 | case 100: | ||
147 | return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0; | ||
148 | case 9: | ||
149 | case 8: | ||
150 | return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0; | ||
151 | case 7: | ||
152 | case 6: | ||
153 | return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0; | ||
154 | default: | ||
155 | return 0; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | static int set_pio_mode(ide_drive_t *drive, int arg) | ||
160 | { | ||
161 | ide_hwif_t *hwif = drive->hwif; | ||
162 | const struct ide_port_ops *port_ops = hwif->port_ops; | ||
163 | |||
164 | if (arg < 0 || arg > 255) | ||
165 | return -EINVAL; | ||
166 | |||
167 | if (port_ops == NULL || port_ops->set_pio_mode == NULL || | ||
168 | (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)) | ||
169 | return -ENOSYS; | ||
170 | |||
171 | if (set_pio_mode_abuse(drive->hwif, arg)) { | ||
172 | if (arg == 8 || arg == 9) { | ||
173 | unsigned long flags; | ||
174 | |||
175 | /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ | ||
176 | spin_lock_irqsave(&hwif->lock, flags); | ||
177 | port_ops->set_pio_mode(drive, arg); | ||
178 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
179 | } else | ||
180 | port_ops->set_pio_mode(drive, arg); | ||
181 | } else { | ||
182 | int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | ||
183 | |||
184 | ide_set_pio(drive, arg); | ||
185 | |||
186 | if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { | ||
187 | if (keep_dma) | ||
188 | ide_dma_on(drive); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK); | ||
196 | |||
197 | static int set_unmaskirq(ide_drive_t *drive, int arg) | ||
198 | { | ||
199 | if (drive->dev_flags & IDE_DFLAG_NO_UNMASK) | ||
200 | return -EPERM; | ||
201 | |||
202 | if (arg < 0 || arg > 1) | ||
203 | return -EINVAL; | ||
204 | |||
205 | if (arg) | ||
206 | drive->dev_flags |= IDE_DFLAG_UNMASK; | ||
207 | else | ||
208 | drive->dev_flags &= ~IDE_DFLAG_UNMASK; | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | ide_ext_devset_rw_sync(io_32bit, io_32bit); | ||
214 | ide_ext_devset_rw_sync(keepsettings, ksettings); | ||
215 | ide_ext_devset_rw_sync(unmaskirq, unmaskirq); | ||
216 | ide_ext_devset_rw_sync(using_dma, using_dma); | ||
217 | __IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode); | ||
218 | |||
219 | /** | 65 | /** |
220 | * ide_device_get - get an additional reference to a ide_drive_t | 66 | * ide_device_get - get an additional reference to a ide_drive_t |
221 | * @drive: device to get a reference to | 67 | * @drive: device to get a reference to |
@@ -527,6 +373,8 @@ static int __init ide_init(void) | |||
527 | goto out_port_class; | 373 | goto out_port_class; |
528 | } | 374 | } |
529 | 375 | ||
376 | ide_acpi_init(); | ||
377 | |||
530 | proc_ide_create(); | 378 | proc_ide_create(); |
531 | 379 | ||
532 | return 0; | 380 | return 0; |
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index 13b8153112ed..6b9fc950b4af 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c | |||
@@ -603,7 +603,7 @@ static void it8212_disable_raid(struct pci_dev *dev) | |||
603 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); | 603 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); |
604 | } | 604 | } |
605 | 605 | ||
606 | static unsigned int init_chipset_it821x(struct pci_dev *dev) | 606 | static int init_chipset_it821x(struct pci_dev *dev) |
607 | { | 607 | { |
608 | u8 conf; | 608 | u8 conf; |
609 | static char *mode[2] = { "pass through", "smart" }; | 609 | static char *mode[2] = { "pass through", "smart" }; |
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c index 83643ed9a426..ea48a3ee8063 100644 --- a/drivers/ide/ns87415.c +++ b/drivers/ide/ns87415.c | |||
@@ -286,9 +286,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) | |||
286 | } | 286 | } |
287 | 287 | ||
288 | if (!using_inta) | 288 | if (!using_inta) |
289 | hwif->irq = __ide_default_irq(hwif->io_ports.data_addr); | 289 | hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel); |
290 | else if (!hwif->irq && hwif->mate && hwif->mate->irq) | ||
291 | hwif->irq = hwif->mate->irq; /* share IRQ with mate */ | ||
292 | 290 | ||
293 | if (!hwif->dma_base) | 291 | if (!hwif->dma_base) |
294 | return; | 292 | return; |
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c index f21290c4b447..b68906c3c17e 100644 --- a/drivers/ide/pdc202xx_new.c +++ b/drivers/ide/pdc202xx_new.c | |||
@@ -325,7 +325,7 @@ static void apple_kiwi_init(struct pci_dev *pdev) | |||
325 | } | 325 | } |
326 | #endif /* CONFIG_PPC_PMAC */ | 326 | #endif /* CONFIG_PPC_PMAC */ |
327 | 327 | ||
328 | static unsigned int init_chipset_pdcnew(struct pci_dev *dev) | 328 | static int init_chipset_pdcnew(struct pci_dev *dev) |
329 | { | 329 | { |
330 | const char *name = DRV_NAME; | 330 | const char *name = DRV_NAME; |
331 | unsigned long dma_base = pci_resource_start(dev, 4); | 331 | unsigned long dma_base = pci_resource_start(dev, 4); |
@@ -444,7 +444,7 @@ static unsigned int init_chipset_pdcnew(struct pci_dev *dev) | |||
444 | #endif | 444 | #endif |
445 | 445 | ||
446 | out: | 446 | out: |
447 | return dev->irq; | 447 | return 0; |
448 | } | 448 | } |
449 | 449 | ||
450 | static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev) | 450 | static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev) |
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index 97193323aebf..cba66ebce4e3 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c | |||
@@ -264,7 +264,7 @@ static void pdc202xx_dma_timeout(ide_drive_t *drive) | |||
264 | ide_dma_timeout(drive); | 264 | ide_dma_timeout(drive); |
265 | } | 265 | } |
266 | 266 | ||
267 | static unsigned int init_chipset_pdc202xx(struct pci_dev *dev) | 267 | static int init_chipset_pdc202xx(struct pci_dev *dev) |
268 | { | 268 | { |
269 | unsigned long dmabase = pci_resource_start(dev, 4); | 269 | unsigned long dmabase = pci_resource_start(dev, 4); |
270 | u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0; | 270 | u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0; |
@@ -290,7 +290,7 @@ static unsigned int init_chipset_pdc202xx(struct pci_dev *dev) | |||
290 | printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN"); | 290 | printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN"); |
291 | } | 291 | } |
292 | out: | 292 | out: |
293 | return dev->irq; | 293 | return 0; |
294 | } | 294 | } |
295 | 295 | ||
296 | static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev, | 296 | static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev, |
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index f1e2e4ef0d71..2aa699933064 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c | |||
@@ -204,7 +204,7 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
204 | * out to be nice and simple. | 204 | * out to be nice and simple. |
205 | */ | 205 | */ |
206 | 206 | ||
207 | static unsigned int init_chipset_ich(struct pci_dev *dev) | 207 | static int init_chipset_ich(struct pci_dev *dev) |
208 | { | 208 | { |
209 | u32 extra = 0; | 209 | u32 extra = 0; |
210 | 210 | ||
@@ -318,19 +318,12 @@ static const struct ide_port_ops ich_port_ops = { | |||
318 | .cable_detect = piix_cable_detect, | 318 | .cable_detect = piix_cable_detect, |
319 | }; | 319 | }; |
320 | 320 | ||
321 | #ifndef CONFIG_IA64 | ||
322 | #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS | ||
323 | #else | ||
324 | #define IDE_HFLAGS_PIIX 0 | ||
325 | #endif | ||
326 | |||
327 | #define DECLARE_PIIX_DEV(udma) \ | 321 | #define DECLARE_PIIX_DEV(udma) \ |
328 | { \ | 322 | { \ |
329 | .name = DRV_NAME, \ | 323 | .name = DRV_NAME, \ |
330 | .init_hwif = init_hwif_piix, \ | 324 | .init_hwif = init_hwif_piix, \ |
331 | .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ | 325 | .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ |
332 | .port_ops = &piix_port_ops, \ | 326 | .port_ops = &piix_port_ops, \ |
333 | .host_flags = IDE_HFLAGS_PIIX, \ | ||
334 | .pio_mask = ATA_PIO4, \ | 327 | .pio_mask = ATA_PIO4, \ |
335 | .swdma_mask = ATA_SWDMA2_ONLY, \ | 328 | .swdma_mask = ATA_SWDMA2_ONLY, \ |
336 | .mwdma_mask = ATA_MWDMA12_ONLY, \ | 329 | .mwdma_mask = ATA_MWDMA12_ONLY, \ |
@@ -344,7 +337,6 @@ static const struct ide_port_ops ich_port_ops = { | |||
344 | .init_hwif = init_hwif_piix, \ | 337 | .init_hwif = init_hwif_piix, \ |
345 | .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ | 338 | .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ |
346 | .port_ops = &ich_port_ops, \ | 339 | .port_ops = &ich_port_ops, \ |
347 | .host_flags = IDE_HFLAGS_PIIX, \ | ||
348 | .pio_mask = ATA_PIO4, \ | 340 | .pio_mask = ATA_PIO4, \ |
349 | .swdma_mask = ATA_SWDMA2_ONLY, \ | 341 | .swdma_mask = ATA_SWDMA2_ONLY, \ |
350 | .mwdma_mask = ATA_MWDMA12_ONLY, \ | 342 | .mwdma_mask = ATA_MWDMA12_ONLY, \ |
@@ -360,8 +352,7 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = { | |||
360 | */ | 352 | */ |
361 | .name = DRV_NAME, | 353 | .name = DRV_NAME, |
362 | .enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}}, | 354 | .enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}}, |
363 | .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA | | 355 | .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA, |
364 | IDE_HFLAGS_PIIX, | ||
365 | .pio_mask = ATA_PIO4, | 356 | .pio_mask = ATA_PIO4, |
366 | /* This is a painful system best to let it self tune for now */ | 357 | /* This is a painful system best to let it self tune for now */ |
367 | }, | 358 | }, |
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c index 382102ba467b..b6554ef92716 100644 --- a/drivers/ide/serverworks.c +++ b/drivers/ide/serverworks.c | |||
@@ -175,7 +175,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
175 | pci_write_config_byte(dev, 0x54, ultra_enable); | 175 | pci_write_config_byte(dev, 0x54, ultra_enable); |
176 | } | 176 | } |
177 | 177 | ||
178 | static unsigned int init_chipset_svwks(struct pci_dev *dev) | 178 | static int init_chipset_svwks(struct pci_dev *dev) |
179 | { | 179 | { |
180 | unsigned int reg; | 180 | unsigned int reg; |
181 | u8 btr; | 181 | u8 btr; |
@@ -270,7 +270,7 @@ static unsigned int init_chipset_svwks(struct pci_dev *dev) | |||
270 | pci_write_config_byte(dev, 0x5A, btr); | 270 | pci_write_config_byte(dev, 0x5A, btr); |
271 | } | 271 | } |
272 | 272 | ||
273 | return dev->irq; | 273 | return 0; |
274 | } | 274 | } |
275 | 275 | ||
276 | static u8 ata66_svwks_svwks(ide_hwif_t *hwif) | 276 | static u8 ata66_svwks_svwks(ide_hwif_t *hwif) |
@@ -353,14 +353,11 @@ static const struct ide_port_ops svwks_port_ops = { | |||
353 | .cable_detect = svwks_cable_detect, | 353 | .cable_detect = svwks_cable_detect, |
354 | }; | 354 | }; |
355 | 355 | ||
356 | #define IDE_HFLAGS_SVWKS IDE_HFLAG_LEGACY_IRQS | ||
357 | |||
358 | static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | 356 | static const struct ide_port_info serverworks_chipsets[] __devinitdata = { |
359 | { /* 0: OSB4 */ | 357 | { /* 0: OSB4 */ |
360 | .name = DRV_NAME, | 358 | .name = DRV_NAME, |
361 | .init_chipset = init_chipset_svwks, | 359 | .init_chipset = init_chipset_svwks, |
362 | .port_ops = &osb4_port_ops, | 360 | .port_ops = &osb4_port_ops, |
363 | .host_flags = IDE_HFLAGS_SVWKS, | ||
364 | .pio_mask = ATA_PIO4, | 361 | .pio_mask = ATA_PIO4, |
365 | .mwdma_mask = ATA_MWDMA2, | 362 | .mwdma_mask = ATA_MWDMA2, |
366 | .udma_mask = 0x00, /* UDMA is problematic on OSB4 */ | 363 | .udma_mask = 0x00, /* UDMA is problematic on OSB4 */ |
@@ -369,7 +366,6 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | |||
369 | .name = DRV_NAME, | 366 | .name = DRV_NAME, |
370 | .init_chipset = init_chipset_svwks, | 367 | .init_chipset = init_chipset_svwks, |
371 | .port_ops = &svwks_port_ops, | 368 | .port_ops = &svwks_port_ops, |
372 | .host_flags = IDE_HFLAGS_SVWKS, | ||
373 | .pio_mask = ATA_PIO4, | 369 | .pio_mask = ATA_PIO4, |
374 | .mwdma_mask = ATA_MWDMA2, | 370 | .mwdma_mask = ATA_MWDMA2, |
375 | .udma_mask = ATA_UDMA5, | 371 | .udma_mask = ATA_UDMA5, |
@@ -378,7 +374,6 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | |||
378 | .name = DRV_NAME, | 374 | .name = DRV_NAME, |
379 | .init_chipset = init_chipset_svwks, | 375 | .init_chipset = init_chipset_svwks, |
380 | .port_ops = &svwks_port_ops, | 376 | .port_ops = &svwks_port_ops, |
381 | .host_flags = IDE_HFLAGS_SVWKS, | ||
382 | .pio_mask = ATA_PIO4, | 377 | .pio_mask = ATA_PIO4, |
383 | .mwdma_mask = ATA_MWDMA2, | 378 | .mwdma_mask = ATA_MWDMA2, |
384 | .udma_mask = ATA_UDMA5, | 379 | .udma_mask = ATA_UDMA5, |
@@ -387,7 +382,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | |||
387 | .name = DRV_NAME, | 382 | .name = DRV_NAME, |
388 | .init_chipset = init_chipset_svwks, | 383 | .init_chipset = init_chipset_svwks, |
389 | .port_ops = &svwks_port_ops, | 384 | .port_ops = &svwks_port_ops, |
390 | .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE, | 385 | .host_flags = IDE_HFLAG_SINGLE, |
391 | .pio_mask = ATA_PIO4, | 386 | .pio_mask = ATA_PIO4, |
392 | .mwdma_mask = ATA_MWDMA2, | 387 | .mwdma_mask = ATA_MWDMA2, |
393 | .udma_mask = ATA_UDMA5, | 388 | .udma_mask = ATA_UDMA5, |
@@ -396,7 +391,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | |||
396 | .name = DRV_NAME, | 391 | .name = DRV_NAME, |
397 | .init_chipset = init_chipset_svwks, | 392 | .init_chipset = init_chipset_svwks, |
398 | .port_ops = &svwks_port_ops, | 393 | .port_ops = &svwks_port_ops, |
399 | .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE, | 394 | .host_flags = IDE_HFLAG_SINGLE, |
400 | .pio_mask = ATA_PIO4, | 395 | .pio_mask = ATA_PIO4, |
401 | .mwdma_mask = ATA_MWDMA2, | 396 | .mwdma_mask = ATA_MWDMA2, |
402 | .udma_mask = ATA_UDMA5, | 397 | .udma_mask = ATA_UDMA5, |
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index e85d1ed29c2a..24bc884826fc 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -305,7 +305,6 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info * | |||
305 | * @dev: PCI device holding interface | 305 | * @dev: PCI device holding interface |
306 | * @d: IDE port info | 306 | * @d: IDE port info |
307 | * @port: port number | 307 | * @port: port number |
308 | * @irq: PCI IRQ | ||
309 | * @hw: hw_regs_t instance corresponding to this port | 308 | * @hw: hw_regs_t instance corresponding to this port |
310 | * | 309 | * |
311 | * Perform the initial set up for the hardware interface structure. This | 310 | * Perform the initial set up for the hardware interface structure. This |
@@ -316,7 +315,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info * | |||
316 | */ | 315 | */ |
317 | 316 | ||
318 | static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, | 317 | static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, |
319 | unsigned int port, int irq, hw_regs_t *hw) | 318 | unsigned int port, hw_regs_t *hw) |
320 | { | 319 | { |
321 | unsigned long ctl = 0, base = 0; | 320 | unsigned long ctl = 0, base = 0; |
322 | 321 | ||
@@ -344,7 +343,6 @@ static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, | |||
344 | } | 343 | } |
345 | 344 | ||
346 | memset(hw, 0, sizeof(*hw)); | 345 | memset(hw, 0, sizeof(*hw)); |
347 | hw->irq = irq; | ||
348 | hw->dev = &dev->dev; | 346 | hw->dev = &dev->dev; |
349 | hw->chipset = d->chipset ? d->chipset : ide_pci; | 347 | hw->chipset = d->chipset ? d->chipset : ide_pci; |
350 | ide_std_init_ports(hw, base, ctl | 2); | 348 | ide_std_init_ports(hw, base, ctl | 2); |
@@ -448,7 +446,6 @@ out: | |||
448 | * ide_pci_setup_ports - configure ports/devices on PCI IDE | 446 | * ide_pci_setup_ports - configure ports/devices on PCI IDE |
449 | * @dev: PCI device | 447 | * @dev: PCI device |
450 | * @d: IDE port info | 448 | * @d: IDE port info |
451 | * @pciirq: IRQ line | ||
452 | * @hw: hw_regs_t instances corresponding to this PCI IDE device | 449 | * @hw: hw_regs_t instances corresponding to this PCI IDE device |
453 | * @hws: hw_regs_t pointers table to update | 450 | * @hws: hw_regs_t pointers table to update |
454 | * | 451 | * |
@@ -462,7 +459,7 @@ out: | |||
462 | */ | 459 | */ |
463 | 460 | ||
464 | void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, | 461 | void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, |
465 | int pciirq, hw_regs_t *hw, hw_regs_t **hws) | 462 | hw_regs_t *hw, hw_regs_t **hws) |
466 | { | 463 | { |
467 | int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port; | 464 | int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port; |
468 | u8 tmp; | 465 | u8 tmp; |
@@ -481,7 +478,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, | |||
481 | continue; /* port not enabled */ | 478 | continue; /* port not enabled */ |
482 | } | 479 | } |
483 | 480 | ||
484 | if (ide_hw_configure(dev, d, port, pciirq, hw + port)) | 481 | if (ide_hw_configure(dev, d, port, hw + port)) |
485 | continue; | 482 | continue; |
486 | 483 | ||
487 | *(hws + port) = hw + port; | 484 | *(hws + port) = hw + port; |
@@ -524,7 +521,7 @@ static int do_ide_setup_pci_device(struct pci_dev *dev, | |||
524 | if (noisy) | 521 | if (noisy) |
525 | printk(KERN_INFO "%s %s: not 100%% native mode: will " | 522 | printk(KERN_INFO "%s %s: not 100%% native mode: will " |
526 | "probe irqs later\n", d->name, pci_name(dev)); | 523 | "probe irqs later\n", d->name, pci_name(dev)); |
527 | pciirq = ret; | 524 | pciirq = 0; |
528 | } else if (!pciirq && noisy) { | 525 | } else if (!pciirq && noisy) { |
529 | printk(KERN_WARNING "%s %s: bad irq (%d): will probe later\n", | 526 | printk(KERN_WARNING "%s %s: bad irq (%d): will probe later\n", |
530 | d->name, pci_name(dev), pciirq); | 527 | d->name, pci_name(dev), pciirq); |
@@ -549,7 +546,7 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d, | |||
549 | if (ret < 0) | 546 | if (ret < 0) |
550 | goto out; | 547 | goto out; |
551 | 548 | ||
552 | ide_pci_setup_ports(dev, d, 0, &hw[0], &hws[0]); | 549 | ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); |
553 | 550 | ||
554 | host = ide_host_alloc(d, hws); | 551 | host = ide_host_alloc(d, hws); |
555 | if (host == NULL) { | 552 | if (host == NULL) { |
@@ -568,7 +565,11 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d, | |||
568 | goto out; | 565 | goto out; |
569 | 566 | ||
570 | /* fixup IRQ */ | 567 | /* fixup IRQ */ |
571 | hw[1].irq = hw[0].irq = ret; | 568 | if (ide_pci_is_in_compatibility_mode(dev)) { |
569 | hw[0].irq = pci_get_legacy_ide_irq(dev, 0); | ||
570 | hw[1].irq = pci_get_legacy_ide_irq(dev, 1); | ||
571 | } else | ||
572 | hw[1].irq = hw[0].irq = ret; | ||
572 | 573 | ||
573 | ret = ide_host_register(host, d, hws); | 574 | ret = ide_host_register(host, d, hws); |
574 | if (ret) | 575 | if (ret) |
@@ -591,7 +592,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, | |||
591 | if (ret < 0) | 592 | if (ret < 0) |
592 | goto out; | 593 | goto out; |
593 | 594 | ||
594 | ide_pci_setup_ports(pdev[i], d, 0, &hw[i*2], &hws[i*2]); | 595 | ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]); |
595 | } | 596 | } |
596 | 597 | ||
597 | host = ide_host_alloc(d, hws); | 598 | host = ide_host_alloc(d, hws); |
@@ -619,7 +620,11 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, | |||
619 | goto out; | 620 | goto out; |
620 | 621 | ||
621 | /* fixup IRQ */ | 622 | /* fixup IRQ */ |
622 | hw[i*2 + 1].irq = hw[i*2].irq = ret; | 623 | if (ide_pci_is_in_compatibility_mode(pdev[i])) { |
624 | hw[i*2].irq = pci_get_legacy_ide_irq(pdev[i], 0); | ||
625 | hw[i*2 + 1].irq = pci_get_legacy_ide_irq(pdev[i], 1); | ||
626 | } else | ||
627 | hw[i*2 + 1].irq = hw[i*2].irq = ret; | ||
623 | } | 628 | } |
624 | 629 | ||
625 | ret = ide_host_register(host, d, hws); | 630 | ret = ide_host_register(host, d, hws); |
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c index cb2b352b876b..1811ae9cd843 100644 --- a/drivers/ide/siimage.c +++ b/drivers/ide/siimage.c | |||
@@ -464,7 +464,7 @@ static void sil_sata_pre_reset(ide_drive_t *drive) | |||
464 | * to 133 MHz clocking if the system isn't already set up to do it. | 464 | * to 133 MHz clocking if the system isn't already set up to do it. |
465 | */ | 465 | */ |
466 | 466 | ||
467 | static unsigned int init_chipset_siimage(struct pci_dev *dev) | 467 | static int init_chipset_siimage(struct pci_dev *dev) |
468 | { | 468 | { |
469 | struct ide_host *host = pci_get_drvdata(dev); | 469 | struct ide_host *host = pci_get_drvdata(dev); |
470 | void __iomem *ioaddr = host->host_priv; | 470 | void __iomem *ioaddr = host->host_priv; |
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c index 9ec1a4a4432c..afca22beaadf 100644 --- a/drivers/ide/sis5513.c +++ b/drivers/ide/sis5513.c | |||
@@ -447,7 +447,7 @@ static int __devinit sis_find_family(struct pci_dev *dev) | |||
447 | return chipset_family; | 447 | return chipset_family; |
448 | } | 448 | } |
449 | 449 | ||
450 | static unsigned int init_chipset_sis5513(struct pci_dev *dev) | 450 | static int init_chipset_sis5513(struct pci_dev *dev) |
451 | { | 451 | { |
452 | /* Make general config ops here | 452 | /* Make general config ops here |
453 | 1/ tell IDE channels to operate in Compatibility mode only | 453 | 1/ tell IDE channels to operate in Compatibility mode only |
@@ -563,7 +563,7 @@ static const struct ide_port_info sis5513_chipset __devinitdata = { | |||
563 | .name = DRV_NAME, | 563 | .name = DRV_NAME, |
564 | .init_chipset = init_chipset_sis5513, | 564 | .init_chipset = init_chipset_sis5513, |
565 | .enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} }, | 565 | .enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} }, |
566 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA, | 566 | .host_flags = IDE_HFLAG_NO_AUTODMA, |
567 | .pio_mask = ATA_PIO4, | 567 | .pio_mask = ATA_PIO4, |
568 | .mwdma_mask = ATA_MWDMA2, | 568 | .mwdma_mask = ATA_MWDMA2, |
569 | }; | 569 | }; |
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c index 6297956507c0..dba213c51baa 100644 --- a/drivers/ide/sl82c105.c +++ b/drivers/ide/sl82c105.c | |||
@@ -271,7 +271,7 @@ static u8 sl82c105_bridge_revision(struct pci_dev *dev) | |||
271 | * channel 0 here at least, but channel 1 has to be enabled by | 271 | * channel 0 here at least, but channel 1 has to be enabled by |
272 | * firmware or arch code. We still set both to 16 bits mode. | 272 | * firmware or arch code. We still set both to 16 bits mode. |
273 | */ | 273 | */ |
274 | static unsigned int init_chipset_sl82c105(struct pci_dev *dev) | 274 | static int init_chipset_sl82c105(struct pci_dev *dev) |
275 | { | 275 | { |
276 | u32 val; | 276 | u32 val; |
277 | 277 | ||
@@ -281,7 +281,7 @@ static unsigned int init_chipset_sl82c105(struct pci_dev *dev) | |||
281 | val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; | 281 | val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; |
282 | pci_write_config_dword(dev, 0x40, val); | 282 | pci_write_config_dword(dev, 0x40, val); |
283 | 283 | ||
284 | return dev->irq; | 284 | return 0; |
285 | } | 285 | } |
286 | 286 | ||
287 | static const struct ide_port_ops sl82c105_port_ops = { | 287 | static const struct ide_port_ops sl82c105_port_ops = { |
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c index 40b4b94a4288..f55d7d6313e8 100644 --- a/drivers/ide/slc90e66.c +++ b/drivers/ide/slc90e66.c | |||
@@ -136,7 +136,6 @@ static const struct ide_port_info slc90e66_chipset __devinitdata = { | |||
136 | .name = DRV_NAME, | 136 | .name = DRV_NAME, |
137 | .enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} }, | 137 | .enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} }, |
138 | .port_ops = &slc90e66_port_ops, | 138 | .port_ops = &slc90e66_port_ops, |
139 | .host_flags = IDE_HFLAG_LEGACY_IRQS, | ||
140 | .pio_mask = ATA_PIO4, | 139 | .pio_mask = ATA_PIO4, |
141 | .swdma_mask = ATA_SWDMA2_ONLY, | 140 | .swdma_mask = ATA_SWDMA2_ONLY, |
142 | .mwdma_mask = ATA_MWDMA12_ONLY, | 141 | .mwdma_mask = ATA_MWDMA12_ONLY, |
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c index b6a1285a4021..1c09e549c423 100644 --- a/drivers/ide/trm290.c +++ b/drivers/ide/trm290.c | |||
@@ -277,9 +277,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) | |||
277 | if (reg & 0x10) | 277 | if (reg & 0x10) |
278 | /* legacy mode */ | 278 | /* legacy mode */ |
279 | hwif->irq = hwif->channel ? 15 : 14; | 279 | hwif->irq = hwif->channel ? 15 : 14; |
280 | else if (!hwif->irq && hwif->mate && hwif->mate->irq) | ||
281 | /* sharing IRQ with mate */ | ||
282 | hwif->irq = hwif->mate->irq; | ||
283 | 280 | ||
284 | #if 1 | 281 | #if 1 |
285 | { | 282 | { |
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 6092fe3f409d..3ff7231e4858 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c | |||
@@ -267,7 +267,7 @@ static void via_cable_detect(struct via82cxxx_dev *vdev, u32 u) | |||
267 | * and initialize its drive independent registers. | 267 | * and initialize its drive independent registers. |
268 | */ | 268 | */ |
269 | 269 | ||
270 | static unsigned int init_chipset_via82cxxx(struct pci_dev *dev) | 270 | static int init_chipset_via82cxxx(struct pci_dev *dev) |
271 | { | 271 | { |
272 | struct ide_host *host = pci_get_drvdata(dev); | 272 | struct ide_host *host = pci_get_drvdata(dev); |
273 | struct via82cxxx_dev *vdev = host->host_priv; | 273 | struct via82cxxx_dev *vdev = host->host_priv; |
@@ -443,16 +443,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i | |||
443 | if ((via_config->flags & VIA_NO_UNMASK) == 0) | 443 | if ((via_config->flags & VIA_NO_UNMASK) == 0) |
444 | d.host_flags |= IDE_HFLAG_UNMASK_IRQS; | 444 | d.host_flags |= IDE_HFLAG_UNMASK_IRQS; |
445 | 445 | ||
446 | #ifdef CONFIG_PPC_CHRP | ||
447 | if (machine_is(chrp) && _chrp_type == _CHRP_Pegasos) | ||
448 | d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS; | ||
449 | #endif | ||
450 | |||
451 | #ifdef CONFIG_AMIGAONE | ||
452 | if (machine_is(amigaone)) | ||
453 | d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS; | ||
454 | #endif | ||
455 | |||
456 | d.udma_mask = via_config->udma_mask; | 446 | d.udma_mask = via_config->udma_mask; |
457 | 447 | ||
458 | vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); | 448 | vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); |
diff --git a/drivers/input/joystick/maplecontrol.c b/drivers/input/joystick/maplecontrol.c index e50047bfe938..77cfde571bd9 100644 --- a/drivers/input/joystick/maplecontrol.c +++ b/drivers/input/joystick/maplecontrol.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Based on drivers/usb/iforce.c | 3 | * Based on drivers/usb/iforce.c |
4 | * | 4 | * |
5 | * Copyright Yaegashi Takeshi, 2001 | 5 | * Copyright Yaegashi Takeshi, 2001 |
6 | * Adrian McMenamin, 2008 | 6 | * Adrian McMenamin, 2008 - 2009 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
@@ -29,7 +29,7 @@ static void dc_pad_callback(struct mapleq *mq) | |||
29 | struct maple_device *mapledev = mq->dev; | 29 | struct maple_device *mapledev = mq->dev; |
30 | struct dc_pad *pad = maple_get_drvdata(mapledev); | 30 | struct dc_pad *pad = maple_get_drvdata(mapledev); |
31 | struct input_dev *dev = pad->dev; | 31 | struct input_dev *dev = pad->dev; |
32 | unsigned char *res = mq->recvbuf; | 32 | unsigned char *res = mq->recvbuf->buf; |
33 | 33 | ||
34 | buttons = ~le16_to_cpup((__le16 *)(res + 8)); | 34 | buttons = ~le16_to_cpup((__le16 *)(res + 8)); |
35 | 35 | ||
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 22f17a593be7..5aa2361aef95 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * SEGA Dreamcast keyboard driver | 2 | * SEGA Dreamcast keyboard driver |
3 | * Based on drivers/usb/usbkbd.c | 3 | * Based on drivers/usb/usbkbd.c |
4 | * Copyright YAEGASHI Takeshi, 2001 | 4 | * Copyright (c) YAEGASHI Takeshi, 2001 |
5 | * Porting to 2.6 Copyright Adrian McMenamin, 2007, 2008 | 5 | * Porting to 2.6 Copyright (c) Adrian McMenamin, 2007 - 2009 |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -33,7 +33,7 @@ static DEFINE_MUTEX(maple_keyb_mutex); | |||
33 | 33 | ||
34 | #define NR_SCANCODES 256 | 34 | #define NR_SCANCODES 256 |
35 | 35 | ||
36 | MODULE_AUTHOR("YAEGASHI Takeshi, Adrian McMenamin"); | 36 | MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk"); |
37 | MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver"); | 37 | MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver"); |
38 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
39 | 39 | ||
@@ -115,7 +115,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd) | |||
115 | input_event(dev, EV_MSC, MSC_SCAN, code); | 115 | input_event(dev, EV_MSC, MSC_SCAN, code); |
116 | input_report_key(dev, keycode, 0); | 116 | input_report_key(dev, keycode, 0); |
117 | } else | 117 | } else |
118 | printk(KERN_DEBUG "maple_keyb: " | 118 | dev_dbg(&dev->dev, |
119 | "Unknown key (scancode %#x) released.", | 119 | "Unknown key (scancode %#x) released.", |
120 | code); | 120 | code); |
121 | } | 121 | } |
@@ -127,7 +127,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd) | |||
127 | input_event(dev, EV_MSC, MSC_SCAN, code); | 127 | input_event(dev, EV_MSC, MSC_SCAN, code); |
128 | input_report_key(dev, keycode, 1); | 128 | input_report_key(dev, keycode, 1); |
129 | } else | 129 | } else |
130 | printk(KERN_DEBUG "maple_keyb: " | 130 | dev_dbg(&dev->dev, |
131 | "Unknown key (scancode %#x) pressed.", | 131 | "Unknown key (scancode %#x) pressed.", |
132 | code); | 132 | code); |
133 | } | 133 | } |
@@ -140,7 +140,7 @@ static void dc_kbd_callback(struct mapleq *mq) | |||
140 | { | 140 | { |
141 | struct maple_device *mapledev = mq->dev; | 141 | struct maple_device *mapledev = mq->dev; |
142 | struct dc_kbd *kbd = maple_get_drvdata(mapledev); | 142 | struct dc_kbd *kbd = maple_get_drvdata(mapledev); |
143 | unsigned long *buf = mq->recvbuf; | 143 | unsigned long *buf = (unsigned long *)(mq->recvbuf->buf); |
144 | 144 | ||
145 | /* | 145 | /* |
146 | * We should always get the lock because the only | 146 | * We should always get the lock because the only |
@@ -159,22 +159,27 @@ static void dc_kbd_callback(struct mapleq *mq) | |||
159 | 159 | ||
160 | static int probe_maple_kbd(struct device *dev) | 160 | static int probe_maple_kbd(struct device *dev) |
161 | { | 161 | { |
162 | struct maple_device *mdev = to_maple_dev(dev); | 162 | struct maple_device *mdev; |
163 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | 163 | struct maple_driver *mdrv; |
164 | int i, error; | 164 | int i, error; |
165 | struct dc_kbd *kbd; | 165 | struct dc_kbd *kbd; |
166 | struct input_dev *idev; | 166 | struct input_dev *idev; |
167 | 167 | ||
168 | if (!(mdev->function & MAPLE_FUNC_KEYBOARD)) | 168 | mdev = to_maple_dev(dev); |
169 | return -EINVAL; | 169 | mdrv = to_maple_driver(dev->driver); |
170 | 170 | ||
171 | kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); | 171 | kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); |
172 | idev = input_allocate_device(); | 172 | if (!kbd) { |
173 | if (!kbd || !idev) { | ||
174 | error = -ENOMEM; | 173 | error = -ENOMEM; |
175 | goto fail; | 174 | goto fail; |
176 | } | 175 | } |
177 | 176 | ||
177 | idev = input_allocate_device(); | ||
178 | if (!idev) { | ||
179 | error = -ENOMEM; | ||
180 | goto fail_idev_alloc; | ||
181 | } | ||
182 | |||
178 | kbd->dev = idev; | 183 | kbd->dev = idev; |
179 | memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); | 184 | memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); |
180 | 185 | ||
@@ -195,7 +200,7 @@ static int probe_maple_kbd(struct device *dev) | |||
195 | 200 | ||
196 | error = input_register_device(idev); | 201 | error = input_register_device(idev); |
197 | if (error) | 202 | if (error) |
198 | goto fail; | 203 | goto fail_register; |
199 | 204 | ||
200 | /* Maple polling is locked to VBLANK - which may be just 50/s */ | 205 | /* Maple polling is locked to VBLANK - which may be just 50/s */ |
201 | maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, | 206 | maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, |
@@ -207,10 +212,12 @@ static int probe_maple_kbd(struct device *dev) | |||
207 | 212 | ||
208 | return error; | 213 | return error; |
209 | 214 | ||
210 | fail: | 215 | fail_register: |
216 | maple_set_drvdata(mdev, NULL); | ||
211 | input_free_device(idev); | 217 | input_free_device(idev); |
218 | fail_idev_alloc: | ||
212 | kfree(kbd); | 219 | kfree(kbd); |
213 | maple_set_drvdata(mdev, NULL); | 220 | fail: |
214 | return error; | 221 | return error; |
215 | } | 222 | } |
216 | 223 | ||
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 5c8a1bcf7ca7..e1480fb11de3 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -219,6 +219,8 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
219 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); | 219 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); |
220 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 220 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); |
221 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | 221 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); |
222 | |||
223 | device_init_wakeup(&pdev->dev, 1); | ||
222 | return 0; | 224 | return 0; |
223 | err5: | 225 | err5: |
224 | free_irq(irq, pdev); | 226 | free_irq(irq, pdev); |
@@ -253,17 +255,33 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
253 | return 0; | 255 | return 0; |
254 | } | 256 | } |
255 | 257 | ||
258 | static int sh_keysc_suspend(struct device *dev) | ||
259 | { | ||
260 | struct platform_device *pdev = to_platform_device(dev); | ||
261 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | ||
262 | unsigned short value; | ||
263 | |||
264 | value = ioread16(priv->iomem_base + KYCR1_OFFS); | ||
265 | |||
266 | if (device_may_wakeup(dev)) | ||
267 | value |= 0x80; | ||
268 | else | ||
269 | value &= ~0x80; | ||
256 | 270 | ||
257 | #define sh_keysc_suspend NULL | 271 | iowrite16(value, priv->iomem_base + KYCR1_OFFS); |
258 | #define sh_keysc_resume NULL | 272 | return 0; |
273 | } | ||
274 | |||
275 | static struct dev_pm_ops sh_keysc_dev_pm_ops = { | ||
276 | .suspend = sh_keysc_suspend, | ||
277 | }; | ||
259 | 278 | ||
260 | struct platform_driver sh_keysc_device_driver = { | 279 | struct platform_driver sh_keysc_device_driver = { |
261 | .probe = sh_keysc_probe, | 280 | .probe = sh_keysc_probe, |
262 | .remove = __devexit_p(sh_keysc_remove), | 281 | .remove = __devexit_p(sh_keysc_remove), |
263 | .suspend = sh_keysc_suspend, | ||
264 | .resume = sh_keysc_resume, | ||
265 | .driver = { | 282 | .driver = { |
266 | .name = "sh_keysc", | 283 | .name = "sh_keysc", |
284 | .pm = &sh_keysc_dev_pm_ops, | ||
267 | } | 285 | } |
268 | }; | 286 | }; |
269 | 287 | ||
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index ac245e7e96a5..3071a52467ed 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
@@ -389,8 +389,7 @@ static void gigaset_freecshw(struct cardstate *cs) | |||
389 | 389 | ||
390 | static void gigaset_device_release(struct device *dev) | 390 | static void gigaset_device_release(struct device *dev) |
391 | { | 391 | { |
392 | struct platform_device *pdev = | 392 | struct platform_device *pdev = to_platform_device(dev); |
393 | container_of(dev, struct platform_device, dev); | ||
394 | 393 | ||
395 | /* adapted from platform_device_release() in drivers/base/platform.c */ | 394 | /* adapted from platform_device_release() in drivers/base/platform.c */ |
396 | //FIXME is this actually necessary? | 395 | //FIXME is this actually necessary? |
diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c index ef2dbfe74714..ada5ebbaa255 100644 --- a/drivers/mca/mca-bus.c +++ b/drivers/mca/mca-bus.c | |||
@@ -110,7 +110,7 @@ int __init mca_register_device(int bus, struct mca_device *mca_dev) | |||
110 | 110 | ||
111 | mca_dev->dev.parent = &mca_bus->dev; | 111 | mca_dev->dev.parent = &mca_bus->dev; |
112 | mca_dev->dev.bus = &mca_bus_type; | 112 | mca_dev->dev.bus = &mca_bus_type; |
113 | sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot); | 113 | dev_set_name(&mca_dev->dev, "%02d:%02X", bus, mca_dev->slot); |
114 | mca_dev->dma_mask = mca_bus->default_dma_mask; | 114 | mca_dev->dma_mask = mca_bus->default_dma_mask; |
115 | mca_dev->dev.dma_mask = &mca_dev->dma_mask; | 115 | mca_dev->dev.dma_mask = &mca_dev->dma_mask; |
116 | mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask; | 116 | mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask; |
@@ -151,7 +151,7 @@ struct mca_bus * __devinit mca_attach_bus(int bus) | |||
151 | if (!mca_bus) | 151 | if (!mca_bus) |
152 | return NULL; | 152 | return NULL; |
153 | 153 | ||
154 | sprintf(mca_bus->dev.bus_id,"mca%d",bus); | 154 | dev_set_name(&mca_bus->dev, "mca%d", bus); |
155 | sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary"); | 155 | sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary"); |
156 | if (device_register(&mca_bus->dev)) { | 156 | if (device_register(&mca_bus->dev)) { |
157 | kfree(mca_bus); | 157 | kfree(mca_bus); |
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 4d35308fc1ff..393623818ade 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c | |||
@@ -298,7 +298,8 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
298 | 298 | ||
299 | strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver)); | 299 | strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver)); |
300 | strlcpy(v->card, dev->name, sizeof(v->card)); | 300 | strlcpy(v->card, dev->name, sizeof(v->card)); |
301 | snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id); | 301 | snprintf(v->bus_info, sizeof(v->bus_info), |
302 | "I2C:%s", dev_name(&dev->dev)); | ||
302 | v->version = RADIO_VERSION; | 303 | v->version = RADIO_VERSION; |
303 | v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; | 304 | v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; |
304 | return 0; | 305 | return 0; |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 66c755c116dc..ce98d955231a 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -803,9 +803,10 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, | |||
803 | return (-ENOENT); | 803 | return (-ENOENT); |
804 | } | 804 | } |
805 | 805 | ||
806 | card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t)); | 806 | err = snd_card_create(index[devno], id[devno], THIS_MODULE, |
807 | if (!card) | 807 | sizeof(snd_cx88_card_t), &card); |
808 | return (-ENOMEM); | 808 | if (err < 0) |
809 | return err; | ||
809 | 810 | ||
810 | card->private_free = snd_cx88_dev_free; | 811 | card->private_free = snd_cx88_dev_free; |
811 | 812 | ||
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 2ac738fa6a07..f132e31f6edd 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
@@ -448,9 +448,10 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
448 | printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " | 448 | printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " |
449 | "Rechberger\n"); | 449 | "Rechberger\n"); |
450 | 450 | ||
451 | card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0); | 451 | err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0, |
452 | if (card == NULL) | 452 | &card); |
453 | return -ENOMEM; | 453 | if (err < 0) |
454 | return err; | ||
454 | 455 | ||
455 | spin_lock_init(&adev->slock); | 456 | spin_lock_init(&adev->slock); |
456 | err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); | 457 | err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index c750d3dd57d2..8b0b64a89874 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -990,10 +990,10 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) | |||
990 | if (!enable[devnum]) | 990 | if (!enable[devnum]) |
991 | return -ENODEV; | 991 | return -ENODEV; |
992 | 992 | ||
993 | card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t)); | 993 | err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, |
994 | 994 | sizeof(snd_card_saa7134_t), &card); | |
995 | if (card == NULL) | 995 | if (err < 0) |
996 | return -ENOMEM; | 996 | return err; |
997 | 997 | ||
998 | strcpy(card->driver, "SAA7134"); | 998 | strcpy(card->driver, "SAA7134"); |
999 | 999 | ||
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index cf9d4c7f571a..8a4b74f3129f 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c | |||
@@ -34,7 +34,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) | |||
34 | spin_lock_init(&v4l2_dev->lock); | 34 | spin_lock_init(&v4l2_dev->lock); |
35 | v4l2_dev->dev = dev; | 35 | v4l2_dev->dev = dev; |
36 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", | 36 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", |
37 | dev->driver->name, dev->bus_id); | 37 | dev->driver->name, dev_name(dev)); |
38 | dev_set_drvdata(dev, v4l2_dev); | 38 | dev_set_drvdata(dev, v4l2_dev); |
39 | return 0; | 39 | return 0; |
40 | } | 40 | } |
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index 6063dc2b52e8..57271cb3b316 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c | |||
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(mcp_host_alloc); | |||
214 | 214 | ||
215 | int mcp_host_register(struct mcp *mcp) | 215 | int mcp_host_register(struct mcp *mcp) |
216 | { | 216 | { |
217 | strcpy(mcp->attached_device.bus_id, "mcp0"); | 217 | dev_set_name(&mcp->attached_device, "mcp0"); |
218 | return device_register(&mcp->attached_device); | 218 | return device_register(&mcp->attached_device); |
219 | } | 219 | } |
220 | EXPORT_SYMBOL(mcp_host_register); | 220 | EXPORT_SYMBOL(mcp_host_register); |
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 6860c924f364..fea9085fe52c 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c | |||
@@ -492,7 +492,7 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
492 | 492 | ||
493 | ucb->dev.class = &ucb1x00_class; | 493 | ucb->dev.class = &ucb1x00_class; |
494 | ucb->dev.parent = &mcp->attached_device; | 494 | ucb->dev.parent = &mcp->attached_device; |
495 | strlcpy(ucb->dev.bus_id, "ucb1x00", sizeof(ucb->dev.bus_id)); | 495 | dev_set_name(&ucb->dev, "ucb1x00"); |
496 | 496 | ||
497 | spin_lock_init(&ucb->lock); | 497 | spin_lock_init(&ucb->lock); |
498 | spin_lock_init(&ucb->io_lock); | 498 | spin_lock_init(&ucb->io_lock); |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 2b1196e6142c..e94e92001e7c 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -1603,7 +1603,7 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1603 | 1603 | ||
1604 | tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host); | 1604 | tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host); |
1605 | 1605 | ||
1606 | ret = request_irq(irq, atmci_interrupt, 0, pdev->dev.bus_id, host); | 1606 | ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host); |
1607 | if (ret) | 1607 | if (ret) |
1608 | goto err_request_irq; | 1608 | goto err_request_irq; |
1609 | 1609 | ||
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index fb2921f8099d..0c44d560bf1a 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c | |||
@@ -103,7 +103,7 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) | |||
103 | if (!gpio_is_valid(oms->gpios[i])) | 103 | if (!gpio_is_valid(oms->gpios[i])) |
104 | continue; | 104 | continue; |
105 | 105 | ||
106 | ret = gpio_request(oms->gpios[i], dev->bus_id); | 106 | ret = gpio_request(oms->gpios[i], dev_name(dev)); |
107 | if (ret < 0) { | 107 | if (ret < 0) { |
108 | oms->gpios[i] = -EINVAL; | 108 | oms->gpios[i] = -EINVAL; |
109 | continue; | 109 | continue; |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 043d50fb6ef6..729f899a5cd5 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -551,5 +551,15 @@ config MTD_PLATRAM | |||
551 | 551 | ||
552 | This selection automatically selects the map_ram driver. | 552 | This selection automatically selects the map_ram driver. |
553 | 553 | ||
554 | endmenu | 554 | config MTD_VMU |
555 | tristate "Map driver for Dreamcast VMU" | ||
556 | depends on MAPLE | ||
557 | help | ||
558 | This driver enables access to the Dreamcast Visual Memory Unit (VMU). | ||
559 | |||
560 | Most Dreamcast users will want to say Y here. | ||
555 | 561 | ||
562 | To build this as a module select M here, the module will be called | ||
563 | vmu-flash. | ||
564 | |||
565 | endmenu | ||
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 6d9ba35caf11..26b28a7a90b5 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile | |||
@@ -61,3 +61,4 @@ obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o | |||
61 | obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o | 61 | obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o |
62 | obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o | 62 | obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o |
63 | obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o | 63 | obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o |
64 | obj-$(CONFIG_MTD_VMU) += vmu-flash.o | ||
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 771139c5bf87..e9026cb1c5b2 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info { | |||
41 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 41 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
42 | 42 | ||
43 | 43 | ||
44 | static int __init pxa2xx_flash_probe(struct device *dev) | 44 | static int __init pxa2xx_flash_probe(struct platform_device *pdev) |
45 | { | 45 | { |
46 | struct platform_device *pdev = to_platform_device(dev); | ||
47 | struct flash_platform_data *flash = pdev->dev.platform_data; | 46 | struct flash_platform_data *flash = pdev->dev.platform_data; |
48 | struct pxa2xx_flash_info *info; | 47 | struct pxa2xx_flash_info *info; |
49 | struct mtd_partition *parts; | 48 | struct mtd_partition *parts; |
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(struct device *dev) | |||
114 | add_mtd_device(info->mtd); | 113 | add_mtd_device(info->mtd); |
115 | } | 114 | } |
116 | 115 | ||
117 | dev_set_drvdata(dev, info); | 116 | platform_set_drvdata(pdev, info); |
118 | return 0; | 117 | return 0; |
119 | } | 118 | } |
120 | 119 | ||
121 | static int __exit pxa2xx_flash_remove(struct device *dev) | 120 | static int __exit pxa2xx_flash_remove(struct platform_device *dev) |
122 | { | 121 | { |
123 | struct pxa2xx_flash_info *info = dev_get_drvdata(dev); | 122 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
124 | 123 | ||
125 | dev_set_drvdata(dev, NULL); | 124 | platform_set_drvdata(dev, NULL); |
126 | 125 | ||
127 | #ifdef CONFIG_MTD_PARTITIONS | 126 | #ifdef CONFIG_MTD_PARTITIONS |
128 | if (info->nr_parts) | 127 | if (info->nr_parts) |
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(struct device *dev) | |||
141 | } | 140 | } |
142 | 141 | ||
143 | #ifdef CONFIG_PM | 142 | #ifdef CONFIG_PM |
144 | static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state) | 143 | static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state) |
145 | { | 144 | { |
146 | struct pxa2xx_flash_info *info = dev_get_drvdata(dev); | 145 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
147 | int ret = 0; | 146 | int ret = 0; |
148 | 147 | ||
149 | if (info->mtd && info->mtd->suspend) | 148 | if (info->mtd && info->mtd->suspend) |
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state) | |||
151 | return ret; | 150 | return ret; |
152 | } | 151 | } |
153 | 152 | ||
154 | static int pxa2xx_flash_resume(struct device *dev) | 153 | static int pxa2xx_flash_resume(struct platform_device *dev) |
155 | { | 154 | { |
156 | struct pxa2xx_flash_info *info = dev_get_drvdata(dev); | 155 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
157 | 156 | ||
158 | if (info->mtd && info->mtd->resume) | 157 | if (info->mtd && info->mtd->resume) |
159 | info->mtd->resume(info->mtd); | 158 | info->mtd->resume(info->mtd); |
160 | return 0; | 159 | return 0; |
161 | } | 160 | } |
162 | static void pxa2xx_flash_shutdown(struct device *dev) | 161 | static void pxa2xx_flash_shutdown(struct platform_device *dev) |
163 | { | 162 | { |
164 | struct pxa2xx_flash_info *info = dev_get_drvdata(dev); | 163 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
165 | 164 | ||
166 | if (info && info->mtd->suspend(info->mtd) == 0) | 165 | if (info && info->mtd->suspend(info->mtd) == 0) |
167 | info->mtd->resume(info->mtd); | 166 | info->mtd->resume(info->mtd); |
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct device *dev) | |||
172 | #define pxa2xx_flash_shutdown NULL | 171 | #define pxa2xx_flash_shutdown NULL |
173 | #endif | 172 | #endif |
174 | 173 | ||
175 | static struct device_driver pxa2xx_flash_driver = { | 174 | static struct platform_driver pxa2xx_flash_driver = { |
176 | .name = "pxa2xx-flash", | 175 | .driver = { |
177 | .bus = &platform_bus_type, | 176 | .name = "pxa2xx-flash", |
177 | .owner = THIS_MODULE, | ||
178 | }, | ||
178 | .probe = pxa2xx_flash_probe, | 179 | .probe = pxa2xx_flash_probe, |
179 | .remove = __exit_p(pxa2xx_flash_remove), | 180 | .remove = __devexit_p(pxa2xx_flash_remove), |
180 | .suspend = pxa2xx_flash_suspend, | 181 | .suspend = pxa2xx_flash_suspend, |
181 | .resume = pxa2xx_flash_resume, | 182 | .resume = pxa2xx_flash_resume, |
182 | .shutdown = pxa2xx_flash_shutdown, | 183 | .shutdown = pxa2xx_flash_shutdown, |
@@ -184,12 +185,12 @@ static struct device_driver pxa2xx_flash_driver = { | |||
184 | 185 | ||
185 | static int __init init_pxa2xx_flash(void) | 186 | static int __init init_pxa2xx_flash(void) |
186 | { | 187 | { |
187 | return driver_register(&pxa2xx_flash_driver); | 188 | return platform_driver_register(&pxa2xx_flash_driver); |
188 | } | 189 | } |
189 | 190 | ||
190 | static void __exit cleanup_pxa2xx_flash(void) | 191 | static void __exit cleanup_pxa2xx_flash(void) |
191 | { | 192 | { |
192 | driver_unregister(&pxa2xx_flash_driver); | 193 | platform_driver_unregister(&pxa2xx_flash_driver); |
193 | } | 194 | } |
194 | 195 | ||
195 | module_init(init_pxa2xx_flash); | 196 | module_init(init_pxa2xx_flash); |
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c new file mode 100644 index 000000000000..1f73297e7776 --- /dev/null +++ b/drivers/mtd/maps/vmu-flash.c | |||
@@ -0,0 +1,832 @@ | |||
1 | /* vmu-flash.c | ||
2 | * Driver for SEGA Dreamcast Visual Memory Unit | ||
3 | * | ||
4 | * Copyright (c) Adrian McMenamin 2002 - 2009 | ||
5 | * Copyright (c) Paul Mundt 2001 | ||
6 | * | ||
7 | * Licensed under version 2 of the | ||
8 | * GNU General Public Licence | ||
9 | */ | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/sched.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/maple.h> | ||
14 | #include <linux/mtd/mtd.h> | ||
15 | #include <linux/mtd/map.h> | ||
16 | |||
17 | struct vmu_cache { | ||
18 | unsigned char *buffer; /* Cache */ | ||
19 | unsigned int block; /* Which block was cached */ | ||
20 | unsigned long jiffies_atc; /* When was it cached? */ | ||
21 | int valid; | ||
22 | }; | ||
23 | |||
24 | struct mdev_part { | ||
25 | struct maple_device *mdev; | ||
26 | int partition; | ||
27 | }; | ||
28 | |||
29 | struct vmupart { | ||
30 | u16 user_blocks; | ||
31 | u16 root_block; | ||
32 | u16 numblocks; | ||
33 | char *name; | ||
34 | struct vmu_cache *pcache; | ||
35 | }; | ||
36 | |||
37 | struct memcard { | ||
38 | u16 tempA; | ||
39 | u16 tempB; | ||
40 | u32 partitions; | ||
41 | u32 blocklen; | ||
42 | u32 writecnt; | ||
43 | u32 readcnt; | ||
44 | u32 removeable; | ||
45 | int partition; | ||
46 | int read; | ||
47 | unsigned char *blockread; | ||
48 | struct vmupart *parts; | ||
49 | struct mtd_info *mtd; | ||
50 | }; | ||
51 | |||
52 | struct vmu_block { | ||
53 | unsigned int num; /* block number */ | ||
54 | unsigned int ofs; /* block offset */ | ||
55 | }; | ||
56 | |||
57 | static struct vmu_block *ofs_to_block(unsigned long src_ofs, | ||
58 | struct mtd_info *mtd, int partition) | ||
59 | { | ||
60 | struct vmu_block *vblock; | ||
61 | struct maple_device *mdev; | ||
62 | struct memcard *card; | ||
63 | struct mdev_part *mpart; | ||
64 | int num; | ||
65 | |||
66 | mpart = mtd->priv; | ||
67 | mdev = mpart->mdev; | ||
68 | card = maple_get_drvdata(mdev); | ||
69 | |||
70 | if (src_ofs >= card->parts[partition].numblocks * card->blocklen) | ||
71 | goto failed; | ||
72 | |||
73 | num = src_ofs / card->blocklen; | ||
74 | if (num > card->parts[partition].numblocks) | ||
75 | goto failed; | ||
76 | |||
77 | vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL); | ||
78 | if (!vblock) | ||
79 | goto failed; | ||
80 | |||
81 | vblock->num = num; | ||
82 | vblock->ofs = src_ofs % card->blocklen; | ||
83 | return vblock; | ||
84 | |||
85 | failed: | ||
86 | return NULL; | ||
87 | } | ||
88 | |||
89 | /* Maple bus callback function for reads */ | ||
90 | static void vmu_blockread(struct mapleq *mq) | ||
91 | { | ||
92 | struct maple_device *mdev; | ||
93 | struct memcard *card; | ||
94 | |||
95 | mdev = mq->dev; | ||
96 | card = maple_get_drvdata(mdev); | ||
97 | /* copy the read in data */ | ||
98 | |||
99 | if (unlikely(!card->blockread)) | ||
100 | return; | ||
101 | |||
102 | memcpy(card->blockread, mq->recvbuf->buf + 12, | ||
103 | card->blocklen/card->readcnt); | ||
104 | |||
105 | } | ||
106 | |||
107 | /* Interface with maple bus to read blocks | ||
108 | * caching the results so that other parts | ||
109 | * of the driver can access block reads */ | ||
110 | static int maple_vmu_read_block(unsigned int num, unsigned char *buf, | ||
111 | struct mtd_info *mtd) | ||
112 | { | ||
113 | struct memcard *card; | ||
114 | struct mdev_part *mpart; | ||
115 | struct maple_device *mdev; | ||
116 | int partition, error = 0, x, wait; | ||
117 | unsigned char *blockread = NULL; | ||
118 | struct vmu_cache *pcache; | ||
119 | __be32 sendbuf; | ||
120 | |||
121 | mpart = mtd->priv; | ||
122 | mdev = mpart->mdev; | ||
123 | partition = mpart->partition; | ||
124 | card = maple_get_drvdata(mdev); | ||
125 | pcache = card->parts[partition].pcache; | ||
126 | pcache->valid = 0; | ||
127 | |||
128 | /* prepare the cache for this block */ | ||
129 | if (!pcache->buffer) { | ||
130 | pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL); | ||
131 | if (!pcache->buffer) { | ||
132 | dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due" | ||
133 | " to lack of memory\n", mdev->port, | ||
134 | mdev->unit); | ||
135 | error = -ENOMEM; | ||
136 | goto outB; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Reads may be phased - again the hardware spec | ||
142 | * supports this - though may not be any devices in | ||
143 | * the wild that implement it, but we will here | ||
144 | */ | ||
145 | for (x = 0; x < card->readcnt; x++) { | ||
146 | sendbuf = cpu_to_be32(partition << 24 | x << 16 | num); | ||
147 | |||
148 | if (atomic_read(&mdev->busy) == 1) { | ||
149 | wait_event_interruptible_timeout(mdev->maple_wait, | ||
150 | atomic_read(&mdev->busy) == 0, HZ); | ||
151 | if (atomic_read(&mdev->busy) == 1) { | ||
152 | dev_notice(&mdev->dev, "VMU at (%d, %d)" | ||
153 | " is busy\n", mdev->port, mdev->unit); | ||
154 | error = -EAGAIN; | ||
155 | goto outB; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | atomic_set(&mdev->busy, 1); | ||
160 | blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL); | ||
161 | if (!blockread) { | ||
162 | error = -ENOMEM; | ||
163 | atomic_set(&mdev->busy, 0); | ||
164 | goto outB; | ||
165 | } | ||
166 | card->blockread = blockread; | ||
167 | |||
168 | maple_getcond_callback(mdev, vmu_blockread, 0, | ||
169 | MAPLE_FUNC_MEMCARD); | ||
170 | error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD, | ||
171 | MAPLE_COMMAND_BREAD, 2, &sendbuf); | ||
172 | /* Very long timeouts seem to be needed when box is stressed */ | ||
173 | wait = wait_event_interruptible_timeout(mdev->maple_wait, | ||
174 | (atomic_read(&mdev->busy) == 0 || | ||
175 | atomic_read(&mdev->busy) == 2), HZ * 3); | ||
176 | /* | ||
177 | * MTD layer does not handle hotplugging well | ||
178 | * so have to return errors when VMU is unplugged | ||
179 | * in the middle of a read (busy == 2) | ||
180 | */ | ||
181 | if (error || atomic_read(&mdev->busy) == 2) { | ||
182 | if (atomic_read(&mdev->busy) == 2) | ||
183 | error = -ENXIO; | ||
184 | atomic_set(&mdev->busy, 0); | ||
185 | card->blockread = NULL; | ||
186 | goto outA; | ||
187 | } | ||
188 | if (wait == 0 || wait == -ERESTARTSYS) { | ||
189 | card->blockread = NULL; | ||
190 | atomic_set(&mdev->busy, 0); | ||
191 | error = -EIO; | ||
192 | list_del_init(&(mdev->mq->list)); | ||
193 | kfree(mdev->mq->sendbuf); | ||
194 | mdev->mq->sendbuf = NULL; | ||
195 | if (wait == -ERESTARTSYS) { | ||
196 | dev_warn(&mdev->dev, "VMU read on (%d, %d)" | ||
197 | " interrupted on block 0x%X\n", | ||
198 | mdev->port, mdev->unit, num); | ||
199 | } else | ||
200 | dev_notice(&mdev->dev, "VMU read on (%d, %d)" | ||
201 | " timed out on block 0x%X\n", | ||
202 | mdev->port, mdev->unit, num); | ||
203 | goto outA; | ||
204 | } | ||
205 | |||
206 | memcpy(buf + (card->blocklen/card->readcnt) * x, blockread, | ||
207 | card->blocklen/card->readcnt); | ||
208 | |||
209 | memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x, | ||
210 | card->blockread, card->blocklen/card->readcnt); | ||
211 | card->blockread = NULL; | ||
212 | pcache->block = num; | ||
213 | pcache->jiffies_atc = jiffies; | ||
214 | pcache->valid = 1; | ||
215 | kfree(blockread); | ||
216 | } | ||
217 | |||
218 | return error; | ||
219 | |||
220 | outA: | ||
221 | kfree(blockread); | ||
222 | outB: | ||
223 | return error; | ||
224 | } | ||
225 | |||
226 | /* communicate with maple bus for phased writing */ | ||
227 | static int maple_vmu_write_block(unsigned int num, const unsigned char *buf, | ||
228 | struct mtd_info *mtd) | ||
229 | { | ||
230 | struct memcard *card; | ||
231 | struct mdev_part *mpart; | ||
232 | struct maple_device *mdev; | ||
233 | int partition, error, locking, x, phaselen, wait; | ||
234 | __be32 *sendbuf; | ||
235 | |||
236 | mpart = mtd->priv; | ||
237 | mdev = mpart->mdev; | ||
238 | partition = mpart->partition; | ||
239 | card = maple_get_drvdata(mdev); | ||
240 | |||
241 | phaselen = card->blocklen/card->writecnt; | ||
242 | |||
243 | sendbuf = kmalloc(phaselen + 4, GFP_KERNEL); | ||
244 | if (!sendbuf) { | ||
245 | error = -ENOMEM; | ||
246 | goto fail_nosendbuf; | ||
247 | } | ||
248 | for (x = 0; x < card->writecnt; x++) { | ||
249 | sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num); | ||
250 | memcpy(&sendbuf[1], buf + phaselen * x, phaselen); | ||
251 | /* wait until the device is not busy doing something else | ||
252 | * or 1 second - which ever is longer */ | ||
253 | if (atomic_read(&mdev->busy) == 1) { | ||
254 | wait_event_interruptible_timeout(mdev->maple_wait, | ||
255 | atomic_read(&mdev->busy) == 0, HZ); | ||
256 | if (atomic_read(&mdev->busy) == 1) { | ||
257 | error = -EBUSY; | ||
258 | dev_notice(&mdev->dev, "VMU write at (%d, %d)" | ||
259 | "failed - device is busy\n", | ||
260 | mdev->port, mdev->unit); | ||
261 | goto fail_nolock; | ||
262 | } | ||
263 | } | ||
264 | atomic_set(&mdev->busy, 1); | ||
265 | |||
266 | locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD, | ||
267 | MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf); | ||
268 | wait = wait_event_interruptible_timeout(mdev->maple_wait, | ||
269 | atomic_read(&mdev->busy) == 0, HZ/10); | ||
270 | if (locking) { | ||
271 | error = -EIO; | ||
272 | atomic_set(&mdev->busy, 0); | ||
273 | goto fail_nolock; | ||
274 | } | ||
275 | if (atomic_read(&mdev->busy) == 2) { | ||
276 | atomic_set(&mdev->busy, 0); | ||
277 | } else if (wait == 0 || wait == -ERESTARTSYS) { | ||
278 | error = -EIO; | ||
279 | dev_warn(&mdev->dev, "Write at (%d, %d) of block" | ||
280 | " 0x%X at phase %d failed: could not" | ||
281 | " communicate with VMU", mdev->port, | ||
282 | mdev->unit, num, x); | ||
283 | atomic_set(&mdev->busy, 0); | ||
284 | kfree(mdev->mq->sendbuf); | ||
285 | mdev->mq->sendbuf = NULL; | ||
286 | list_del_init(&(mdev->mq->list)); | ||
287 | goto fail_nolock; | ||
288 | } | ||
289 | } | ||
290 | kfree(sendbuf); | ||
291 | |||
292 | return card->blocklen; | ||
293 | |||
294 | fail_nolock: | ||
295 | kfree(sendbuf); | ||
296 | fail_nosendbuf: | ||
297 | dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port, | ||
298 | mdev->unit); | ||
299 | return error; | ||
300 | } | ||
301 | |||
302 | /* mtd function to simulate reading byte by byte */ | ||
303 | static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval, | ||
304 | struct mtd_info *mtd) | ||
305 | { | ||
306 | struct vmu_block *vblock; | ||
307 | struct memcard *card; | ||
308 | struct mdev_part *mpart; | ||
309 | struct maple_device *mdev; | ||
310 | unsigned char *buf, ret; | ||
311 | int partition, error; | ||
312 | |||
313 | mpart = mtd->priv; | ||
314 | mdev = mpart->mdev; | ||
315 | partition = mpart->partition; | ||
316 | card = maple_get_drvdata(mdev); | ||
317 | *retval = 0; | ||
318 | |||
319 | buf = kmalloc(card->blocklen, GFP_KERNEL); | ||
320 | if (!buf) { | ||
321 | *retval = 1; | ||
322 | ret = -ENOMEM; | ||
323 | goto finish; | ||
324 | } | ||
325 | |||
326 | vblock = ofs_to_block(ofs, mtd, partition); | ||
327 | if (!vblock) { | ||
328 | *retval = 3; | ||
329 | ret = -ENOMEM; | ||
330 | goto out_buf; | ||
331 | } | ||
332 | |||
333 | error = maple_vmu_read_block(vblock->num, buf, mtd); | ||
334 | if (error) { | ||
335 | ret = error; | ||
336 | *retval = 2; | ||
337 | goto out_vblock; | ||
338 | } | ||
339 | |||
340 | ret = buf[vblock->ofs]; | ||
341 | |||
342 | out_vblock: | ||
343 | kfree(vblock); | ||
344 | out_buf: | ||
345 | kfree(buf); | ||
346 | finish: | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | /* mtd higher order function to read flash */ | ||
351 | static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len, | ||
352 | size_t *retlen, u_char *buf) | ||
353 | { | ||
354 | struct maple_device *mdev; | ||
355 | struct memcard *card; | ||
356 | struct mdev_part *mpart; | ||
357 | struct vmu_cache *pcache; | ||
358 | struct vmu_block *vblock; | ||
359 | int index = 0, retval, partition, leftover, numblocks; | ||
360 | unsigned char cx; | ||
361 | |||
362 | if (len < 1) | ||
363 | return -EIO; | ||
364 | |||
365 | mpart = mtd->priv; | ||
366 | mdev = mpart->mdev; | ||
367 | partition = mpart->partition; | ||
368 | card = maple_get_drvdata(mdev); | ||
369 | |||
370 | numblocks = card->parts[partition].numblocks; | ||
371 | if (from + len > numblocks * card->blocklen) | ||
372 | len = numblocks * card->blocklen - from; | ||
373 | if (len == 0) | ||
374 | return -EIO; | ||
375 | /* Have we cached this bit already? */ | ||
376 | pcache = card->parts[partition].pcache; | ||
377 | do { | ||
378 | vblock = ofs_to_block(from + index, mtd, partition); | ||
379 | if (!vblock) | ||
380 | return -ENOMEM; | ||
381 | /* Have we cached this and is the cache valid and timely? */ | ||
382 | if (pcache->valid && | ||
383 | time_before(jiffies, pcache->jiffies_atc + HZ) && | ||
384 | (pcache->block == vblock->num)) { | ||
385 | /* we have cached it, so do necessary copying */ | ||
386 | leftover = card->blocklen - vblock->ofs; | ||
387 | if (vblock->ofs + len - index < card->blocklen) { | ||
388 | /* only a bit of this block to copy */ | ||
389 | memcpy(buf + index, | ||
390 | pcache->buffer + vblock->ofs, | ||
391 | len - index); | ||
392 | index = len; | ||
393 | } else { | ||
394 | /* otherwise copy remainder of whole block */ | ||
395 | memcpy(buf + index, pcache->buffer + | ||
396 | vblock->ofs, leftover); | ||
397 | index += leftover; | ||
398 | } | ||
399 | } else { | ||
400 | /* | ||
401 | * Not cached so read one byte - | ||
402 | * but cache the rest of the block | ||
403 | */ | ||
404 | cx = vmu_flash_read_char(from + index, &retval, mtd); | ||
405 | if (retval) { | ||
406 | *retlen = index; | ||
407 | kfree(vblock); | ||
408 | return cx; | ||
409 | } | ||
410 | memset(buf + index, cx, 1); | ||
411 | index++; | ||
412 | } | ||
413 | kfree(vblock); | ||
414 | } while (len > index); | ||
415 | *retlen = index; | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len, | ||
421 | size_t *retlen, const u_char *buf) | ||
422 | { | ||
423 | struct maple_device *mdev; | ||
424 | struct memcard *card; | ||
425 | struct mdev_part *mpart; | ||
426 | int index = 0, partition, error = 0, numblocks; | ||
427 | struct vmu_cache *pcache; | ||
428 | struct vmu_block *vblock; | ||
429 | unsigned char *buffer; | ||
430 | |||
431 | mpart = mtd->priv; | ||
432 | mdev = mpart->mdev; | ||
433 | partition = mpart->partition; | ||
434 | card = maple_get_drvdata(mdev); | ||
435 | |||
436 | /* simple sanity checks */ | ||
437 | if (len < 1) { | ||
438 | error = -EIO; | ||
439 | goto failed; | ||
440 | } | ||
441 | numblocks = card->parts[partition].numblocks; | ||
442 | if (to + len > numblocks * card->blocklen) | ||
443 | len = numblocks * card->blocklen - to; | ||
444 | if (len == 0) { | ||
445 | error = -EIO; | ||
446 | goto failed; | ||
447 | } | ||
448 | |||
449 | vblock = ofs_to_block(to, mtd, partition); | ||
450 | if (!vblock) { | ||
451 | error = -ENOMEM; | ||
452 | goto failed; | ||
453 | } | ||
454 | |||
455 | buffer = kmalloc(card->blocklen, GFP_KERNEL); | ||
456 | if (!buffer) { | ||
457 | error = -ENOMEM; | ||
458 | goto fail_buffer; | ||
459 | } | ||
460 | |||
461 | do { | ||
462 | /* Read in the block we are to write to */ | ||
463 | error = maple_vmu_read_block(vblock->num, buffer, mtd); | ||
464 | if (error) | ||
465 | goto fail_io; | ||
466 | |||
467 | do { | ||
468 | buffer[vblock->ofs] = buf[index]; | ||
469 | vblock->ofs++; | ||
470 | index++; | ||
471 | if (index >= len) | ||
472 | break; | ||
473 | } while (vblock->ofs < card->blocklen); | ||
474 | |||
475 | /* write out new buffer */ | ||
476 | error = maple_vmu_write_block(vblock->num, buffer, mtd); | ||
477 | /* invalidate the cache */ | ||
478 | pcache = card->parts[partition].pcache; | ||
479 | pcache->valid = 0; | ||
480 | |||
481 | if (error != card->blocklen) | ||
482 | goto fail_io; | ||
483 | |||
484 | vblock->num++; | ||
485 | vblock->ofs = 0; | ||
486 | } while (len > index); | ||
487 | |||
488 | kfree(buffer); | ||
489 | *retlen = index; | ||
490 | kfree(vblock); | ||
491 | return 0; | ||
492 | |||
493 | fail_io: | ||
494 | kfree(buffer); | ||
495 | fail_buffer: | ||
496 | kfree(vblock); | ||
497 | failed: | ||
498 | dev_err(&mdev->dev, "VMU write failing with error %d\n", error); | ||
499 | return error; | ||
500 | } | ||
501 | |||
502 | static void vmu_flash_sync(struct mtd_info *mtd) | ||
503 | { | ||
504 | /* Do nothing here */ | ||
505 | } | ||
506 | |||
507 | /* Maple bus callback function to recursively query hardware details */ | ||
508 | static void vmu_queryblocks(struct mapleq *mq) | ||
509 | { | ||
510 | struct maple_device *mdev; | ||
511 | unsigned short *res; | ||
512 | struct memcard *card; | ||
513 | __be32 partnum; | ||
514 | struct vmu_cache *pcache; | ||
515 | struct mdev_part *mpart; | ||
516 | struct mtd_info *mtd_cur; | ||
517 | struct vmupart *part_cur; | ||
518 | int error; | ||
519 | |||
520 | mdev = mq->dev; | ||
521 | card = maple_get_drvdata(mdev); | ||
522 | res = (unsigned short *) (mq->recvbuf->buf); | ||
523 | card->tempA = res[12]; | ||
524 | card->tempB = res[6]; | ||
525 | |||
526 | dev_info(&mdev->dev, "VMU device at partition %d has %d user " | ||
527 | "blocks with a root block at %d\n", card->partition, | ||
528 | card->tempA, card->tempB); | ||
529 | |||
530 | part_cur = &card->parts[card->partition]; | ||
531 | part_cur->user_blocks = card->tempA; | ||
532 | part_cur->root_block = card->tempB; | ||
533 | part_cur->numblocks = card->tempB + 1; | ||
534 | part_cur->name = kmalloc(12, GFP_KERNEL); | ||
535 | if (!part_cur->name) | ||
536 | goto fail_name; | ||
537 | |||
538 | sprintf(part_cur->name, "vmu%d.%d.%d", | ||
539 | mdev->port, mdev->unit, card->partition); | ||
540 | mtd_cur = &card->mtd[card->partition]; | ||
541 | mtd_cur->name = part_cur->name; | ||
542 | mtd_cur->type = 8; | ||
543 | mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE; | ||
544 | mtd_cur->size = part_cur->numblocks * card->blocklen; | ||
545 | mtd_cur->erasesize = card->blocklen; | ||
546 | mtd_cur->write = vmu_flash_write; | ||
547 | mtd_cur->read = vmu_flash_read; | ||
548 | mtd_cur->sync = vmu_flash_sync; | ||
549 | mtd_cur->writesize = card->blocklen; | ||
550 | |||
551 | mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL); | ||
552 | if (!mpart) | ||
553 | goto fail_mpart; | ||
554 | |||
555 | mpart->mdev = mdev; | ||
556 | mpart->partition = card->partition; | ||
557 | mtd_cur->priv = mpart; | ||
558 | mtd_cur->owner = THIS_MODULE; | ||
559 | |||
560 | pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL); | ||
561 | if (!pcache) | ||
562 | goto fail_cache_create; | ||
563 | part_cur->pcache = pcache; | ||
564 | |||
565 | error = add_mtd_device(mtd_cur); | ||
566 | if (error) | ||
567 | goto fail_mtd_register; | ||
568 | |||
569 | maple_getcond_callback(mdev, NULL, 0, | ||
570 | MAPLE_FUNC_MEMCARD); | ||
571 | |||
572 | /* | ||
573 | * Set up a recursive call to the (probably theoretical) | ||
574 | * second or more partition | ||
575 | */ | ||
576 | if (++card->partition < card->partitions) { | ||
577 | partnum = cpu_to_be32(card->partition << 24); | ||
578 | maple_getcond_callback(mdev, vmu_queryblocks, 0, | ||
579 | MAPLE_FUNC_MEMCARD); | ||
580 | maple_add_packet(mdev, MAPLE_FUNC_MEMCARD, | ||
581 | MAPLE_COMMAND_GETMINFO, 2, &partnum); | ||
582 | } | ||
583 | return; | ||
584 | |||
585 | fail_mtd_register: | ||
586 | dev_err(&mdev->dev, "Could not register maple device at (%d, %d)" | ||
587 | "error is 0x%X\n", mdev->port, mdev->unit, error); | ||
588 | for (error = 0; error <= card->partition; error++) { | ||
589 | kfree(((card->parts)[error]).pcache); | ||
590 | ((card->parts)[error]).pcache = NULL; | ||
591 | } | ||
592 | fail_cache_create: | ||
593 | fail_mpart: | ||
594 | for (error = 0; error <= card->partition; error++) { | ||
595 | kfree(((card->mtd)[error]).priv); | ||
596 | ((card->mtd)[error]).priv = NULL; | ||
597 | } | ||
598 | maple_getcond_callback(mdev, NULL, 0, | ||
599 | MAPLE_FUNC_MEMCARD); | ||
600 | kfree(part_cur->name); | ||
601 | fail_name: | ||
602 | return; | ||
603 | } | ||
604 | |||
605 | /* Handles very basic info about the flash, queries for details */ | ||
606 | static int __devinit vmu_connect(struct maple_device *mdev) | ||
607 | { | ||
608 | unsigned long test_flash_data, basic_flash_data; | ||
609 | int c, error; | ||
610 | struct memcard *card; | ||
611 | u32 partnum = 0; | ||
612 | |||
613 | test_flash_data = be32_to_cpu(mdev->devinfo.function); | ||
614 | /* Need to count how many bits are set - to find out which | ||
615 | * function_data element has details of the memory card: | ||
616 | * using Brian Kernighan's/Peter Wegner's method */ | ||
617 | for (c = 0; test_flash_data; c++) | ||
618 | test_flash_data &= test_flash_data - 1; | ||
619 | |||
620 | basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]); | ||
621 | |||
622 | card = kmalloc(sizeof(struct memcard), GFP_KERNEL); | ||
623 | if (!card) { | ||
624 | error = ENOMEM; | ||
625 | goto fail_nomem; | ||
626 | } | ||
627 | |||
628 | card->partitions = (basic_flash_data >> 24 & 0xFF) + 1; | ||
629 | card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5; | ||
630 | card->writecnt = basic_flash_data >> 12 & 0xF; | ||
631 | card->readcnt = basic_flash_data >> 8 & 0xF; | ||
632 | card->removeable = basic_flash_data >> 7 & 1; | ||
633 | |||
634 | card->partition = 0; | ||
635 | |||
636 | /* | ||
637 | * Not sure there are actually any multi-partition devices in the | ||
638 | * real world, but the hardware supports them, so, so will we | ||
639 | */ | ||
640 | card->parts = kmalloc(sizeof(struct vmupart) * card->partitions, | ||
641 | GFP_KERNEL); | ||
642 | if (!card->parts) { | ||
643 | error = -ENOMEM; | ||
644 | goto fail_partitions; | ||
645 | } | ||
646 | |||
647 | card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions, | ||
648 | GFP_KERNEL); | ||
649 | if (!card->mtd) { | ||
650 | error = -ENOMEM; | ||
651 | goto fail_mtd_info; | ||
652 | } | ||
653 | |||
654 | maple_set_drvdata(mdev, card); | ||
655 | |||
656 | /* | ||
657 | * We want to trap meminfo not get cond | ||
658 | * so set interval to zero, but rely on maple bus | ||
659 | * driver to pass back the results of the meminfo | ||
660 | */ | ||
661 | maple_getcond_callback(mdev, vmu_queryblocks, 0, | ||
662 | MAPLE_FUNC_MEMCARD); | ||
663 | |||
664 | /* Make sure we are clear to go */ | ||
665 | if (atomic_read(&mdev->busy) == 1) { | ||
666 | wait_event_interruptible_timeout(mdev->maple_wait, | ||
667 | atomic_read(&mdev->busy) == 0, HZ); | ||
668 | if (atomic_read(&mdev->busy) == 1) { | ||
669 | dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n", | ||
670 | mdev->port, mdev->unit); | ||
671 | error = -EAGAIN; | ||
672 | goto fail_device_busy; | ||
673 | } | ||
674 | } | ||
675 | |||
676 | atomic_set(&mdev->busy, 1); | ||
677 | |||
678 | /* | ||
679 | * Set up the minfo call: vmu_queryblocks will handle | ||
680 | * the information passed back | ||
681 | */ | ||
682 | error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD, | ||
683 | MAPLE_COMMAND_GETMINFO, 2, &partnum); | ||
684 | if (error) { | ||
685 | dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)" | ||
686 | " error is 0x%X\n", mdev->port, mdev->unit, error); | ||
687 | goto fail_mtd_info; | ||
688 | } | ||
689 | return 0; | ||
690 | |||
691 | fail_device_busy: | ||
692 | kfree(card->mtd); | ||
693 | fail_mtd_info: | ||
694 | kfree(card->parts); | ||
695 | fail_partitions: | ||
696 | kfree(card); | ||
697 | fail_nomem: | ||
698 | return error; | ||
699 | } | ||
700 | |||
701 | static void __devexit vmu_disconnect(struct maple_device *mdev) | ||
702 | { | ||
703 | struct memcard *card; | ||
704 | struct mdev_part *mpart; | ||
705 | int x; | ||
706 | |||
707 | mdev->callback = NULL; | ||
708 | card = maple_get_drvdata(mdev); | ||
709 | for (x = 0; x < card->partitions; x++) { | ||
710 | mpart = ((card->mtd)[x]).priv; | ||
711 | mpart->mdev = NULL; | ||
712 | del_mtd_device(&((card->mtd)[x])); | ||
713 | kfree(((card->parts)[x]).name); | ||
714 | } | ||
715 | kfree(card->parts); | ||
716 | kfree(card->mtd); | ||
717 | kfree(card); | ||
718 | } | ||
719 | |||
720 | /* Callback to handle eccentricities of both mtd subsystem | ||
721 | * and general flakyness of Dreamcast VMUs | ||
722 | */ | ||
723 | static int vmu_can_unload(struct maple_device *mdev) | ||
724 | { | ||
725 | struct memcard *card; | ||
726 | int x; | ||
727 | struct mtd_info *mtd; | ||
728 | |||
729 | card = maple_get_drvdata(mdev); | ||
730 | for (x = 0; x < card->partitions; x++) { | ||
731 | mtd = &((card->mtd)[x]); | ||
732 | if (mtd->usecount > 0) | ||
733 | return 0; | ||
734 | } | ||
735 | return 1; | ||
736 | } | ||
737 | |||
738 | #define ERRSTR "VMU at (%d, %d) file error -" | ||
739 | |||
740 | static void vmu_file_error(struct maple_device *mdev, void *recvbuf) | ||
741 | { | ||
742 | enum maple_file_errors error = ((int *)recvbuf)[1]; | ||
743 | |||
744 | switch (error) { | ||
745 | |||
746 | case MAPLE_FILEERR_INVALID_PARTITION: | ||
747 | dev_notice(&mdev->dev, ERRSTR " invalid partition number\n", | ||
748 | mdev->port, mdev->unit); | ||
749 | break; | ||
750 | |||
751 | case MAPLE_FILEERR_PHASE_ERROR: | ||
752 | dev_notice(&mdev->dev, ERRSTR " phase error\n", | ||
753 | mdev->port, mdev->unit); | ||
754 | break; | ||
755 | |||
756 | case MAPLE_FILEERR_INVALID_BLOCK: | ||
757 | dev_notice(&mdev->dev, ERRSTR " invalid block number\n", | ||
758 | mdev->port, mdev->unit); | ||
759 | break; | ||
760 | |||
761 | case MAPLE_FILEERR_WRITE_ERROR: | ||
762 | dev_notice(&mdev->dev, ERRSTR " write error\n", | ||
763 | mdev->port, mdev->unit); | ||
764 | break; | ||
765 | |||
766 | case MAPLE_FILEERR_INVALID_WRITE_LENGTH: | ||
767 | dev_notice(&mdev->dev, ERRSTR " invalid write length\n", | ||
768 | mdev->port, mdev->unit); | ||
769 | break; | ||
770 | |||
771 | case MAPLE_FILEERR_BAD_CRC: | ||
772 | dev_notice(&mdev->dev, ERRSTR " bad CRC\n", | ||
773 | mdev->port, mdev->unit); | ||
774 | break; | ||
775 | |||
776 | default: | ||
777 | dev_notice(&mdev->dev, ERRSTR " 0x%X\n", | ||
778 | mdev->port, mdev->unit, error); | ||
779 | } | ||
780 | } | ||
781 | |||
782 | |||
783 | static int __devinit probe_maple_vmu(struct device *dev) | ||
784 | { | ||
785 | int error; | ||
786 | struct maple_device *mdev = to_maple_dev(dev); | ||
787 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | ||
788 | |||
789 | mdev->can_unload = vmu_can_unload; | ||
790 | mdev->fileerr_handler = vmu_file_error; | ||
791 | mdev->driver = mdrv; | ||
792 | |||
793 | error = vmu_connect(mdev); | ||
794 | if (error) | ||
795 | return error; | ||
796 | |||
797 | return 0; | ||
798 | } | ||
799 | |||
800 | static int __devexit remove_maple_vmu(struct device *dev) | ||
801 | { | ||
802 | struct maple_device *mdev = to_maple_dev(dev); | ||
803 | |||
804 | vmu_disconnect(mdev); | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | static struct maple_driver vmu_flash_driver = { | ||
809 | .function = MAPLE_FUNC_MEMCARD, | ||
810 | .drv = { | ||
811 | .name = "Dreamcast_visual_memory", | ||
812 | .probe = probe_maple_vmu, | ||
813 | .remove = __devexit_p(remove_maple_vmu), | ||
814 | }, | ||
815 | }; | ||
816 | |||
817 | static int __init vmu_flash_map_init(void) | ||
818 | { | ||
819 | return maple_driver_register(&vmu_flash_driver); | ||
820 | } | ||
821 | |||
822 | static void __exit vmu_flash_map_exit(void) | ||
823 | { | ||
824 | maple_driver_unregister(&vmu_flash_driver); | ||
825 | } | ||
826 | |||
827 | module_init(vmu_flash_map_init); | ||
828 | module_exit(vmu_flash_map_exit); | ||
829 | |||
830 | MODULE_LICENSE("GPL"); | ||
831 | MODULE_AUTHOR("Adrian McMenamin"); | ||
832 | MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory"); | ||
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c index ced14b5294d5..72446fb48d4b 100644 --- a/drivers/mtd/nand/excite_nandflash.c +++ b/drivers/mtd/nand/excite_nandflash.c | |||
@@ -128,11 +128,11 @@ static int excite_nand_devready(struct mtd_info *mtd) | |||
128 | * The binding to the mtd and all allocated | 128 | * The binding to the mtd and all allocated |
129 | * resources are released. | 129 | * resources are released. |
130 | */ | 130 | */ |
131 | static int __exit excite_nand_remove(struct device *dev) | 131 | static int __exit excite_nand_remove(struct platform_device *dev) |
132 | { | 132 | { |
133 | struct excite_nand_drvdata * const this = dev_get_drvdata(dev); | 133 | struct excite_nand_drvdata * const this = platform_get_drvdata(dev); |
134 | 134 | ||
135 | dev_set_drvdata(dev, NULL); | 135 | platform_set_drvdata(dev, NULL); |
136 | 136 | ||
137 | if (unlikely(!this)) { | 137 | if (unlikely(!this)) { |
138 | printk(KERN_ERR "%s: called %s without private data!!", | 138 | printk(KERN_ERR "%s: called %s without private data!!", |
@@ -159,9 +159,8 @@ static int __exit excite_nand_remove(struct device *dev) | |||
159 | * it can allocate all necessary resources then calls the | 159 | * it can allocate all necessary resources then calls the |
160 | * nand layer to look for devices. | 160 | * nand layer to look for devices. |
161 | */ | 161 | */ |
162 | static int __init excite_nand_probe(struct device *dev) | 162 | static int __init excite_nand_probe(struct platform_device *pdev) |
163 | { | 163 | { |
164 | struct platform_device * const pdev = to_platform_device(dev); | ||
165 | struct excite_nand_drvdata *drvdata; /* private driver data */ | 164 | struct excite_nand_drvdata *drvdata; /* private driver data */ |
166 | struct nand_chip *board_chip; /* private flash chip data */ | 165 | struct nand_chip *board_chip; /* private flash chip data */ |
167 | struct mtd_info *board_mtd; /* mtd info for this board */ | 166 | struct mtd_info *board_mtd; /* mtd info for this board */ |
@@ -175,7 +174,7 @@ static int __init excite_nand_probe(struct device *dev) | |||
175 | } | 174 | } |
176 | 175 | ||
177 | /* bind private data into driver */ | 176 | /* bind private data into driver */ |
178 | dev_set_drvdata(dev, drvdata); | 177 | platform_set_drvdata(pdev, drvdata); |
179 | 178 | ||
180 | /* allocate and map the resource */ | 179 | /* allocate and map the resource */ |
181 | drvdata->regs = | 180 | drvdata->regs = |
@@ -219,23 +218,25 @@ static int __init excite_nand_probe(struct device *dev) | |||
219 | return 0; | 218 | return 0; |
220 | } | 219 | } |
221 | 220 | ||
222 | static struct device_driver excite_nand_driver = { | 221 | static struct platform_driver excite_nand_driver = { |
223 | .name = "excite_nand", | 222 | .driver = { |
224 | .bus = &platform_bus_type, | 223 | .name = "excite_nand", |
224 | .owner = THIS_MODULE, | ||
225 | }, | ||
225 | .probe = excite_nand_probe, | 226 | .probe = excite_nand_probe, |
226 | .remove = __exit_p(excite_nand_remove) | 227 | .remove = __devexit_p(excite_nand_remove) |
227 | }; | 228 | }; |
228 | 229 | ||
229 | static int __init excite_nand_init(void) | 230 | static int __init excite_nand_init(void) |
230 | { | 231 | { |
231 | pr_info("Basler eXcite nand flash driver Version " | 232 | pr_info("Basler eXcite nand flash driver Version " |
232 | EXCITE_NANDFLASH_VERSION "\n"); | 233 | EXCITE_NANDFLASH_VERSION "\n"); |
233 | return driver_register(&excite_nand_driver); | 234 | return platform_driver_register(&excite_nand_driver); |
234 | } | 235 | } |
235 | 236 | ||
236 | static void __exit excite_nand_exit(void) | 237 | static void __exit excite_nand_exit(void) |
237 | { | 238 | { |
238 | driver_unregister(&excite_nand_driver); | 239 | platform_driver_unregister(&excite_nand_driver); |
239 | } | 240 | } |
240 | 241 | ||
241 | module_init(excite_nand_init); | 242 | module_init(excite_nand_init); |
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 582cf80f555a..89bf85af642c 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c | |||
@@ -187,7 +187,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, | |||
187 | return -ENODEV; | 187 | return -ENODEV; |
188 | 188 | ||
189 | ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", | 189 | ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", |
190 | ndfc->ofdev->dev.bus_id, flash_np->name); | 190 | dev_name(&ndfc->ofdev->dev), flash_np->name); |
191 | if (!ndfc->mtd.name) { | 191 | if (!ndfc->mtd.name) { |
192 | ret = -ENOMEM; | 192 | ret = -ENOMEM; |
193 | goto err; | 193 | goto err; |
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 5b69e7773c6c..3a496c33fb52 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c | |||
@@ -36,10 +36,9 @@ struct onenand_info { | |||
36 | struct onenand_chip onenand; | 36 | struct onenand_chip onenand; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static int __devinit generic_onenand_probe(struct device *dev) | 39 | static int __devinit generic_onenand_probe(struct platform_device *pdev) |
40 | { | 40 | { |
41 | struct onenand_info *info; | 41 | struct onenand_info *info; |
42 | struct platform_device *pdev = to_platform_device(dev); | ||
43 | struct flash_platform_data *pdata = pdev->dev.platform_data; | 42 | struct flash_platform_data *pdata = pdev->dev.platform_data; |
44 | struct resource *res = pdev->resource; | 43 | struct resource *res = pdev->resource; |
45 | unsigned long size = res->end - res->start + 1; | 44 | unsigned long size = res->end - res->start + 1; |
@@ -49,7 +48,7 @@ static int __devinit generic_onenand_probe(struct device *dev) | |||
49 | if (!info) | 48 | if (!info) |
50 | return -ENOMEM; | 49 | return -ENOMEM; |
51 | 50 | ||
52 | if (!request_mem_region(res->start, size, dev->driver->name)) { | 51 | if (!request_mem_region(res->start, size, pdev->dev.driver->name)) { |
53 | err = -EBUSY; | 52 | err = -EBUSY; |
54 | goto out_free_info; | 53 | goto out_free_info; |
55 | } | 54 | } |
@@ -82,7 +81,7 @@ static int __devinit generic_onenand_probe(struct device *dev) | |||
82 | #endif | 81 | #endif |
83 | err = add_mtd_device(&info->mtd); | 82 | err = add_mtd_device(&info->mtd); |
84 | 83 | ||
85 | dev_set_drvdata(&pdev->dev, info); | 84 | platform_set_drvdata(pdev, info); |
86 | 85 | ||
87 | return 0; | 86 | return 0; |
88 | 87 | ||
@@ -96,14 +95,13 @@ out_free_info: | |||
96 | return err; | 95 | return err; |
97 | } | 96 | } |
98 | 97 | ||
99 | static int __devexit generic_onenand_remove(struct device *dev) | 98 | static int __devexit generic_onenand_remove(struct platform_device *pdev) |
100 | { | 99 | { |
101 | struct platform_device *pdev = to_platform_device(dev); | 100 | struct onenand_info *info = platform_get_drvdata(pdev); |
102 | struct onenand_info *info = dev_get_drvdata(&pdev->dev); | ||
103 | struct resource *res = pdev->resource; | 101 | struct resource *res = pdev->resource; |
104 | unsigned long size = res->end - res->start + 1; | 102 | unsigned long size = res->end - res->start + 1; |
105 | 103 | ||
106 | dev_set_drvdata(&pdev->dev, NULL); | 104 | platform_set_drvdata(pdev, NULL); |
107 | 105 | ||
108 | if (info) { | 106 | if (info) { |
109 | if (info->parts) | 107 | if (info->parts) |
@@ -120,9 +118,11 @@ static int __devexit generic_onenand_remove(struct device *dev) | |||
120 | return 0; | 118 | return 0; |
121 | } | 119 | } |
122 | 120 | ||
123 | static struct device_driver generic_onenand_driver = { | 121 | static struct platform_driver generic_onenand_driver = { |
124 | .name = DRIVER_NAME, | 122 | .driver = { |
125 | .bus = &platform_bus_type, | 123 | .name = DRIVER_NAME, |
124 | .owner = THIS_MODULE, | ||
125 | }, | ||
126 | .probe = generic_onenand_probe, | 126 | .probe = generic_onenand_probe, |
127 | .remove = __devexit_p(generic_onenand_remove), | 127 | .remove = __devexit_p(generic_onenand_remove), |
128 | }; | 128 | }; |
@@ -131,12 +131,12 @@ MODULE_ALIAS(DRIVER_NAME); | |||
131 | 131 | ||
132 | static int __init generic_onenand_init(void) | 132 | static int __init generic_onenand_init(void) |
133 | { | 133 | { |
134 | return driver_register(&generic_onenand_driver); | 134 | return platform_driver_register(&generic_onenand_driver); |
135 | } | 135 | } |
136 | 136 | ||
137 | static void __exit generic_onenand_exit(void) | 137 | static void __exit generic_onenand_exit(void) |
138 | { | 138 | { |
139 | driver_unregister(&generic_onenand_driver); | 139 | platform_driver_unregister(&generic_onenand_driver); |
140 | } | 140 | } |
141 | 141 | ||
142 | module_init(generic_onenand_init); | 142 | module_init(generic_onenand_init); |
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index f3a127434897..35cd264abae7 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c | |||
@@ -1059,7 +1059,7 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) | |||
1059 | { | 1059 | { |
1060 | strlcpy(info->driver, MODULENAME, sizeof(info->driver)); | 1060 | strlcpy(info->driver, MODULENAME, sizeof(info->driver)); |
1061 | strlcpy(info->version, MODULEVERSION, sizeof(info->version)); | 1061 | strlcpy(info->version, MODULEVERSION, sizeof(info->version)); |
1062 | strlcpy(info->bus_info, ndev->dev.parent->bus_id, | 1062 | strlcpy(info->bus_info, dev_name(ndev->dev.parent), |
1063 | sizeof(info->bus_info)); | 1063 | sizeof(info->bus_info)); |
1064 | } | 1064 | } |
1065 | 1065 | ||
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 9c875bb3f76c..79aec32c6add 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -355,8 +355,8 @@ static int mii_probe (struct net_device *dev) | |||
355 | /* now we are supposed to have a proper phydev, to attach to... */ | 355 | /* now we are supposed to have a proper phydev, to attach to... */ |
356 | BUG_ON(phydev->attached_dev); | 356 | BUG_ON(phydev->attached_dev); |
357 | 357 | ||
358 | phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0, | 358 | phydev = phy_connect(dev, dev_name(&phydev->dev), &au1000_adjust_link, |
359 | PHY_INTERFACE_MODE_MII); | 359 | 0, PHY_INTERFACE_MODE_MII); |
360 | 360 | ||
361 | if (IS_ERR(phydev)) { | 361 | if (IS_ERR(phydev)) { |
362 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | 362 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); |
@@ -381,8 +381,8 @@ static int mii_probe (struct net_device *dev) | |||
381 | aup->phy_dev = phydev; | 381 | aup->phy_dev = phydev; |
382 | 382 | ||
383 | printk(KERN_INFO "%s: attached PHY driver [%s] " | 383 | printk(KERN_INFO "%s: attached PHY driver [%s] " |
384 | "(mii_bus:phy_addr=%s, irq=%d)\n", | 384 | "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, |
385 | dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq); | 385 | phydev->drv->name, dev_name(&phydev->dev), phydev->irq); |
386 | 386 | ||
387 | return 0; | 387 | return 0; |
388 | } | 388 | } |
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 78e31aa861e0..9afe8092dfc4 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
@@ -415,11 +415,11 @@ static int mii_probe(struct net_device *dev) | |||
415 | } | 415 | } |
416 | 416 | ||
417 | #if defined(CONFIG_BFIN_MAC_RMII) | 417 | #if defined(CONFIG_BFIN_MAC_RMII) |
418 | phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0, | 418 | phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link, |
419 | PHY_INTERFACE_MODE_RMII); | 419 | 0, PHY_INTERFACE_MODE_RMII); |
420 | #else | 420 | #else |
421 | phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0, | 421 | phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link, |
422 | PHY_INTERFACE_MODE_MII); | 422 | 0, PHY_INTERFACE_MODE_MII); |
423 | #endif | 423 | #endif |
424 | 424 | ||
425 | if (IS_ERR(phydev)) { | 425 | if (IS_ERR(phydev)) { |
@@ -447,7 +447,7 @@ static int mii_probe(struct net_device *dev) | |||
447 | printk(KERN_INFO "%s: attached PHY driver [%s] " | 447 | printk(KERN_INFO "%s: attached PHY driver [%s] " |
448 | "(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)" | 448 | "(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)" |
449 | "@sclk=%dMHz)\n", | 449 | "@sclk=%dMHz)\n", |
450 | DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq, | 450 | DRV_NAME, phydev->drv->name, dev_name(&phydev->dev), phydev->irq, |
451 | MDC_CLK, mdc_div, sclk/1000000); | 451 | MDC_CLK, mdc_div, sclk/1000000); |
452 | 452 | ||
453 | return 0; | 453 | return 0; |
@@ -488,7 +488,7 @@ static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev, | |||
488 | strcpy(info->driver, DRV_NAME); | 488 | strcpy(info->driver, DRV_NAME); |
489 | strcpy(info->version, DRV_VERSION); | 489 | strcpy(info->version, DRV_VERSION); |
490 | strcpy(info->fw_version, "N/A"); | 490 | strcpy(info->fw_version, "N/A"); |
491 | strcpy(info->bus_info, dev->dev.bus_id); | 491 | strcpy(info->bus_info, dev_name(&dev->dev)); |
492 | } | 492 | } |
493 | 493 | ||
494 | static struct ethtool_ops bfin_mac_ethtool_ops = { | 494 | static struct ethtool_ops bfin_mac_ethtool_ops = { |
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 8a546a33d581..1ab58375d061 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c | |||
@@ -1240,7 +1240,7 @@ static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *inf | |||
1240 | { | 1240 | { |
1241 | struct bmac_data *bp = netdev_priv(dev); | 1241 | struct bmac_data *bp = netdev_priv(dev); |
1242 | strcpy(info->driver, "bmac"); | 1242 | strcpy(info->driver, "bmac"); |
1243 | strcpy(info->bus_info, bp->mdev->ofdev.dev.bus_id); | 1243 | strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev)); |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | static const struct ethtool_ops bmac_ethtool_ops = { | 1246 | static const struct ethtool_ops bmac_ethtool_ops = { |
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index f66548751c38..79741c5f9fe7 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c | |||
@@ -1161,7 +1161,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev) | |||
1161 | priv->msg_enable = netif_msg_init(debug_level, 0xff); | 1161 | priv->msg_enable = netif_msg_init(debug_level, 0xff); |
1162 | memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); | 1162 | memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); |
1163 | 1163 | ||
1164 | priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id, | 1164 | priv->phy = phy_connect(dev, dev_name(&cpmac_mii->phy_map[phy_id]->dev), |
1165 | &cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); | 1165 | &cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); |
1166 | if (IS_ERR(priv->phy)) { | 1166 | if (IS_ERR(priv->phy)) { |
1167 | if (netif_msg_drv(priv)) | 1167 | if (netif_msg_drv(priv)) |
diff --git a/drivers/net/declance.c b/drivers/net/declance.c index 7ce3053530f9..861c867fca87 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c | |||
@@ -1027,7 +1027,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type) | |||
1027 | printk(version); | 1027 | printk(version); |
1028 | 1028 | ||
1029 | if (bdev) | 1029 | if (bdev) |
1030 | snprintf(name, sizeof(name), "%s", bdev->bus_id); | 1030 | snprintf(name, sizeof(name), "%s", dev_name(bdev)); |
1031 | else { | 1031 | else { |
1032 | i = 0; | 1032 | i = 0; |
1033 | dev = root_lance_dev; | 1033 | dev = root_lance_dev; |
@@ -1105,10 +1105,10 @@ static int __init dec_lance_probe(struct device *bdev, const int type) | |||
1105 | 1105 | ||
1106 | start = to_tc_dev(bdev)->resource.start; | 1106 | start = to_tc_dev(bdev)->resource.start; |
1107 | len = to_tc_dev(bdev)->resource.end - start + 1; | 1107 | len = to_tc_dev(bdev)->resource.end - start + 1; |
1108 | if (!request_mem_region(start, len, bdev->bus_id)) { | 1108 | if (!request_mem_region(start, len, dev_name(bdev))) { |
1109 | printk(KERN_ERR | 1109 | printk(KERN_ERR |
1110 | "%s: Unable to reserve MMIO resource\n", | 1110 | "%s: Unable to reserve MMIO resource\n", |
1111 | bdev->bus_id); | 1111 | dev_name(bdev)); |
1112 | ret = -EBUSY; | 1112 | ret = -EBUSY; |
1113 | goto err_out_dev; | 1113 | goto err_out_dev; |
1114 | } | 1114 | } |
diff --git a/drivers/net/depca.c b/drivers/net/depca.c index e4cef491dc73..55625dbbae5a 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c | |||
@@ -606,8 +606,8 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) | |||
606 | if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown) | 606 | if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown) |
607 | return -ENXIO; | 607 | return -ENXIO; |
608 | 608 | ||
609 | printk ("%s: %s at 0x%04lx", | 609 | printk("%s: %s at 0x%04lx", |
610 | device->bus_id, depca_signature[lp->adapter], ioaddr); | 610 | dev_name(device), depca_signature[lp->adapter], ioaddr); |
611 | 611 | ||
612 | switch (lp->depca_bus) { | 612 | switch (lp->depca_bus) { |
613 | #ifdef CONFIG_MCA | 613 | #ifdef CONFIG_MCA |
@@ -669,7 +669,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) | |||
669 | 669 | ||
670 | spin_lock_init(&lp->lock); | 670 | spin_lock_init(&lp->lock); |
671 | sprintf(lp->adapter_name, "%s (%s)", | 671 | sprintf(lp->adapter_name, "%s (%s)", |
672 | depca_signature[lp->adapter], device->bus_id); | 672 | depca_signature[lp->adapter], dev_name(device)); |
673 | status = -EBUSY; | 673 | status = -EBUSY; |
674 | 674 | ||
675 | /* Initialisation Block */ | 675 | /* Initialisation Block */ |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index dfe92264e825..8e7c16535ad7 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -3040,7 +3040,7 @@ static struct device *ehea_register_port(struct ehea_port *port, | |||
3040 | port->ofdev.dev.parent = &port->adapter->ofdev->dev; | 3040 | port->ofdev.dev.parent = &port->adapter->ofdev->dev; |
3041 | port->ofdev.dev.bus = &ibmebus_bus_type; | 3041 | port->ofdev.dev.bus = &ibmebus_bus_type; |
3042 | 3042 | ||
3043 | sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++); | 3043 | dev_set_name(&port->ofdev.dev, "port%d", port_name_cnt++); |
3044 | port->ofdev.dev.release = logical_port_release; | 3044 | port->ofdev.dev.release = logical_port_release; |
3045 | 3045 | ||
3046 | ret = of_device_register(&port->ofdev); | 3046 | ret = of_device_register(&port->ofdev); |
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 334ff9e12cdd..14248cfc3dfd 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c | |||
@@ -131,7 +131,8 @@ static int __init sonic_probe1(struct net_device *dev) | |||
131 | if (sonic_debug && version_printed++ == 0) | 131 | if (sonic_debug && version_printed++ == 0) |
132 | printk(version); | 132 | printk(version); |
133 | 133 | ||
134 | printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", lp->device->bus_id, dev->base_addr); | 134 | printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", |
135 | dev_name(lp->device), dev->base_addr); | ||
135 | 136 | ||
136 | /* | 137 | /* |
137 | * Put the sonic into software reset, then | 138 | * Put the sonic into software reset, then |
@@ -156,7 +157,8 @@ static int __init sonic_probe1(struct net_device *dev) | |||
156 | if ((lp->descriptors = dma_alloc_coherent(lp->device, | 157 | if ((lp->descriptors = dma_alloc_coherent(lp->device, |
157 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | 158 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), |
158 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { | 159 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { |
159 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id); | 160 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", |
161 | dev_name(lp->device)); | ||
160 | goto out; | 162 | goto out; |
161 | } | 163 | } |
162 | 164 | ||
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index f6c4936e2fa8..f4086542c358 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c | |||
@@ -211,10 +211,10 @@ static int macb_mii_probe(struct net_device *dev) | |||
211 | 211 | ||
212 | /* attach the mac to the phy */ | 212 | /* attach the mac to the phy */ |
213 | if (pdata && pdata->is_rmii) { | 213 | if (pdata && pdata->is_rmii) { |
214 | phydev = phy_connect(dev, phydev->dev.bus_id, | 214 | phydev = phy_connect(dev, dev_name(&phydev->dev), |
215 | &macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII); | 215 | &macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII); |
216 | } else { | 216 | } else { |
217 | phydev = phy_connect(dev, phydev->dev.bus_id, | 217 | phydev = phy_connect(dev, dev_name(&phydev->dev), |
218 | &macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII); | 218 | &macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII); |
219 | } | 219 | } |
220 | 220 | ||
@@ -1077,7 +1077,7 @@ static void macb_get_drvinfo(struct net_device *dev, | |||
1077 | 1077 | ||
1078 | strcpy(info->driver, bp->pdev->dev.driver->name); | 1078 | strcpy(info->driver, bp->pdev->dev.driver->name); |
1079 | strcpy(info->version, "$Revision: 1.14 $"); | 1079 | strcpy(info->version, "$Revision: 1.14 $"); |
1080 | strcpy(info->bus_info, bp->pdev->dev.bus_id); | 1080 | strcpy(info->bus_info, dev_name(&bp->pdev->dev)); |
1081 | } | 1081 | } |
1082 | 1082 | ||
1083 | static struct ethtool_ops macb_ethtool_ops = { | 1083 | static struct ethtool_ops macb_ethtool_ops = { |
@@ -1234,8 +1234,8 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1234 | 1234 | ||
1235 | phydev = bp->phy_dev; | 1235 | phydev = bp->phy_dev; |
1236 | printk(KERN_INFO "%s: attached PHY driver [%s] " | 1236 | printk(KERN_INFO "%s: attached PHY driver [%s] " |
1237 | "(mii_bus:phy_addr=%s, irq=%d)\n", | 1237 | "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, |
1238 | dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq); | 1238 | phydev->drv->name, dev_name(&phydev->dev), phydev->irq); |
1239 | 1239 | ||
1240 | return 0; | 1240 | return 0; |
1241 | 1241 | ||
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 205bb05c25d6..527166e35d56 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c | |||
@@ -176,7 +176,8 @@ static int __init macsonic_init(struct net_device *dev) | |||
176 | if ((lp->descriptors = dma_alloc_coherent(lp->device, | 176 | if ((lp->descriptors = dma_alloc_coherent(lp->device, |
177 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | 177 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), |
178 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { | 178 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { |
179 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id); | 179 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", |
180 | dev_name(lp->device)); | ||
180 | return -ENOMEM; | 181 | return -ENOMEM; |
181 | } | 182 | } |
182 | 183 | ||
@@ -337,7 +338,7 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev) | |||
337 | sonic_version_printed = 1; | 338 | sonic_version_printed = 1; |
338 | } | 339 | } |
339 | printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n", | 340 | printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n", |
340 | lp->device->bus_id, dev->base_addr); | 341 | dev_name(lp->device), dev->base_addr); |
341 | 342 | ||
342 | /* The PowerBook's SONIC is 16 bit always. */ | 343 | /* The PowerBook's SONIC is 16 bit always. */ |
343 | if (macintosh_config->ident == MAC_MODEL_PB520) { | 344 | if (macintosh_config->ident == MAC_MODEL_PB520) { |
@@ -370,10 +371,10 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev) | |||
370 | } | 371 | } |
371 | printk(KERN_INFO | 372 | printk(KERN_INFO |
372 | "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | 373 | "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", |
373 | lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset); | 374 | dev_name(lp->device), sr, lp->dma_bitmode?32:16, lp->reg_offset); |
374 | 375 | ||
375 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ | 376 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ |
376 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id, | 377 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device), |
377 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); | 378 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); |
378 | #endif | 379 | #endif |
379 | 380 | ||
@@ -525,12 +526,12 @@ static int __init mac_nubus_sonic_probe(struct net_device *dev) | |||
525 | sonic_version_printed = 1; | 526 | sonic_version_printed = 1; |
526 | } | 527 | } |
527 | printk(KERN_INFO "%s: %s in slot %X\n", | 528 | printk(KERN_INFO "%s: %s in slot %X\n", |
528 | lp->device->bus_id, ndev->board->name, ndev->board->slot); | 529 | dev_name(lp->device), ndev->board->name, ndev->board->slot); |
529 | printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | 530 | printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", |
530 | lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset); | 531 | dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset); |
531 | 532 | ||
532 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ | 533 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ |
533 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id, | 534 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device), |
534 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); | 535 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); |
535 | #endif | 536 | #endif |
536 | 537 | ||
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index 4e7a5faf0351..664835b822fb 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c | |||
@@ -237,7 +237,7 @@ static void mipsnet_set_mclist(struct net_device *dev) | |||
237 | { | 237 | { |
238 | } | 238 | } |
239 | 239 | ||
240 | static int __init mipsnet_probe(struct device *dev) | 240 | static int __init mipsnet_probe(struct platform_device *dev) |
241 | { | 241 | { |
242 | struct net_device *netdev; | 242 | struct net_device *netdev; |
243 | int err; | 243 | int err; |
@@ -248,7 +248,7 @@ static int __init mipsnet_probe(struct device *dev) | |||
248 | goto out; | 248 | goto out; |
249 | } | 249 | } |
250 | 250 | ||
251 | dev_set_drvdata(dev, netdev); | 251 | platform_set_drvdata(dev, netdev); |
252 | 252 | ||
253 | netdev->open = mipsnet_open; | 253 | netdev->open = mipsnet_open; |
254 | netdev->stop = mipsnet_close; | 254 | netdev->stop = mipsnet_close; |
@@ -293,23 +293,25 @@ out: | |||
293 | return err; | 293 | return err; |
294 | } | 294 | } |
295 | 295 | ||
296 | static int __devexit mipsnet_device_remove(struct device *device) | 296 | static int __devexit mipsnet_device_remove(struct platform_device *device) |
297 | { | 297 | { |
298 | struct net_device *dev = dev_get_drvdata(device); | 298 | struct net_device *dev = platform_get_drvdata(device); |
299 | 299 | ||
300 | unregister_netdev(dev); | 300 | unregister_netdev(dev); |
301 | release_region(dev->base_addr, sizeof(struct mipsnet_regs)); | 301 | release_region(dev->base_addr, sizeof(struct mipsnet_regs)); |
302 | free_netdev(dev); | 302 | free_netdev(dev); |
303 | dev_set_drvdata(device, NULL); | 303 | platform_set_drvdata(device, NULL); |
304 | 304 | ||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
308 | static struct device_driver mipsnet_driver = { | 308 | static struct platform_driver mipsnet_driver = { |
309 | .name = mipsnet_string, | 309 | .driver = { |
310 | .bus = &platform_bus_type, | 310 | .name = mipsnet_string, |
311 | .probe = mipsnet_probe, | 311 | .owner = THIS_MODULE, |
312 | .remove = __devexit_p(mipsnet_device_remove), | 312 | }, |
313 | .probe = mipsnet_probe, | ||
314 | .remove = __devexit_p(mipsnet_device_remove), | ||
313 | }; | 315 | }; |
314 | 316 | ||
315 | static int __init mipsnet_init_module(void) | 317 | static int __init mipsnet_init_module(void) |
@@ -319,7 +321,7 @@ static int __init mipsnet_init_module(void) | |||
319 | printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. " | 321 | printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. " |
320 | "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION); | 322 | "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION); |
321 | 323 | ||
322 | err = driver_register(&mipsnet_driver); | 324 | err = platform_driver_register(&mipsnet_driver); |
323 | if (err) | 325 | if (err) |
324 | printk(KERN_ERR "Driver registration failed\n"); | 326 | printk(KERN_ERR "Driver registration failed\n"); |
325 | 327 | ||
@@ -328,7 +330,7 @@ static int __init mipsnet_init_module(void) | |||
328 | 330 | ||
329 | static void __exit mipsnet_exit_module(void) | 331 | static void __exit mipsnet_exit_module(void) |
330 | { | 332 | { |
331 | driver_unregister(&mipsnet_driver); | 333 | platform_driver_unregister(&mipsnet_driver); |
332 | } | 334 | } |
333 | 335 | ||
334 | module_init(mipsnet_init_module); | 336 | module_init(mipsnet_init_module); |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index b0bc3bc18e9c..fe4e158c893d 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -2588,7 +2588,7 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex) | |||
2588 | 2588 | ||
2589 | phy_reset(mp); | 2589 | phy_reset(mp); |
2590 | 2590 | ||
2591 | phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII); | 2591 | phy_attach(mp->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_GMII); |
2592 | 2592 | ||
2593 | if (speed == 0) { | 2593 | if (speed == 0) { |
2594 | phy->autoneg = AUTONEG_ENABLE; | 2594 | phy->autoneg = AUTONEG_ENABLE; |
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 31e38fae017f..845431c186ac 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c | |||
@@ -2478,7 +2478,7 @@ static int sbmac_mii_probe(struct net_device *dev) | |||
2478 | return -ENXIO; | 2478 | return -ENXIO; |
2479 | } | 2479 | } |
2480 | 2480 | ||
2481 | phy_dev = phy_connect(dev, phy_dev->dev.bus_id, &sbmac_mii_poll, 0, | 2481 | phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &sbmac_mii_poll, 0, |
2482 | PHY_INTERFACE_MODE_GMII); | 2482 | PHY_INTERFACE_MODE_GMII); |
2483 | if (IS_ERR(phy_dev)) { | 2483 | if (IS_ERR(phy_dev)) { |
2484 | printk(KERN_ERR "%s: could not attach to PHY\n", dev->name); | 2484 | printk(KERN_ERR "%s: could not attach to PHY\n", dev->name); |
@@ -2500,7 +2500,7 @@ static int sbmac_mii_probe(struct net_device *dev) | |||
2500 | 2500 | ||
2501 | pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", | 2501 | pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", |
2502 | dev->name, phy_dev->drv->name, | 2502 | dev->name, phy_dev->drv->name, |
2503 | phy_dev->dev.bus_id, phy_dev->irq); | 2503 | dev_name(&phy_dev->dev), phy_dev->irq); |
2504 | 2504 | ||
2505 | sc->phy_dev = phy_dev; | 2505 | sc->phy_dev = phy_dev; |
2506 | 2506 | ||
@@ -2697,7 +2697,7 @@ static int __init sbmac_probe(struct platform_device *pldev) | |||
2697 | sbm_base = ioremap_nocache(res->start, res->end - res->start + 1); | 2697 | sbm_base = ioremap_nocache(res->start, res->end - res->start + 1); |
2698 | if (!sbm_base) { | 2698 | if (!sbm_base) { |
2699 | printk(KERN_ERR "%s: unable to map device registers\n", | 2699 | printk(KERN_ERR "%s: unable to map device registers\n", |
2700 | pldev->dev.bus_id); | 2700 | dev_name(&pldev->dev)); |
2701 | err = -ENOMEM; | 2701 | err = -ENOMEM; |
2702 | goto out_out; | 2702 | goto out_out; |
2703 | } | 2703 | } |
@@ -2708,7 +2708,7 @@ static int __init sbmac_probe(struct platform_device *pldev) | |||
2708 | * If we find a zero, skip this MAC. | 2708 | * If we find a zero, skip this MAC. |
2709 | */ | 2709 | */ |
2710 | sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR); | 2710 | sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR); |
2711 | pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", pldev->dev.bus_id, | 2711 | pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", dev_name(&pldev->dev), |
2712 | sbmac_orig_hwaddr ? "" : "not ", (long long)res->start); | 2712 | sbmac_orig_hwaddr ? "" : "not ", (long long)res->start); |
2713 | if (sbmac_orig_hwaddr == 0) { | 2713 | if (sbmac_orig_hwaddr == 0) { |
2714 | err = 0; | 2714 | err = 0; |
@@ -2721,7 +2721,7 @@ static int __init sbmac_probe(struct platform_device *pldev) | |||
2721 | dev = alloc_etherdev(sizeof(struct sbmac_softc)); | 2721 | dev = alloc_etherdev(sizeof(struct sbmac_softc)); |
2722 | if (!dev) { | 2722 | if (!dev) { |
2723 | printk(KERN_ERR "%s: unable to allocate etherdev\n", | 2723 | printk(KERN_ERR "%s: unable to allocate etherdev\n", |
2724 | pldev->dev.bus_id); | 2724 | dev_name(&pldev->dev)); |
2725 | err = -ENOMEM; | 2725 | err = -ENOMEM; |
2726 | goto out_unmap; | 2726 | goto out_unmap; |
2727 | } | 2727 | } |
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 223cde0d43be..293610334a77 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c | |||
@@ -1545,7 +1545,7 @@ smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
1545 | { | 1545 | { |
1546 | strncpy(info->driver, CARDNAME, sizeof(info->driver)); | 1546 | strncpy(info->driver, CARDNAME, sizeof(info->driver)); |
1547 | strncpy(info->version, version, sizeof(info->version)); | 1547 | strncpy(info->version, version, sizeof(info->version)); |
1548 | strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info)); | 1548 | strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info)); |
1549 | } | 1549 | } |
1550 | 1550 | ||
1551 | static int smc911x_ethtool_nwayreset(struct net_device *dev) | 1551 | static int smc911x_ethtool_nwayreset(struct net_device *dev) |
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index b215a8d85e62..0b6da9501444 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -1614,7 +1614,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
1614 | { | 1614 | { |
1615 | strncpy(info->driver, CARDNAME, sizeof(info->driver)); | 1615 | strncpy(info->driver, CARDNAME, sizeof(info->driver)); |
1616 | strncpy(info->version, version, sizeof(info->version)); | 1616 | strncpy(info->version, version, sizeof(info->version)); |
1617 | strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info)); | 1617 | strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info)); |
1618 | } | 1618 | } |
1619 | 1619 | ||
1620 | static int smc_ethtool_nwayreset(struct net_device *dev) | 1620 | static int smc_ethtool_nwayreset(struct net_device *dev) |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index d1590ac55e4b..ab18ee0f60f3 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -769,7 +769,7 @@ static int smsc911x_mii_probe(struct net_device *dev) | |||
769 | return -ENODEV; | 769 | return -ENODEV; |
770 | } | 770 | } |
771 | 771 | ||
772 | phydev = phy_connect(dev, phydev->dev.bus_id, | 772 | phydev = phy_connect(dev, dev_name(&phydev->dev), |
773 | &smsc911x_phy_adjust_link, 0, pdata->config.phy_interface); | 773 | &smsc911x_phy_adjust_link, 0, pdata->config.phy_interface); |
774 | 774 | ||
775 | if (IS_ERR(phydev)) { | 775 | if (IS_ERR(phydev)) { |
@@ -778,7 +778,8 @@ static int smsc911x_mii_probe(struct net_device *dev) | |||
778 | } | 778 | } |
779 | 779 | ||
780 | pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", | 780 | pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", |
781 | dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq); | 781 | dev->name, phydev->drv->name, |
782 | dev_name(&phydev->dev), phydev->irq); | ||
782 | 783 | ||
783 | /* mask with MAC supported features */ | 784 | /* mask with MAC supported features */ |
784 | phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | | 785 | phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | |
@@ -1549,7 +1550,7 @@ static void smsc911x_ethtool_getdrvinfo(struct net_device *dev, | |||
1549 | { | 1550 | { |
1550 | strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver)); | 1551 | strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver)); |
1551 | strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version)); | 1552 | strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version)); |
1552 | strlcpy(info->bus_info, dev->dev.parent->bus_id, | 1553 | strlcpy(info->bus_info, dev_name(dev->dev.parent), |
1553 | sizeof(info->bus_info)); | 1554 | sizeof(info->bus_info)); |
1554 | } | 1555 | } |
1555 | 1556 | ||
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 4e15ae068b3f..72f1348eb809 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c | |||
@@ -1160,7 +1160,7 @@ static int smsc9420_mii_probe(struct net_device *dev) | |||
1160 | smsc_info(PROBE, "PHY addr %d, phy_id 0x%08X", phydev->addr, | 1160 | smsc_info(PROBE, "PHY addr %d, phy_id 0x%08X", phydev->addr, |
1161 | phydev->phy_id); | 1161 | phydev->phy_id); |
1162 | 1162 | ||
1163 | phydev = phy_connect(dev, phydev->dev.bus_id, | 1163 | phydev = phy_connect(dev, dev_name(&phydev->dev), |
1164 | &smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII); | 1164 | &smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII); |
1165 | 1165 | ||
1166 | if (IS_ERR(phydev)) { | 1166 | if (IS_ERR(phydev)) { |
@@ -1169,7 +1169,7 @@ static int smsc9420_mii_probe(struct net_device *dev) | |||
1169 | } | 1169 | } |
1170 | 1170 | ||
1171 | pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", | 1171 | pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", |
1172 | dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq); | 1172 | dev->name, phydev->drv->name, dev_name(&phydev->dev), phydev->irq); |
1173 | 1173 | ||
1174 | /* mask with MAC supported features */ | 1174 | /* mask with MAC supported features */ |
1175 | phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | | 1175 | phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | |
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index bcd0e60cbda9..e1f8eb96a45c 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -725,7 +725,7 @@ static int tc_mii_probe(struct net_device *dev) | |||
725 | } | 725 | } |
726 | 726 | ||
727 | /* attach the mac to the phy */ | 727 | /* attach the mac to the phy */ |
728 | phydev = phy_connect(dev, phydev->dev.bus_id, | 728 | phydev = phy_connect(dev, dev_name(&phydev->dev), |
729 | &tc_handle_link_change, 0, | 729 | &tc_handle_link_change, 0, |
730 | lp->chiptype == TC35815_TX4939 ? | 730 | lp->chiptype == TC35815_TX4939 ? |
731 | PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII); | 731 | PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII); |
@@ -735,7 +735,7 @@ static int tc_mii_probe(struct net_device *dev) | |||
735 | } | 735 | } |
736 | printk(KERN_INFO "%s: attached PHY driver [%s] " | 736 | printk(KERN_INFO "%s: attached PHY driver [%s] " |
737 | "(mii_bus:phy_addr=%s, id=%x)\n", | 737 | "(mii_bus:phy_addr=%s, id=%x)\n", |
738 | dev->name, phydev->drv->name, phydev->dev.bus_id, | 738 | dev->name, phydev->drv->name, dev_name(&phydev->dev), |
739 | phydev->phy_id); | 739 | phydev->phy_id); |
740 | 740 | ||
741 | /* mask with MAC supported features */ | 741 | /* mask with MAC supported features */ |
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index e80a0b65a754..d58b971faa64 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c | |||
@@ -613,7 +613,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) | |||
613 | d_fnstart(3, dev, "(i2400m %p)\n", i2400m); | 613 | d_fnstart(3, dev, "(i2400m %p)\n", i2400m); |
614 | 614 | ||
615 | snprintf(wimax_dev->name, sizeof(wimax_dev->name), | 615 | snprintf(wimax_dev->name, sizeof(wimax_dev->name), |
616 | "i2400m-%s:%s", dev->bus->name, dev->bus_id); | 616 | "i2400m-%s:%s", dev->bus->name, dev_name(dev)); |
617 | 617 | ||
618 | i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL); | 618 | i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL); |
619 | if (i2400m->bm_cmd_buf == NULL) { | 619 | if (i2400m->bm_cmd_buf == NULL) { |
diff --git a/drivers/net/wimax/i2400m/usb-notif.c b/drivers/net/wimax/i2400m/usb-notif.c index 9702c22b2497..0528879f6d39 100644 --- a/drivers/net/wimax/i2400m/usb-notif.c +++ b/drivers/net/wimax/i2400m/usb-notif.c | |||
@@ -102,7 +102,7 @@ int i2400mu_notification_grok(struct i2400mu *i2400mu, const void *buf, | |||
102 | dev_err(dev, "HW BUG? Unknown/unexpected data in notification " | 102 | dev_err(dev, "HW BUG? Unknown/unexpected data in notification " |
103 | "message (%zu bytes)\n", buf_len); | 103 | "message (%zu bytes)\n", buf_len); |
104 | snprintf(prefix, sizeof(prefix), "%s %s: ", | 104 | snprintf(prefix, sizeof(prefix), "%s %s: ", |
105 | dev_driver_string(dev) , dev->bus_id); | 105 | dev_driver_string(dev) , dev_name(dev)); |
106 | if (buf_len > 64) { | 106 | if (buf_len > 64) { |
107 | print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, | 107 | print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, |
108 | 8, 4, buf, 64, 0); | 108 | 8, 4, buf, 64, 0); |
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c index 03a3f34e9039..a12a7211c982 100644 --- a/drivers/net/xtsonic.c +++ b/drivers/net/xtsonic.c | |||
@@ -183,7 +183,7 @@ static int __init sonic_probe1(struct net_device *dev) | |||
183 | 183 | ||
184 | if (lp->descriptors == NULL) { | 184 | if (lp->descriptors == NULL) { |
185 | printk(KERN_ERR "%s: couldn't alloc DMA memory for " | 185 | printk(KERN_ERR "%s: couldn't alloc DMA memory for " |
186 | " descriptors.\n", lp->device->bus_id); | 186 | " descriptors.\n", dev_name(lp->device)); |
187 | goto out; | 187 | goto out; |
188 | } | 188 | } |
189 | 189 | ||
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index a13abf55d784..8450f4a6568a 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -225,7 +225,8 @@ void cpqhp_shutdown_debugfs(void) | |||
225 | 225 | ||
226 | void cpqhp_create_debugfs_files(struct controller *ctrl) | 226 | void cpqhp_create_debugfs_files(struct controller *ctrl) |
227 | { | 227 | { |
228 | ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops); | 228 | ctrl->dentry = debugfs_create_file(dev_name(&ctrl->pci_dev->dev), |
229 | S_IRUGO, root, ctrl, &debug_ops); | ||
229 | } | 230 | } |
230 | 231 | ||
231 | void cpqhp_remove_debugfs_files(struct controller *ctrl) | 232 | void cpqhp_remove_debugfs_files(struct controller *ctrl) |
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index fc1de46fd20a..90013341cd5f 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c | |||
@@ -468,13 +468,13 @@ out: | |||
468 | return ret; | 468 | return ret; |
469 | } | 469 | } |
470 | 470 | ||
471 | int au1x00_drv_pcmcia_remove(struct device *dev) | 471 | int au1x00_drv_pcmcia_remove(struct platform_device *dev) |
472 | { | 472 | { |
473 | struct skt_dev_info *sinfo = dev_get_drvdata(dev); | 473 | struct skt_dev_info *sinfo = platform_get_drvdata(dev); |
474 | int i; | 474 | int i; |
475 | 475 | ||
476 | mutex_lock(&pcmcia_sockets_lock); | 476 | mutex_lock(&pcmcia_sockets_lock); |
477 | dev_set_drvdata(dev, NULL); | 477 | platform_set_drvdata(dev, NULL); |
478 | 478 | ||
479 | for (i = 0; i < sinfo->nskt; i++) { | 479 | for (i = 0; i < sinfo->nskt; i++) { |
480 | struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); | 480 | struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); |
@@ -498,13 +498,13 @@ int au1x00_drv_pcmcia_remove(struct device *dev) | |||
498 | * PCMCIA "Driver" API | 498 | * PCMCIA "Driver" API |
499 | */ | 499 | */ |
500 | 500 | ||
501 | static int au1x00_drv_pcmcia_probe(struct device *dev) | 501 | static int au1x00_drv_pcmcia_probe(struct platform_device *dev) |
502 | { | 502 | { |
503 | int i, ret = -ENODEV; | 503 | int i, ret = -ENODEV; |
504 | 504 | ||
505 | mutex_lock(&pcmcia_sockets_lock); | 505 | mutex_lock(&pcmcia_sockets_lock); |
506 | for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) { | 506 | for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) { |
507 | ret = au1x00_pcmcia_hw_init[i](dev); | 507 | ret = au1x00_pcmcia_hw_init[i](&dev->dev); |
508 | if (ret == 0) | 508 | if (ret == 0) |
509 | break; | 509 | break; |
510 | } | 510 | } |
@@ -512,14 +512,26 @@ static int au1x00_drv_pcmcia_probe(struct device *dev) | |||
512 | return ret; | 512 | return ret; |
513 | } | 513 | } |
514 | 514 | ||
515 | static int au1x00_drv_pcmcia_suspend(struct platform_device *dev, | ||
516 | pm_message_t state) | ||
517 | { | ||
518 | return pcmcia_socket_dev_suspend(&dev->dev, state); | ||
519 | } | ||
520 | |||
521 | static int au1x00_drv_pcmcia_resume(struct platform_device *dev) | ||
522 | { | ||
523 | return pcmcia_socket_dev_resume(&dev->dev); | ||
524 | } | ||
515 | 525 | ||
516 | static struct device_driver au1x00_pcmcia_driver = { | 526 | static struct platform_driver au1x00_pcmcia_driver = { |
527 | .driver = { | ||
528 | .name = "au1x00-pcmcia", | ||
529 | .owner = THIS_MODULE, | ||
530 | }, | ||
517 | .probe = au1x00_drv_pcmcia_probe, | 531 | .probe = au1x00_drv_pcmcia_probe, |
518 | .remove = au1x00_drv_pcmcia_remove, | 532 | .remove = au1x00_drv_pcmcia_remove, |
519 | .name = "au1x00-pcmcia", | 533 | .suspend = au1x00_drv_pcmcia_suspend, |
520 | .bus = &platform_bus_type, | 534 | .resume = au1x00_drv_pcmcia_resume, |
521 | .suspend = pcmcia_socket_dev_suspend, | ||
522 | .resume = pcmcia_socket_dev_resume, | ||
523 | }; | 535 | }; |
524 | 536 | ||
525 | 537 | ||
@@ -533,8 +545,7 @@ static struct device_driver au1x00_pcmcia_driver = { | |||
533 | static int __init au1x00_pcmcia_init(void) | 545 | static int __init au1x00_pcmcia_init(void) |
534 | { | 546 | { |
535 | int error = 0; | 547 | int error = 0; |
536 | if ((error = driver_register(&au1x00_pcmcia_driver))) | 548 | error = platform_driver_register(&au1x00_pcmcia_driver); |
537 | return error; | ||
538 | return error; | 549 | return error; |
539 | } | 550 | } |
540 | 551 | ||
@@ -544,7 +555,7 @@ static int __init au1x00_pcmcia_init(void) | |||
544 | */ | 555 | */ |
545 | static void __exit au1x00_pcmcia_exit(void) | 556 | static void __exit au1x00_pcmcia_exit(void) |
546 | { | 557 | { |
547 | driver_unregister(&au1x00_pcmcia_driver); | 558 | platform_driver_unregister(&au1x00_pcmcia_driver); |
548 | } | 559 | } |
549 | 560 | ||
550 | module_init(au1x00_pcmcia_init); | 561 | module_init(au1x00_pcmcia_init); |
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 71653ab84890..40d4953e4b12 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -1238,6 +1238,16 @@ static int pcic_init(struct pcmcia_socket *s) | |||
1238 | return 0; | 1238 | return 0; |
1239 | } | 1239 | } |
1240 | 1240 | ||
1241 | static int i82365_drv_pcmcia_suspend(struct platform_device *dev, | ||
1242 | pm_message_t state) | ||
1243 | { | ||
1244 | return pcmcia_socket_dev_suspend(&dev->dev, state); | ||
1245 | } | ||
1246 | |||
1247 | static int i82365_drv_pcmcia_resume(struct platform_device *dev) | ||
1248 | { | ||
1249 | return pcmcia_socket_dev_resume(&dev->dev); | ||
1250 | } | ||
1241 | static struct pccard_operations pcic_operations = { | 1251 | static struct pccard_operations pcic_operations = { |
1242 | .init = pcic_init, | 1252 | .init = pcic_init, |
1243 | .get_status = pcic_get_status, | 1253 | .get_status = pcic_get_status, |
@@ -1248,11 +1258,13 @@ static struct pccard_operations pcic_operations = { | |||
1248 | 1258 | ||
1249 | /*====================================================================*/ | 1259 | /*====================================================================*/ |
1250 | 1260 | ||
1251 | static struct device_driver i82365_driver = { | 1261 | static struct platform_driver i82365_driver = { |
1252 | .name = "i82365", | 1262 | .driver = { |
1253 | .bus = &platform_bus_type, | 1263 | .name = "i82365", |
1254 | .suspend = pcmcia_socket_dev_suspend, | 1264 | .owner = THIS_MODULE, |
1255 | .resume = pcmcia_socket_dev_resume, | 1265 | }, |
1266 | .suspend = i82365_drv_pcmcia_suspend, | ||
1267 | .resume = i82365_drv_pcmcia_resume, | ||
1256 | }; | 1268 | }; |
1257 | 1269 | ||
1258 | static struct platform_device *i82365_device; | 1270 | static struct platform_device *i82365_device; |
@@ -1261,7 +1273,7 @@ static int __init init_i82365(void) | |||
1261 | { | 1273 | { |
1262 | int i, ret; | 1274 | int i, ret; |
1263 | 1275 | ||
1264 | ret = driver_register(&i82365_driver); | 1276 | ret = platform_driver_register(&i82365_driver); |
1265 | if (ret) | 1277 | if (ret) |
1266 | goto err_out; | 1278 | goto err_out; |
1267 | 1279 | ||
@@ -1337,7 +1349,7 @@ err_dev_unregister: | |||
1337 | pnp_disable_dev(i82365_pnpdev); | 1349 | pnp_disable_dev(i82365_pnpdev); |
1338 | #endif | 1350 | #endif |
1339 | err_driver_unregister: | 1351 | err_driver_unregister: |
1340 | driver_unregister(&i82365_driver); | 1352 | platform_driver_unregister(&i82365_driver); |
1341 | err_out: | 1353 | err_out: |
1342 | return ret; | 1354 | return ret; |
1343 | } /* init_i82365 */ | 1355 | } /* init_i82365 */ |
@@ -1365,7 +1377,7 @@ static void __exit exit_i82365(void) | |||
1365 | if (i82365_pnpdev) | 1377 | if (i82365_pnpdev) |
1366 | pnp_disable_dev(i82365_pnpdev); | 1378 | pnp_disable_dev(i82365_pnpdev); |
1367 | #endif | 1379 | #endif |
1368 | driver_unregister(&i82365_driver); | 1380 | platform_driver_unregister(&i82365_driver); |
1369 | } /* exit_i82365 */ | 1381 | } /* exit_i82365 */ |
1370 | 1382 | ||
1371 | module_init(init_i82365); | 1383 | module_init(init_i82365); |
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 2ab4f22c21de..62b4ecc97c46 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c | |||
@@ -696,13 +696,25 @@ static struct pccard_operations pcc_operations = { | |||
696 | .set_mem_map = pcc_set_mem_map, | 696 | .set_mem_map = pcc_set_mem_map, |
697 | }; | 697 | }; |
698 | 698 | ||
699 | static int cfc_drv_pcmcia_suspend(struct platform_device *dev, | ||
700 | pm_message_t state) | ||
701 | { | ||
702 | return pcmcia_socket_dev_suspend(&dev->dev, state); | ||
703 | } | ||
704 | |||
705 | static int cfc_drv_pcmcia_resume(struct platform_device *dev) | ||
706 | { | ||
707 | return pcmcia_socket_dev_resume(&dev->dev); | ||
708 | } | ||
699 | /*====================================================================*/ | 709 | /*====================================================================*/ |
700 | 710 | ||
701 | static struct device_driver pcc_driver = { | 711 | static struct platform_driver pcc_driver = { |
702 | .name = "cfc", | 712 | .driver = { |
703 | .bus = &platform_bus_type, | 713 | .name = "cfc", |
704 | .suspend = pcmcia_socket_dev_suspend, | 714 | .owner = THIS_MODULE, |
705 | .resume = pcmcia_socket_dev_resume, | 715 | }, |
716 | .suspend = cfc_drv_pcmcia_suspend, | ||
717 | .resume = cfc_drv_pcmcia_resume, | ||
706 | }; | 718 | }; |
707 | 719 | ||
708 | static struct platform_device pcc_device = { | 720 | static struct platform_device pcc_device = { |
@@ -716,13 +728,13 @@ static int __init init_m32r_pcc(void) | |||
716 | { | 728 | { |
717 | int i, ret; | 729 | int i, ret; |
718 | 730 | ||
719 | ret = driver_register(&pcc_driver); | 731 | ret = platform_driver_register(&pcc_driver); |
720 | if (ret) | 732 | if (ret) |
721 | return ret; | 733 | return ret; |
722 | 734 | ||
723 | ret = platform_device_register(&pcc_device); | 735 | ret = platform_device_register(&pcc_device); |
724 | if (ret){ | 736 | if (ret){ |
725 | driver_unregister(&pcc_driver); | 737 | platform_driver_unregister(&pcc_driver); |
726 | return ret; | 738 | return ret; |
727 | } | 739 | } |
728 | 740 | ||
@@ -754,7 +766,7 @@ static int __init init_m32r_pcc(void) | |||
754 | if (pcc_sockets == 0) { | 766 | if (pcc_sockets == 0) { |
755 | printk("socket is not found.\n"); | 767 | printk("socket is not found.\n"); |
756 | platform_device_unregister(&pcc_device); | 768 | platform_device_unregister(&pcc_device); |
757 | driver_unregister(&pcc_driver); | 769 | platform_driver_unregister(&pcc_driver); |
758 | return -ENODEV; | 770 | return -ENODEV; |
759 | } | 771 | } |
760 | 772 | ||
@@ -802,7 +814,7 @@ static void __exit exit_m32r_pcc(void) | |||
802 | if (poll_interval != 0) | 814 | if (poll_interval != 0) |
803 | del_timer_sync(&poll_timer); | 815 | del_timer_sync(&poll_timer); |
804 | 816 | ||
805 | driver_unregister(&pcc_driver); | 817 | platform_driver_unregister(&pcc_driver); |
806 | } /* exit_m32r_pcc */ | 818 | } /* exit_m32r_pcc */ |
807 | 819 | ||
808 | module_init(init_m32r_pcc); | 820 | module_init(init_m32r_pcc); |
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 2f108c23dbd9..12034b41d196 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c | |||
@@ -672,13 +672,25 @@ static struct pccard_operations pcc_operations = { | |||
672 | .set_mem_map = pcc_set_mem_map, | 672 | .set_mem_map = pcc_set_mem_map, |
673 | }; | 673 | }; |
674 | 674 | ||
675 | static int pcc_drv_pcmcia_suspend(struct platform_device *dev, | ||
676 | pm_message_t state) | ||
677 | { | ||
678 | return pcmcia_socket_dev_suspend(&dev->dev, state); | ||
679 | } | ||
680 | |||
681 | static int pcc_drv_pcmcia_resume(struct platform_device *dev) | ||
682 | { | ||
683 | return pcmcia_socket_dev_resume(&dev->dev); | ||
684 | } | ||
675 | /*====================================================================*/ | 685 | /*====================================================================*/ |
676 | 686 | ||
677 | static struct device_driver pcc_driver = { | 687 | static struct platform_driver pcc_driver = { |
678 | .name = "pcc", | 688 | .driver = { |
679 | .bus = &platform_bus_type, | 689 | .name = "pcc", |
680 | .suspend = pcmcia_socket_dev_suspend, | 690 | .owner = THIS_MODULE, |
681 | .resume = pcmcia_socket_dev_resume, | 691 | }, |
692 | .suspend = pcc_drv_pcmcia_suspend, | ||
693 | .resume = pcc_drv_pcmcia_resume, | ||
682 | }; | 694 | }; |
683 | 695 | ||
684 | static struct platform_device pcc_device = { | 696 | static struct platform_device pcc_device = { |
@@ -692,13 +704,13 @@ static int __init init_m32r_pcc(void) | |||
692 | { | 704 | { |
693 | int i, ret; | 705 | int i, ret; |
694 | 706 | ||
695 | ret = driver_register(&pcc_driver); | 707 | ret = platform_driver_register(&pcc_driver); |
696 | if (ret) | 708 | if (ret) |
697 | return ret; | 709 | return ret; |
698 | 710 | ||
699 | ret = platform_device_register(&pcc_device); | 711 | ret = platform_device_register(&pcc_device); |
700 | if (ret){ | 712 | if (ret){ |
701 | driver_unregister(&pcc_driver); | 713 | platform_driver_unregister(&pcc_driver); |
702 | return ret; | 714 | return ret; |
703 | } | 715 | } |
704 | 716 | ||
@@ -715,7 +727,7 @@ static int __init init_m32r_pcc(void) | |||
715 | if (pcc_sockets == 0) { | 727 | if (pcc_sockets == 0) { |
716 | printk("socket is not found.\n"); | 728 | printk("socket is not found.\n"); |
717 | platform_device_unregister(&pcc_device); | 729 | platform_device_unregister(&pcc_device); |
718 | driver_unregister(&pcc_driver); | 730 | platform_driver_unregister(&pcc_driver); |
719 | return -ENODEV; | 731 | return -ENODEV; |
720 | } | 732 | } |
721 | 733 | ||
@@ -763,7 +775,7 @@ static void __exit exit_m32r_pcc(void) | |||
763 | if (poll_interval != 0) | 775 | if (poll_interval != 0) |
764 | del_timer_sync(&poll_timer); | 776 | del_timer_sync(&poll_timer); |
765 | 777 | ||
766 | driver_unregister(&pcc_driver); | 778 | platform_driver_unregister(&pcc_driver); |
767 | } /* exit_m32r_pcc */ | 779 | } /* exit_m32r_pcc */ |
768 | 780 | ||
769 | module_init(init_m32r_pcc); | 781 | module_init(init_m32r_pcc); |
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index c0e2afc79e3e..e592e0e0d7ed 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c | |||
@@ -153,7 +153,7 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num, | |||
153 | unsigned long align, struct pcmcia_socket *s) | 153 | unsigned long align, struct pcmcia_socket *s) |
154 | { | 154 | { |
155 | struct resource *res = make_resource(0, num, IORESOURCE_IO, | 155 | struct resource *res = make_resource(0, num, IORESOURCE_IO, |
156 | s->dev.bus_id); | 156 | dev_name(&s->dev)); |
157 | struct pcmcia_align_data data; | 157 | struct pcmcia_align_data data; |
158 | unsigned long min = base; | 158 | unsigned long min = base; |
159 | int ret; | 159 | int ret; |
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index c5b2a44b4c37..d8da5ac844e9 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c | |||
@@ -65,7 +65,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = { | |||
65 | #endif | 65 | #endif |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static int sa11x0_drv_pcmcia_probe(struct device *dev) | 68 | static int sa11x0_drv_pcmcia_probe(struct platform_device *dev) |
69 | { | 69 | { |
70 | int i, ret = -ENODEV; | 70 | int i, ret = -ENODEV; |
71 | 71 | ||
@@ -73,7 +73,7 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev) | |||
73 | * Initialise any "on-board" PCMCIA sockets. | 73 | * Initialise any "on-board" PCMCIA sockets. |
74 | */ | 74 | */ |
75 | for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) { | 75 | for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) { |
76 | ret = sa11x0_pcmcia_hw_init[i](dev); | 76 | ret = sa11x0_pcmcia_hw_init[i](&dev->dev); |
77 | if (ret == 0) | 77 | if (ret == 0) |
78 | break; | 78 | break; |
79 | } | 79 | } |
@@ -81,13 +81,31 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev) | |||
81 | return ret; | 81 | return ret; |
82 | } | 82 | } |
83 | 83 | ||
84 | static struct device_driver sa11x0_pcmcia_driver = { | 84 | static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) |
85 | { | ||
86 | return soc_common_drv_pcmcia_remove(&dev->dev); | ||
87 | } | ||
88 | |||
89 | static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev, | ||
90 | pm_message_t state) | ||
91 | { | ||
92 | return pcmcia_socket_dev_suspend(&dev->dev, state); | ||
93 | } | ||
94 | |||
95 | static int sa11x0_drv_pcmcia_resume(struct platform_device *dev) | ||
96 | { | ||
97 | return pcmcia_socket_dev_resume(&dev->dev); | ||
98 | } | ||
99 | |||
100 | static struct platform_driver sa11x0_pcmcia_driver = { | ||
101 | .driver = { | ||
102 | .name = "sa11x0-pcmcia", | ||
103 | .owner = THIS_MODULE, | ||
104 | }, | ||
85 | .probe = sa11x0_drv_pcmcia_probe, | 105 | .probe = sa11x0_drv_pcmcia_probe, |
86 | .remove = soc_common_drv_pcmcia_remove, | 106 | .remove = sa11x0_drv_pcmcia_remove, |
87 | .name = "sa11x0-pcmcia", | 107 | .suspend = sa11x0_drv_pcmcia_suspend, |
88 | .bus = &platform_bus_type, | 108 | .resume = sa11x0_drv_pcmcia_resume, |
89 | .suspend = pcmcia_socket_dev_suspend, | ||
90 | .resume = pcmcia_socket_dev_resume, | ||
91 | }; | 109 | }; |
92 | 110 | ||
93 | /* sa11x0_pcmcia_init() | 111 | /* sa11x0_pcmcia_init() |
@@ -100,7 +118,7 @@ static struct device_driver sa11x0_pcmcia_driver = { | |||
100 | */ | 118 | */ |
101 | static int __init sa11x0_pcmcia_init(void) | 119 | static int __init sa11x0_pcmcia_init(void) |
102 | { | 120 | { |
103 | return driver_register(&sa11x0_pcmcia_driver); | 121 | return platform_driver_register(&sa11x0_pcmcia_driver); |
104 | } | 122 | } |
105 | 123 | ||
106 | /* sa11x0_pcmcia_exit() | 124 | /* sa11x0_pcmcia_exit() |
@@ -110,7 +128,7 @@ static int __init sa11x0_pcmcia_init(void) | |||
110 | */ | 128 | */ |
111 | static void __exit sa11x0_pcmcia_exit(void) | 129 | static void __exit sa11x0_pcmcia_exit(void) |
112 | { | 130 | { |
113 | driver_unregister(&sa11x0_pcmcia_driver); | 131 | platform_driver_unregister(&sa11x0_pcmcia_driver); |
114 | } | 132 | } |
115 | 133 | ||
116 | MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>"); | 134 | MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>"); |
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 2a613e920fd4..9ad97ea836e8 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c | |||
@@ -363,13 +363,25 @@ static int __init get_tcic_id(void) | |||
363 | return id; | 363 | return id; |
364 | } | 364 | } |
365 | 365 | ||
366 | static int tcic_drv_pcmcia_suspend(struct platform_device *dev, | ||
367 | pm_message_t state) | ||
368 | { | ||
369 | return pcmcia_socket_dev_suspend(&dev->dev, state); | ||
370 | } | ||
371 | |||
372 | static int tcic_drv_pcmcia_resume(struct platform_device *dev) | ||
373 | { | ||
374 | return pcmcia_socket_dev_resume(&dev->dev); | ||
375 | } | ||
366 | /*====================================================================*/ | 376 | /*====================================================================*/ |
367 | 377 | ||
368 | static struct device_driver tcic_driver = { | 378 | static struct platform_driver tcic_driver = { |
369 | .name = "tcic-pcmcia", | 379 | .driver = { |
370 | .bus = &platform_bus_type, | 380 | .name = "tcic-pcmcia", |
371 | .suspend = pcmcia_socket_dev_suspend, | 381 | .owner = THIS_MODULE, |
372 | .resume = pcmcia_socket_dev_resume, | 382 | }, |
383 | .suspend = tcic_drv_pcmcia_suspend, | ||
384 | .resume = tcic_drv_pcmcia_resume, | ||
373 | }; | 385 | }; |
374 | 386 | ||
375 | static struct platform_device tcic_device = { | 387 | static struct platform_device tcic_device = { |
@@ -383,7 +395,7 @@ static int __init init_tcic(void) | |||
383 | int i, sock, ret = 0; | 395 | int i, sock, ret = 0; |
384 | u_int mask, scan; | 396 | u_int mask, scan; |
385 | 397 | ||
386 | if (driver_register(&tcic_driver)) | 398 | if (platform_driver_register(&tcic_driver)) |
387 | return -1; | 399 | return -1; |
388 | 400 | ||
389 | printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: "); | 401 | printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: "); |
@@ -391,7 +403,7 @@ static int __init init_tcic(void) | |||
391 | 403 | ||
392 | if (!request_region(tcic_base, 16, "tcic-2")) { | 404 | if (!request_region(tcic_base, 16, "tcic-2")) { |
393 | printk("could not allocate ports,\n "); | 405 | printk("could not allocate ports,\n "); |
394 | driver_unregister(&tcic_driver); | 406 | platform_driver_unregister(&tcic_driver); |
395 | return -ENODEV; | 407 | return -ENODEV; |
396 | } | 408 | } |
397 | else { | 409 | else { |
@@ -414,7 +426,7 @@ static int __init init_tcic(void) | |||
414 | if (sock == 0) { | 426 | if (sock == 0) { |
415 | printk("not found.\n"); | 427 | printk("not found.\n"); |
416 | release_region(tcic_base, 16); | 428 | release_region(tcic_base, 16); |
417 | driver_unregister(&tcic_driver); | 429 | platform_driver_unregister(&tcic_driver); |
418 | return -ENODEV; | 430 | return -ENODEV; |
419 | } | 431 | } |
420 | 432 | ||
@@ -542,7 +554,7 @@ static void __exit exit_tcic(void) | |||
542 | } | 554 | } |
543 | 555 | ||
544 | platform_device_unregister(&tcic_device); | 556 | platform_device_unregister(&tcic_device); |
545 | driver_unregister(&tcic_driver); | 557 | platform_driver_unregister(&tcic_driver); |
546 | } /* exit_tcic */ | 558 | } /* exit_tcic */ |
547 | 559 | ||
548 | /*====================================================================*/ | 560 | /*====================================================================*/ |
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index b2c412419059..659421d0ca46 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c | |||
@@ -704,24 +704,37 @@ static int __devinit vrc4171_card_setup(char *options) | |||
704 | 704 | ||
705 | __setup("vrc4171_card=", vrc4171_card_setup); | 705 | __setup("vrc4171_card=", vrc4171_card_setup); |
706 | 706 | ||
707 | static struct device_driver vrc4171_card_driver = { | 707 | static int vrc4171_card_suspend(struct platform_device *dev, |
708 | .name = vrc4171_card_name, | 708 | pm_message_t state) |
709 | .bus = &platform_bus_type, | 709 | { |
710 | .suspend = pcmcia_socket_dev_suspend, | 710 | return pcmcia_socket_dev_suspend(&dev->dev, state); |
711 | .resume = pcmcia_socket_dev_resume, | 711 | } |
712 | |||
713 | static int vrc4171_card_resume(struct platform_device *dev) | ||
714 | { | ||
715 | return pcmcia_socket_dev_resume(&dev->dev); | ||
716 | } | ||
717 | |||
718 | static struct platform_driver vrc4171_card_driver = { | ||
719 | .driver = { | ||
720 | .name = vrc4171_card_name, | ||
721 | .owner = THIS_MODULE, | ||
722 | }, | ||
723 | .suspend = vrc4171_card_suspend, | ||
724 | .resume = vrc4171_card_resume, | ||
712 | }; | 725 | }; |
713 | 726 | ||
714 | static int __devinit vrc4171_card_init(void) | 727 | static int __devinit vrc4171_card_init(void) |
715 | { | 728 | { |
716 | int retval; | 729 | int retval; |
717 | 730 | ||
718 | retval = driver_register(&vrc4171_card_driver); | 731 | retval = platform_driver_register(&vrc4171_card_driver); |
719 | if (retval < 0) | 732 | if (retval < 0) |
720 | return retval; | 733 | return retval; |
721 | 734 | ||
722 | retval = platform_device_register(&vrc4171_card_device); | 735 | retval = platform_device_register(&vrc4171_card_device); |
723 | if (retval < 0) { | 736 | if (retval < 0) { |
724 | driver_unregister(&vrc4171_card_driver); | 737 | platform_driver_unregister(&vrc4171_card_driver); |
725 | return retval; | 738 | return retval; |
726 | } | 739 | } |
727 | 740 | ||
@@ -735,11 +748,12 @@ static int __devinit vrc4171_card_init(void) | |||
735 | if (retval < 0) { | 748 | if (retval < 0) { |
736 | vrc4171_remove_sockets(); | 749 | vrc4171_remove_sockets(); |
737 | platform_device_unregister(&vrc4171_card_device); | 750 | platform_device_unregister(&vrc4171_card_device); |
738 | driver_unregister(&vrc4171_card_driver); | 751 | platform_driver_unregister(&vrc4171_card_driver); |
739 | return retval; | 752 | return retval; |
740 | } | 753 | } |
741 | 754 | ||
742 | printk(KERN_INFO "%s, connected to IRQ %d\n", vrc4171_card_driver.name, vrc4171_irq); | 755 | printk(KERN_INFO "%s, connected to IRQ %d\n", |
756 | vrc4171_card_driver.driver.name, vrc4171_irq); | ||
743 | 757 | ||
744 | return 0; | 758 | return 0; |
745 | } | 759 | } |
@@ -749,7 +763,7 @@ static void __devexit vrc4171_card_exit(void) | |||
749 | free_irq(vrc4171_irq, vrc4171_sockets); | 763 | free_irq(vrc4171_irq, vrc4171_sockets); |
750 | vrc4171_remove_sockets(); | 764 | vrc4171_remove_sockets(); |
751 | platform_device_unregister(&vrc4171_card_device); | 765 | platform_device_unregister(&vrc4171_card_device); |
752 | driver_unregister(&vrc4171_card_driver); | 766 | platform_driver_unregister(&vrc4171_card_driver); |
753 | } | 767 | } |
754 | 768 | ||
755 | module_init(vrc4171_card_init); | 769 | module_init(vrc4171_card_init); |
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index addb87cf44d9..3222fa3c808c 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c | |||
@@ -193,7 +193,7 @@ static int rio_match_bus(struct device *dev, struct device_driver *drv) | |||
193 | } | 193 | } |
194 | 194 | ||
195 | static struct device rio_bus = { | 195 | static struct device rio_bus = { |
196 | .bus_id = "rapidio", | 196 | .init_name = "rapidio", |
197 | }; | 197 | }; |
198 | 198 | ||
199 | struct bus_type rio_bus_type = { | 199 | struct bus_type rio_bus_type = { |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index d5e4e637ddec..86c61f143515 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -351,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
351 | /* register irq handler after we know what name we'll use */ | 351 | /* register irq handler after we know what name we'll use */ |
352 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, | 352 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, |
353 | IRQF_DISABLED | IRQF_SHARED, | 353 | IRQF_DISABLED | IRQF_SHARED, |
354 | rtc->rtcdev->dev.bus_id, rtc); | 354 | dev_name(&rtc->rtcdev->dev), rtc); |
355 | if (ret) { | 355 | if (ret) { |
356 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); | 356 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); |
357 | rtc_device_unregister(rtc->rtcdev); | 357 | rtc_device_unregister(rtc->rtcdev); |
@@ -366,7 +366,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
366 | 366 | ||
367 | if (gpbr_readl(rtc) == 0) | 367 | if (gpbr_readl(rtc) == 0) |
368 | dev_warn(&pdev->dev, "%s: SET TIME!\n", | 368 | dev_warn(&pdev->dev, "%s: SET TIME!\n", |
369 | rtc->rtcdev->dev.bus_id); | 369 | dev_name(&rtc->rtcdev->dev)); |
370 | 370 | ||
371 | return 0; | 371 | return 0; |
372 | 372 | ||
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 2cbeb0794f14..bd1ce8e2bc18 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -377,13 +377,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
377 | 377 | ||
378 | /* handle periodic and alarm irqs */ | 378 | /* handle periodic and alarm irqs */ |
379 | if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, | 379 | if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, |
380 | rtc->dev.bus_id, rtc)) { | 380 | dev_name(&rtc->dev), rtc)) { |
381 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", | 381 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", |
382 | pdev->name, omap_rtc_timer); | 382 | pdev->name, omap_rtc_timer); |
383 | goto fail0; | 383 | goto fail0; |
384 | } | 384 | } |
385 | if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, | 385 | if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, |
386 | rtc->dev.bus_id, rtc)) { | 386 | dev_name(&rtc->dev), rtc)) { |
387 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", | 387 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", |
388 | pdev->name, omap_rtc_alarm); | 388 | pdev->name, omap_rtc_alarm); |
389 | goto fail1; | 389 | goto fail1; |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 1c3fc6b428e9..4898f7fe8518 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <asm/rtc.h> | 28 | #include <asm/rtc.h> |
29 | 29 | ||
30 | #define DRV_NAME "sh-rtc" | 30 | #define DRV_NAME "sh-rtc" |
31 | #define DRV_VERSION "0.2.0" | 31 | #define DRV_VERSION "0.2.1" |
32 | 32 | ||
33 | #define RTC_REG(r) ((r) * rtc_reg_size) | 33 | #define RTC_REG(r) ((r) * rtc_reg_size) |
34 | 34 | ||
@@ -99,56 +99,51 @@ struct sh_rtc { | |||
99 | unsigned short periodic_freq; | 99 | unsigned short periodic_freq; |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | 102 | static int __sh_rtc_interrupt(struct sh_rtc *rtc) |
103 | { | 103 | { |
104 | struct sh_rtc *rtc = dev_id; | 104 | unsigned int tmp, pending; |
105 | unsigned int tmp; | ||
106 | |||
107 | spin_lock(&rtc->lock); | ||
108 | 105 | ||
109 | tmp = readb(rtc->regbase + RCR1); | 106 | tmp = readb(rtc->regbase + RCR1); |
107 | pending = tmp & RCR1_CF; | ||
110 | tmp &= ~RCR1_CF; | 108 | tmp &= ~RCR1_CF; |
111 | writeb(tmp, rtc->regbase + RCR1); | 109 | writeb(tmp, rtc->regbase + RCR1); |
112 | 110 | ||
113 | /* Users have requested One x Second IRQ */ | 111 | /* Users have requested One x Second IRQ */ |
114 | if (rtc->periodic_freq & PF_OXS) | 112 | if (pending && rtc->periodic_freq & PF_OXS) |
115 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); | 113 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); |
116 | 114 | ||
117 | spin_unlock(&rtc->lock); | 115 | return pending; |
118 | |||
119 | return IRQ_HANDLED; | ||
120 | } | 116 | } |
121 | 117 | ||
122 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) | 118 | static int __sh_rtc_alarm(struct sh_rtc *rtc) |
123 | { | 119 | { |
124 | struct sh_rtc *rtc = dev_id; | 120 | unsigned int tmp, pending; |
125 | unsigned int tmp; | ||
126 | |||
127 | spin_lock(&rtc->lock); | ||
128 | 121 | ||
129 | tmp = readb(rtc->regbase + RCR1); | 122 | tmp = readb(rtc->regbase + RCR1); |
123 | pending = tmp & RCR1_AF; | ||
130 | tmp &= ~(RCR1_AF | RCR1_AIE); | 124 | tmp &= ~(RCR1_AF | RCR1_AIE); |
131 | writeb(tmp, rtc->regbase + RCR1); | 125 | writeb(tmp, rtc->regbase + RCR1); |
132 | |||
133 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); | ||
134 | 126 | ||
135 | spin_unlock(&rtc->lock); | 127 | if (pending) |
128 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); | ||
136 | 129 | ||
137 | return IRQ_HANDLED; | 130 | return pending; |
138 | } | 131 | } |
139 | 132 | ||
140 | static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | 133 | static int __sh_rtc_periodic(struct sh_rtc *rtc) |
141 | { | 134 | { |
142 | struct sh_rtc *rtc = dev_id; | ||
143 | struct rtc_device *rtc_dev = rtc->rtc_dev; | 135 | struct rtc_device *rtc_dev = rtc->rtc_dev; |
144 | unsigned int tmp; | 136 | struct rtc_task *irq_task; |
145 | 137 | unsigned int tmp, pending; | |
146 | spin_lock(&rtc->lock); | ||
147 | 138 | ||
148 | tmp = readb(rtc->regbase + RCR2); | 139 | tmp = readb(rtc->regbase + RCR2); |
140 | pending = tmp & RCR2_PEF; | ||
149 | tmp &= ~RCR2_PEF; | 141 | tmp &= ~RCR2_PEF; |
150 | writeb(tmp, rtc->regbase + RCR2); | 142 | writeb(tmp, rtc->regbase + RCR2); |
151 | 143 | ||
144 | if (!pending) | ||
145 | return 0; | ||
146 | |||
152 | /* Half period enabled than one skipped and the next notified */ | 147 | /* Half period enabled than one skipped and the next notified */ |
153 | if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT)) | 148 | if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT)) |
154 | rtc->periodic_freq &= ~PF_COUNT; | 149 | rtc->periodic_freq &= ~PF_COUNT; |
@@ -157,16 +152,65 @@ static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | |||
157 | rtc->periodic_freq |= PF_COUNT; | 152 | rtc->periodic_freq |= PF_COUNT; |
158 | if (rtc->periodic_freq & PF_KOU) { | 153 | if (rtc->periodic_freq & PF_KOU) { |
159 | spin_lock(&rtc_dev->irq_task_lock); | 154 | spin_lock(&rtc_dev->irq_task_lock); |
160 | if (rtc_dev->irq_task) | 155 | irq_task = rtc_dev->irq_task; |
161 | rtc_dev->irq_task->func(rtc_dev->irq_task->private_data); | 156 | if (irq_task) |
157 | irq_task->func(irq_task->private_data); | ||
162 | spin_unlock(&rtc_dev->irq_task_lock); | 158 | spin_unlock(&rtc_dev->irq_task_lock); |
163 | } else | 159 | } else |
164 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); | 160 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); |
165 | } | 161 | } |
166 | 162 | ||
163 | return pending; | ||
164 | } | ||
165 | |||
166 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | ||
167 | { | ||
168 | struct sh_rtc *rtc = dev_id; | ||
169 | int ret; | ||
170 | |||
171 | spin_lock(&rtc->lock); | ||
172 | ret = __sh_rtc_interrupt(rtc); | ||
173 | spin_unlock(&rtc->lock); | ||
174 | |||
175 | return IRQ_RETVAL(ret); | ||
176 | } | ||
177 | |||
178 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) | ||
179 | { | ||
180 | struct sh_rtc *rtc = dev_id; | ||
181 | int ret; | ||
182 | |||
183 | spin_lock(&rtc->lock); | ||
184 | ret = __sh_rtc_alarm(rtc); | ||
185 | spin_unlock(&rtc->lock); | ||
186 | |||
187 | return IRQ_RETVAL(ret); | ||
188 | } | ||
189 | |||
190 | static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | ||
191 | { | ||
192 | struct sh_rtc *rtc = dev_id; | ||
193 | int ret; | ||
194 | |||
195 | spin_lock(&rtc->lock); | ||
196 | ret = __sh_rtc_periodic(rtc); | ||
167 | spin_unlock(&rtc->lock); | 197 | spin_unlock(&rtc->lock); |
168 | 198 | ||
169 | return IRQ_HANDLED; | 199 | return IRQ_RETVAL(ret); |
200 | } | ||
201 | |||
202 | static irqreturn_t sh_rtc_shared(int irq, void *dev_id) | ||
203 | { | ||
204 | struct sh_rtc *rtc = dev_id; | ||
205 | int ret; | ||
206 | |||
207 | spin_lock(&rtc->lock); | ||
208 | ret = __sh_rtc_interrupt(rtc); | ||
209 | ret |= __sh_rtc_alarm(rtc); | ||
210 | ret |= __sh_rtc_periodic(rtc); | ||
211 | spin_unlock(&rtc->lock); | ||
212 | |||
213 | return IRQ_RETVAL(ret); | ||
170 | } | 214 | } |
171 | 215 | ||
172 | static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) | 216 | static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) |
@@ -275,6 +319,25 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq) | |||
275 | return 0; | 319 | return 0; |
276 | } | 320 | } |
277 | 321 | ||
322 | static inline void sh_rtc_setcie(struct device *dev, unsigned int enable) | ||
323 | { | ||
324 | struct sh_rtc *rtc = dev_get_drvdata(dev); | ||
325 | unsigned int tmp; | ||
326 | |||
327 | spin_lock_irq(&rtc->lock); | ||
328 | |||
329 | tmp = readb(rtc->regbase + RCR1); | ||
330 | |||
331 | if (!enable) | ||
332 | tmp &= ~RCR1_CIE; | ||
333 | else | ||
334 | tmp |= RCR1_CIE; | ||
335 | |||
336 | writeb(tmp, rtc->regbase + RCR1); | ||
337 | |||
338 | spin_unlock_irq(&rtc->lock); | ||
339 | } | ||
340 | |||
278 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 341 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
279 | { | 342 | { |
280 | struct sh_rtc *rtc = dev_get_drvdata(dev); | 343 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
@@ -291,9 +354,11 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
291 | break; | 354 | break; |
292 | case RTC_UIE_OFF: | 355 | case RTC_UIE_OFF: |
293 | rtc->periodic_freq &= ~PF_OXS; | 356 | rtc->periodic_freq &= ~PF_OXS; |
357 | sh_rtc_setcie(dev, 0); | ||
294 | break; | 358 | break; |
295 | case RTC_UIE_ON: | 359 | case RTC_UIE_ON: |
296 | rtc->periodic_freq |= PF_OXS; | 360 | rtc->periodic_freq |= PF_OXS; |
361 | sh_rtc_setcie(dev, 1); | ||
297 | break; | 362 | break; |
298 | case RTC_IRQP_READ: | 363 | case RTC_IRQP_READ: |
299 | ret = put_user(rtc->rtc_dev->irq_freq, | 364 | ret = put_user(rtc->rtc_dev->irq_freq, |
@@ -356,18 +421,17 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
356 | tm->tm_sec--; | 421 | tm->tm_sec--; |
357 | #endif | 422 | #endif |
358 | 423 | ||
424 | /* only keep the carry interrupt enabled if UIE is on */ | ||
425 | if (!(rtc->periodic_freq & PF_OXS)) | ||
426 | sh_rtc_setcie(dev, 0); | ||
427 | |||
359 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 428 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
360 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 429 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
361 | __func__, | 430 | __func__, |
362 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 431 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
363 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); | 432 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); |
364 | 433 | ||
365 | if (rtc_valid_tm(tm) < 0) { | 434 | return rtc_valid_tm(tm); |
366 | dev_err(dev, "invalid date\n"); | ||
367 | rtc_time_to_tm(0, tm); | ||
368 | } | ||
369 | |||
370 | return 0; | ||
371 | } | 435 | } |
372 | 436 | ||
373 | static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) | 437 | static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) |
@@ -572,7 +636,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
572 | { | 636 | { |
573 | struct sh_rtc *rtc; | 637 | struct sh_rtc *rtc; |
574 | struct resource *res; | 638 | struct resource *res; |
575 | unsigned int tmp; | 639 | struct rtc_time r; |
576 | int ret; | 640 | int ret; |
577 | 641 | ||
578 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); | 642 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); |
@@ -585,26 +649,12 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
585 | ret = platform_get_irq(pdev, 0); | 649 | ret = platform_get_irq(pdev, 0); |
586 | if (unlikely(ret <= 0)) { | 650 | if (unlikely(ret <= 0)) { |
587 | ret = -ENOENT; | 651 | ret = -ENOENT; |
588 | dev_err(&pdev->dev, "No IRQ for period\n"); | 652 | dev_err(&pdev->dev, "No IRQ resource\n"); |
589 | goto err_badres; | 653 | goto err_badres; |
590 | } | 654 | } |
591 | rtc->periodic_irq = ret; | 655 | rtc->periodic_irq = ret; |
592 | 656 | rtc->carry_irq = platform_get_irq(pdev, 1); | |
593 | ret = platform_get_irq(pdev, 1); | 657 | rtc->alarm_irq = platform_get_irq(pdev, 2); |
594 | if (unlikely(ret <= 0)) { | ||
595 | ret = -ENOENT; | ||
596 | dev_err(&pdev->dev, "No IRQ for carry\n"); | ||
597 | goto err_badres; | ||
598 | } | ||
599 | rtc->carry_irq = ret; | ||
600 | |||
601 | ret = platform_get_irq(pdev, 2); | ||
602 | if (unlikely(ret <= 0)) { | ||
603 | ret = -ENOENT; | ||
604 | dev_err(&pdev->dev, "No IRQ for alarm\n"); | ||
605 | goto err_badres; | ||
606 | } | ||
607 | rtc->alarm_irq = ret; | ||
608 | 658 | ||
609 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 659 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
610 | if (unlikely(res == NULL)) { | 660 | if (unlikely(res == NULL)) { |
@@ -646,47 +696,66 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
646 | } | 696 | } |
647 | 697 | ||
648 | rtc->rtc_dev->max_user_freq = 256; | 698 | rtc->rtc_dev->max_user_freq = 256; |
649 | rtc->rtc_dev->irq_freq = 1; | ||
650 | rtc->periodic_freq = 0x60; | ||
651 | 699 | ||
652 | platform_set_drvdata(pdev, rtc); | 700 | platform_set_drvdata(pdev, rtc); |
653 | 701 | ||
654 | /* register periodic/carry/alarm irqs */ | 702 | if (rtc->carry_irq <= 0) { |
655 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, | 703 | /* register shared periodic/carry/alarm irq */ |
656 | "sh-rtc period", rtc); | 704 | ret = request_irq(rtc->periodic_irq, sh_rtc_shared, |
657 | if (unlikely(ret)) { | 705 | IRQF_DISABLED, "sh-rtc", rtc); |
658 | dev_err(&pdev->dev, | 706 | if (unlikely(ret)) { |
659 | "request period IRQ failed with %d, IRQ %d\n", ret, | 707 | dev_err(&pdev->dev, |
660 | rtc->periodic_irq); | 708 | "request IRQ failed with %d, IRQ %d\n", ret, |
661 | goto err_unmap; | 709 | rtc->periodic_irq); |
662 | } | 710 | goto err_unmap; |
711 | } | ||
712 | } else { | ||
713 | /* register periodic/carry/alarm irqs */ | ||
714 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, | ||
715 | IRQF_DISABLED, "sh-rtc period", rtc); | ||
716 | if (unlikely(ret)) { | ||
717 | dev_err(&pdev->dev, | ||
718 | "request period IRQ failed with %d, IRQ %d\n", | ||
719 | ret, rtc->periodic_irq); | ||
720 | goto err_unmap; | ||
721 | } | ||
663 | 722 | ||
664 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, | 723 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, |
665 | "sh-rtc carry", rtc); | 724 | IRQF_DISABLED, "sh-rtc carry", rtc); |
666 | if (unlikely(ret)) { | 725 | if (unlikely(ret)) { |
667 | dev_err(&pdev->dev, | 726 | dev_err(&pdev->dev, |
668 | "request carry IRQ failed with %d, IRQ %d\n", ret, | 727 | "request carry IRQ failed with %d, IRQ %d\n", |
669 | rtc->carry_irq); | 728 | ret, rtc->carry_irq); |
670 | free_irq(rtc->periodic_irq, rtc); | 729 | free_irq(rtc->periodic_irq, rtc); |
671 | goto err_unmap; | 730 | goto err_unmap; |
672 | } | 731 | } |
673 | 732 | ||
674 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED, | 733 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, |
675 | "sh-rtc alarm", rtc); | 734 | IRQF_DISABLED, "sh-rtc alarm", rtc); |
676 | if (unlikely(ret)) { | 735 | if (unlikely(ret)) { |
677 | dev_err(&pdev->dev, | 736 | dev_err(&pdev->dev, |
678 | "request alarm IRQ failed with %d, IRQ %d\n", ret, | 737 | "request alarm IRQ failed with %d, IRQ %d\n", |
679 | rtc->alarm_irq); | 738 | ret, rtc->alarm_irq); |
680 | free_irq(rtc->carry_irq, rtc); | 739 | free_irq(rtc->carry_irq, rtc); |
681 | free_irq(rtc->periodic_irq, rtc); | 740 | free_irq(rtc->periodic_irq, rtc); |
682 | goto err_unmap; | 741 | goto err_unmap; |
742 | } | ||
683 | } | 743 | } |
684 | 744 | ||
685 | tmp = readb(rtc->regbase + RCR1); | 745 | /* everything disabled by default */ |
686 | tmp &= ~RCR1_CF; | 746 | rtc->periodic_freq = 0; |
687 | tmp |= RCR1_CIE; | 747 | rtc->rtc_dev->irq_freq = 0; |
688 | writeb(tmp, rtc->regbase + RCR1); | 748 | sh_rtc_setpie(&pdev->dev, 0); |
749 | sh_rtc_setaie(&pdev->dev, 0); | ||
750 | sh_rtc_setcie(&pdev->dev, 0); | ||
751 | |||
752 | /* reset rtc to epoch 0 if time is invalid */ | ||
753 | if (rtc_read_time(rtc->rtc_dev, &r) < 0) { | ||
754 | rtc_time_to_tm(0, &r); | ||
755 | rtc_set_time(rtc->rtc_dev, &r); | ||
756 | } | ||
689 | 757 | ||
758 | device_init_wakeup(&pdev->dev, 1); | ||
690 | return 0; | 759 | return 0; |
691 | 760 | ||
692 | err_unmap: | 761 | err_unmap: |
@@ -708,10 +777,13 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev) | |||
708 | 777 | ||
709 | sh_rtc_setpie(&pdev->dev, 0); | 778 | sh_rtc_setpie(&pdev->dev, 0); |
710 | sh_rtc_setaie(&pdev->dev, 0); | 779 | sh_rtc_setaie(&pdev->dev, 0); |
780 | sh_rtc_setcie(&pdev->dev, 0); | ||
711 | 781 | ||
712 | free_irq(rtc->carry_irq, rtc); | ||
713 | free_irq(rtc->periodic_irq, rtc); | 782 | free_irq(rtc->periodic_irq, rtc); |
714 | free_irq(rtc->alarm_irq, rtc); | 783 | if (rtc->carry_irq > 0) { |
784 | free_irq(rtc->carry_irq, rtc); | ||
785 | free_irq(rtc->alarm_irq, rtc); | ||
786 | } | ||
715 | 787 | ||
716 | release_resource(rtc->res); | 788 | release_resource(rtc->res); |
717 | 789 | ||
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c index ad35f76c46b7..a6341e4f9a0f 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl4030.c | |||
@@ -426,7 +426,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) | |||
426 | 426 | ||
427 | ret = request_irq(irq, twl4030_rtc_interrupt, | 427 | ret = request_irq(irq, twl4030_rtc_interrupt, |
428 | IRQF_TRIGGER_RISING, | 428 | IRQF_TRIGGER_RISING, |
429 | rtc->dev.bus_id, rtc); | 429 | dev_name(&rtc->dev), rtc); |
430 | if (ret < 0) { | 430 | if (ret < 0) { |
431 | dev_err(&pdev->dev, "IRQ is not free.\n"); | 431 | dev_err(&pdev->dev, "IRQ is not free.\n"); |
432 | goto out1; | 432 | goto out1; |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 918e6fce2573..b91c1719b075 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -104,8 +104,9 @@ ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const | |||
104 | rc = device_schedule_callback(dev, ccwgroup_ungroup_callback); | 104 | rc = device_schedule_callback(dev, ccwgroup_ungroup_callback); |
105 | out: | 105 | out: |
106 | if (rc) { | 106 | if (rc) { |
107 | /* Release onoff "lock" when ungrouping failed. */ | 107 | if (rc != -EAGAIN) |
108 | atomic_set(&gdev->onoff, 0); | 108 | /* Release onoff "lock" when ungrouping failed. */ |
109 | atomic_set(&gdev->onoff, 0); | ||
109 | return rc; | 110 | return rc; |
110 | } | 111 | } |
111 | return count; | 112 | return count; |
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 0a2f2edafc03..93eca1731b81 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c | |||
@@ -84,8 +84,8 @@ static int chsc_subchannel_probe(struct subchannel *sch) | |||
84 | kfree(private); | 84 | kfree(private); |
85 | } else { | 85 | } else { |
86 | sch->private = private; | 86 | sch->private = private; |
87 | if (sch->dev.uevent_suppress) { | 87 | if (dev_get_uevent_suppress(&sch->dev)) { |
88 | sch->dev.uevent_suppress = 0; | 88 | dev_set_uevent_suppress(&sch->dev, 0); |
89 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 89 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
90 | } | 90 | } |
91 | } | 91 | } |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 8019288bc6de..427d11d88069 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -272,7 +272,7 @@ static int css_register_subchannel(struct subchannel *sch) | |||
272 | * the subchannel driver can decide itself when it wants to inform | 272 | * the subchannel driver can decide itself when it wants to inform |
273 | * userspace of its existence. | 273 | * userspace of its existence. |
274 | */ | 274 | */ |
275 | sch->dev.uevent_suppress = 1; | 275 | dev_set_uevent_suppress(&sch->dev, 1); |
276 | css_update_ssd_info(sch); | 276 | css_update_ssd_info(sch); |
277 | /* make it known to the system */ | 277 | /* make it known to the system */ |
278 | ret = css_sch_device_register(sch); | 278 | ret = css_sch_device_register(sch); |
@@ -287,7 +287,7 @@ static int css_register_subchannel(struct subchannel *sch) | |||
287 | * a fitting driver module may be loaded based on the | 287 | * a fitting driver module may be loaded based on the |
288 | * modalias. | 288 | * modalias. |
289 | */ | 289 | */ |
290 | sch->dev.uevent_suppress = 0; | 290 | dev_set_uevent_suppress(&sch->dev, 0); |
291 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 291 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
292 | } | 292 | } |
293 | return ret; | 293 | return ret; |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 23d5752349b5..e28f8ae53453 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -799,7 +799,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch, | |||
799 | return; | 799 | return; |
800 | other_sch = to_subchannel(cdev->dev.parent); | 800 | other_sch = to_subchannel(cdev->dev.parent); |
801 | /* Note: device_move() changes cdev->dev.parent */ | 801 | /* Note: device_move() changes cdev->dev.parent */ |
802 | ret = device_move(&cdev->dev, &sch->dev); | 802 | ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV); |
803 | if (ret) { | 803 | if (ret) { |
804 | CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed " | 804 | CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed " |
805 | "(ret=%d)!\n", cdev->private->dev_id.ssid, | 805 | "(ret=%d)!\n", cdev->private->dev_id.ssid, |
@@ -830,7 +830,7 @@ static void sch_attach_orphaned_device(struct subchannel *sch, | |||
830 | * Try to move the ccw device to its new subchannel. | 830 | * Try to move the ccw device to its new subchannel. |
831 | * Note: device_move() changes cdev->dev.parent | 831 | * Note: device_move() changes cdev->dev.parent |
832 | */ | 832 | */ |
833 | ret = device_move(&cdev->dev, &sch->dev); | 833 | ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV); |
834 | if (ret) { | 834 | if (ret) { |
835 | CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage " | 835 | CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage " |
836 | "failed (ret=%d)!\n", | 836 | "failed (ret=%d)!\n", |
@@ -897,7 +897,8 @@ void ccw_device_move_to_orphanage(struct work_struct *work) | |||
897 | * ccw device can take its place on the subchannel. | 897 | * ccw device can take its place on the subchannel. |
898 | * Note: device_move() changes cdev->dev.parent | 898 | * Note: device_move() changes cdev->dev.parent |
899 | */ | 899 | */ |
900 | ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev); | 900 | ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev, |
901 | DPM_ORDER_NONE); | ||
901 | if (ret) { | 902 | if (ret) { |
902 | CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed " | 903 | CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed " |
903 | "(ret=%d)!\n", cdev->private->dev_id.ssid, | 904 | "(ret=%d)!\n", cdev->private->dev_id.ssid, |
@@ -981,7 +982,7 @@ io_subchannel_register(struct work_struct *work) | |||
981 | * Now we know this subchannel will stay, we can throw | 982 | * Now we know this subchannel will stay, we can throw |
982 | * our delayed uevent. | 983 | * our delayed uevent. |
983 | */ | 984 | */ |
984 | sch->dev.uevent_suppress = 0; | 985 | dev_set_uevent_suppress(&sch->dev, 0); |
985 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 986 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
986 | /* make it known to the system */ | 987 | /* make it known to the system */ |
987 | ret = ccw_device_register(cdev); | 988 | ret = ccw_device_register(cdev); |
@@ -1129,7 +1130,7 @@ static void ccw_device_move_to_sch(struct work_struct *work) | |||
1129 | * Try to move the ccw device to its new subchannel. | 1130 | * Try to move the ccw device to its new subchannel. |
1130 | * Note: device_move() changes cdev->dev.parent | 1131 | * Note: device_move() changes cdev->dev.parent |
1131 | */ | 1132 | */ |
1132 | rc = device_move(&cdev->dev, &sch->dev); | 1133 | rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV); |
1133 | mutex_unlock(&sch->reg_mutex); | 1134 | mutex_unlock(&sch->reg_mutex); |
1134 | if (rc) { | 1135 | if (rc) { |
1135 | CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel " | 1136 | CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel " |
@@ -1243,7 +1244,7 @@ static int io_subchannel_probe(struct subchannel *sch) | |||
1243 | * the ccw_device and exit. This happens for all early | 1244 | * the ccw_device and exit. This happens for all early |
1244 | * devices, e.g. the console. | 1245 | * devices, e.g. the console. |
1245 | */ | 1246 | */ |
1246 | sch->dev.uevent_suppress = 0; | 1247 | dev_set_uevent_suppress(&sch->dev, 0); |
1247 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 1248 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
1248 | cdev->dev.groups = ccwdev_attr_groups; | 1249 | cdev->dev.groups = ccwdev_attr_groups; |
1249 | device_initialize(&cdev->dev); | 1250 | device_initialize(&cdev->dev); |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 3d04920b9bb9..0dcc036d34aa 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -1038,7 +1038,7 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card) | |||
1038 | rc = qeth_query_setadapterparms(card); | 1038 | rc = qeth_query_setadapterparms(card); |
1039 | if (rc) { | 1039 | if (rc) { |
1040 | QETH_DBF_MESSAGE(2, "%s couldn't set adapter parameters: " | 1040 | QETH_DBF_MESSAGE(2, "%s couldn't set adapter parameters: " |
1041 | "0x%x\n", card->gdev->dev.bus_id, rc); | 1041 | "0x%x\n", dev_name(&card->gdev->dev), rc); |
1042 | return rc; | 1042 | return rc; |
1043 | } | 1043 | } |
1044 | if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) { | 1044 | if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) { |
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index d4bda2017746..61af3d91ac8a 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c | |||
@@ -35,7 +35,7 @@ static struct platform_device *a4000t_scsi_device; | |||
35 | 35 | ||
36 | #define A4000T_SCSI_ADDR 0xdd0040 | 36 | #define A4000T_SCSI_ADDR 0xdd0040 |
37 | 37 | ||
38 | static int __devinit a4000t_probe(struct device *dev) | 38 | static int __devinit a4000t_probe(struct platform_device *dev) |
39 | { | 39 | { |
40 | struct Scsi_Host *host; | 40 | struct Scsi_Host *host; |
41 | struct NCR_700_Host_Parameters *hostdata; | 41 | struct NCR_700_Host_Parameters *hostdata; |
@@ -61,7 +61,8 @@ static int __devinit a4000t_probe(struct device *dev) | |||
61 | hostdata->dcntl_extra = EA_710; | 61 | hostdata->dcntl_extra = EA_710; |
62 | 62 | ||
63 | /* and register the chip */ | 63 | /* and register the chip */ |
64 | host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata, dev); | 64 | host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata, |
65 | &dev->dev); | ||
65 | if (!host) { | 66 | if (!host) { |
66 | printk(KERN_ERR "a4000t-scsi: No host detected; " | 67 | printk(KERN_ERR "a4000t-scsi: No host detected; " |
67 | "board configuration problem?\n"); | 68 | "board configuration problem?\n"); |
@@ -78,7 +79,7 @@ static int __devinit a4000t_probe(struct device *dev) | |||
78 | goto out_put_host; | 79 | goto out_put_host; |
79 | } | 80 | } |
80 | 81 | ||
81 | dev_set_drvdata(dev, host); | 82 | platform_set_drvdata(dev, host); |
82 | scsi_scan_host(host); | 83 | scsi_scan_host(host); |
83 | 84 | ||
84 | return 0; | 85 | return 0; |
@@ -93,9 +94,9 @@ static int __devinit a4000t_probe(struct device *dev) | |||
93 | return -ENODEV; | 94 | return -ENODEV; |
94 | } | 95 | } |
95 | 96 | ||
96 | static __devexit int a4000t_device_remove(struct device *dev) | 97 | static __devexit int a4000t_device_remove(struct platform_device *dev) |
97 | { | 98 | { |
98 | struct Scsi_Host *host = dev_get_drvdata(dev); | 99 | struct Scsi_Host *host = platform_get_drvdata(dev); |
99 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); | 100 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); |
100 | 101 | ||
101 | scsi_remove_host(host); | 102 | scsi_remove_host(host); |
@@ -108,25 +109,27 @@ static __devexit int a4000t_device_remove(struct device *dev) | |||
108 | return 0; | 109 | return 0; |
109 | } | 110 | } |
110 | 111 | ||
111 | static struct device_driver a4000t_scsi_driver = { | 112 | static struct platform_driver a4000t_scsi_driver = { |
112 | .name = "a4000t-scsi", | 113 | .driver = { |
113 | .bus = &platform_bus_type, | 114 | .name = "a4000t-scsi", |
114 | .probe = a4000t_probe, | 115 | .owner = THIS_MODULE, |
115 | .remove = __devexit_p(a4000t_device_remove), | 116 | }, |
117 | .probe = a4000t_probe, | ||
118 | .remove = __devexit_p(a4000t_device_remove), | ||
116 | }; | 119 | }; |
117 | 120 | ||
118 | static int __init a4000t_scsi_init(void) | 121 | static int __init a4000t_scsi_init(void) |
119 | { | 122 | { |
120 | int err; | 123 | int err; |
121 | 124 | ||
122 | err = driver_register(&a4000t_scsi_driver); | 125 | err = platform_driver_register(&a4000t_scsi_driver); |
123 | if (err) | 126 | if (err) |
124 | return err; | 127 | return err; |
125 | 128 | ||
126 | a4000t_scsi_device = platform_device_register_simple("a4000t-scsi", | 129 | a4000t_scsi_device = platform_device_register_simple("a4000t-scsi", |
127 | -1, NULL, 0); | 130 | -1, NULL, 0); |
128 | if (IS_ERR(a4000t_scsi_device)) { | 131 | if (IS_ERR(a4000t_scsi_device)) { |
129 | driver_unregister(&a4000t_scsi_driver); | 132 | platform_driver_register(&a4000t_scsi_driver); |
130 | return PTR_ERR(a4000t_scsi_device); | 133 | return PTR_ERR(a4000t_scsi_device); |
131 | } | 134 | } |
132 | 135 | ||
@@ -136,7 +139,7 @@ static int __init a4000t_scsi_init(void) | |||
136 | static void __exit a4000t_scsi_exit(void) | 139 | static void __exit a4000t_scsi_exit(void) |
137 | { | 140 | { |
138 | platform_device_unregister(a4000t_scsi_device); | 141 | platform_device_unregister(a4000t_scsi_device); |
139 | driver_unregister(&a4000t_scsi_driver); | 142 | platform_driver_unregister(&a4000t_scsi_driver); |
140 | } | 143 | } |
141 | 144 | ||
142 | module_init(a4000t_scsi_init); | 145 | module_init(a4000t_scsi_init); |
diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c index d858f3d41274..5799cb5cba6b 100644 --- a/drivers/scsi/bvme6000_scsi.c +++ b/drivers/scsi/bvme6000_scsi.c | |||
@@ -34,7 +34,7 @@ static struct scsi_host_template bvme6000_scsi_driver_template = { | |||
34 | static struct platform_device *bvme6000_scsi_device; | 34 | static struct platform_device *bvme6000_scsi_device; |
35 | 35 | ||
36 | static __devinit int | 36 | static __devinit int |
37 | bvme6000_probe(struct device *dev) | 37 | bvme6000_probe(struct platform_device *dev) |
38 | { | 38 | { |
39 | struct Scsi_Host *host; | 39 | struct Scsi_Host *host; |
40 | struct NCR_700_Host_Parameters *hostdata; | 40 | struct NCR_700_Host_Parameters *hostdata; |
@@ -58,7 +58,8 @@ bvme6000_probe(struct device *dev) | |||
58 | hostdata->ctest7_extra = CTEST7_TT1; | 58 | hostdata->ctest7_extra = CTEST7_TT1; |
59 | 59 | ||
60 | /* and register the chip */ | 60 | /* and register the chip */ |
61 | host = NCR_700_detect(&bvme6000_scsi_driver_template, hostdata, dev); | 61 | host = NCR_700_detect(&bvme6000_scsi_driver_template, hostdata, |
62 | &dev->dev); | ||
62 | if (!host) { | 63 | if (!host) { |
63 | printk(KERN_ERR "bvme6000-scsi: No host detected; " | 64 | printk(KERN_ERR "bvme6000-scsi: No host detected; " |
64 | "board configuration problem?\n"); | 65 | "board configuration problem?\n"); |
@@ -73,7 +74,7 @@ bvme6000_probe(struct device *dev) | |||
73 | goto out_put_host; | 74 | goto out_put_host; |
74 | } | 75 | } |
75 | 76 | ||
76 | dev_set_drvdata(dev, host); | 77 | platform_set_drvdata(dev, host); |
77 | scsi_scan_host(host); | 78 | scsi_scan_host(host); |
78 | 79 | ||
79 | return 0; | 80 | return 0; |
@@ -87,9 +88,9 @@ bvme6000_probe(struct device *dev) | |||
87 | } | 88 | } |
88 | 89 | ||
89 | static __devexit int | 90 | static __devexit int |
90 | bvme6000_device_remove(struct device *dev) | 91 | bvme6000_device_remove(struct platform_device *dev) |
91 | { | 92 | { |
92 | struct Scsi_Host *host = dev_get_drvdata(dev); | 93 | struct Scsi_Host *host = platform_get_drvdata(dev); |
93 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); | 94 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); |
94 | 95 | ||
95 | scsi_remove_host(host); | 96 | scsi_remove_host(host); |
@@ -100,25 +101,27 @@ bvme6000_device_remove(struct device *dev) | |||
100 | return 0; | 101 | return 0; |
101 | } | 102 | } |
102 | 103 | ||
103 | static struct device_driver bvme6000_scsi_driver = { | 104 | static struct platform_driver bvme6000_scsi_driver = { |
104 | .name = "bvme6000-scsi", | 105 | .driver = { |
105 | .bus = &platform_bus_type, | 106 | .name = "bvme6000-scsi", |
106 | .probe = bvme6000_probe, | 107 | .owner = THIS_MODULE, |
107 | .remove = __devexit_p(bvme6000_device_remove), | 108 | }, |
109 | .probe = bvme6000_probe, | ||
110 | .remove = __devexit_p(bvme6000_device_remove), | ||
108 | }; | 111 | }; |
109 | 112 | ||
110 | static int __init bvme6000_scsi_init(void) | 113 | static int __init bvme6000_scsi_init(void) |
111 | { | 114 | { |
112 | int err; | 115 | int err; |
113 | 116 | ||
114 | err = driver_register(&bvme6000_scsi_driver); | 117 | err = platform_driver_register(&bvme6000_scsi_driver); |
115 | if (err) | 118 | if (err) |
116 | return err; | 119 | return err; |
117 | 120 | ||
118 | bvme6000_scsi_device = platform_device_register_simple("bvme6000-scsi", | 121 | bvme6000_scsi_device = platform_device_register_simple("bvme6000-scsi", |
119 | -1, NULL, 0); | 122 | -1, NULL, 0); |
120 | if (IS_ERR(bvme6000_scsi_device)) { | 123 | if (IS_ERR(bvme6000_scsi_device)) { |
121 | driver_unregister(&bvme6000_scsi_driver); | 124 | platform_driver_unregister(&bvme6000_scsi_driver); |
122 | return PTR_ERR(bvme6000_scsi_device); | 125 | return PTR_ERR(bvme6000_scsi_device); |
123 | } | 126 | } |
124 | 127 | ||
@@ -128,7 +131,7 @@ static int __init bvme6000_scsi_init(void) | |||
128 | static void __exit bvme6000_scsi_exit(void) | 131 | static void __exit bvme6000_scsi_exit(void) |
129 | { | 132 | { |
130 | platform_device_unregister(bvme6000_scsi_device); | 133 | platform_device_unregister(bvme6000_scsi_device); |
131 | driver_unregister(&bvme6000_scsi_driver); | 134 | platform_driver_unregister(&bvme6000_scsi_driver); |
132 | } | 135 | } |
133 | 136 | ||
134 | module_init(bvme6000_scsi_init); | 137 | module_init(bvme6000_scsi_init); |
diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c index b264b499d982..b5fbfd6ce870 100644 --- a/drivers/scsi/mvme16x_scsi.c +++ b/drivers/scsi/mvme16x_scsi.c | |||
@@ -34,7 +34,7 @@ static struct scsi_host_template mvme16x_scsi_driver_template = { | |||
34 | static struct platform_device *mvme16x_scsi_device; | 34 | static struct platform_device *mvme16x_scsi_device; |
35 | 35 | ||
36 | static __devinit int | 36 | static __devinit int |
37 | mvme16x_probe(struct device *dev) | 37 | mvme16x_probe(struct platform_device *dev) |
38 | { | 38 | { |
39 | struct Scsi_Host * host = NULL; | 39 | struct Scsi_Host * host = NULL; |
40 | struct NCR_700_Host_Parameters *hostdata; | 40 | struct NCR_700_Host_Parameters *hostdata; |
@@ -64,7 +64,8 @@ mvme16x_probe(struct device *dev) | |||
64 | hostdata->ctest7_extra = CTEST7_TT1; | 64 | hostdata->ctest7_extra = CTEST7_TT1; |
65 | 65 | ||
66 | /* and register the chip */ | 66 | /* and register the chip */ |
67 | host = NCR_700_detect(&mvme16x_scsi_driver_template, hostdata, dev); | 67 | host = NCR_700_detect(&mvme16x_scsi_driver_template, hostdata, |
68 | &dev->dev); | ||
68 | if (!host) { | 69 | if (!host) { |
69 | printk(KERN_ERR "mvme16x-scsi: No host detected; " | 70 | printk(KERN_ERR "mvme16x-scsi: No host detected; " |
70 | "board configuration problem?\n"); | 71 | "board configuration problem?\n"); |
@@ -88,7 +89,7 @@ mvme16x_probe(struct device *dev) | |||
88 | out_be32(0xfff4202c, v); | 89 | out_be32(0xfff4202c, v); |
89 | } | 90 | } |
90 | 91 | ||
91 | dev_set_drvdata(dev, host); | 92 | platform_set_drvdata(dev, host); |
92 | scsi_scan_host(host); | 93 | scsi_scan_host(host); |
93 | 94 | ||
94 | return 0; | 95 | return 0; |
@@ -102,9 +103,9 @@ mvme16x_probe(struct device *dev) | |||
102 | } | 103 | } |
103 | 104 | ||
104 | static __devexit int | 105 | static __devexit int |
105 | mvme16x_device_remove(struct device *dev) | 106 | mvme16x_device_remove(struct platform_device *dev) |
106 | { | 107 | { |
107 | struct Scsi_Host *host = dev_get_drvdata(dev); | 108 | struct Scsi_Host *host = platform_get_drvdata(dev); |
108 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); | 109 | struct NCR_700_Host_Parameters *hostdata = shost_priv(host); |
109 | 110 | ||
110 | /* Disable scsi chip ints */ | 111 | /* Disable scsi chip ints */ |
@@ -123,25 +124,27 @@ mvme16x_device_remove(struct device *dev) | |||
123 | return 0; | 124 | return 0; |
124 | } | 125 | } |
125 | 126 | ||
126 | static struct device_driver mvme16x_scsi_driver = { | 127 | static struct platform_driver mvme16x_scsi_driver = { |
127 | .name = "mvme16x-scsi", | 128 | .driver = { |
128 | .bus = &platform_bus_type, | 129 | .name = "mvme16x-scsi", |
129 | .probe = mvme16x_probe, | 130 | .owner = THIS_MODULE, |
130 | .remove = __devexit_p(mvme16x_device_remove), | 131 | }, |
132 | .probe = mvme16x_probe, | ||
133 | .remove = __devexit_p(mvme16x_device_remove), | ||
131 | }; | 134 | }; |
132 | 135 | ||
133 | static int __init mvme16x_scsi_init(void) | 136 | static int __init mvme16x_scsi_init(void) |
134 | { | 137 | { |
135 | int err; | 138 | int err; |
136 | 139 | ||
137 | err = driver_register(&mvme16x_scsi_driver); | 140 | err = platform_driver_register(&mvme16x_scsi_driver); |
138 | if (err) | 141 | if (err) |
139 | return err; | 142 | return err; |
140 | 143 | ||
141 | mvme16x_scsi_device = platform_device_register_simple("mvme16x-scsi", | 144 | mvme16x_scsi_device = platform_device_register_simple("mvme16x-scsi", |
142 | -1, NULL, 0); | 145 | -1, NULL, 0); |
143 | if (IS_ERR(mvme16x_scsi_device)) { | 146 | if (IS_ERR(mvme16x_scsi_device)) { |
144 | driver_unregister(&mvme16x_scsi_driver); | 147 | platform_driver_unregister(&mvme16x_scsi_driver); |
145 | return PTR_ERR(mvme16x_scsi_device); | 148 | return PTR_ERR(mvme16x_scsi_device); |
146 | } | 149 | } |
147 | 150 | ||
@@ -151,7 +154,7 @@ static int __init mvme16x_scsi_init(void) | |||
151 | static void __exit mvme16x_scsi_exit(void) | 154 | static void __exit mvme16x_scsi_exit(void) |
152 | { | 155 | { |
153 | platform_device_unregister(mvme16x_scsi_device); | 156 | platform_device_unregister(mvme16x_scsi_device); |
154 | driver_unregister(&mvme16x_scsi_driver); | 157 | platform_driver_unregister(&mvme16x_scsi_driver); |
155 | } | 158 | } |
156 | 159 | ||
157 | module_init(mvme16x_scsi_init); | 160 | module_init(mvme16x_scsi_init); |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 557b54ab2f25..dbf5357a77b3 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -139,7 +139,7 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c) | |||
139 | } while (!(status & SCxSR_TDxE(port))); | 139 | } while (!(status & SCxSR_TDxE(port))); |
140 | 140 | ||
141 | sci_in(port, SCxSR); /* Dummy read */ | 141 | sci_in(port, SCxSR); /* Dummy read */ |
142 | sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); | 142 | sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port)); |
143 | sci_out(port, SCxTDR, c); | 143 | sci_out(port, SCxTDR, c); |
144 | } | 144 | } |
145 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ | 145 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ |
@@ -263,6 +263,7 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
263 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | 263 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
264 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 264 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
265 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 265 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
266 | defined(CONFIG_CPU_SUBTYPE_SH7786) || \ | ||
266 | defined(CONFIG_CPU_SUBTYPE_SHX3) | 267 | defined(CONFIG_CPU_SUBTYPE_SHX3) |
267 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | 268 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) |
268 | { | 269 | { |
@@ -284,7 +285,8 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
284 | 285 | ||
285 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ | 286 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ |
286 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 287 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
287 | defined(CONFIG_CPU_SUBTYPE_SH7785) | 288 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
289 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
288 | static inline int scif_txroom(struct uart_port *port) | 290 | static inline int scif_txroom(struct uart_port *port) |
289 | { | 291 | { |
290 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); | 292 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); |
@@ -1095,6 +1097,7 @@ static void serial_console_write(struct console *co, const char *s, | |||
1095 | unsigned count) | 1097 | unsigned count) |
1096 | { | 1098 | { |
1097 | struct uart_port *port = &serial_console_port->port; | 1099 | struct uart_port *port = &serial_console_port->port; |
1100 | unsigned short bits; | ||
1098 | int i; | 1101 | int i; |
1099 | 1102 | ||
1100 | for (i = 0; i < count; i++) { | 1103 | for (i = 0; i < count; i++) { |
@@ -1103,6 +1106,11 @@ static void serial_console_write(struct console *co, const char *s, | |||
1103 | 1106 | ||
1104 | sci_poll_put_char(port, *s++); | 1107 | sci_poll_put_char(port, *s++); |
1105 | } | 1108 | } |
1109 | |||
1110 | /* wait until fifo is empty and last bit has been transmitted */ | ||
1111 | bits = SCxSR_TDxE(port) | SCxSR_TEND(port); | ||
1112 | while ((sci_in(port, SCxSR) & bits) != bits) | ||
1113 | cpu_relax(); | ||
1106 | } | 1114 | } |
1107 | 1115 | ||
1108 | static int __init serial_console_setup(struct console *co, char *options) | 1116 | static int __init serial_console_setup(struct console *co, char *options) |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 022e89ffec1d..d0aa82d7fce0 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -1,6 +1,6 @@ | |||
1 | #include <linux/serial_core.h> | 1 | #include <linux/serial_core.h> |
2 | #include <asm/io.h> | 2 | #include <asm/io.h> |
3 | #include <asm/gpio.h> | 3 | #include <linux/gpio.h> |
4 | 4 | ||
5 | #if defined(CONFIG_H83007) || defined(CONFIG_H83068) | 5 | #if defined(CONFIG_H83007) || defined(CONFIG_H83068) |
6 | #include <asm/regs306x.h> | 6 | #include <asm/regs306x.h> |
@@ -126,7 +126,8 @@ | |||
126 | # define SCSPTR1 0xffe10024 /* 16 bit SCIF */ | 126 | # define SCSPTR1 0xffe10024 /* 16 bit SCIF */ |
127 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | 127 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
128 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 128 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
129 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) | 129 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
130 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
130 | # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ | 131 | # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ |
131 | # define SCSPTR1 0xffeb0024 /* 16 bit SCIF */ | 132 | # define SCSPTR1 0xffeb0024 /* 16 bit SCIF */ |
132 | # define SCSPTR2 0xffec0024 /* 16 bit SCIF */ | 133 | # define SCSPTR2 0xffec0024 /* 16 bit SCIF */ |
@@ -182,6 +183,7 @@ | |||
182 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | 183 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
183 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 184 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
184 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 185 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
186 | defined(CONFIG_CPU_SUBTYPE_SH7786) || \ | ||
185 | defined(CONFIG_CPU_SUBTYPE_SHX3) | 187 | defined(CONFIG_CPU_SUBTYPE_SHX3) |
186 | #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ | 188 | #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ |
187 | #else | 189 | #else |
@@ -413,7 +415,8 @@ SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) | |||
413 | SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) | 415 | SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) |
414 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ | 416 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ |
415 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 417 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
416 | defined(CONFIG_CPU_SUBTYPE_SH7785) | 418 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
419 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
417 | SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) | 420 | SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) |
418 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) | 421 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) |
419 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) | 422 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) |
@@ -644,7 +647,8 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
644 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 647 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
645 | return 1; | 648 | return 1; |
646 | } | 649 | } |
647 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) | 650 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
651 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
648 | static inline int sci_rxd_in(struct uart_port *port) | 652 | static inline int sci_rxd_in(struct uart_port *port) |
649 | { | 653 | { |
650 | if (port->mapbase == 0xffea0000) | 654 | if (port->mapbase == 0xffea0000) |
@@ -746,7 +750,8 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
746 | */ | 750 | */ |
747 | 751 | ||
748 | #if defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 752 | #if defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
749 | defined(CONFIG_CPU_SUBTYPE_SH7785) | 753 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
754 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
750 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) | 755 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) |
751 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 756 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
752 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 757 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 45a299f35617..e09d3cebb4fb 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1438,12 +1438,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1438 | } else { | 1438 | } else { |
1439 | printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) " | 1439 | printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) " |
1440 | "is a %s\n", | 1440 | "is a %s\n", |
1441 | op->dev.bus_id, | 1441 | dev_name(&op->dev), |
1442 | (unsigned long long) up[0].port.mapbase, | 1442 | (unsigned long long) up[0].port.mapbase, |
1443 | op->irqs[0], sunzilog_type(&up[0].port)); | 1443 | op->irqs[0], sunzilog_type(&up[0].port)); |
1444 | printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) " | 1444 | printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) " |
1445 | "is a %s\n", | 1445 | "is a %s\n", |
1446 | op->dev.bus_id, | 1446 | dev_name(&op->dev), |
1447 | (unsigned long long) up[1].port.mapbase, | 1447 | (unsigned long long) up[1].port.mapbase, |
1448 | op->irqs[0], sunzilog_type(&up[1].port)); | 1448 | op->irqs[0], sunzilog_type(&up[1].port)); |
1449 | kbm_inst++; | 1449 | kbm_inst++; |
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index 58d24c5a76ce..2269fbcaa182 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c | |||
@@ -568,6 +568,10 @@ static void __init intc_register_irq(struct intc_desc *desc, | |||
568 | if (!data[0] && data[1]) | 568 | if (!data[0] && data[1]) |
569 | primary = 1; | 569 | primary = 1; |
570 | 570 | ||
571 | if (!data[0] && !data[1]) | ||
572 | pr_warning("intc: missing unique irq mask for " | ||
573 | "irq %d (vect 0x%04x)\n", irq, irq2evt(irq)); | ||
574 | |||
571 | data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); | 575 | data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); |
572 | data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); | 576 | data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); |
573 | 577 | ||
@@ -641,6 +645,17 @@ static unsigned int __init save_reg(struct intc_desc_int *d, | |||
641 | return 0; | 645 | return 0; |
642 | } | 646 | } |
643 | 647 | ||
648 | static unsigned char *intc_evt2irq_table; | ||
649 | |||
650 | unsigned int intc_evt2irq(unsigned int vector) | ||
651 | { | ||
652 | unsigned int irq = evt2irq(vector); | ||
653 | |||
654 | if (intc_evt2irq_table && intc_evt2irq_table[irq]) | ||
655 | irq = intc_evt2irq_table[irq]; | ||
656 | |||
657 | return irq; | ||
658 | } | ||
644 | 659 | ||
645 | void __init register_intc_controller(struct intc_desc *desc) | 660 | void __init register_intc_controller(struct intc_desc *desc) |
646 | { | 661 | { |
@@ -705,9 +720,41 @@ void __init register_intc_controller(struct intc_desc *desc) | |||
705 | 720 | ||
706 | BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ | 721 | BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ |
707 | 722 | ||
723 | /* keep the first vector only if same enum is used multiple times */ | ||
724 | for (i = 0; i < desc->nr_vectors; i++) { | ||
725 | struct intc_vect *vect = desc->vectors + i; | ||
726 | int first_irq = evt2irq(vect->vect); | ||
727 | |||
728 | if (!vect->enum_id) | ||
729 | continue; | ||
730 | |||
731 | for (k = i + 1; k < desc->nr_vectors; k++) { | ||
732 | struct intc_vect *vect2 = desc->vectors + k; | ||
733 | |||
734 | if (vect->enum_id != vect2->enum_id) | ||
735 | continue; | ||
736 | |||
737 | vect2->enum_id = 0; | ||
738 | |||
739 | if (!intc_evt2irq_table) | ||
740 | intc_evt2irq_table = alloc_bootmem(NR_IRQS); | ||
741 | |||
742 | if (!intc_evt2irq_table) { | ||
743 | pr_warning("intc: cannot allocate evt2irq!\n"); | ||
744 | continue; | ||
745 | } | ||
746 | |||
747 | intc_evt2irq_table[evt2irq(vect2->vect)] = first_irq; | ||
748 | } | ||
749 | } | ||
750 | |||
751 | /* register the vectors one by one */ | ||
708 | for (i = 0; i < desc->nr_vectors; i++) { | 752 | for (i = 0; i < desc->nr_vectors; i++) { |
709 | struct intc_vect *vect = desc->vectors + i; | 753 | struct intc_vect *vect = desc->vectors + i; |
710 | 754 | ||
755 | if (!vect->enum_id) | ||
756 | continue; | ||
757 | |||
711 | intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); | 758 | intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); |
712 | } | 759 | } |
713 | } | 760 | } |
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index 63f0de29aa14..cab1ab7cfb78 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c | |||
@@ -1,16 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * Core maple bus functionality | 2 | * Core maple bus functionality |
3 | * | 3 | * |
4 | * Copyright (C) 2007, 2008 Adrian McMenamin | 4 | * Copyright (C) 2007 - 2009 Adrian McMenamin |
5 | * Copyright (C) 2001 - 2008 Paul Mundt | 5 | * Copyright (C) 2001 - 2008 Paul Mundt |
6 | * | 6 | * Copyright (C) 2000 - 2001 YAEGASHI Takeshi |
7 | * Based on 2.4 code by: | ||
8 | * | ||
9 | * Copyright (C) 2000-2001 YAEGASHI Takeshi | ||
10 | * Copyright (C) 2001 M. R. Brown | 7 | * Copyright (C) 2001 M. R. Brown |
11 | * Copyright (C) 2001 Paul Mundt | ||
12 | * | ||
13 | * and others. | ||
14 | * | 8 | * |
15 | * This file is subject to the terms and conditions of the GNU General Public | 9 | * This file is subject to the terms and conditions of the GNU General Public |
16 | * License. See the file "COPYING" in the main directory of this archive | 10 | * License. See the file "COPYING" in the main directory of this archive |
@@ -32,7 +26,7 @@ | |||
32 | #include <mach/dma.h> | 26 | #include <mach/dma.h> |
33 | #include <mach/sysasic.h> | 27 | #include <mach/sysasic.h> |
34 | 28 | ||
35 | MODULE_AUTHOR("Yaegashi Takeshi, Paul Mundt, M. R. Brown, Adrian McMenamin"); | 29 | MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>"); |
36 | MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); | 30 | MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); |
37 | MODULE_LICENSE("GPL v2"); | 31 | MODULE_LICENSE("GPL v2"); |
38 | MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}"); | 32 | MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}"); |
@@ -49,7 +43,7 @@ static LIST_HEAD(maple_sentq); | |||
49 | /* mutex to protect queue of waiting packets */ | 43 | /* mutex to protect queue of waiting packets */ |
50 | static DEFINE_MUTEX(maple_wlist_lock); | 44 | static DEFINE_MUTEX(maple_wlist_lock); |
51 | 45 | ||
52 | static struct maple_driver maple_dummy_driver; | 46 | static struct maple_driver maple_unsupported_device; |
53 | static struct device maple_bus; | 47 | static struct device maple_bus; |
54 | static int subdevice_map[MAPLE_PORTS]; | 48 | static int subdevice_map[MAPLE_PORTS]; |
55 | static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; | 49 | static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; |
@@ -62,8 +56,9 @@ struct maple_device_specify { | |||
62 | int unit; | 56 | int unit; |
63 | }; | 57 | }; |
64 | 58 | ||
65 | static bool checked[4]; | 59 | static bool checked[MAPLE_PORTS]; |
66 | static struct maple_device *baseunits[4]; | 60 | static bool empty[MAPLE_PORTS]; |
61 | static struct maple_device *baseunits[MAPLE_PORTS]; | ||
67 | 62 | ||
68 | /** | 63 | /** |
69 | * maple_driver_register - register a maple driver | 64 | * maple_driver_register - register a maple driver |
@@ -97,12 +92,20 @@ void maple_driver_unregister(struct maple_driver *drv) | |||
97 | EXPORT_SYMBOL_GPL(maple_driver_unregister); | 92 | EXPORT_SYMBOL_GPL(maple_driver_unregister); |
98 | 93 | ||
99 | /* set hardware registers to enable next round of dma */ | 94 | /* set hardware registers to enable next round of dma */ |
100 | static void maplebus_dma_reset(void) | 95 | static void maple_dma_reset(void) |
101 | { | 96 | { |
102 | ctrl_outl(MAPLE_MAGIC, MAPLE_RESET); | 97 | ctrl_outl(MAPLE_MAGIC, MAPLE_RESET); |
103 | /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */ | 98 | /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */ |
104 | ctrl_outl(1, MAPLE_TRIGTYPE); | 99 | ctrl_outl(1, MAPLE_TRIGTYPE); |
105 | ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(50000), MAPLE_SPEED); | 100 | /* |
101 | * Maple system register | ||
102 | * bits 31 - 16 timeout in units of 20nsec | ||
103 | * bit 12 hard trigger - set 0 to keep responding to VBLANK | ||
104 | * bits 9 - 8 set 00 for 2 Mbps, 01 for 1 Mbps | ||
105 | * bits 3 - 0 delay (in 1.3ms) between VBLANK and start of DMA | ||
106 | * max delay is 11 | ||
107 | */ | ||
108 | ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(0xFFFF), MAPLE_SPEED); | ||
106 | ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); | 109 | ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); |
107 | ctrl_outl(1, MAPLE_ENABLE); | 110 | ctrl_outl(1, MAPLE_ENABLE); |
108 | } | 111 | } |
@@ -134,21 +137,16 @@ static void maple_release_device(struct device *dev) | |||
134 | { | 137 | { |
135 | struct maple_device *mdev; | 138 | struct maple_device *mdev; |
136 | struct mapleq *mq; | 139 | struct mapleq *mq; |
137 | if (!dev) | 140 | |
138 | return; | ||
139 | mdev = to_maple_dev(dev); | 141 | mdev = to_maple_dev(dev); |
140 | mq = mdev->mq; | 142 | mq = mdev->mq; |
141 | if (mq) { | 143 | kmem_cache_free(maple_queue_cache, mq->recvbuf); |
142 | if (mq->recvbufdcsp) | 144 | kfree(mq); |
143 | kmem_cache_free(maple_queue_cache, mq->recvbufdcsp); | ||
144 | kfree(mq); | ||
145 | mq = NULL; | ||
146 | } | ||
147 | kfree(mdev); | 145 | kfree(mdev); |
148 | } | 146 | } |
149 | 147 | ||
150 | /** | 148 | /** |
151 | * maple_add_packet - add a single instruction to the queue | 149 | * maple_add_packet - add a single instruction to the maple bus queue |
152 | * @mdev: maple device | 150 | * @mdev: maple device |
153 | * @function: function on device being queried | 151 | * @function: function on device being queried |
154 | * @command: maple command to add | 152 | * @command: maple command to add |
@@ -158,68 +156,12 @@ static void maple_release_device(struct device *dev) | |||
158 | int maple_add_packet(struct maple_device *mdev, u32 function, u32 command, | 156 | int maple_add_packet(struct maple_device *mdev, u32 function, u32 command, |
159 | size_t length, void *data) | 157 | size_t length, void *data) |
160 | { | 158 | { |
161 | int locking, ret = 0; | 159 | int ret = 0; |
162 | void *sendbuf = NULL; | 160 | void *sendbuf = NULL; |
163 | 161 | ||
164 | mutex_lock(&maple_wlist_lock); | ||
165 | /* bounce if device already locked */ | ||
166 | locking = mutex_is_locked(&mdev->mq->mutex); | ||
167 | if (locking) { | ||
168 | ret = -EBUSY; | ||
169 | goto out; | ||
170 | } | ||
171 | |||
172 | mutex_lock(&mdev->mq->mutex); | ||
173 | |||
174 | if (length) { | 162 | if (length) { |
175 | sendbuf = kmalloc(length * 4, GFP_KERNEL); | 163 | sendbuf = kzalloc(length * 4, GFP_KERNEL); |
176 | if (!sendbuf) { | 164 | if (!sendbuf) { |
177 | mutex_unlock(&mdev->mq->mutex); | ||
178 | ret = -ENOMEM; | ||
179 | goto out; | ||
180 | } | ||
181 | ((__be32 *)sendbuf)[0] = cpu_to_be32(function); | ||
182 | } | ||
183 | |||
184 | mdev->mq->command = command; | ||
185 | mdev->mq->length = length; | ||
186 | if (length > 1) | ||
187 | memcpy(sendbuf + 4, data, (length - 1) * 4); | ||
188 | mdev->mq->sendbuf = sendbuf; | ||
189 | |||
190 | list_add(&mdev->mq->list, &maple_waitq); | ||
191 | out: | ||
192 | mutex_unlock(&maple_wlist_lock); | ||
193 | return ret; | ||
194 | } | ||
195 | EXPORT_SYMBOL_GPL(maple_add_packet); | ||
196 | |||
197 | /** | ||
198 | * maple_add_packet_sleeps - add a single instruction to the queue | ||
199 | * @mdev: maple device | ||
200 | * @function: function on device being queried | ||
201 | * @command: maple command to add | ||
202 | * @length: length of command string (in 32 bit words) | ||
203 | * @data: remainder of command string | ||
204 | * | ||
205 | * Same as maple_add_packet(), but waits for the lock to become free. | ||
206 | */ | ||
207 | int maple_add_packet_sleeps(struct maple_device *mdev, u32 function, | ||
208 | u32 command, size_t length, void *data) | ||
209 | { | ||
210 | int locking, ret = 0; | ||
211 | void *sendbuf = NULL; | ||
212 | |||
213 | locking = mutex_lock_interruptible(&mdev->mq->mutex); | ||
214 | if (locking) { | ||
215 | ret = -EIO; | ||
216 | goto out; | ||
217 | } | ||
218 | |||
219 | if (length) { | ||
220 | sendbuf = kmalloc(length * 4, GFP_KERNEL); | ||
221 | if (!sendbuf) { | ||
222 | mutex_unlock(&mdev->mq->mutex); | ||
223 | ret = -ENOMEM; | 165 | ret = -ENOMEM; |
224 | goto out; | 166 | goto out; |
225 | } | 167 | } |
@@ -233,38 +175,35 @@ int maple_add_packet_sleeps(struct maple_device *mdev, u32 function, | |||
233 | mdev->mq->sendbuf = sendbuf; | 175 | mdev->mq->sendbuf = sendbuf; |
234 | 176 | ||
235 | mutex_lock(&maple_wlist_lock); | 177 | mutex_lock(&maple_wlist_lock); |
236 | list_add(&mdev->mq->list, &maple_waitq); | 178 | list_add_tail(&mdev->mq->list, &maple_waitq); |
237 | mutex_unlock(&maple_wlist_lock); | 179 | mutex_unlock(&maple_wlist_lock); |
238 | out: | 180 | out: |
239 | return ret; | 181 | return ret; |
240 | } | 182 | } |
241 | EXPORT_SYMBOL_GPL(maple_add_packet_sleeps); | 183 | EXPORT_SYMBOL_GPL(maple_add_packet); |
242 | 184 | ||
243 | static struct mapleq *maple_allocq(struct maple_device *mdev) | 185 | static struct mapleq *maple_allocq(struct maple_device *mdev) |
244 | { | 186 | { |
245 | struct mapleq *mq; | 187 | struct mapleq *mq; |
246 | 188 | ||
247 | mq = kmalloc(sizeof(*mq), GFP_KERNEL); | 189 | mq = kzalloc(sizeof(*mq), GFP_KERNEL); |
248 | if (!mq) | 190 | if (!mq) |
249 | goto failed_nomem; | 191 | goto failed_nomem; |
250 | 192 | ||
193 | INIT_LIST_HEAD(&mq->list); | ||
251 | mq->dev = mdev; | 194 | mq->dev = mdev; |
252 | mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL); | 195 | mq->recvbuf = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL); |
253 | mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp); | ||
254 | if (!mq->recvbuf) | 196 | if (!mq->recvbuf) |
255 | goto failed_p2; | 197 | goto failed_p2; |
256 | /* | 198 | mq->recvbuf->buf = &((mq->recvbuf->bufx)[0]); |
257 | * most devices do not need the mutex - but | ||
258 | * anything that injects block reads or writes | ||
259 | * will rely on it | ||
260 | */ | ||
261 | mutex_init(&mq->mutex); | ||
262 | 199 | ||
263 | return mq; | 200 | return mq; |
264 | 201 | ||
265 | failed_p2: | 202 | failed_p2: |
266 | kfree(mq); | 203 | kfree(mq); |
267 | failed_nomem: | 204 | failed_nomem: |
205 | dev_err(&mdev->dev, "could not allocate memory for device (%d, %d)\n", | ||
206 | mdev->port, mdev->unit); | ||
268 | return NULL; | 207 | return NULL; |
269 | } | 208 | } |
270 | 209 | ||
@@ -272,12 +211,16 @@ static struct maple_device *maple_alloc_dev(int port, int unit) | |||
272 | { | 211 | { |
273 | struct maple_device *mdev; | 212 | struct maple_device *mdev; |
274 | 213 | ||
214 | /* zero this out to avoid kobj subsystem | ||
215 | * thinking it has already been registered */ | ||
216 | |||
275 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | 217 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); |
276 | if (!mdev) | 218 | if (!mdev) |
277 | return NULL; | 219 | return NULL; |
278 | 220 | ||
279 | mdev->port = port; | 221 | mdev->port = port; |
280 | mdev->unit = unit; | 222 | mdev->unit = unit; |
223 | |||
281 | mdev->mq = maple_allocq(mdev); | 224 | mdev->mq = maple_allocq(mdev); |
282 | 225 | ||
283 | if (!mdev->mq) { | 226 | if (!mdev->mq) { |
@@ -286,19 +229,14 @@ static struct maple_device *maple_alloc_dev(int port, int unit) | |||
286 | } | 229 | } |
287 | mdev->dev.bus = &maple_bus_type; | 230 | mdev->dev.bus = &maple_bus_type; |
288 | mdev->dev.parent = &maple_bus; | 231 | mdev->dev.parent = &maple_bus; |
232 | init_waitqueue_head(&mdev->maple_wait); | ||
289 | return mdev; | 233 | return mdev; |
290 | } | 234 | } |
291 | 235 | ||
292 | static void maple_free_dev(struct maple_device *mdev) | 236 | static void maple_free_dev(struct maple_device *mdev) |
293 | { | 237 | { |
294 | if (!mdev) | 238 | kmem_cache_free(maple_queue_cache, mdev->mq->recvbuf); |
295 | return; | 239 | kfree(mdev->mq); |
296 | if (mdev->mq) { | ||
297 | if (mdev->mq->recvbufdcsp) | ||
298 | kmem_cache_free(maple_queue_cache, | ||
299 | mdev->mq->recvbufdcsp); | ||
300 | kfree(mdev->mq); | ||
301 | } | ||
302 | kfree(mdev); | 240 | kfree(mdev); |
303 | } | 241 | } |
304 | 242 | ||
@@ -320,7 +258,7 @@ static void maple_build_block(struct mapleq *mq) | |||
320 | maple_lastptr = maple_sendptr; | 258 | maple_lastptr = maple_sendptr; |
321 | 259 | ||
322 | *maple_sendptr++ = (port << 16) | len | 0x80000000; | 260 | *maple_sendptr++ = (port << 16) | len | 0x80000000; |
323 | *maple_sendptr++ = PHYSADDR(mq->recvbuf); | 261 | *maple_sendptr++ = PHYSADDR(mq->recvbuf->buf); |
324 | *maple_sendptr++ = | 262 | *maple_sendptr++ = |
325 | mq->command | (to << 8) | (from << 16) | (len << 24); | 263 | mq->command | (to << 8) | (from << 16) | (len << 24); |
326 | while (len-- > 0) | 264 | while (len-- > 0) |
@@ -333,20 +271,28 @@ static void maple_send(void) | |||
333 | int i, maple_packets = 0; | 271 | int i, maple_packets = 0; |
334 | struct mapleq *mq, *nmq; | 272 | struct mapleq *mq, *nmq; |
335 | 273 | ||
336 | if (!list_empty(&maple_sentq)) | 274 | if (!maple_dma_done()) |
337 | return; | 275 | return; |
276 | |||
277 | /* disable DMA */ | ||
278 | ctrl_outl(0, MAPLE_ENABLE); | ||
279 | |||
280 | if (!list_empty(&maple_sentq)) | ||
281 | goto finish; | ||
282 | |||
338 | mutex_lock(&maple_wlist_lock); | 283 | mutex_lock(&maple_wlist_lock); |
339 | if (list_empty(&maple_waitq) || !maple_dma_done()) { | 284 | if (list_empty(&maple_waitq)) { |
340 | mutex_unlock(&maple_wlist_lock); | 285 | mutex_unlock(&maple_wlist_lock); |
341 | return; | 286 | goto finish; |
342 | } | 287 | } |
343 | mutex_unlock(&maple_wlist_lock); | 288 | |
344 | maple_lastptr = maple_sendbuf; | 289 | maple_lastptr = maple_sendbuf; |
345 | maple_sendptr = maple_sendbuf; | 290 | maple_sendptr = maple_sendbuf; |
346 | mutex_lock(&maple_wlist_lock); | 291 | |
347 | list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { | 292 | list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { |
348 | maple_build_block(mq); | 293 | maple_build_block(mq); |
349 | list_move(&mq->list, &maple_sentq); | 294 | list_del_init(&mq->list); |
295 | list_add_tail(&mq->list, &maple_sentq); | ||
350 | if (maple_packets++ > MAPLE_MAXPACKETS) | 296 | if (maple_packets++ > MAPLE_MAXPACKETS) |
351 | break; | 297 | break; |
352 | } | 298 | } |
@@ -356,10 +302,13 @@ static void maple_send(void) | |||
356 | dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE, | 302 | dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE, |
357 | PAGE_SIZE, DMA_BIDIRECTIONAL); | 303 | PAGE_SIZE, DMA_BIDIRECTIONAL); |
358 | } | 304 | } |
305 | |||
306 | finish: | ||
307 | maple_dma_reset(); | ||
359 | } | 308 | } |
360 | 309 | ||
361 | /* check if there is a driver registered likely to match this device */ | 310 | /* check if there is a driver registered likely to match this device */ |
362 | static int check_matching_maple_driver(struct device_driver *driver, | 311 | static int maple_check_matching_driver(struct device_driver *driver, |
363 | void *devptr) | 312 | void *devptr) |
364 | { | 313 | { |
365 | struct maple_driver *maple_drv; | 314 | struct maple_driver *maple_drv; |
@@ -374,10 +323,7 @@ static int check_matching_maple_driver(struct device_driver *driver, | |||
374 | 323 | ||
375 | static void maple_detach_driver(struct maple_device *mdev) | 324 | static void maple_detach_driver(struct maple_device *mdev) |
376 | { | 325 | { |
377 | if (!mdev) | ||
378 | return; | ||
379 | device_unregister(&mdev->dev); | 326 | device_unregister(&mdev->dev); |
380 | mdev = NULL; | ||
381 | } | 327 | } |
382 | 328 | ||
383 | /* process initial MAPLE_COMMAND_DEVINFO for each device or port */ | 329 | /* process initial MAPLE_COMMAND_DEVINFO for each device or port */ |
@@ -385,9 +331,9 @@ static void maple_attach_driver(struct maple_device *mdev) | |||
385 | { | 331 | { |
386 | char *p, *recvbuf; | 332 | char *p, *recvbuf; |
387 | unsigned long function; | 333 | unsigned long function; |
388 | int matched, retval; | 334 | int matched, error; |
389 | 335 | ||
390 | recvbuf = mdev->mq->recvbuf; | 336 | recvbuf = mdev->mq->recvbuf->buf; |
391 | /* copy the data as individual elements in | 337 | /* copy the data as individual elements in |
392 | * case of memory optimisation */ | 338 | * case of memory optimisation */ |
393 | memcpy(&mdev->devinfo.function, recvbuf + 4, 4); | 339 | memcpy(&mdev->devinfo.function, recvbuf + 4, 4); |
@@ -395,7 +341,6 @@ static void maple_attach_driver(struct maple_device *mdev) | |||
395 | memcpy(&mdev->devinfo.area_code, recvbuf + 20, 1); | 341 | memcpy(&mdev->devinfo.area_code, recvbuf + 20, 1); |
396 | memcpy(&mdev->devinfo.connector_direction, recvbuf + 21, 1); | 342 | memcpy(&mdev->devinfo.connector_direction, recvbuf + 21, 1); |
397 | memcpy(&mdev->devinfo.product_name[0], recvbuf + 22, 30); | 343 | memcpy(&mdev->devinfo.product_name[0], recvbuf + 22, 30); |
398 | memcpy(&mdev->devinfo.product_licence[0], recvbuf + 52, 60); | ||
399 | memcpy(&mdev->devinfo.standby_power, recvbuf + 112, 2); | 344 | memcpy(&mdev->devinfo.standby_power, recvbuf + 112, 2); |
400 | memcpy(&mdev->devinfo.max_power, recvbuf + 114, 2); | 345 | memcpy(&mdev->devinfo.max_power, recvbuf + 114, 2); |
401 | memcpy(mdev->product_name, mdev->devinfo.product_name, 30); | 346 | memcpy(mdev->product_name, mdev->devinfo.product_name, 30); |
@@ -414,43 +359,39 @@ static void maple_attach_driver(struct maple_device *mdev) | |||
414 | else | 359 | else |
415 | break; | 360 | break; |
416 | 361 | ||
417 | printk(KERN_INFO "Maple device detected: %s\n", | ||
418 | mdev->product_name); | ||
419 | printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); | ||
420 | |||
421 | function = be32_to_cpu(mdev->devinfo.function); | 362 | function = be32_to_cpu(mdev->devinfo.function); |
422 | 363 | ||
364 | dev_info(&mdev->dev, "detected %s: function 0x%lX: at (%d, %d)\n", | ||
365 | mdev->product_name, function, mdev->port, mdev->unit); | ||
366 | |||
423 | if (function > 0x200) { | 367 | if (function > 0x200) { |
424 | /* Do this silently - as not a real device */ | 368 | /* Do this silently - as not a real device */ |
425 | function = 0; | 369 | function = 0; |
426 | mdev->driver = &maple_dummy_driver; | 370 | mdev->driver = &maple_unsupported_device; |
427 | sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port); | 371 | dev_set_name(&mdev->dev, "%d:0.port", mdev->port); |
428 | } else { | 372 | } else { |
429 | printk(KERN_INFO | ||
430 | "Maple bus at (%d, %d): Function 0x%lX\n", | ||
431 | mdev->port, mdev->unit, function); | ||
432 | |||
433 | matched = | 373 | matched = |
434 | bus_for_each_drv(&maple_bus_type, NULL, mdev, | 374 | bus_for_each_drv(&maple_bus_type, NULL, mdev, |
435 | check_matching_maple_driver); | 375 | maple_check_matching_driver); |
436 | 376 | ||
437 | if (matched == 0) { | 377 | if (matched == 0) { |
438 | /* Driver does not exist yet */ | 378 | /* Driver does not exist yet */ |
439 | printk(KERN_INFO | 379 | dev_info(&mdev->dev, "no driver found\n"); |
440 | "No maple driver found.\n"); | 380 | mdev->driver = &maple_unsupported_device; |
441 | mdev->driver = &maple_dummy_driver; | ||
442 | } | 381 | } |
443 | sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port, | 382 | dev_set_name(&mdev->dev, "%d:0%d.%lX", mdev->port, |
444 | mdev->unit, function); | 383 | mdev->unit, function); |
445 | } | 384 | } |
385 | |||
446 | mdev->function = function; | 386 | mdev->function = function; |
447 | mdev->dev.release = &maple_release_device; | 387 | mdev->dev.release = &maple_release_device; |
448 | retval = device_register(&mdev->dev); | 388 | |
449 | if (retval) { | 389 | atomic_set(&mdev->busy, 0); |
450 | printk(KERN_INFO | 390 | error = device_register(&mdev->dev); |
451 | "Maple bus: Attempt to register device" | 391 | if (error) { |
452 | " (%x, %x) failed.\n", | 392 | dev_warn(&mdev->dev, "could not register device at" |
453 | mdev->port, mdev->unit); | 393 | " (%d, %d), with error 0x%X\n", mdev->unit, |
394 | mdev->port, error); | ||
454 | maple_free_dev(mdev); | 395 | maple_free_dev(mdev); |
455 | mdev = NULL; | 396 | mdev = NULL; |
456 | return; | 397 | return; |
@@ -462,7 +403,7 @@ static void maple_attach_driver(struct maple_device *mdev) | |||
462 | * port and unit then return 1 - allows identification | 403 | * port and unit then return 1 - allows identification |
463 | * of which devices need to be attached or detached | 404 | * of which devices need to be attached or detached |
464 | */ | 405 | */ |
465 | static int detach_maple_device(struct device *device, void *portptr) | 406 | static int check_maple_device(struct device *device, void *portptr) |
466 | { | 407 | { |
467 | struct maple_device_specify *ds; | 408 | struct maple_device_specify *ds; |
468 | struct maple_device *mdev; | 409 | struct maple_device *mdev; |
@@ -477,21 +418,25 @@ static int detach_maple_device(struct device *device, void *portptr) | |||
477 | static int setup_maple_commands(struct device *device, void *ignored) | 418 | static int setup_maple_commands(struct device *device, void *ignored) |
478 | { | 419 | { |
479 | int add; | 420 | int add; |
480 | struct maple_device *maple_dev = to_maple_dev(device); | 421 | struct maple_device *mdev = to_maple_dev(device); |
481 | 422 | if (mdev->interval > 0 && atomic_read(&mdev->busy) == 0 && | |
482 | if ((maple_dev->interval > 0) | 423 | time_after(jiffies, mdev->when)) { |
483 | && time_after(jiffies, maple_dev->when)) { | 424 | /* bounce if we cannot add */ |
484 | /* bounce if we cannot lock */ | 425 | add = maple_add_packet(mdev, |
485 | add = maple_add_packet(maple_dev, | 426 | be32_to_cpu(mdev->devinfo.function), |
486 | be32_to_cpu(maple_dev->devinfo.function), | ||
487 | MAPLE_COMMAND_GETCOND, 1, NULL); | 427 | MAPLE_COMMAND_GETCOND, 1, NULL); |
488 | if (!add) | 428 | if (!add) |
489 | maple_dev->when = jiffies + maple_dev->interval; | 429 | mdev->when = jiffies + mdev->interval; |
490 | } else { | 430 | } else { |
491 | if (time_after(jiffies, maple_pnp_time)) | 431 | if (time_after(jiffies, maple_pnp_time)) |
492 | /* This will also bounce */ | 432 | /* Ensure we don't have block reads and devinfo |
493 | maple_add_packet(maple_dev, 0, | 433 | * calls interfering with one another - so flag the |
494 | MAPLE_COMMAND_DEVINFO, 0, NULL); | 434 | * device as busy */ |
435 | if (atomic_read(&mdev->busy) == 0) { | ||
436 | atomic_set(&mdev->busy, 1); | ||
437 | maple_add_packet(mdev, 0, | ||
438 | MAPLE_COMMAND_DEVINFO, 0, NULL); | ||
439 | } | ||
495 | } | 440 | } |
496 | return 0; | 441 | return 0; |
497 | } | 442 | } |
@@ -499,29 +444,50 @@ static int setup_maple_commands(struct device *device, void *ignored) | |||
499 | /* VBLANK bottom half - implemented via workqueue */ | 444 | /* VBLANK bottom half - implemented via workqueue */ |
500 | static void maple_vblank_handler(struct work_struct *work) | 445 | static void maple_vblank_handler(struct work_struct *work) |
501 | { | 446 | { |
502 | if (!list_empty(&maple_sentq) || !maple_dma_done()) | 447 | int x, locking; |
448 | struct maple_device *mdev; | ||
449 | |||
450 | if (!maple_dma_done()) | ||
503 | return; | 451 | return; |
504 | 452 | ||
505 | ctrl_outl(0, MAPLE_ENABLE); | 453 | ctrl_outl(0, MAPLE_ENABLE); |
506 | 454 | ||
455 | if (!list_empty(&maple_sentq)) | ||
456 | goto finish; | ||
457 | |||
458 | /* | ||
459 | * Set up essential commands - to fetch data and | ||
460 | * check devices are still present | ||
461 | */ | ||
507 | bus_for_each_dev(&maple_bus_type, NULL, NULL, | 462 | bus_for_each_dev(&maple_bus_type, NULL, NULL, |
508 | setup_maple_commands); | 463 | setup_maple_commands); |
464 | |||
465 | if (time_after(jiffies, maple_pnp_time)) { | ||
466 | /* | ||
467 | * Scan the empty ports - bus is flakey and may have | ||
468 | * mis-reported emptyness | ||
469 | */ | ||
470 | for (x = 0; x < MAPLE_PORTS; x++) { | ||
471 | if (checked[x] && empty[x]) { | ||
472 | mdev = baseunits[x]; | ||
473 | if (!mdev) | ||
474 | break; | ||
475 | atomic_set(&mdev->busy, 1); | ||
476 | locking = maple_add_packet(mdev, 0, | ||
477 | MAPLE_COMMAND_DEVINFO, 0, NULL); | ||
478 | if (!locking) | ||
479 | break; | ||
480 | } | ||
481 | } | ||
509 | 482 | ||
510 | if (time_after(jiffies, maple_pnp_time)) | ||
511 | maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; | 483 | maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; |
512 | |||
513 | mutex_lock(&maple_wlist_lock); | ||
514 | if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) { | ||
515 | mutex_unlock(&maple_wlist_lock); | ||
516 | maple_send(); | ||
517 | } else { | ||
518 | mutex_unlock(&maple_wlist_lock); | ||
519 | } | 484 | } |
520 | 485 | ||
521 | maplebus_dma_reset(); | 486 | finish: |
487 | maple_send(); | ||
522 | } | 488 | } |
523 | 489 | ||
524 | /* handle devices added via hotplugs - placing them on queue for DEVINFO*/ | 490 | /* handle devices added via hotplugs - placing them on queue for DEVINFO */ |
525 | static void maple_map_subunits(struct maple_device *mdev, int submask) | 491 | static void maple_map_subunits(struct maple_device *mdev, int submask) |
526 | { | 492 | { |
527 | int retval, k, devcheck; | 493 | int retval, k, devcheck; |
@@ -533,7 +499,7 @@ static void maple_map_subunits(struct maple_device *mdev, int submask) | |||
533 | ds.unit = k + 1; | 499 | ds.unit = k + 1; |
534 | retval = | 500 | retval = |
535 | bus_for_each_dev(&maple_bus_type, NULL, &ds, | 501 | bus_for_each_dev(&maple_bus_type, NULL, &ds, |
536 | detach_maple_device); | 502 | check_maple_device); |
537 | if (retval) { | 503 | if (retval) { |
538 | submask = submask >> 1; | 504 | submask = submask >> 1; |
539 | continue; | 505 | continue; |
@@ -543,6 +509,7 @@ static void maple_map_subunits(struct maple_device *mdev, int submask) | |||
543 | mdev_add = maple_alloc_dev(mdev->port, k + 1); | 509 | mdev_add = maple_alloc_dev(mdev->port, k + 1); |
544 | if (!mdev_add) | 510 | if (!mdev_add) |
545 | return; | 511 | return; |
512 | atomic_set(&mdev_add->busy, 1); | ||
546 | maple_add_packet(mdev_add, 0, MAPLE_COMMAND_DEVINFO, | 513 | maple_add_packet(mdev_add, 0, MAPLE_COMMAND_DEVINFO, |
547 | 0, NULL); | 514 | 0, NULL); |
548 | /* mark that we are checking sub devices */ | 515 | /* mark that we are checking sub devices */ |
@@ -564,27 +531,45 @@ static void maple_clean_submap(struct maple_device *mdev) | |||
564 | } | 531 | } |
565 | 532 | ||
566 | /* handle empty port or hotplug removal */ | 533 | /* handle empty port or hotplug removal */ |
567 | static void maple_response_none(struct maple_device *mdev, | 534 | static void maple_response_none(struct maple_device *mdev) |
568 | struct mapleq *mq) | 535 | { |
569 | { | 536 | maple_clean_submap(mdev); |
570 | if (mdev->unit != 0) { | 537 | |
571 | list_del(&mq->list); | 538 | if (likely(mdev->unit != 0)) { |
572 | maple_clean_submap(mdev); | 539 | /* |
573 | printk(KERN_INFO | 540 | * Block devices play up |
574 | "Maple bus device detaching at (%d, %d)\n", | 541 | * and give the impression they have |
575 | mdev->port, mdev->unit); | 542 | * been removed even when still in place or |
543 | * trip the mtd layer when they have | ||
544 | * really gone - this code traps that eventuality | ||
545 | * and ensures we aren't overloaded with useless | ||
546 | * error messages | ||
547 | */ | ||
548 | if (mdev->can_unload) { | ||
549 | if (!mdev->can_unload(mdev)) { | ||
550 | atomic_set(&mdev->busy, 2); | ||
551 | wake_up(&mdev->maple_wait); | ||
552 | return; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | dev_info(&mdev->dev, "detaching device at (%d, %d)\n", | ||
557 | mdev->port, mdev->unit); | ||
576 | maple_detach_driver(mdev); | 558 | maple_detach_driver(mdev); |
577 | return; | 559 | return; |
578 | } | 560 | } else { |
579 | if (!started || !fullscan) { | 561 | if (!started || !fullscan) { |
580 | if (checked[mdev->port] == false) { | 562 | if (checked[mdev->port] == false) { |
581 | checked[mdev->port] = true; | 563 | checked[mdev->port] = true; |
582 | printk(KERN_INFO "No maple devices attached" | 564 | empty[mdev->port] = true; |
583 | " to port %d\n", mdev->port); | 565 | dev_info(&mdev->dev, "no devices" |
566 | " to port %d\n", mdev->port); | ||
567 | } | ||
568 | return; | ||
584 | } | 569 | } |
585 | return; | ||
586 | } | 570 | } |
587 | maple_clean_submap(mdev); | 571 | /* Some hardware devices generate false detach messages on unit 0 */ |
572 | atomic_set(&mdev->busy, 0); | ||
588 | } | 573 | } |
589 | 574 | ||
590 | /* preprocess hotplugs or scans */ | 575 | /* preprocess hotplugs or scans */ |
@@ -599,8 +584,11 @@ static void maple_response_devinfo(struct maple_device *mdev, | |||
599 | } else { | 584 | } else { |
600 | if (mdev->unit != 0) | 585 | if (mdev->unit != 0) |
601 | maple_attach_driver(mdev); | 586 | maple_attach_driver(mdev); |
587 | if (mdev->unit == 0) { | ||
588 | empty[mdev->port] = false; | ||
589 | maple_attach_driver(mdev); | ||
590 | } | ||
602 | } | 591 | } |
603 | return; | ||
604 | } | 592 | } |
605 | if (mdev->unit == 0) { | 593 | if (mdev->unit == 0) { |
606 | submask = recvbuf[2] & 0x1F; | 594 | submask = recvbuf[2] & 0x1F; |
@@ -611,6 +599,17 @@ static void maple_response_devinfo(struct maple_device *mdev, | |||
611 | } | 599 | } |
612 | } | 600 | } |
613 | 601 | ||
602 | static void maple_response_fileerr(struct maple_device *mdev, void *recvbuf) | ||
603 | { | ||
604 | if (mdev->fileerr_handler) { | ||
605 | mdev->fileerr_handler(mdev, recvbuf); | ||
606 | return; | ||
607 | } else | ||
608 | dev_warn(&mdev->dev, "device at (%d, %d) reports" | ||
609 | "file error 0x%X\n", mdev->port, mdev->unit, | ||
610 | ((int *)recvbuf)[1]); | ||
611 | } | ||
612 | |||
614 | static void maple_port_rescan(void) | 613 | static void maple_port_rescan(void) |
615 | { | 614 | { |
616 | int i; | 615 | int i; |
@@ -621,12 +620,6 @@ static void maple_port_rescan(void) | |||
621 | if (checked[i] == false) { | 620 | if (checked[i] == false) { |
622 | fullscan = 0; | 621 | fullscan = 0; |
623 | mdev = baseunits[i]; | 622 | mdev = baseunits[i]; |
624 | /* | ||
625 | * test lock in case scan has failed | ||
626 | * but device is still locked | ||
627 | */ | ||
628 | if (mutex_is_locked(&mdev->mq->mutex)) | ||
629 | mutex_unlock(&mdev->mq->mutex); | ||
630 | maple_add_packet(mdev, 0, MAPLE_COMMAND_DEVINFO, | 623 | maple_add_packet(mdev, 0, MAPLE_COMMAND_DEVINFO, |
631 | 0, NULL); | 624 | 0, NULL); |
632 | } | 625 | } |
@@ -637,7 +630,7 @@ static void maple_port_rescan(void) | |||
637 | static void maple_dma_handler(struct work_struct *work) | 630 | static void maple_dma_handler(struct work_struct *work) |
638 | { | 631 | { |
639 | struct mapleq *mq, *nmq; | 632 | struct mapleq *mq, *nmq; |
640 | struct maple_device *dev; | 633 | struct maple_device *mdev; |
641 | char *recvbuf; | 634 | char *recvbuf; |
642 | enum maple_code code; | 635 | enum maple_code code; |
643 | 636 | ||
@@ -646,43 +639,56 @@ static void maple_dma_handler(struct work_struct *work) | |||
646 | ctrl_outl(0, MAPLE_ENABLE); | 639 | ctrl_outl(0, MAPLE_ENABLE); |
647 | if (!list_empty(&maple_sentq)) { | 640 | if (!list_empty(&maple_sentq)) { |
648 | list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { | 641 | list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { |
649 | recvbuf = mq->recvbuf; | 642 | mdev = mq->dev; |
643 | recvbuf = mq->recvbuf->buf; | ||
644 | dma_cache_sync(&mdev->dev, recvbuf, 0x400, | ||
645 | DMA_FROM_DEVICE); | ||
650 | code = recvbuf[0]; | 646 | code = recvbuf[0]; |
651 | dev = mq->dev; | ||
652 | kfree(mq->sendbuf); | 647 | kfree(mq->sendbuf); |
653 | mutex_unlock(&mq->mutex); | ||
654 | list_del_init(&mq->list); | 648 | list_del_init(&mq->list); |
655 | |||
656 | switch (code) { | 649 | switch (code) { |
657 | case MAPLE_RESPONSE_NONE: | 650 | case MAPLE_RESPONSE_NONE: |
658 | maple_response_none(dev, mq); | 651 | maple_response_none(mdev); |
659 | break; | 652 | break; |
660 | 653 | ||
661 | case MAPLE_RESPONSE_DEVINFO: | 654 | case MAPLE_RESPONSE_DEVINFO: |
662 | maple_response_devinfo(dev, recvbuf); | 655 | maple_response_devinfo(mdev, recvbuf); |
656 | atomic_set(&mdev->busy, 0); | ||
663 | break; | 657 | break; |
664 | 658 | ||
665 | case MAPLE_RESPONSE_DATATRF: | 659 | case MAPLE_RESPONSE_DATATRF: |
666 | if (dev->callback) | 660 | if (mdev->callback) |
667 | dev->callback(mq); | 661 | mdev->callback(mq); |
662 | atomic_set(&mdev->busy, 0); | ||
663 | wake_up(&mdev->maple_wait); | ||
668 | break; | 664 | break; |
669 | 665 | ||
670 | case MAPLE_RESPONSE_FILEERR: | 666 | case MAPLE_RESPONSE_FILEERR: |
667 | maple_response_fileerr(mdev, recvbuf); | ||
668 | atomic_set(&mdev->busy, 0); | ||
669 | wake_up(&mdev->maple_wait); | ||
670 | break; | ||
671 | |||
671 | case MAPLE_RESPONSE_AGAIN: | 672 | case MAPLE_RESPONSE_AGAIN: |
672 | case MAPLE_RESPONSE_BADCMD: | 673 | case MAPLE_RESPONSE_BADCMD: |
673 | case MAPLE_RESPONSE_BADFUNC: | 674 | case MAPLE_RESPONSE_BADFUNC: |
674 | printk(KERN_DEBUG | 675 | dev_warn(&mdev->dev, "non-fatal error" |
675 | "Maple non-fatal error 0x%X\n", | 676 | " 0x%X at (%d, %d)\n", code, |
676 | code); | 677 | mdev->port, mdev->unit); |
678 | atomic_set(&mdev->busy, 0); | ||
677 | break; | 679 | break; |
678 | 680 | ||
679 | case MAPLE_RESPONSE_ALLINFO: | 681 | case MAPLE_RESPONSE_ALLINFO: |
680 | printk(KERN_DEBUG | 682 | dev_notice(&mdev->dev, "extended" |
681 | "Maple - extended device information" | 683 | " device information request for (%d, %d)" |
682 | " not supported\n"); | 684 | " but call is not supported\n", mdev->port, |
685 | mdev->unit); | ||
686 | atomic_set(&mdev->busy, 0); | ||
683 | break; | 687 | break; |
684 | 688 | ||
685 | case MAPLE_RESPONSE_OK: | 689 | case MAPLE_RESPONSE_OK: |
690 | atomic_set(&mdev->busy, 0); | ||
691 | wake_up(&mdev->maple_wait); | ||
686 | break; | 692 | break; |
687 | 693 | ||
688 | default: | 694 | default: |
@@ -699,20 +705,19 @@ static void maple_dma_handler(struct work_struct *work) | |||
699 | if (!fullscan) | 705 | if (!fullscan) |
700 | maple_port_rescan(); | 706 | maple_port_rescan(); |
701 | /* mark that we have been through the first scan */ | 707 | /* mark that we have been through the first scan */ |
702 | if (started == 0) | 708 | started = 1; |
703 | started = 1; | ||
704 | } | 709 | } |
705 | maplebus_dma_reset(); | 710 | maple_send(); |
706 | } | 711 | } |
707 | 712 | ||
708 | static irqreturn_t maplebus_dma_interrupt(int irq, void *dev_id) | 713 | static irqreturn_t maple_dma_interrupt(int irq, void *dev_id) |
709 | { | 714 | { |
710 | /* Load everything into the bottom half */ | 715 | /* Load everything into the bottom half */ |
711 | schedule_work(&maple_dma_process); | 716 | schedule_work(&maple_dma_process); |
712 | return IRQ_HANDLED; | 717 | return IRQ_HANDLED; |
713 | } | 718 | } |
714 | 719 | ||
715 | static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id) | 720 | static irqreturn_t maple_vblank_interrupt(int irq, void *dev_id) |
716 | { | 721 | { |
717 | schedule_work(&maple_vblank_process); | 722 | schedule_work(&maple_vblank_process); |
718 | return IRQ_HANDLED; | 723 | return IRQ_HANDLED; |
@@ -720,14 +725,14 @@ static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id) | |||
720 | 725 | ||
721 | static int maple_set_dma_interrupt_handler(void) | 726 | static int maple_set_dma_interrupt_handler(void) |
722 | { | 727 | { |
723 | return request_irq(HW_EVENT_MAPLE_DMA, maplebus_dma_interrupt, | 728 | return request_irq(HW_EVENT_MAPLE_DMA, maple_dma_interrupt, |
724 | IRQF_SHARED, "maple bus DMA", &maple_dummy_driver); | 729 | IRQF_SHARED, "maple bus DMA", &maple_unsupported_device); |
725 | } | 730 | } |
726 | 731 | ||
727 | static int maple_set_vblank_interrupt_handler(void) | 732 | static int maple_set_vblank_interrupt_handler(void) |
728 | { | 733 | { |
729 | return request_irq(HW_EVENT_VSYNC, maplebus_vblank_interrupt, | 734 | return request_irq(HW_EVENT_VSYNC, maple_vblank_interrupt, |
730 | IRQF_SHARED, "maple bus VBLANK", &maple_dummy_driver); | 735 | IRQF_SHARED, "maple bus VBLANK", &maple_unsupported_device); |
731 | } | 736 | } |
732 | 737 | ||
733 | static int maple_get_dma_buffer(void) | 738 | static int maple_get_dma_buffer(void) |
@@ -740,7 +745,7 @@ static int maple_get_dma_buffer(void) | |||
740 | return 0; | 745 | return 0; |
741 | } | 746 | } |
742 | 747 | ||
743 | static int match_maple_bus_driver(struct device *devptr, | 748 | static int maple_match_bus_driver(struct device *devptr, |
744 | struct device_driver *drvptr) | 749 | struct device_driver *drvptr) |
745 | { | 750 | { |
746 | struct maple_driver *maple_drv = to_maple_driver(drvptr); | 751 | struct maple_driver *maple_drv = to_maple_driver(drvptr); |
@@ -765,22 +770,24 @@ static void maple_bus_release(struct device *dev) | |||
765 | { | 770 | { |
766 | } | 771 | } |
767 | 772 | ||
768 | static struct maple_driver maple_dummy_driver = { | 773 | static struct maple_driver maple_unsupported_device = { |
769 | .drv = { | 774 | .drv = { |
770 | .name = "maple_dummy_driver", | 775 | .name = "maple_unsupported_device", |
771 | .bus = &maple_bus_type, | 776 | .bus = &maple_bus_type, |
772 | }, | 777 | }, |
773 | }; | 778 | }; |
774 | 779 | /** | |
780 | * maple_bus_type - core maple bus structure | ||
781 | */ | ||
775 | struct bus_type maple_bus_type = { | 782 | struct bus_type maple_bus_type = { |
776 | .name = "maple", | 783 | .name = "maple", |
777 | .match = match_maple_bus_driver, | 784 | .match = maple_match_bus_driver, |
778 | .uevent = maple_bus_uevent, | 785 | .uevent = maple_bus_uevent, |
779 | }; | 786 | }; |
780 | EXPORT_SYMBOL_GPL(maple_bus_type); | 787 | EXPORT_SYMBOL_GPL(maple_bus_type); |
781 | 788 | ||
782 | static struct device maple_bus = { | 789 | static struct device maple_bus = { |
783 | .bus_id = "maple", | 790 | .init_name = "maple", |
784 | .release = maple_bus_release, | 791 | .release = maple_bus_release, |
785 | }; | 792 | }; |
786 | 793 | ||
@@ -788,7 +795,8 @@ static int __init maple_bus_init(void) | |||
788 | { | 795 | { |
789 | int retval, i; | 796 | int retval, i; |
790 | struct maple_device *mdev[MAPLE_PORTS]; | 797 | struct maple_device *mdev[MAPLE_PORTS]; |
791 | ctrl_outl(0, MAPLE_STATE); | 798 | |
799 | ctrl_outl(0, MAPLE_ENABLE); | ||
792 | 800 | ||
793 | retval = device_register(&maple_bus); | 801 | retval = device_register(&maple_bus); |
794 | if (retval) | 802 | if (retval) |
@@ -798,36 +806,33 @@ static int __init maple_bus_init(void) | |||
798 | if (retval) | 806 | if (retval) |
799 | goto cleanup_device; | 807 | goto cleanup_device; |
800 | 808 | ||
801 | retval = driver_register(&maple_dummy_driver.drv); | 809 | retval = driver_register(&maple_unsupported_device.drv); |
802 | if (retval) | 810 | if (retval) |
803 | goto cleanup_bus; | 811 | goto cleanup_bus; |
804 | 812 | ||
805 | /* allocate memory for maple bus dma */ | 813 | /* allocate memory for maple bus dma */ |
806 | retval = maple_get_dma_buffer(); | 814 | retval = maple_get_dma_buffer(); |
807 | if (retval) { | 815 | if (retval) { |
808 | printk(KERN_INFO | 816 | dev_err(&maple_bus, "failed to allocate DMA buffers\n"); |
809 | "Maple bus: Failed to allocate Maple DMA buffers\n"); | ||
810 | goto cleanup_basic; | 817 | goto cleanup_basic; |
811 | } | 818 | } |
812 | 819 | ||
813 | /* set up DMA interrupt handler */ | 820 | /* set up DMA interrupt handler */ |
814 | retval = maple_set_dma_interrupt_handler(); | 821 | retval = maple_set_dma_interrupt_handler(); |
815 | if (retval) { | 822 | if (retval) { |
816 | printk(KERN_INFO | 823 | dev_err(&maple_bus, "bus failed to grab maple " |
817 | "Maple bus: Failed to grab maple DMA IRQ\n"); | 824 | "DMA IRQ\n"); |
818 | goto cleanup_dma; | 825 | goto cleanup_dma; |
819 | } | 826 | } |
820 | 827 | ||
821 | /* set up VBLANK interrupt handler */ | 828 | /* set up VBLANK interrupt handler */ |
822 | retval = maple_set_vblank_interrupt_handler(); | 829 | retval = maple_set_vblank_interrupt_handler(); |
823 | if (retval) { | 830 | if (retval) { |
824 | printk(KERN_INFO "Maple bus: Failed to grab VBLANK IRQ\n"); | 831 | dev_err(&maple_bus, "bus failed to grab VBLANK IRQ\n"); |
825 | goto cleanup_irq; | 832 | goto cleanup_irq; |
826 | } | 833 | } |
827 | 834 | ||
828 | maple_queue_cache = | 835 | maple_queue_cache = KMEM_CACHE(maple_buffer, SLAB_HWCACHE_ALIGN); |
829 | kmem_cache_create("maple_queue_cache", 0x400, 0, | ||
830 | SLAB_HWCACHE_ALIGN, NULL); | ||
831 | 836 | ||
832 | if (!maple_queue_cache) | 837 | if (!maple_queue_cache) |
833 | goto cleanup_bothirqs; | 838 | goto cleanup_bothirqs; |
@@ -838,23 +843,23 @@ static int __init maple_bus_init(void) | |||
838 | /* setup maple ports */ | 843 | /* setup maple ports */ |
839 | for (i = 0; i < MAPLE_PORTS; i++) { | 844 | for (i = 0; i < MAPLE_PORTS; i++) { |
840 | checked[i] = false; | 845 | checked[i] = false; |
846 | empty[i] = false; | ||
841 | mdev[i] = maple_alloc_dev(i, 0); | 847 | mdev[i] = maple_alloc_dev(i, 0); |
842 | baseunits[i] = mdev[i]; | ||
843 | if (!mdev[i]) { | 848 | if (!mdev[i]) { |
844 | while (i-- > 0) | 849 | while (i-- > 0) |
845 | maple_free_dev(mdev[i]); | 850 | maple_free_dev(mdev[i]); |
846 | goto cleanup_cache; | 851 | goto cleanup_cache; |
847 | } | 852 | } |
853 | baseunits[i] = mdev[i]; | ||
854 | atomic_set(&mdev[i]->busy, 1); | ||
848 | maple_add_packet(mdev[i], 0, MAPLE_COMMAND_DEVINFO, 0, NULL); | 855 | maple_add_packet(mdev[i], 0, MAPLE_COMMAND_DEVINFO, 0, NULL); |
849 | subdevice_map[i] = 0; | 856 | subdevice_map[i] = 0; |
850 | } | 857 | } |
851 | 858 | ||
852 | /* setup maplebus hardware */ | 859 | maple_pnp_time = jiffies + HZ; |
853 | maplebus_dma_reset(); | 860 | /* prepare initial queue */ |
854 | /* initial detection */ | ||
855 | maple_send(); | 861 | maple_send(); |
856 | maple_pnp_time = jiffies; | 862 | dev_info(&maple_bus, "bus core now registered\n"); |
857 | printk(KERN_INFO "Maple bus core now registered.\n"); | ||
858 | 863 | ||
859 | return 0; | 864 | return 0; |
860 | 865 | ||
@@ -871,7 +876,7 @@ cleanup_dma: | |||
871 | free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES); | 876 | free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES); |
872 | 877 | ||
873 | cleanup_basic: | 878 | cleanup_basic: |
874 | driver_unregister(&maple_dummy_driver.drv); | 879 | driver_unregister(&maple_unsupported_device.drv); |
875 | 880 | ||
876 | cleanup_bus: | 881 | cleanup_bus: |
877 | bus_unregister(&maple_bus_type); | 882 | bus_unregister(&maple_bus_type); |
@@ -880,7 +885,7 @@ cleanup_device: | |||
880 | device_unregister(&maple_bus); | 885 | device_unregister(&maple_bus); |
881 | 886 | ||
882 | cleanup: | 887 | cleanup: |
883 | printk(KERN_INFO "Maple bus registration failed\n"); | 888 | printk(KERN_ERR "Maple bus registration failed\n"); |
884 | return retval; | 889 | return retval; |
885 | } | 890 | } |
886 | /* Push init to later to ensure hardware gets detected */ | 891 | /* Push init to later to ensure hardware gets detected */ |
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c index 4d0282b821b5..2d9e7f3d5611 100644 --- a/drivers/sh/superhyway/superhyway.c +++ b/drivers/sh/superhyway/superhyway.c | |||
@@ -22,7 +22,7 @@ | |||
22 | static int superhyway_devices; | 22 | static int superhyway_devices; |
23 | 23 | ||
24 | static struct device superhyway_bus_device = { | 24 | static struct device superhyway_bus_device = { |
25 | .bus_id = "superhyway", | 25 | .init_name = "superhyway", |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static void superhyway_device_release(struct device *dev) | 28 | static void superhyway_device_release(struct device *dev) |
@@ -83,7 +83,7 @@ int superhyway_add_device(unsigned long base, struct superhyway_device *sdev, | |||
83 | dev->id.id = dev->vcr.mod_id; | 83 | dev->id.id = dev->vcr.mod_id; |
84 | 84 | ||
85 | sprintf(dev->name, "SuperHyway device %04x", dev->id.id); | 85 | sprintf(dev->name, "SuperHyway device %04x", dev->id.id); |
86 | sprintf(dev->dev.bus_id, "%02x", superhyway_devices); | 86 | dev_set_name(&dev->dev, "%02x", superhyway_devices); |
87 | 87 | ||
88 | superhyway_devices++; | 88 | superhyway_devices++; |
89 | 89 | ||
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 56ff3e6864ea..12e443cc4ac9 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
@@ -322,7 +322,7 @@ static void atmel_spi_next_message(struct spi_master *master) | |||
322 | spi = msg->spi; | 322 | spi = msg->spi; |
323 | 323 | ||
324 | dev_dbg(master->dev.parent, "start message %p for %s\n", | 324 | dev_dbg(master->dev.parent, "start message %p for %s\n", |
325 | msg, spi->dev.bus_id); | 325 | msg, dev_name(&spi->dev)); |
326 | 326 | ||
327 | /* select chip if it's not still active */ | 327 | /* select chip if it's not still active */ |
328 | if (as->stay) { | 328 | if (as->stay) { |
@@ -627,7 +627,7 @@ static int atmel_spi_setup(struct spi_device *spi) | |||
627 | if (!asd) | 627 | if (!asd) |
628 | return -ENOMEM; | 628 | return -ENOMEM; |
629 | 629 | ||
630 | ret = gpio_request(npcs_pin, spi->dev.bus_id); | 630 | ret = gpio_request(npcs_pin, dev_name(&spi->dev)); |
631 | if (ret) { | 631 | if (ret) { |
632 | kfree(asd); | 632 | kfree(asd); |
633 | return ret; | 633 | return ret; |
@@ -668,7 +668,7 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) | |||
668 | as = spi_master_get_devdata(spi->master); | 668 | as = spi_master_get_devdata(spi->master); |
669 | 669 | ||
670 | dev_dbg(controller, "new message %p submitted for %s\n", | 670 | dev_dbg(controller, "new message %p submitted for %s\n", |
671 | msg, spi->dev.bus_id); | 671 | msg, dev_name(&spi->dev)); |
672 | 672 | ||
673 | if (unlikely(list_empty(&msg->transfers))) | 673 | if (unlikely(list_empty(&msg->transfers))) |
674 | return -EINVAL; | 674 | return -EINVAL; |
@@ -803,7 +803,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev) | |||
803 | as->clk = clk; | 803 | as->clk = clk; |
804 | 804 | ||
805 | ret = request_irq(irq, atmel_spi_interrupt, 0, | 805 | ret = request_irq(irq, atmel_spi_interrupt, 0, |
806 | pdev->dev.bus_id, master); | 806 | dev_name(&pdev->dev), master); |
807 | if (ret) | 807 | if (ret) |
808 | goto out_unmap_regs; | 808 | goto out_unmap_regs; |
809 | 809 | ||
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 3b97803e1d11..68c77a911595 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c | |||
@@ -429,7 +429,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, | |||
429 | INIT_LIST_HEAD(&mps->queue); | 429 | INIT_LIST_HEAD(&mps->queue); |
430 | 430 | ||
431 | mps->workqueue = create_singlethread_workqueue( | 431 | mps->workqueue = create_singlethread_workqueue( |
432 | master->dev.parent->bus_id); | 432 | dev_name(master->dev.parent)); |
433 | if (mps->workqueue == NULL) { | 433 | if (mps->workqueue == NULL) { |
434 | ret = -EBUSY; | 434 | ret = -EBUSY; |
435 | goto free_irq; | 435 | goto free_irq; |
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 454a2712e629..1c65e380c845 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c | |||
@@ -1003,7 +1003,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
1003 | goto err1; | 1003 | goto err1; |
1004 | } | 1004 | } |
1005 | if (!request_mem_region(r->start, (r->end - r->start) + 1, | 1005 | if (!request_mem_region(r->start, (r->end - r->start) + 1, |
1006 | pdev->dev.bus_id)) { | 1006 | dev_name(&pdev->dev))) { |
1007 | status = -EBUSY; | 1007 | status = -EBUSY; |
1008 | goto err1; | 1008 | goto err1; |
1009 | } | 1009 | } |
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c index bab6ff061e91..60b5381c65c4 100644 --- a/drivers/spi/omap_uwire.c +++ b/drivers/spi/omap_uwire.c | |||
@@ -245,7 +245,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
245 | 245 | ||
246 | #ifdef VERBOSE | 246 | #ifdef VERBOSE |
247 | pr_debug("%s: write-%d =%04x\n", | 247 | pr_debug("%s: write-%d =%04x\n", |
248 | spi->dev.bus_id, bits, val); | 248 | dev_name(&spi->dev), bits, val); |
249 | #endif | 249 | #endif |
250 | if (wait_uwire_csr_flag(CSRB, 0, 0)) | 250 | if (wait_uwire_csr_flag(CSRB, 0, 0)) |
251 | goto eio; | 251 | goto eio; |
@@ -305,7 +305,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t) | |||
305 | status += bytes; | 305 | status += bytes; |
306 | #ifdef VERBOSE | 306 | #ifdef VERBOSE |
307 | pr_debug("%s: read-%d =%04x\n", | 307 | pr_debug("%s: read-%d =%04x\n", |
308 | spi->dev.bus_id, bits, val); | 308 | dev_name(&spi->dev), bits, val); |
309 | #endif | 309 | #endif |
310 | 310 | ||
311 | } | 311 | } |
@@ -331,7 +331,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
331 | uwire = spi_master_get_devdata(spi->master); | 331 | uwire = spi_master_get_devdata(spi->master); |
332 | 332 | ||
333 | if (spi->chip_select > 3) { | 333 | if (spi->chip_select > 3) { |
334 | pr_debug("%s: cs%d?\n", spi->dev.bus_id, spi->chip_select); | 334 | pr_debug("%s: cs%d?\n", dev_name(&spi->dev), spi->chip_select); |
335 | status = -ENODEV; | 335 | status = -ENODEV; |
336 | goto done; | 336 | goto done; |
337 | } | 337 | } |
@@ -343,7 +343,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
343 | bits = 8; | 343 | bits = 8; |
344 | 344 | ||
345 | if (bits > 16) { | 345 | if (bits > 16) { |
346 | pr_debug("%s: wordsize %d?\n", spi->dev.bus_id, bits); | 346 | pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits); |
347 | status = -ENODEV; | 347 | status = -ENODEV; |
348 | goto done; | 348 | goto done; |
349 | } | 349 | } |
@@ -378,7 +378,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
378 | hz = t->speed_hz; | 378 | hz = t->speed_hz; |
379 | 379 | ||
380 | if (!hz) { | 380 | if (!hz) { |
381 | pr_debug("%s: zero speed?\n", spi->dev.bus_id); | 381 | pr_debug("%s: zero speed?\n", dev_name(&spi->dev)); |
382 | status = -EINVAL; | 382 | status = -EINVAL; |
383 | goto done; | 383 | goto done; |
384 | } | 384 | } |
@@ -406,7 +406,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
406 | } | 406 | } |
407 | if (div1_idx == 4) { | 407 | if (div1_idx == 4) { |
408 | pr_debug("%s: lowest clock %ld, need %d\n", | 408 | pr_debug("%s: lowest clock %ld, need %d\n", |
409 | spi->dev.bus_id, rate / 10 / 8, hz); | 409 | dev_name(&spi->dev), rate / 10 / 8, hz); |
410 | status = -EDOM; | 410 | status = -EDOM; |
411 | goto done; | 411 | goto done; |
412 | } | 412 | } |
diff --git a/drivers/spi/orion_spi.c b/drivers/spi/orion_spi.c index 014becb7d530..c8b0babdc2a6 100644 --- a/drivers/spi/orion_spi.c +++ b/drivers/spi/orion_spi.c | |||
@@ -496,7 +496,7 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
496 | } | 496 | } |
497 | 497 | ||
498 | if (!request_mem_region(r->start, (r->end - r->start) + 1, | 498 | if (!request_mem_region(r->start, (r->end - r->start) + 1, |
499 | pdev->dev.bus_id)) { | 499 | dev_name(&pdev->dev))) { |
500 | status = -EBUSY; | 500 | status = -EBUSY; |
501 | goto out; | 501 | goto out; |
502 | } | 502 | } |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index d0fc4ca2f656..ec24f2d16f3c 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -1333,7 +1333,7 @@ static int __init init_queue(struct driver_data *drv_data) | |||
1333 | 1333 | ||
1334 | INIT_WORK(&drv_data->pump_messages, pump_messages); | 1334 | INIT_WORK(&drv_data->pump_messages, pump_messages); |
1335 | drv_data->workqueue = create_singlethread_workqueue( | 1335 | drv_data->workqueue = create_singlethread_workqueue( |
1336 | drv_data->master->dev.parent->bus_id); | 1336 | dev_name(drv_data->master->dev.parent)); |
1337 | if (drv_data->workqueue == NULL) | 1337 | if (drv_data->workqueue == NULL) |
1338 | return -EBUSY; | 1338 | return -EBUSY; |
1339 | 1339 | ||
@@ -1462,7 +1462,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1462 | drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR; | 1462 | drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR; |
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data); | 1465 | status = request_irq(ssp->irq, ssp_int, 0, dev_name(dev), drv_data); |
1466 | if (status < 0) { | 1466 | if (status < 0) { |
1467 | dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq); | 1467 | dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq); |
1468 | goto out_error_master_alloc; | 1468 | goto out_error_master_alloc; |
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 7fea3cf4588a..3410b0c55ed2 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -1160,8 +1160,8 @@ static inline int init_queue(struct driver_data *drv_data) | |||
1160 | 1160 | ||
1161 | /* init messages workqueue */ | 1161 | /* init messages workqueue */ |
1162 | INIT_WORK(&drv_data->pump_messages, pump_messages); | 1162 | INIT_WORK(&drv_data->pump_messages, pump_messages); |
1163 | drv_data->workqueue = | 1163 | drv_data->workqueue = create_singlethread_workqueue( |
1164 | create_singlethread_workqueue(drv_data->master->dev.parent->bus_id); | 1164 | dev_name(drv_data->master->dev.parent)); |
1165 | if (drv_data->workqueue == NULL) | 1165 | if (drv_data->workqueue == NULL) |
1166 | return -EBUSY; | 1166 | return -EBUSY; |
1167 | 1167 | ||
diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c index f5ed9721aabb..d2866c293dee 100644 --- a/drivers/spi/spi_gpio.c +++ b/drivers/spi/spi_gpio.c | |||
@@ -191,7 +191,7 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
191 | return -EINVAL; | 191 | return -EINVAL; |
192 | 192 | ||
193 | if (!spi->controller_state) { | 193 | if (!spi->controller_state) { |
194 | status = gpio_request(cs, spi->dev.bus_id); | 194 | status = gpio_request(cs, dev_name(&spi->dev)); |
195 | if (status) | 195 | if (status) |
196 | return status; | 196 | return status; |
197 | status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); | 197 | status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); |
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 269a55ec52ef..0480d8bb19d3 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
@@ -1381,7 +1381,7 @@ static int __init init_queue(struct driver_data *drv_data) | |||
1381 | 1381 | ||
1382 | INIT_WORK(&drv_data->work, pump_messages); | 1382 | INIT_WORK(&drv_data->work, pump_messages); |
1383 | drv_data->workqueue = create_singlethread_workqueue( | 1383 | drv_data->workqueue = create_singlethread_workqueue( |
1384 | drv_data->master->dev.parent->bus_id); | 1384 | dev_name(drv_data->master->dev.parent)); |
1385 | if (drv_data->workqueue == NULL) | 1385 | if (drv_data->workqueue == NULL) |
1386 | return -EBUSY; | 1386 | return -EBUSY; |
1387 | 1387 | ||
@@ -1525,7 +1525,8 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
1525 | status = -ENODEV; | 1525 | status = -ENODEV; |
1526 | goto err_no_irqres; | 1526 | goto err_no_irqres; |
1527 | } | 1527 | } |
1528 | status = request_irq(irq, spi_int, IRQF_DISABLED, dev->bus_id, drv_data); | 1528 | status = request_irq(irq, spi_int, IRQF_DISABLED, |
1529 | dev_name(dev), drv_data); | ||
1529 | if (status < 0) { | 1530 | if (status < 0) { |
1530 | dev_err(&pdev->dev, "probe - cannot get IRQ (%d)\n", status); | 1531 | dev_err(&pdev->dev, "probe - cannot get IRQ (%d)\n", status); |
1531 | goto err_no_irqres; | 1532 | goto err_no_irqres; |
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index ac0e3e4b3c54..44a2b46ccb79 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c | |||
@@ -637,7 +637,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) | |||
637 | INIT_LIST_HEAD(&mpc83xx_spi->queue); | 637 | INIT_LIST_HEAD(&mpc83xx_spi->queue); |
638 | 638 | ||
639 | mpc83xx_spi->workqueue = create_singlethread_workqueue( | 639 | mpc83xx_spi->workqueue = create_singlethread_workqueue( |
640 | master->dev.parent->bus_id); | 640 | dev_name(master->dev.parent)); |
641 | if (mpc83xx_spi->workqueue == NULL) { | 641 | if (mpc83xx_spi->workqueue == NULL) { |
642 | ret = -EBUSY; | 642 | ret = -EBUSY; |
643 | goto free_irq; | 643 | goto free_irq; |
@@ -649,7 +649,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev) | |||
649 | 649 | ||
650 | printk(KERN_INFO | 650 | printk(KERN_INFO |
651 | "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n", | 651 | "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n", |
652 | dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq); | 652 | dev_name(&dev->dev), mpc83xx_spi->base, mpc83xx_spi->irq); |
653 | 653 | ||
654 | return ret; | 654 | return ret; |
655 | 655 | ||
diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c index 2296f37ea3c6..29cbb065618a 100644 --- a/drivers/spi/spi_txx9.c +++ b/drivers/spi/spi_txx9.c | |||
@@ -404,7 +404,8 @@ static int __init txx9spi_probe(struct platform_device *dev) | |||
404 | if (ret) | 404 | if (ret) |
405 | goto exit; | 405 | goto exit; |
406 | 406 | ||
407 | c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id); | 407 | c->workqueue = create_singlethread_workqueue( |
408 | dev_name(master->dev.parent)); | ||
408 | if (!c->workqueue) | 409 | if (!c->workqueue) |
409 | goto exit_busy; | 410 | goto exit_busy; |
410 | c->last_chipselect = -1; | 411 | c->last_chipselect = -1; |
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c index a7de401f61ab..cd19be6c00e0 100644 --- a/drivers/staging/go7007/snd-go7007.c +++ b/drivers/staging/go7007/snd-go7007.c | |||
@@ -248,10 +248,11 @@ int go7007_snd_init(struct go7007 *go) | |||
248 | spin_lock_init(&gosnd->lock); | 248 | spin_lock_init(&gosnd->lock); |
249 | gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0; | 249 | gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0; |
250 | gosnd->capturing = 0; | 250 | gosnd->capturing = 0; |
251 | gosnd->card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 251 | ret = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, |
252 | if (gosnd->card == NULL) { | 252 | &gosnd->card); |
253 | if (ret < 0) { | ||
253 | kfree(gosnd); | 254 | kfree(gosnd); |
254 | return -ENOMEM; | 255 | return ret; |
255 | } | 256 | } |
256 | ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go, | 257 | ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go, |
257 | &go7007_snd_device_ops); | 258 | &go7007_snd_device_ops); |
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index f77f62a4b325..e5bd4470a570 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c | |||
@@ -86,7 +86,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) | |||
86 | slot); | 86 | slot); |
87 | goto out_err; | 87 | goto out_err; |
88 | } | 88 | } |
89 | sprintf(tdev->dev.bus_id, "tc%x", slot); | 89 | dev_set_name(&tdev->dev, "tc%x", slot); |
90 | tdev->bus = tbus; | 90 | tdev->bus = tbus; |
91 | tdev->dev.parent = &tbus->dev; | 91 | tdev->dev.parent = &tbus->dev; |
92 | tdev->dev.bus = &tc_bus_type; | 92 | tdev->dev.bus = &tc_bus_type; |
@@ -104,7 +104,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) | |||
104 | tdev->vendor[8] = 0; | 104 | tdev->vendor[8] = 0; |
105 | tdev->name[8] = 0; | 105 | tdev->name[8] = 0; |
106 | 106 | ||
107 | pr_info("%s: %s %s %s\n", tdev->dev.bus_id, tdev->vendor, | 107 | pr_info("%s: %s %s %s\n", dev_name(&tdev->dev), tdev->vendor, |
108 | tdev->name, tdev->firmware); | 108 | tdev->name, tdev->firmware); |
109 | 109 | ||
110 | devsize = readb(module + offset + TC_SLOT_SIZE); | 110 | devsize = readb(module + offset + TC_SLOT_SIZE); |
@@ -118,7 +118,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) | |||
118 | } else { | 118 | } else { |
119 | printk(KERN_ERR "%s: Cannot provide slot space " | 119 | printk(KERN_ERR "%s: Cannot provide slot space " |
120 | "(%dMiB required, up to %dMiB supported)\n", | 120 | "(%dMiB required, up to %dMiB supported)\n", |
121 | tdev->dev.bus_id, devsize >> 20, | 121 | dev_name(&tdev->dev), devsize >> 20, |
122 | max(slotsize, extslotsize) >> 20); | 122 | max(slotsize, extslotsize) >> 20); |
123 | kfree(tdev); | 123 | kfree(tdev); |
124 | goto out_err; | 124 | goto out_err; |
@@ -146,7 +146,7 @@ static int __init tc_init(void) | |||
146 | return 0; | 146 | return 0; |
147 | 147 | ||
148 | INIT_LIST_HEAD(&tc_bus.devices); | 148 | INIT_LIST_HEAD(&tc_bus.devices); |
149 | strcpy(tc_bus.dev.bus_id, "tc"); | 149 | dev_set_name(&tc_bus.dev, "tc"); |
150 | device_register(&tc_bus.dev); | 150 | device_register(&tc_bus.dev); |
151 | 151 | ||
152 | if (tc_bus.info.slot_size) { | 152 | if (tc_bus.info.slot_size) { |
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig index 04b954cfce76..7f86534de269 100644 --- a/drivers/uio/Kconfig +++ b/drivers/uio/Kconfig | |||
@@ -58,6 +58,24 @@ config UIO_SMX | |||
58 | 58 | ||
59 | If you compile this as a module, it will be called uio_smx. | 59 | If you compile this as a module, it will be called uio_smx. |
60 | 60 | ||
61 | config UIO_AEC | ||
62 | tristate "AEC video timestamp device" | ||
63 | depends on PCI | ||
64 | default n | ||
65 | help | ||
66 | |||
67 | UIO driver for the Adrienne Electronics Corporation PCI time | ||
68 | code device. | ||
69 | |||
70 | This device differs from other UIO devices since it uses I/O | ||
71 | ports instead of memory mapped I/O. In order to make it | ||
72 | possible for UIO to work with this device a utility, uioport, | ||
73 | can be used to read and write the ports: | ||
74 | |||
75 | git clone git://ifup.org/philips/uioport.git | ||
76 | |||
77 | If you compile this as a module, it will be called uio_aec. | ||
78 | |||
61 | config UIO_SERCOS3 | 79 | config UIO_SERCOS3 |
62 | tristate "Automata Sercos III PCI card driver" | 80 | tristate "Automata Sercos III PCI card driver" |
63 | default n | 81 | default n |
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile index e69558149859..5c2586d75797 100644 --- a/drivers/uio/Makefile +++ b/drivers/uio/Makefile | |||
@@ -3,4 +3,5 @@ obj-$(CONFIG_UIO_CIF) += uio_cif.o | |||
3 | obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o | 3 | obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o |
4 | obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o | 4 | obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o |
5 | obj-$(CONFIG_UIO_SMX) += uio_smx.o | 5 | obj-$(CONFIG_UIO_SMX) += uio_smx.o |
6 | obj-$(CONFIG_UIO_AEC) += uio_aec.o | ||
6 | obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o | 7 | obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o |
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 4ca85a113aa2..03efb065455f 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -61,6 +61,14 @@ struct uio_map { | |||
61 | }; | 61 | }; |
62 | #define to_map(map) container_of(map, struct uio_map, kobj) | 62 | #define to_map(map) container_of(map, struct uio_map, kobj) |
63 | 63 | ||
64 | static ssize_t map_name_show(struct uio_mem *mem, char *buf) | ||
65 | { | ||
66 | if (unlikely(!mem->name)) | ||
67 | mem->name = ""; | ||
68 | |||
69 | return sprintf(buf, "%s\n", mem->name); | ||
70 | } | ||
71 | |||
64 | static ssize_t map_addr_show(struct uio_mem *mem, char *buf) | 72 | static ssize_t map_addr_show(struct uio_mem *mem, char *buf) |
65 | { | 73 | { |
66 | return sprintf(buf, "0x%lx\n", mem->addr); | 74 | return sprintf(buf, "0x%lx\n", mem->addr); |
@@ -82,6 +90,8 @@ struct map_sysfs_entry { | |||
82 | ssize_t (*store)(struct uio_mem *, const char *, size_t); | 90 | ssize_t (*store)(struct uio_mem *, const char *, size_t); |
83 | }; | 91 | }; |
84 | 92 | ||
93 | static struct map_sysfs_entry name_attribute = | ||
94 | __ATTR(name, S_IRUGO, map_name_show, NULL); | ||
85 | static struct map_sysfs_entry addr_attribute = | 95 | static struct map_sysfs_entry addr_attribute = |
86 | __ATTR(addr, S_IRUGO, map_addr_show, NULL); | 96 | __ATTR(addr, S_IRUGO, map_addr_show, NULL); |
87 | static struct map_sysfs_entry size_attribute = | 97 | static struct map_sysfs_entry size_attribute = |
@@ -90,6 +100,7 @@ static struct map_sysfs_entry offset_attribute = | |||
90 | __ATTR(offset, S_IRUGO, map_offset_show, NULL); | 100 | __ATTR(offset, S_IRUGO, map_offset_show, NULL); |
91 | 101 | ||
92 | static struct attribute *attrs[] = { | 102 | static struct attribute *attrs[] = { |
103 | &name_attribute.attr, | ||
93 | &addr_attribute.attr, | 104 | &addr_attribute.attr, |
94 | &size_attribute.attr, | 105 | &size_attribute.attr, |
95 | &offset_attribute.attr, | 106 | &offset_attribute.attr, |
@@ -133,6 +144,14 @@ struct uio_portio { | |||
133 | }; | 144 | }; |
134 | #define to_portio(portio) container_of(portio, struct uio_portio, kobj) | 145 | #define to_portio(portio) container_of(portio, struct uio_portio, kobj) |
135 | 146 | ||
147 | static ssize_t portio_name_show(struct uio_port *port, char *buf) | ||
148 | { | ||
149 | if (unlikely(!port->name)) | ||
150 | port->name = ""; | ||
151 | |||
152 | return sprintf(buf, "%s\n", port->name); | ||
153 | } | ||
154 | |||
136 | static ssize_t portio_start_show(struct uio_port *port, char *buf) | 155 | static ssize_t portio_start_show(struct uio_port *port, char *buf) |
137 | { | 156 | { |
138 | return sprintf(buf, "0x%lx\n", port->start); | 157 | return sprintf(buf, "0x%lx\n", port->start); |
@@ -159,6 +178,8 @@ struct portio_sysfs_entry { | |||
159 | ssize_t (*store)(struct uio_port *, const char *, size_t); | 178 | ssize_t (*store)(struct uio_port *, const char *, size_t); |
160 | }; | 179 | }; |
161 | 180 | ||
181 | static struct portio_sysfs_entry portio_name_attribute = | ||
182 | __ATTR(name, S_IRUGO, portio_name_show, NULL); | ||
162 | static struct portio_sysfs_entry portio_start_attribute = | 183 | static struct portio_sysfs_entry portio_start_attribute = |
163 | __ATTR(start, S_IRUGO, portio_start_show, NULL); | 184 | __ATTR(start, S_IRUGO, portio_start_show, NULL); |
164 | static struct portio_sysfs_entry portio_size_attribute = | 185 | static struct portio_sysfs_entry portio_size_attribute = |
@@ -167,6 +188,7 @@ static struct portio_sysfs_entry portio_porttype_attribute = | |||
167 | __ATTR(porttype, S_IRUGO, portio_porttype_show, NULL); | 188 | __ATTR(porttype, S_IRUGO, portio_porttype_show, NULL); |
168 | 189 | ||
169 | static struct attribute *portio_attrs[] = { | 190 | static struct attribute *portio_attrs[] = { |
191 | &portio_name_attribute.attr, | ||
170 | &portio_start_attribute.attr, | 192 | &portio_start_attribute.attr, |
171 | &portio_size_attribute.attr, | 193 | &portio_size_attribute.attr, |
172 | &portio_porttype_attribute.attr, | 194 | &portio_porttype_attribute.attr, |
@@ -686,7 +708,8 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma) | |||
686 | return -EINVAL; | 708 | return -EINVAL; |
687 | 709 | ||
688 | requested_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 710 | requested_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
689 | actual_pages = (idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT; | 711 | actual_pages = ((idev->info->mem[mi].addr & ~PAGE_MASK) |
712 | + idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT; | ||
690 | if (requested_pages > actual_pages) | 713 | if (requested_pages > actual_pages) |
691 | return -EINVAL; | 714 | return -EINVAL; |
692 | 715 | ||
diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c new file mode 100644 index 000000000000..b7830e9a3baa --- /dev/null +++ b/drivers/uio/uio_aec.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * uio_aec.c -- simple driver for Adrienne Electronics Corp time code PCI device | ||
3 | * | ||
4 | * Copyright (C) 2008 Brandon Philips <brandon@ifup.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., 59 | ||
17 | * Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/cdev.h> | ||
26 | #include <linux/fs.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/uaccess.h> | ||
29 | #include <linux/uio_driver.h> | ||
30 | |||
31 | #define PCI_VENDOR_ID_AEC 0xaecb | ||
32 | #define PCI_DEVICE_ID_AEC_VITCLTC 0x6250 | ||
33 | |||
34 | #define INT_ENABLE_ADDR 0xFC | ||
35 | #define INT_ENABLE 0x10 | ||
36 | #define INT_DISABLE 0x0 | ||
37 | |||
38 | #define INT_MASK_ADDR 0x2E | ||
39 | #define INT_MASK_ALL 0x3F | ||
40 | |||
41 | #define INTA_DRVR_ADDR 0xFE | ||
42 | #define INTA_ENABLED_FLAG 0x08 | ||
43 | #define INTA_FLAG 0x01 | ||
44 | |||
45 | #define MAILBOX 0x0F | ||
46 | |||
47 | static struct pci_device_id ids[] = { | ||
48 | { PCI_DEVICE(PCI_VENDOR_ID_AEC, PCI_DEVICE_ID_AEC_VITCLTC), }, | ||
49 | { 0, } | ||
50 | }; | ||
51 | MODULE_DEVICE_TABLE(pci, ids); | ||
52 | |||
53 | static irqreturn_t aectc_irq(int irq, struct uio_info *dev_info) | ||
54 | { | ||
55 | void __iomem *int_flag = dev_info->priv + INTA_DRVR_ADDR; | ||
56 | unsigned char status = ioread8(int_flag); | ||
57 | |||
58 | |||
59 | if ((status & INTA_ENABLED_FLAG) && (status & INTA_FLAG)) { | ||
60 | /* application writes 0x00 to 0x2F to get next interrupt */ | ||
61 | status = ioread8(dev_info->priv + MAILBOX); | ||
62 | return IRQ_HANDLED; | ||
63 | } | ||
64 | |||
65 | return IRQ_NONE; | ||
66 | } | ||
67 | |||
68 | static void print_board_data(struct pci_dev *pdev, struct uio_info *i) | ||
69 | { | ||
70 | dev_info(&pdev->dev, "PCI-TC board vendor: %x%x number: %x%x" | ||
71 | " revision: %c%c\n", | ||
72 | ioread8(i->priv + 0x01), | ||
73 | ioread8(i->priv + 0x00), | ||
74 | ioread8(i->priv + 0x03), | ||
75 | ioread8(i->priv + 0x02), | ||
76 | ioread8(i->priv + 0x06), | ||
77 | ioread8(i->priv + 0x07)); | ||
78 | } | ||
79 | |||
80 | static int __devinit probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
81 | { | ||
82 | struct uio_info *info; | ||
83 | int ret; | ||
84 | |||
85 | info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); | ||
86 | if (!info) | ||
87 | return -ENOMEM; | ||
88 | |||
89 | if (pci_enable_device(pdev)) | ||
90 | goto out_free; | ||
91 | |||
92 | if (pci_request_regions(pdev, "aectc")) | ||
93 | goto out_disable; | ||
94 | |||
95 | info->name = "aectc"; | ||
96 | info->port[0].start = pci_resource_start(pdev, 0); | ||
97 | if (!info->port[0].start) | ||
98 | goto out_release; | ||
99 | info->priv = pci_iomap(pdev, 0, 0); | ||
100 | if (!info->priv) | ||
101 | goto out_release; | ||
102 | info->port[0].size = pci_resource_len(pdev, 0); | ||
103 | info->port[0].porttype = UIO_PORT_GPIO; | ||
104 | |||
105 | info->version = "0.0.1"; | ||
106 | info->irq = pdev->irq; | ||
107 | info->irq_flags = IRQF_SHARED; | ||
108 | info->handler = aectc_irq; | ||
109 | |||
110 | print_board_data(pdev, info); | ||
111 | ret = uio_register_device(&pdev->dev, info); | ||
112 | if (ret) | ||
113 | goto out_unmap; | ||
114 | |||
115 | iowrite32(INT_ENABLE, info->priv + INT_ENABLE_ADDR); | ||
116 | iowrite8(INT_MASK_ALL, info->priv + INT_MASK_ADDR); | ||
117 | if (!(ioread8(info->priv + INTA_DRVR_ADDR) | ||
118 | & INTA_ENABLED_FLAG)) | ||
119 | dev_err(&pdev->dev, "aectc: interrupts not enabled\n"); | ||
120 | |||
121 | pci_set_drvdata(pdev, info); | ||
122 | |||
123 | return 0; | ||
124 | |||
125 | out_unmap: | ||
126 | pci_iounmap(pdev, info->priv); | ||
127 | out_release: | ||
128 | pci_release_regions(pdev); | ||
129 | out_disable: | ||
130 | pci_disable_device(pdev); | ||
131 | out_free: | ||
132 | kfree(info); | ||
133 | return -ENODEV; | ||
134 | } | ||
135 | |||
136 | static void remove(struct pci_dev *pdev) | ||
137 | { | ||
138 | struct uio_info *info = pci_get_drvdata(pdev); | ||
139 | |||
140 | /* disable interrupts */ | ||
141 | iowrite8(INT_DISABLE, info->priv + INT_MASK_ADDR); | ||
142 | iowrite32(INT_DISABLE, info->priv + INT_ENABLE_ADDR); | ||
143 | /* read mailbox to ensure board drops irq */ | ||
144 | ioread8(info->priv + MAILBOX); | ||
145 | |||
146 | uio_unregister_device(info); | ||
147 | pci_release_regions(pdev); | ||
148 | pci_disable_device(pdev); | ||
149 | pci_set_drvdata(pdev, NULL); | ||
150 | iounmap(info->priv); | ||
151 | |||
152 | kfree(info); | ||
153 | } | ||
154 | |||
155 | static struct pci_driver pci_driver = { | ||
156 | .name = "aectc", | ||
157 | .id_table = ids, | ||
158 | .probe = probe, | ||
159 | .remove = remove, | ||
160 | }; | ||
161 | |||
162 | static int __init aectc_init(void) | ||
163 | { | ||
164 | return pci_register_driver(&pci_driver); | ||
165 | } | ||
166 | |||
167 | static void __exit aectc_exit(void) | ||
168 | { | ||
169 | pci_unregister_driver(&pci_driver); | ||
170 | } | ||
171 | |||
172 | MODULE_LICENSE("GPL"); | ||
173 | |||
174 | module_init(aectc_init); | ||
175 | module_exit(aectc_exit); | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 83babb0a1df7..c6c816b7ecb5 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -47,6 +47,7 @@ config USB_ARCH_HAS_OHCI | |||
47 | default y if CPU_SUBTYPE_SH7720 | 47 | default y if CPU_SUBTYPE_SH7720 |
48 | default y if CPU_SUBTYPE_SH7721 | 48 | default y if CPU_SUBTYPE_SH7721 |
49 | default y if CPU_SUBTYPE_SH7763 | 49 | default y if CPU_SUBTYPE_SH7763 |
50 | default y if CPU_SUBTYPE_SH7786 | ||
50 | # more: | 51 | # more: |
51 | default PCI | 52 | default PCI |
52 | 53 | ||
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index b2ceb4aff233..89299a5ce168 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_USB_SL811_HCD) += host/ | |||
19 | obj-$(CONFIG_USB_U132_HCD) += host/ | 19 | obj-$(CONFIG_USB_U132_HCD) += host/ |
20 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ | 20 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ |
21 | obj-$(CONFIG_USB_HWA_HCD) += host/ | 21 | obj-$(CONFIG_USB_HWA_HCD) += host/ |
22 | obj-$(CONFIG_USB_ISP1760_HCD) += host/ | ||
22 | 23 | ||
23 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ | 24 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ |
24 | 25 | ||
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 3f3ee1351930..d2747a49b974 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -880,16 +880,19 @@ static int usblp_wwait(struct usblp *usblp, int nonblock) | |||
880 | if (rc <= 0) | 880 | if (rc <= 0) |
881 | break; | 881 | break; |
882 | 882 | ||
883 | if (usblp->flags & LP_ABORT) { | 883 | if (schedule_timeout(msecs_to_jiffies(1500)) == 0) { |
884 | if (schedule_timeout(msecs_to_jiffies(5000)) == 0) { | 884 | if (usblp->flags & LP_ABORT) { |
885 | err = usblp_check_status(usblp, err); | 885 | err = usblp_check_status(usblp, err); |
886 | if (err == 1) { /* Paper out */ | 886 | if (err == 1) { /* Paper out */ |
887 | rc = -ENOSPC; | 887 | rc = -ENOSPC; |
888 | break; | 888 | break; |
889 | } | 889 | } |
890 | } else { | ||
891 | /* Prod the printer, Gentoo#251237. */ | ||
892 | mutex_lock(&usblp->mut); | ||
893 | usblp_read_status(usblp, usblp->statusbuf); | ||
894 | mutex_unlock(&usblp->mut); | ||
890 | } | 895 | } |
891 | } else { | ||
892 | schedule(); | ||
893 | } | 896 | } |
894 | } | 897 | } |
895 | set_current_state(TASK_RUNNING); | 898 | set_current_state(TASK_RUNNING); |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 6ec38175a817..73c108d117b4 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -187,7 +187,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end, | |||
187 | } | 187 | } |
188 | 188 | ||
189 | /* this isn't checking for illegal values */ | 189 | /* this isn't checking for illegal values */ |
190 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 190 | switch (usb_endpoint_type(desc)) { |
191 | case USB_ENDPOINT_XFER_CONTROL: | 191 | case USB_ENDPOINT_XFER_CONTROL: |
192 | type = "Ctrl"; | 192 | type = "Ctrl"; |
193 | if (speed == USB_SPEED_HIGH) /* uframes per NAK */ | 193 | if (speed == USB_SPEED_HIGH) /* uframes per NAK */ |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6585f527e381..df3c539f652a 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -104,7 +104,7 @@ MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); | |||
104 | 104 | ||
105 | #define MAX_USBFS_BUFFER_SIZE 16384 | 105 | #define MAX_USBFS_BUFFER_SIZE 16384 |
106 | 106 | ||
107 | static inline int connected(struct dev_state *ps) | 107 | static int connected(struct dev_state *ps) |
108 | { | 108 | { |
109 | return (!list_empty(&ps->list) && | 109 | return (!list_empty(&ps->list) && |
110 | ps->dev->state != USB_STATE_NOTATTACHED); | 110 | ps->dev->state != USB_STATE_NOTATTACHED); |
@@ -248,7 +248,7 @@ static void free_async(struct async *as) | |||
248 | kfree(as); | 248 | kfree(as); |
249 | } | 249 | } |
250 | 250 | ||
251 | static inline void async_newpending(struct async *as) | 251 | static void async_newpending(struct async *as) |
252 | { | 252 | { |
253 | struct dev_state *ps = as->ps; | 253 | struct dev_state *ps = as->ps; |
254 | unsigned long flags; | 254 | unsigned long flags; |
@@ -258,7 +258,7 @@ static inline void async_newpending(struct async *as) | |||
258 | spin_unlock_irqrestore(&ps->lock, flags); | 258 | spin_unlock_irqrestore(&ps->lock, flags); |
259 | } | 259 | } |
260 | 260 | ||
261 | static inline void async_removepending(struct async *as) | 261 | static void async_removepending(struct async *as) |
262 | { | 262 | { |
263 | struct dev_state *ps = as->ps; | 263 | struct dev_state *ps = as->ps; |
264 | unsigned long flags; | 264 | unsigned long flags; |
@@ -268,7 +268,7 @@ static inline void async_removepending(struct async *as) | |||
268 | spin_unlock_irqrestore(&ps->lock, flags); | 268 | spin_unlock_irqrestore(&ps->lock, flags); |
269 | } | 269 | } |
270 | 270 | ||
271 | static inline struct async *async_getcompleted(struct dev_state *ps) | 271 | static struct async *async_getcompleted(struct dev_state *ps) |
272 | { | 272 | { |
273 | unsigned long flags; | 273 | unsigned long flags; |
274 | struct async *as = NULL; | 274 | struct async *as = NULL; |
@@ -283,7 +283,7 @@ static inline struct async *async_getcompleted(struct dev_state *ps) | |||
283 | return as; | 283 | return as; |
284 | } | 284 | } |
285 | 285 | ||
286 | static inline struct async *async_getpending(struct dev_state *ps, | 286 | static struct async *async_getpending(struct dev_state *ps, |
287 | void __user *userurb) | 287 | void __user *userurb) |
288 | { | 288 | { |
289 | unsigned long flags; | 289 | unsigned long flags; |
@@ -302,7 +302,7 @@ static inline struct async *async_getpending(struct dev_state *ps, | |||
302 | 302 | ||
303 | static void snoop_urb(struct urb *urb, void __user *userurb) | 303 | static void snoop_urb(struct urb *urb, void __user *userurb) |
304 | { | 304 | { |
305 | int j; | 305 | unsigned j; |
306 | unsigned char *data = urb->transfer_buffer; | 306 | unsigned char *data = urb->transfer_buffer; |
307 | 307 | ||
308 | if (!usbfs_snoop) | 308 | if (!usbfs_snoop) |
@@ -311,9 +311,9 @@ static void snoop_urb(struct urb *urb, void __user *userurb) | |||
311 | dev_info(&urb->dev->dev, "direction=%s\n", | 311 | dev_info(&urb->dev->dev, "direction=%s\n", |
312 | usb_urb_dir_in(urb) ? "IN" : "OUT"); | 312 | usb_urb_dir_in(urb) ? "IN" : "OUT"); |
313 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); | 313 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); |
314 | dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", | 314 | dev_info(&urb->dev->dev, "transfer_buffer_length=%u\n", |
315 | urb->transfer_buffer_length); | 315 | urb->transfer_buffer_length); |
316 | dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); | 316 | dev_info(&urb->dev->dev, "actual_length=%u\n", urb->actual_length); |
317 | dev_info(&urb->dev->dev, "data: "); | 317 | dev_info(&urb->dev->dev, "data: "); |
318 | for (j = 0; j < urb->transfer_buffer_length; ++j) | 318 | for (j = 0; j < urb->transfer_buffer_length; ++j) |
319 | printk("%02x ", data[j]); | 319 | printk("%02x ", data[j]); |
@@ -376,7 +376,7 @@ static void destroy_async_on_interface(struct dev_state *ps, | |||
376 | destroy_async(ps, &hitlist); | 376 | destroy_async(ps, &hitlist); |
377 | } | 377 | } |
378 | 378 | ||
379 | static inline void destroy_all_async(struct dev_state *ps) | 379 | static void destroy_all_async(struct dev_state *ps) |
380 | { | 380 | { |
381 | destroy_async(ps, &ps->async_pending); | 381 | destroy_async(ps, &ps->async_pending); |
382 | } | 382 | } |
@@ -525,7 +525,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, | |||
525 | { | 525 | { |
526 | int ret = 0; | 526 | int ret = 0; |
527 | 527 | ||
528 | if (ps->dev->state != USB_STATE_ADDRESS | 528 | if (ps->dev->state != USB_STATE_UNAUTHENTICATED |
529 | && ps->dev->state != USB_STATE_ADDRESS | ||
529 | && ps->dev->state != USB_STATE_CONFIGURED) | 530 | && ps->dev->state != USB_STATE_CONFIGURED) |
530 | return -EHOSTUNREACH; | 531 | return -EHOSTUNREACH; |
531 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) | 532 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) |
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index e1710f260b4f..40dee2ac0133 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
@@ -66,7 +66,7 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, | |||
66 | struct ep_device *ep = to_ep_device(dev); | 66 | struct ep_device *ep = to_ep_device(dev); |
67 | char *type = "unknown"; | 67 | char *type = "unknown"; |
68 | 68 | ||
69 | switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 69 | switch (usb_endpoint_type(ep->desc)) { |
70 | case USB_ENDPOINT_XFER_CONTROL: | 70 | case USB_ENDPOINT_XFER_CONTROL: |
71 | type = "Control"; | 71 | type = "Control"; |
72 | break; | 72 | break; |
@@ -94,7 +94,7 @@ static ssize_t show_ep_interval(struct device *dev, | |||
94 | 94 | ||
95 | in = (ep->desc->bEndpointAddress & USB_DIR_IN); | 95 | in = (ep->desc->bEndpointAddress & USB_DIR_IN); |
96 | 96 | ||
97 | switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 97 | switch (usb_endpoint_type(ep->desc)) { |
98 | case USB_ENDPOINT_XFER_CONTROL: | 98 | case USB_ENDPOINT_XFER_CONTROL: |
99 | if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ | 99 | if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ |
100 | interval = ep->desc->bInterval; | 100 | interval = ep->desc->bInterval; |
@@ -131,10 +131,9 @@ static ssize_t show_ep_direction(struct device *dev, | |||
131 | struct ep_device *ep = to_ep_device(dev); | 131 | struct ep_device *ep = to_ep_device(dev); |
132 | char *direction; | 132 | char *direction; |
133 | 133 | ||
134 | if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | 134 | if (usb_endpoint_xfer_control(ep->desc)) |
135 | USB_ENDPOINT_XFER_CONTROL) | ||
136 | direction = "both"; | 135 | direction = "both"; |
137 | else if (ep->desc->bEndpointAddress & USB_DIR_IN) | 136 | else if (usb_endpoint_dir_in(ep->desc)) |
138 | direction = "in"; | 137 | direction = "in"; |
139 | else | 138 | else |
140 | direction = "out"; | 139 | direction = "out"; |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 3c711db55d86..81fa8506825d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -279,9 +279,9 @@ static const u8 hs_rh_config_descriptor [] = { | |||
279 | * helper routine for returning string descriptors in UTF-16LE | 279 | * helper routine for returning string descriptors in UTF-16LE |
280 | * input can actually be ISO-8859-1; ASCII is its 7-bit subset | 280 | * input can actually be ISO-8859-1; ASCII is its 7-bit subset |
281 | */ | 281 | */ |
282 | static int ascii2utf (char *s, u8 *utf, int utfmax) | 282 | static unsigned ascii2utf(char *s, u8 *utf, int utfmax) |
283 | { | 283 | { |
284 | int retval; | 284 | unsigned retval; |
285 | 285 | ||
286 | for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { | 286 | for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { |
287 | *utf++ = *s++; | 287 | *utf++ = *s++; |
@@ -304,19 +304,15 @@ static int ascii2utf (char *s, u8 *utf, int utfmax) | |||
304 | * Produces either a manufacturer, product or serial number string for the | 304 | * Produces either a manufacturer, product or serial number string for the |
305 | * virtual root hub device. | 305 | * virtual root hub device. |
306 | */ | 306 | */ |
307 | static int rh_string ( | 307 | static unsigned rh_string(int id, struct usb_hcd *hcd, u8 *data, unsigned len) |
308 | int id, | 308 | { |
309 | struct usb_hcd *hcd, | ||
310 | u8 *data, | ||
311 | int len | ||
312 | ) { | ||
313 | char buf [100]; | 309 | char buf [100]; |
314 | 310 | ||
315 | // language ids | 311 | // language ids |
316 | if (id == 0) { | 312 | if (id == 0) { |
317 | buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ | 313 | buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ |
318 | buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ | 314 | buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ |
319 | len = min (len, 4); | 315 | len = min_t(unsigned, len, 4); |
320 | memcpy (data, buf, len); | 316 | memcpy (data, buf, len); |
321 | return len; | 317 | return len; |
322 | 318 | ||
@@ -332,10 +328,7 @@ static int rh_string ( | |||
332 | } else if (id == 3) { | 328 | } else if (id == 3) { |
333 | snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, | 329 | snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, |
334 | init_utsname()->release, hcd->driver->description); | 330 | init_utsname()->release, hcd->driver->description); |
335 | 331 | } | |
336 | // unsupported IDs --> "protocol stall" | ||
337 | } else | ||
338 | return -EPIPE; | ||
339 | 332 | ||
340 | switch (len) { /* All cases fall through */ | 333 | switch (len) { /* All cases fall through */ |
341 | default: | 334 | default: |
@@ -360,9 +353,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
360 | u8 tbuf [sizeof (struct usb_hub_descriptor)] | 353 | u8 tbuf [sizeof (struct usb_hub_descriptor)] |
361 | __attribute__((aligned(4))); | 354 | __attribute__((aligned(4))); |
362 | const u8 *bufp = tbuf; | 355 | const u8 *bufp = tbuf; |
363 | int len = 0; | 356 | unsigned len = 0; |
364 | int status; | 357 | int status; |
365 | int n; | ||
366 | u8 patch_wakeup = 0; | 358 | u8 patch_wakeup = 0; |
367 | u8 patch_protocol = 0; | 359 | u8 patch_protocol = 0; |
368 | 360 | ||
@@ -456,10 +448,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
456 | patch_wakeup = 1; | 448 | patch_wakeup = 1; |
457 | break; | 449 | break; |
458 | case USB_DT_STRING << 8: | 450 | case USB_DT_STRING << 8: |
459 | n = rh_string (wValue & 0xff, hcd, ubuf, wLength); | 451 | if ((wValue & 0xff) < 4) |
460 | if (n < 0) | 452 | urb->actual_length = rh_string(wValue & 0xff, |
453 | hcd, ubuf, wLength); | ||
454 | else /* unsupported IDs --> "protocol stall" */ | ||
461 | goto error; | 455 | goto error; |
462 | urb->actual_length = n; | ||
463 | break; | 456 | break; |
464 | default: | 457 | default: |
465 | goto error; | 458 | goto error; |
@@ -629,7 +622,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb) | |||
629 | { | 622 | { |
630 | int retval; | 623 | int retval; |
631 | unsigned long flags; | 624 | unsigned long flags; |
632 | int len = 1 + (urb->dev->maxchild / 8); | 625 | unsigned len = 1 + (urb->dev->maxchild / 8); |
633 | 626 | ||
634 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 627 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
635 | if (hcd->status_urb || urb->transfer_buffer_length < len) { | 628 | if (hcd->status_urb || urb->transfer_buffer_length < len) { |
@@ -901,7 +894,7 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
901 | 894 | ||
902 | mutex_lock(&usb_bus_list_lock); | 895 | mutex_lock(&usb_bus_list_lock); |
903 | 896 | ||
904 | usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 897 | usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
905 | retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); | 898 | retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); |
906 | if (retval != sizeof usb_dev->descriptor) { | 899 | if (retval != sizeof usb_dev->descriptor) { |
907 | mutex_unlock(&usb_bus_list_lock); | 900 | mutex_unlock(&usb_bus_list_lock); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index cd50d86029e7..be86ae3f4088 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb) | |||
392 | { | 392 | { |
393 | struct usb_hub *hub = urb->context; | 393 | struct usb_hub *hub = urb->context; |
394 | int status = urb->status; | 394 | int status = urb->status; |
395 | int i; | 395 | unsigned i; |
396 | unsigned long bits; | 396 | unsigned long bits; |
397 | 397 | ||
398 | switch (status) { | 398 | switch (status) { |
@@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev, | |||
1305 | recursively_mark_NOTATTACHED(udev); | 1305 | recursively_mark_NOTATTACHED(udev); |
1306 | spin_unlock_irqrestore(&device_state_lock, flags); | 1306 | spin_unlock_irqrestore(&device_state_lock, flags); |
1307 | } | 1307 | } |
1308 | EXPORT_SYMBOL_GPL(usb_set_device_state); | ||
1308 | 1309 | ||
1309 | /* | 1310 | /* |
1310 | * WUSB devices are simple: they have no hubs behind, so the mapping | 1311 | * WUSB devices are simple: they have no hubs behind, so the mapping |
@@ -2471,20 +2472,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2471 | */ | 2472 | */ |
2472 | switch (udev->speed) { | 2473 | switch (udev->speed) { |
2473 | case USB_SPEED_VARIABLE: /* fixed at 512 */ | 2474 | case USB_SPEED_VARIABLE: /* fixed at 512 */ |
2474 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512); | 2475 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); |
2475 | break; | 2476 | break; |
2476 | case USB_SPEED_HIGH: /* fixed at 64 */ | 2477 | case USB_SPEED_HIGH: /* fixed at 64 */ |
2477 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 2478 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
2478 | break; | 2479 | break; |
2479 | case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ | 2480 | case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ |
2480 | /* to determine the ep0 maxpacket size, try to read | 2481 | /* to determine the ep0 maxpacket size, try to read |
2481 | * the device descriptor to get bMaxPacketSize0 and | 2482 | * the device descriptor to get bMaxPacketSize0 and |
2482 | * then correct our initial guess. | 2483 | * then correct our initial guess. |
2483 | */ | 2484 | */ |
2484 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 2485 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
2485 | break; | 2486 | break; |
2486 | case USB_SPEED_LOW: /* fixed at 8 */ | 2487 | case USB_SPEED_LOW: /* fixed at 8 */ |
2487 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8); | 2488 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); |
2488 | break; | 2489 | break; |
2489 | default: | 2490 | default: |
2490 | goto fail; | 2491 | goto fail; |
@@ -3392,10 +3393,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3392 | udev->descriptor = descriptor; /* for disconnect() calls */ | 3393 | udev->descriptor = descriptor; /* for disconnect() calls */ |
3393 | goto re_enumerate; | 3394 | goto re_enumerate; |
3394 | } | 3395 | } |
3395 | 3396 | ||
3397 | /* Restore the device's previous configuration */ | ||
3396 | if (!udev->actconfig) | 3398 | if (!udev->actconfig) |
3397 | goto done; | 3399 | goto done; |
3398 | |||
3399 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 3400 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
3400 | USB_REQ_SET_CONFIGURATION, 0, | 3401 | USB_REQ_SET_CONFIGURATION, 0, |
3401 | udev->actconfig->desc.bConfigurationValue, 0, | 3402 | udev->actconfig->desc.bConfigurationValue, 0, |
@@ -3408,16 +3409,25 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3408 | } | 3409 | } |
3409 | usb_set_device_state(udev, USB_STATE_CONFIGURED); | 3410 | usb_set_device_state(udev, USB_STATE_CONFIGURED); |
3410 | 3411 | ||
3412 | /* Put interfaces back into the same altsettings as before. | ||
3413 | * Don't bother to send the Set-Interface request for interfaces | ||
3414 | * that were already in altsetting 0; besides being unnecessary, | ||
3415 | * many devices can't handle it. Instead just reset the host-side | ||
3416 | * endpoint state. | ||
3417 | */ | ||
3411 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 3418 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
3412 | struct usb_interface *intf = udev->actconfig->interface[i]; | 3419 | struct usb_interface *intf = udev->actconfig->interface[i]; |
3413 | struct usb_interface_descriptor *desc; | 3420 | struct usb_interface_descriptor *desc; |
3414 | 3421 | ||
3415 | /* set_interface resets host side toggle even | ||
3416 | * for altsetting zero. the interface may have no driver. | ||
3417 | */ | ||
3418 | desc = &intf->cur_altsetting->desc; | 3422 | desc = &intf->cur_altsetting->desc; |
3419 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | 3423 | if (desc->bAlternateSetting == 0) { |
3420 | desc->bAlternateSetting); | 3424 | usb_disable_interface(udev, intf, true); |
3425 | usb_enable_interface(udev, intf, true); | ||
3426 | ret = 0; | ||
3427 | } else { | ||
3428 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | ||
3429 | desc->bAlternateSetting); | ||
3430 | } | ||
3421 | if (ret < 0) { | 3431 | if (ret < 0) { |
3422 | dev_err(&udev->dev, "failed to restore interface %d " | 3432 | dev_err(&udev->dev, "failed to restore interface %d " |
3423 | "altsetting %d (error=%d)\n", | 3433 | "altsetting %d (error=%d)\n", |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 49e7f56e0d7f..30a0690f3683 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -59,7 +59,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) | |||
59 | retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); | 59 | retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); |
60 | 60 | ||
61 | dev_dbg(&urb->dev->dev, | 61 | dev_dbg(&urb->dev->dev, |
62 | "%s timed out on ep%d%s len=%d/%d\n", | 62 | "%s timed out on ep%d%s len=%u/%u\n", |
63 | current->comm, | 63 | current->comm, |
64 | usb_endpoint_num(&urb->ep->desc), | 64 | usb_endpoint_num(&urb->ep->desc), |
65 | usb_urb_dir_in(urb) ? "in" : "out", | 65 | usb_urb_dir_in(urb) ? "in" : "out", |
@@ -804,18 +804,16 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
804 | dev_err(&dev->dev, | 804 | dev_err(&dev->dev, |
805 | "string descriptor 0 read error: %d\n", | 805 | "string descriptor 0 read error: %d\n", |
806 | err); | 806 | err); |
807 | goto errout; | ||
808 | } else if (err < 4) { | 807 | } else if (err < 4) { |
809 | dev_err(&dev->dev, "string descriptor 0 too short\n"); | 808 | dev_err(&dev->dev, "string descriptor 0 too short\n"); |
810 | err = -EINVAL; | ||
811 | goto errout; | ||
812 | } else { | 809 | } else { |
813 | dev->have_langid = 1; | ||
814 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | 810 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); |
815 | /* always use the first langid listed */ | 811 | /* always use the first langid listed */ |
816 | dev_dbg(&dev->dev, "default language 0x%04x\n", | 812 | dev_dbg(&dev->dev, "default language 0x%04x\n", |
817 | dev->string_langid); | 813 | dev->string_langid); |
818 | } | 814 | } |
815 | |||
816 | dev->have_langid = 1; | ||
819 | } | 817 | } |
820 | 818 | ||
821 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 819 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
@@ -1719,7 +1717,8 @@ free_interfaces: | |||
1719 | } | 1717 | } |
1720 | kfree(new_interfaces); | 1718 | kfree(new_interfaces); |
1721 | 1719 | ||
1722 | if (cp->string == NULL) | 1720 | if (cp->string == NULL && |
1721 | !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) | ||
1723 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); | 1722 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); |
1724 | 1723 | ||
1725 | /* Now that all the interfaces are set up, register them | 1724 | /* Now that all the interfaces are set up, register them |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index c070b34b669d..ab93918d9207 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -54,6 +54,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
54 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = | 54 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = |
55 | USB_QUIRK_STRING_FETCH_255 }, | 55 | USB_QUIRK_STRING_FETCH_255 }, |
56 | 56 | ||
57 | /* Saitek Cyborg Gold Joystick */ | ||
58 | { USB_DEVICE(0x06a3, 0x0006), .driver_info = | ||
59 | USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
60 | |||
57 | /* M-Systems Flash Disk Pioneers */ | 61 | /* M-Systems Flash Disk Pioneers */ |
58 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 62 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
59 | 63 | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4cc2456ef3be..c66789197927 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/usb/quirks.h> | ||
16 | #include "usb.h" | 17 | #include "usb.h" |
17 | 18 | ||
18 | /* Active configuration fields */ | 19 | /* Active configuration fields */ |
@@ -813,7 +814,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf) | |||
813 | if (intf->sysfs_files_created || intf->unregistering) | 814 | if (intf->sysfs_files_created || intf->unregistering) |
814 | return 0; | 815 | return 0; |
815 | 816 | ||
816 | if (alt->string == NULL) | 817 | if (alt->string == NULL && |
818 | !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) | ||
817 | alt->string = usb_cache_string(udev, alt->desc.iInterface); | 819 | alt->string = usb_cache_string(udev, alt->desc.iInterface); |
818 | if (alt->string) | 820 | if (alt->string) |
819 | retval = device_create_file(&intf->dev, &dev_attr_interface); | 821 | retval = device_create_file(&intf->dev, &dev_attr_interface); |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 58bc5e3c2560..3376055f36e7 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -295,7 +295,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
295 | if (!urb || urb->hcpriv || !urb->complete) | 295 | if (!urb || urb->hcpriv || !urb->complete) |
296 | return -EINVAL; | 296 | return -EINVAL; |
297 | dev = urb->dev; | 297 | dev = urb->dev; |
298 | if ((!dev) || (dev->state < USB_STATE_DEFAULT)) | 298 | if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) |
299 | return -ENODEV; | 299 | return -ENODEV; |
300 | 300 | ||
301 | /* For now, get the endpoint from the pipe. Eventually drivers | 301 | /* For now, get the endpoint from the pipe. Eventually drivers |
@@ -370,7 +370,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
370 | } | 370 | } |
371 | 371 | ||
372 | /* the I/O buffer must be mapped/unmapped, except when length=0 */ | 372 | /* the I/O buffer must be mapped/unmapped, except when length=0 */ |
373 | if (urb->transfer_buffer_length < 0) | 373 | if (urb->transfer_buffer_length > INT_MAX) |
374 | return -EMSGSIZE; | 374 | return -EMSGSIZE; |
375 | 375 | ||
376 | #ifdef DEBUG | 376 | #ifdef DEBUG |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index e55fef52a5dc..770b3eaa9184 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -254,6 +254,7 @@ config USB_PXA25X_SMALL | |||
254 | config USB_GADGET_PXA27X | 254 | config USB_GADGET_PXA27X |
255 | boolean "PXA 27x" | 255 | boolean "PXA 27x" |
256 | depends on ARCH_PXA && PXA27x | 256 | depends on ARCH_PXA && PXA27x |
257 | select USB_OTG_UTILS | ||
257 | help | 258 | help |
258 | Intel's PXA 27x series XScale ARM v5TE processors include | 259 | Intel's PXA 27x series XScale ARM v5TE processors include |
259 | an integrated full speed USB 1.1 device controller. | 260 | an integrated full speed USB 1.1 device controller. |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index abf8192f89e8..826f3adde5d8 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -551,7 +551,7 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) | |||
551 | dma_desc->status = AMD_ADDBITS(dma_desc->status, | 551 | dma_desc->status = AMD_ADDBITS(dma_desc->status, |
552 | UDC_DMA_STP_STS_BS_HOST_BUSY, | 552 | UDC_DMA_STP_STS_BS_HOST_BUSY, |
553 | UDC_DMA_STP_STS_BS); | 553 | UDC_DMA_STP_STS_BS); |
554 | dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE); | 554 | dma_desc->bufptr = cpu_to_le32(DMA_DONT_USE); |
555 | req->td_data = dma_desc; | 555 | req->td_data = dma_desc; |
556 | req->td_data_last = NULL; | 556 | req->td_data_last = NULL; |
557 | req->chain_len = 1; | 557 | req->chain_len = 1; |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 65b03e3445a1..c22fab164113 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1017,7 +1017,7 @@ static struct usb_endpoint_descriptor usba_ep0_desc = { | |||
1017 | .bDescriptorType = USB_DT_ENDPOINT, | 1017 | .bDescriptorType = USB_DT_ENDPOINT, |
1018 | .bEndpointAddress = 0, | 1018 | .bEndpointAddress = 0, |
1019 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | 1019 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, |
1020 | .wMaxPacketSize = __constant_cpu_to_le16(64), | 1020 | .wMaxPacketSize = cpu_to_le16(64), |
1021 | /* FIXME: I have no idea what to put here */ | 1021 | /* FIXME: I have no idea what to put here */ |
1022 | .bInterval = 1, | 1022 | .bInterval = 1, |
1023 | }; | 1023 | }; |
@@ -1207,21 +1207,21 @@ static int do_test_mode(struct usba_udc *udc) | |||
1207 | /* Avoid overly long expressions */ | 1207 | /* Avoid overly long expressions */ |
1208 | static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq) | 1208 | static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq) |
1209 | { | 1209 | { |
1210 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) | 1210 | if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) |
1211 | return true; | 1211 | return true; |
1212 | return false; | 1212 | return false; |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq) | 1215 | static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq) |
1216 | { | 1216 | { |
1217 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE)) | 1217 | if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE)) |
1218 | return true; | 1218 | return true; |
1219 | return false; | 1219 | return false; |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) | 1222 | static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) |
1223 | { | 1223 | { |
1224 | if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT)) | 1224 | if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT)) |
1225 | return true; | 1225 | return true; |
1226 | return false; | 1226 | return false; |
1227 | } | 1227 | } |
@@ -1239,7 +1239,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
1239 | status = cpu_to_le16(udc->devstatus); | 1239 | status = cpu_to_le16(udc->devstatus); |
1240 | } else if (crq->bRequestType | 1240 | } else if (crq->bRequestType |
1241 | == (USB_DIR_IN | USB_RECIP_INTERFACE)) { | 1241 | == (USB_DIR_IN | USB_RECIP_INTERFACE)) { |
1242 | status = __constant_cpu_to_le16(0); | 1242 | status = cpu_to_le16(0); |
1243 | } else if (crq->bRequestType | 1243 | } else if (crq->bRequestType |
1244 | == (USB_DIR_IN | USB_RECIP_ENDPOINT)) { | 1244 | == (USB_DIR_IN | USB_RECIP_ENDPOINT)) { |
1245 | struct usba_ep *target; | 1245 | struct usba_ep *target; |
@@ -1250,12 +1250,12 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
1250 | 1250 | ||
1251 | status = 0; | 1251 | status = 0; |
1252 | if (is_stalled(udc, target)) | 1252 | if (is_stalled(udc, target)) |
1253 | status |= __constant_cpu_to_le16(1); | 1253 | status |= cpu_to_le16(1); |
1254 | } else | 1254 | } else |
1255 | goto delegate; | 1255 | goto delegate; |
1256 | 1256 | ||
1257 | /* Write directly to the FIFO. No queueing is done. */ | 1257 | /* Write directly to the FIFO. No queueing is done. */ |
1258 | if (crq->wLength != __constant_cpu_to_le16(sizeof(status))) | 1258 | if (crq->wLength != cpu_to_le16(sizeof(status))) |
1259 | goto stall; | 1259 | goto stall; |
1260 | ep->state = DATA_STAGE_IN; | 1260 | ep->state = DATA_STAGE_IN; |
1261 | __raw_writew(status, ep->fifo); | 1261 | __raw_writew(status, ep->fifo); |
@@ -1274,7 +1274,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
1274 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | 1274 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { |
1275 | struct usba_ep *target; | 1275 | struct usba_ep *target; |
1276 | 1276 | ||
1277 | if (crq->wLength != __constant_cpu_to_le16(0) | 1277 | if (crq->wLength != cpu_to_le16(0) |
1278 | || !feature_is_ep_halt(crq)) | 1278 | || !feature_is_ep_halt(crq)) |
1279 | goto stall; | 1279 | goto stall; |
1280 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | 1280 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); |
@@ -1308,7 +1308,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
1308 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | 1308 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { |
1309 | struct usba_ep *target; | 1309 | struct usba_ep *target; |
1310 | 1310 | ||
1311 | if (crq->wLength != __constant_cpu_to_le16(0) | 1311 | if (crq->wLength != cpu_to_le16(0) |
1312 | || !feature_is_ep_halt(crq)) | 1312 | || !feature_is_ep_halt(crq)) |
1313 | goto stall; | 1313 | goto stall; |
1314 | 1314 | ||
@@ -1514,7 +1514,7 @@ restart: | |||
1514 | */ | 1514 | */ |
1515 | ep->state = DATA_STAGE_IN; | 1515 | ep->state = DATA_STAGE_IN; |
1516 | } else { | 1516 | } else { |
1517 | if (crq.crq.wLength != __constant_cpu_to_le16(0)) | 1517 | if (crq.crq.wLength != cpu_to_le16(0)) |
1518 | ep->state = DATA_STAGE_OUT; | 1518 | ep->state = DATA_STAGE_OUT; |
1519 | else | 1519 | else |
1520 | ep->state = STATUS_STAGE_IN; | 1520 | ep->state = STATUS_STAGE_IN; |
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 5495b171cf29..928137d3dbdc 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c | |||
@@ -66,7 +66,7 @@ static struct usb_device_descriptor device_desc = { | |||
66 | .bLength = sizeof device_desc, | 66 | .bLength = sizeof device_desc, |
67 | .bDescriptorType = USB_DT_DEVICE, | 67 | .bDescriptorType = USB_DT_DEVICE, |
68 | 68 | ||
69 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 69 | .bcdUSB = cpu_to_le16(0x0200), |
70 | 70 | ||
71 | .bDeviceClass = USB_CLASS_COMM, | 71 | .bDeviceClass = USB_CLASS_COMM, |
72 | .bDeviceSubClass = 0, | 72 | .bDeviceSubClass = 0, |
@@ -74,8 +74,8 @@ static struct usb_device_descriptor device_desc = { | |||
74 | /* .bMaxPacketSize0 = f(hardware) */ | 74 | /* .bMaxPacketSize0 = f(hardware) */ |
75 | 75 | ||
76 | /* Vendor and product id can be overridden by module parameters. */ | 76 | /* Vendor and product id can be overridden by module parameters. */ |
77 | .idVendor = __constant_cpu_to_le16(CDC_VENDOR_NUM), | 77 | .idVendor = cpu_to_le16(CDC_VENDOR_NUM), |
78 | .idProduct = __constant_cpu_to_le16(CDC_PRODUCT_NUM), | 78 | .idProduct = cpu_to_le16(CDC_PRODUCT_NUM), |
79 | /* .bcdDevice = f(hardware) */ | 79 | /* .bcdDevice = f(hardware) */ |
80 | /* .iManufacturer = DYNAMIC */ | 80 | /* .iManufacturer = DYNAMIC */ |
81 | /* .iProduct = DYNAMIC */ | 81 | /* .iProduct = DYNAMIC */ |
@@ -193,7 +193,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) | |||
193 | gadget->name, | 193 | gadget->name, |
194 | cdc_config_driver.label); | 194 | cdc_config_driver.label); |
195 | device_desc.bcdDevice = | 195 | device_desc.bcdDevice = |
196 | __constant_cpu_to_le16(0x0300 | 0x0099); | 196 | cpu_to_le16(0x0300 | 0x0099); |
197 | } | 197 | } |
198 | 198 | ||
199 | 199 | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index bebf911c7e5f..22c65960c429 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/dma-mapping.h> | 56 | #include <linux/dma-mapping.h> |
57 | #include <linux/init.h> | 57 | #include <linux/init.h> |
58 | #include <linux/interrupt.h> | 58 | #include <linux/interrupt.h> |
59 | #include <linux/interrupt.h> | ||
60 | #include <linux/io.h> | 59 | #include <linux/io.h> |
61 | #include <linux/irq.h> | 60 | #include <linux/irq.h> |
62 | #include <linux/kernel.h> | 61 | #include <linux/kernel.h> |
@@ -2626,7 +2625,7 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | |||
2626 | INIT_LIST_HEAD(&udc->gadget.ep_list); | 2625 | INIT_LIST_HEAD(&udc->gadget.ep_list); |
2627 | udc->gadget.ep0 = NULL; | 2626 | udc->gadget.ep0 = NULL; |
2628 | 2627 | ||
2629 | strcpy(udc->gadget.dev.bus_id, "gadget"); | 2628 | dev_set_name(&udc->gadget.dev, "gadget"); |
2630 | udc->gadget.dev.dma_mask = dev->dma_mask; | 2629 | udc->gadget.dev.dma_mask = dev->dma_mask; |
2631 | udc->gadget.dev.parent = dev; | 2630 | udc->gadget.dev.parent = dev; |
2632 | udc->gadget.dev.release = udc_release; | 2631 | udc->gadget.dev.release = udc_release; |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 5d11c291f1ad..59e85234fa0a 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -149,16 +149,17 @@ done: | |||
149 | int usb_function_deactivate(struct usb_function *function) | 149 | int usb_function_deactivate(struct usb_function *function) |
150 | { | 150 | { |
151 | struct usb_composite_dev *cdev = function->config->cdev; | 151 | struct usb_composite_dev *cdev = function->config->cdev; |
152 | unsigned long flags; | ||
152 | int status = 0; | 153 | int status = 0; |
153 | 154 | ||
154 | spin_lock(&cdev->lock); | 155 | spin_lock_irqsave(&cdev->lock, flags); |
155 | 156 | ||
156 | if (cdev->deactivations == 0) | 157 | if (cdev->deactivations == 0) |
157 | status = usb_gadget_disconnect(cdev->gadget); | 158 | status = usb_gadget_disconnect(cdev->gadget); |
158 | if (status == 0) | 159 | if (status == 0) |
159 | cdev->deactivations++; | 160 | cdev->deactivations++; |
160 | 161 | ||
161 | spin_unlock(&cdev->lock); | 162 | spin_unlock_irqrestore(&cdev->lock, flags); |
162 | return status; | 163 | return status; |
163 | } | 164 | } |
164 | 165 | ||
@@ -1013,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget) | |||
1013 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1014 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
1014 | struct usb_function *f; | 1015 | struct usb_function *f; |
1015 | 1016 | ||
1016 | /* REVISIT: should we have config and device level | 1017 | /* REVISIT: should we have config level |
1017 | * suspend/resume callbacks? | 1018 | * suspend/resume callbacks? |
1018 | */ | 1019 | */ |
1019 | DBG(cdev, "suspend\n"); | 1020 | DBG(cdev, "suspend\n"); |
@@ -1023,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget) | |||
1023 | f->suspend(f); | 1024 | f->suspend(f); |
1024 | } | 1025 | } |
1025 | } | 1026 | } |
1027 | if (composite->suspend) | ||
1028 | composite->suspend(cdev); | ||
1026 | } | 1029 | } |
1027 | 1030 | ||
1028 | static void | 1031 | static void |
@@ -1031,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget) | |||
1031 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1034 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
1032 | struct usb_function *f; | 1035 | struct usb_function *f; |
1033 | 1036 | ||
1034 | /* REVISIT: should we have config and device level | 1037 | /* REVISIT: should we have config level |
1035 | * suspend/resume callbacks? | 1038 | * suspend/resume callbacks? |
1036 | */ | 1039 | */ |
1037 | DBG(cdev, "resume\n"); | 1040 | DBG(cdev, "resume\n"); |
1041 | if (composite->resume) | ||
1042 | composite->resume(cdev); | ||
1038 | if (cdev->config) { | 1043 | if (cdev->config) { |
1039 | list_for_each_entry(f, &cdev->config->functions, list) { | 1044 | list_for_each_entry(f, &cdev->config->functions, list) { |
1040 | if (f->resume) | 1045 | if (f->resume) |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 9064696636ac..a56b24d305f8 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -1437,7 +1437,7 @@ restart: | |||
1437 | } | 1437 | } |
1438 | if (urb->transfer_buffer_length > 1) | 1438 | if (urb->transfer_buffer_length > 1) |
1439 | buf [1] = 0; | 1439 | buf [1] = 0; |
1440 | urb->actual_length = min (2, | 1440 | urb->actual_length = min_t(u32, 2, |
1441 | urb->transfer_buffer_length); | 1441 | urb->transfer_buffer_length); |
1442 | value = 0; | 1442 | value = 0; |
1443 | status = 0; | 1443 | status = 0; |
@@ -1626,7 +1626,7 @@ static int dummy_hub_control ( | |||
1626 | hub_descriptor ((struct usb_hub_descriptor *) buf); | 1626 | hub_descriptor ((struct usb_hub_descriptor *) buf); |
1627 | break; | 1627 | break; |
1628 | case GetHubStatus: | 1628 | case GetHubStatus: |
1629 | *(__le32 *) buf = __constant_cpu_to_le32 (0); | 1629 | *(__le32 *) buf = cpu_to_le32 (0); |
1630 | break; | 1630 | break; |
1631 | case GetPortStatus: | 1631 | case GetPortStatus: |
1632 | if (wIndex != 1) | 1632 | if (wIndex != 1) |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index a36b1175b18d..cd0914ec898e 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -148,7 +148,7 @@ ep_matches ( | |||
148 | return 0; | 148 | return 0; |
149 | 149 | ||
150 | /* BOTH: "high bandwidth" works only at high speed */ | 150 | /* BOTH: "high bandwidth" works only at high speed */ |
151 | if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) { | 151 | if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) { |
152 | if (!gadget->is_dualspeed) | 152 | if (!gadget->is_dualspeed) |
153 | return 0; | 153 | return 0; |
154 | /* configure your hardware with enough buffering!! */ | 154 | /* configure your hardware with enough buffering!! */ |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 37252d0012a7..d006dc652e02 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -156,7 +156,7 @@ static struct usb_device_descriptor device_desc = { | |||
156 | .bLength = sizeof device_desc, | 156 | .bLength = sizeof device_desc, |
157 | .bDescriptorType = USB_DT_DEVICE, | 157 | .bDescriptorType = USB_DT_DEVICE, |
158 | 158 | ||
159 | .bcdUSB = __constant_cpu_to_le16 (0x0200), | 159 | .bcdUSB = cpu_to_le16 (0x0200), |
160 | 160 | ||
161 | .bDeviceClass = USB_CLASS_COMM, | 161 | .bDeviceClass = USB_CLASS_COMM, |
162 | .bDeviceSubClass = 0, | 162 | .bDeviceSubClass = 0, |
@@ -167,8 +167,8 @@ static struct usb_device_descriptor device_desc = { | |||
167 | * we support. (As does bNumConfigurations.) These values can | 167 | * we support. (As does bNumConfigurations.) These values can |
168 | * also be overridden by module parameters. | 168 | * also be overridden by module parameters. |
169 | */ | 169 | */ |
170 | .idVendor = __constant_cpu_to_le16 (CDC_VENDOR_NUM), | 170 | .idVendor = cpu_to_le16 (CDC_VENDOR_NUM), |
171 | .idProduct = __constant_cpu_to_le16 (CDC_PRODUCT_NUM), | 171 | .idProduct = cpu_to_le16 (CDC_PRODUCT_NUM), |
172 | /* .bcdDevice = f(hardware) */ | 172 | /* .bcdDevice = f(hardware) */ |
173 | /* .iManufacturer = DYNAMIC */ | 173 | /* .iManufacturer = DYNAMIC */ |
174 | /* .iProduct = DYNAMIC */ | 174 | /* .iProduct = DYNAMIC */ |
@@ -318,7 +318,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev) | |||
318 | gadget->name, | 318 | gadget->name, |
319 | eth_config_driver.label); | 319 | eth_config_driver.label); |
320 | device_desc.bcdDevice = | 320 | device_desc.bcdDevice = |
321 | __constant_cpu_to_le16(0x0300 | 0x0099); | 321 | cpu_to_le16(0x0300 | 0x0099); |
322 | } | 322 | } |
323 | 323 | ||
324 | 324 | ||
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index c1d34df0b157..7953948bfe4a 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
@@ -125,7 +125,7 @@ static struct usb_cdc_header_desc acm_header_desc __initdata = { | |||
125 | .bLength = sizeof(acm_header_desc), | 125 | .bLength = sizeof(acm_header_desc), |
126 | .bDescriptorType = USB_DT_CS_INTERFACE, | 126 | .bDescriptorType = USB_DT_CS_INTERFACE, |
127 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 127 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
128 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 128 | .bcdCDC = cpu_to_le16(0x0110), |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static struct usb_cdc_call_mgmt_descriptor | 131 | static struct usb_cdc_call_mgmt_descriptor |
@@ -159,7 +159,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = { | |||
159 | .bDescriptorType = USB_DT_ENDPOINT, | 159 | .bDescriptorType = USB_DT_ENDPOINT, |
160 | .bEndpointAddress = USB_DIR_IN, | 160 | .bEndpointAddress = USB_DIR_IN, |
161 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 161 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
162 | .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET), | 162 | .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), |
163 | .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, | 163 | .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, |
164 | }; | 164 | }; |
165 | 165 | ||
@@ -197,7 +197,7 @@ static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = { | |||
197 | .bDescriptorType = USB_DT_ENDPOINT, | 197 | .bDescriptorType = USB_DT_ENDPOINT, |
198 | .bEndpointAddress = USB_DIR_IN, | 198 | .bEndpointAddress = USB_DIR_IN, |
199 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 199 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
200 | .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET), | 200 | .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), |
201 | .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, | 201 | .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, |
202 | }; | 202 | }; |
203 | 203 | ||
@@ -205,14 +205,14 @@ static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = { | |||
205 | .bLength = USB_DT_ENDPOINT_SIZE, | 205 | .bLength = USB_DT_ENDPOINT_SIZE, |
206 | .bDescriptorType = USB_DT_ENDPOINT, | 206 | .bDescriptorType = USB_DT_ENDPOINT, |
207 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 207 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
208 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 208 | .wMaxPacketSize = cpu_to_le16(512), |
209 | }; | 209 | }; |
210 | 210 | ||
211 | static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = { | 211 | static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = { |
212 | .bLength = USB_DT_ENDPOINT_SIZE, | 212 | .bLength = USB_DT_ENDPOINT_SIZE, |
213 | .bDescriptorType = USB_DT_ENDPOINT, | 213 | .bDescriptorType = USB_DT_ENDPOINT, |
214 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 214 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
215 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 215 | .wMaxPacketSize = cpu_to_le16(512), |
216 | }; | 216 | }; |
217 | 217 | ||
218 | static struct usb_descriptor_header *acm_hs_function[] __initdata = { | 218 | static struct usb_descriptor_header *acm_hs_function[] __initdata = { |
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 4ae579948e54..ecf5bdd0ae06 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c | |||
@@ -130,7 +130,7 @@ static struct usb_cdc_header_desc ecm_header_desc __initdata = { | |||
130 | .bDescriptorType = USB_DT_CS_INTERFACE, | 130 | .bDescriptorType = USB_DT_CS_INTERFACE, |
131 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 131 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
132 | 132 | ||
133 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 133 | .bcdCDC = cpu_to_le16(0x0110), |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static struct usb_cdc_union_desc ecm_union_desc __initdata = { | 136 | static struct usb_cdc_union_desc ecm_union_desc __initdata = { |
@@ -148,9 +148,9 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = { | |||
148 | 148 | ||
149 | /* this descriptor actually adds value, surprise! */ | 149 | /* this descriptor actually adds value, surprise! */ |
150 | /* .iMACAddress = DYNAMIC */ | 150 | /* .iMACAddress = DYNAMIC */ |
151 | .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */ | 151 | .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */ |
152 | .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN), | 152 | .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN), |
153 | .wNumberMCFilters = __constant_cpu_to_le16(0), | 153 | .wNumberMCFilters = cpu_to_le16(0), |
154 | .bNumberPowerFilters = 0, | 154 | .bNumberPowerFilters = 0, |
155 | }; | 155 | }; |
156 | 156 | ||
@@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = { | |||
192 | 192 | ||
193 | .bEndpointAddress = USB_DIR_IN, | 193 | .bEndpointAddress = USB_DIR_IN, |
194 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 194 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
195 | .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT), | 195 | .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), |
196 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, | 196 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, |
197 | }; | 197 | }; |
198 | 198 | ||
@@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = { | |||
236 | 236 | ||
237 | .bEndpointAddress = USB_DIR_IN, | 237 | .bEndpointAddress = USB_DIR_IN, |
238 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 238 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
239 | .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT), | 239 | .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), |
240 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, | 240 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, |
241 | }; | 241 | }; |
242 | static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { | 242 | static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { |
@@ -245,7 +245,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { | |||
245 | 245 | ||
246 | .bEndpointAddress = USB_DIR_IN, | 246 | .bEndpointAddress = USB_DIR_IN, |
247 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 247 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
248 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 248 | .wMaxPacketSize = cpu_to_le16(512), |
249 | }; | 249 | }; |
250 | 250 | ||
251 | static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { | 251 | static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { |
@@ -254,7 +254,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { | |||
254 | 254 | ||
255 | .bEndpointAddress = USB_DIR_OUT, | 255 | .bEndpointAddress = USB_DIR_OUT, |
256 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 256 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
257 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 257 | .wMaxPacketSize = cpu_to_le16(512), |
258 | }; | 258 | }; |
259 | 259 | ||
260 | static struct usb_descriptor_header *ecm_hs_function[] __initdata = { | 260 | static struct usb_descriptor_header *ecm_hs_function[] __initdata = { |
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 8affe1dfc2c1..eb6ddfc20857 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c | |||
@@ -100,7 +100,7 @@ static struct usb_endpoint_descriptor hs_loop_source_desc = { | |||
100 | .bDescriptorType = USB_DT_ENDPOINT, | 100 | .bDescriptorType = USB_DT_ENDPOINT, |
101 | 101 | ||
102 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 102 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
103 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 103 | .wMaxPacketSize = cpu_to_le16(512), |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static struct usb_endpoint_descriptor hs_loop_sink_desc = { | 106 | static struct usb_endpoint_descriptor hs_loop_sink_desc = { |
@@ -108,7 +108,7 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = { | |||
108 | .bDescriptorType = USB_DT_ENDPOINT, | 108 | .bDescriptorType = USB_DT_ENDPOINT, |
109 | 109 | ||
110 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 110 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
111 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 111 | .wMaxPacketSize = cpu_to_le16(512), |
112 | }; | 112 | }; |
113 | 113 | ||
114 | static struct usb_descriptor_header *hs_loopback_descs[] = { | 114 | static struct usb_descriptor_header *hs_loopback_descs[] = { |
@@ -359,7 +359,7 @@ static struct usb_configuration loopback_driver = { | |||
359 | * loopback_add - add a loopback testing configuration to a device | 359 | * loopback_add - add a loopback testing configuration to a device |
360 | * @cdev: the device to support the loopback configuration | 360 | * @cdev: the device to support the loopback configuration |
361 | */ | 361 | */ |
362 | int __init loopback_add(struct usb_composite_dev *cdev) | 362 | int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume) |
363 | { | 363 | { |
364 | int id; | 364 | int id; |
365 | 365 | ||
@@ -372,6 +372,10 @@ int __init loopback_add(struct usb_composite_dev *cdev) | |||
372 | loopback_intf.iInterface = id; | 372 | loopback_intf.iInterface = id; |
373 | loopback_driver.iConfiguration = id; | 373 | loopback_driver.iConfiguration = id; |
374 | 374 | ||
375 | /* support autoresume for remote wakeup testing */ | ||
376 | if (autoresume) | ||
377 | sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
378 | |||
375 | /* support OTG systems */ | 379 | /* support OTG systems */ |
376 | if (gadget_is_otg(cdev->gadget)) { | 380 | if (gadget_is_otg(cdev->gadget)) { |
377 | loopback_driver.descriptors = otg_desc; | 381 | loopback_driver.descriptors = otg_desc; |
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index 38aa896cc5db..46d6266f30ec 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c | |||
@@ -123,7 +123,7 @@ static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = { | |||
123 | .bLength = sizeof(obex_cdc_header_desc), | 123 | .bLength = sizeof(obex_cdc_header_desc), |
124 | .bDescriptorType = USB_DT_CS_INTERFACE, | 124 | .bDescriptorType = USB_DT_CS_INTERFACE, |
125 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 125 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
126 | .bcdCDC = __constant_cpu_to_le16(0x0120), | 126 | .bcdCDC = cpu_to_le16(0x0120), |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = { | 129 | static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = { |
@@ -138,7 +138,7 @@ static struct usb_cdc_obex_desc obex_desc __initdata = { | |||
138 | .bLength = sizeof(obex_desc), | 138 | .bLength = sizeof(obex_desc), |
139 | .bDescriptorType = USB_DT_CS_INTERFACE, | 139 | .bDescriptorType = USB_DT_CS_INTERFACE, |
140 | .bDescriptorSubType = USB_CDC_OBEX_TYPE, | 140 | .bDescriptorSubType = USB_CDC_OBEX_TYPE, |
141 | .bcdVersion = __constant_cpu_to_le16(0x0100), | 141 | .bcdVersion = cpu_to_le16(0x0100), |
142 | }; | 142 | }; |
143 | 143 | ||
144 | /* High-Speed Support */ | 144 | /* High-Speed Support */ |
@@ -149,7 +149,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = { | |||
149 | 149 | ||
150 | .bEndpointAddress = USB_DIR_OUT, | 150 | .bEndpointAddress = USB_DIR_OUT, |
151 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 151 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
152 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 152 | .wMaxPacketSize = cpu_to_le16(512), |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = { | 155 | static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = { |
@@ -158,7 +158,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = { | |||
158 | 158 | ||
159 | .bEndpointAddress = USB_DIR_IN, | 159 | .bEndpointAddress = USB_DIR_IN, |
160 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 160 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
161 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 161 | .wMaxPacketSize = cpu_to_le16(512), |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static struct usb_descriptor_header *hs_function[] __initdata = { | 164 | static struct usb_descriptor_header *hs_function[] __initdata = { |
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index c0916c7b217e..c1abeb89b413 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c | |||
@@ -79,7 +79,7 @@ pn_header_desc = { | |||
79 | .bLength = sizeof pn_header_desc, | 79 | .bLength = sizeof pn_header_desc, |
80 | .bDescriptorType = USB_DT_CS_INTERFACE, | 80 | .bDescriptorType = USB_DT_CS_INTERFACE, |
81 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 81 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
82 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 82 | .bcdCDC = cpu_to_le16(0x0110), |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static const struct usb_cdc_header_desc | 85 | static const struct usb_cdc_header_desc |
@@ -87,7 +87,7 @@ pn_phonet_desc = { | |||
87 | .bLength = sizeof pn_phonet_desc, | 87 | .bLength = sizeof pn_phonet_desc, |
88 | .bDescriptorType = USB_DT_CS_INTERFACE, | 88 | .bDescriptorType = USB_DT_CS_INTERFACE, |
89 | .bDescriptorSubType = USB_CDC_PHONET_TYPE, | 89 | .bDescriptorSubType = USB_CDC_PHONET_TYPE, |
90 | .bcdCDC = __constant_cpu_to_le16(0x1505), /* ??? */ | 90 | .bcdCDC = cpu_to_le16(0x1505), /* ??? */ |
91 | }; | 91 | }; |
92 | 92 | ||
93 | static struct usb_cdc_union_desc | 93 | static struct usb_cdc_union_desc |
@@ -138,7 +138,7 @@ pn_hs_sink_desc = { | |||
138 | 138 | ||
139 | .bEndpointAddress = USB_DIR_OUT, | 139 | .bEndpointAddress = USB_DIR_OUT, |
140 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 140 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
141 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 141 | .wMaxPacketSize = cpu_to_le16(512), |
142 | }; | 142 | }; |
143 | 143 | ||
144 | static struct usb_endpoint_descriptor | 144 | static struct usb_endpoint_descriptor |
@@ -157,7 +157,7 @@ pn_hs_source_desc = { | |||
157 | 157 | ||
158 | .bEndpointAddress = USB_DIR_IN, | 158 | .bEndpointAddress = USB_DIR_IN, |
159 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 159 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
160 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 160 | .wMaxPacketSize = cpu_to_le16(512), |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static struct usb_descriptor_header *fs_pn_function[] = { | 163 | static struct usb_descriptor_header *fs_pn_function[] = { |
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 3a8bb53fc473..3279a4726042 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
@@ -137,7 +137,7 @@ static struct usb_cdc_header_desc header_desc __initdata = { | |||
137 | .bDescriptorType = USB_DT_CS_INTERFACE, | 137 | .bDescriptorType = USB_DT_CS_INTERFACE, |
138 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 138 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
139 | 139 | ||
140 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 140 | .bcdCDC = cpu_to_le16(0x0110), |
141 | }; | 141 | }; |
142 | 142 | ||
143 | static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = { | 143 | static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = { |
@@ -187,7 +187,7 @@ static struct usb_endpoint_descriptor fs_notify_desc __initdata = { | |||
187 | 187 | ||
188 | .bEndpointAddress = USB_DIR_IN, | 188 | .bEndpointAddress = USB_DIR_IN, |
189 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 189 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
190 | .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT), | 190 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), |
191 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, | 191 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, |
192 | }; | 192 | }; |
193 | 193 | ||
@@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor hs_notify_desc __initdata = { | |||
230 | 230 | ||
231 | .bEndpointAddress = USB_DIR_IN, | 231 | .bEndpointAddress = USB_DIR_IN, |
232 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 232 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
233 | .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT), | 233 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), |
234 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, | 234 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, |
235 | }; | 235 | }; |
236 | static struct usb_endpoint_descriptor hs_in_desc __initdata = { | 236 | static struct usb_endpoint_descriptor hs_in_desc __initdata = { |
@@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = { | |||
239 | 239 | ||
240 | .bEndpointAddress = USB_DIR_IN, | 240 | .bEndpointAddress = USB_DIR_IN, |
241 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 241 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
242 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 242 | .wMaxPacketSize = cpu_to_le16(512), |
243 | }; | 243 | }; |
244 | 244 | ||
245 | static struct usb_endpoint_descriptor hs_out_desc __initdata = { | 245 | static struct usb_endpoint_descriptor hs_out_desc __initdata = { |
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = { | |||
248 | 248 | ||
249 | .bEndpointAddress = USB_DIR_OUT, | 249 | .bEndpointAddress = USB_DIR_OUT, |
250 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 250 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
251 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 251 | .wMaxPacketSize = cpu_to_le16(512), |
252 | }; | 252 | }; |
253 | 253 | ||
254 | static struct usb_descriptor_header *eth_hs_function[] __initdata = { | 254 | static struct usb_descriptor_header *eth_hs_function[] __initdata = { |
@@ -437,7 +437,7 @@ invalid: | |||
437 | DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n", | 437 | DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n", |
438 | ctrl->bRequestType, ctrl->bRequest, | 438 | ctrl->bRequestType, ctrl->bRequest, |
439 | w_value, w_index, w_length); | 439 | w_value, w_index, w_length); |
440 | req->zero = 0; | 440 | req->zero = (value < w_length); |
441 | req->length = value; | 441 | req->length = value; |
442 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); | 442 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); |
443 | if (value < 0) | 443 | if (value < 0) |
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index fe5674db344b..db0aa93606ef 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c | |||
@@ -89,14 +89,14 @@ static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = { | |||
89 | .bLength = USB_DT_ENDPOINT_SIZE, | 89 | .bLength = USB_DT_ENDPOINT_SIZE, |
90 | .bDescriptorType = USB_DT_ENDPOINT, | 90 | .bDescriptorType = USB_DT_ENDPOINT, |
91 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 91 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
92 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 92 | .wMaxPacketSize = cpu_to_le16(512), |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = { | 95 | static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = { |
96 | .bLength = USB_DT_ENDPOINT_SIZE, | 96 | .bLength = USB_DT_ENDPOINT_SIZE, |
97 | .bDescriptorType = USB_DT_ENDPOINT, | 97 | .bDescriptorType = USB_DT_ENDPOINT, |
98 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 98 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
99 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 99 | .wMaxPacketSize = cpu_to_le16(512), |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static struct usb_descriptor_header *gser_hs_function[] __initdata = { | 102 | static struct usb_descriptor_header *gser_hs_function[] __initdata = { |
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index dc84d26d2835..bffe91d525f9 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c | |||
@@ -59,7 +59,6 @@ struct f_sourcesink { | |||
59 | 59 | ||
60 | struct usb_ep *in_ep; | 60 | struct usb_ep *in_ep; |
61 | struct usb_ep *out_ep; | 61 | struct usb_ep *out_ep; |
62 | struct timer_list resume; | ||
63 | }; | 62 | }; |
64 | 63 | ||
65 | static inline struct f_sourcesink *func_to_ss(struct usb_function *f) | 64 | static inline struct f_sourcesink *func_to_ss(struct usb_function *f) |
@@ -67,10 +66,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f) | |||
67 | return container_of(f, struct f_sourcesink, function); | 66 | return container_of(f, struct f_sourcesink, function); |
68 | } | 67 | } |
69 | 68 | ||
70 | static unsigned autoresume; | ||
71 | module_param(autoresume, uint, 0); | ||
72 | MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup"); | ||
73 | |||
74 | static unsigned pattern; | 69 | static unsigned pattern; |
75 | module_param(pattern, uint, 0); | 70 | module_param(pattern, uint, 0); |
76 | MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 "); | 71 | MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 "); |
@@ -118,7 +113,7 @@ static struct usb_endpoint_descriptor hs_source_desc = { | |||
118 | .bDescriptorType = USB_DT_ENDPOINT, | 113 | .bDescriptorType = USB_DT_ENDPOINT, |
119 | 114 | ||
120 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 115 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
121 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 116 | .wMaxPacketSize = cpu_to_le16(512), |
122 | }; | 117 | }; |
123 | 118 | ||
124 | static struct usb_endpoint_descriptor hs_sink_desc = { | 119 | static struct usb_endpoint_descriptor hs_sink_desc = { |
@@ -126,7 +121,7 @@ static struct usb_endpoint_descriptor hs_sink_desc = { | |||
126 | .bDescriptorType = USB_DT_ENDPOINT, | 121 | .bDescriptorType = USB_DT_ENDPOINT, |
127 | 122 | ||
128 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 123 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
129 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 124 | .wMaxPacketSize = cpu_to_le16(512), |
130 | }; | 125 | }; |
131 | 126 | ||
132 | static struct usb_descriptor_header *hs_source_sink_descs[] = { | 127 | static struct usb_descriptor_header *hs_source_sink_descs[] = { |
@@ -155,21 +150,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = { | |||
155 | 150 | ||
156 | /*-------------------------------------------------------------------------*/ | 151 | /*-------------------------------------------------------------------------*/ |
157 | 152 | ||
158 | static void sourcesink_autoresume(unsigned long _c) | ||
159 | { | ||
160 | struct usb_composite_dev *cdev = (void *)_c; | ||
161 | struct usb_gadget *g = cdev->gadget; | ||
162 | |||
163 | /* Normally the host would be woken up for something | ||
164 | * more significant than just a timer firing; likely | ||
165 | * because of some direct user request. | ||
166 | */ | ||
167 | if (g->speed != USB_SPEED_UNKNOWN) { | ||
168 | int status = usb_gadget_wakeup(g); | ||
169 | DBG(cdev, "%s --> %d\n", __func__, status); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static int __init | 153 | static int __init |
174 | sourcesink_bind(struct usb_configuration *c, struct usb_function *f) | 154 | sourcesink_bind(struct usb_configuration *c, struct usb_function *f) |
175 | { | 155 | { |
@@ -198,9 +178,6 @@ autoconf_fail: | |||
198 | goto autoconf_fail; | 178 | goto autoconf_fail; |
199 | ss->out_ep->driver_data = cdev; /* claim */ | 179 | ss->out_ep->driver_data = cdev; /* claim */ |
200 | 180 | ||
201 | setup_timer(&ss->resume, sourcesink_autoresume, | ||
202 | (unsigned long) c->cdev); | ||
203 | |||
204 | /* support high speed hardware */ | 181 | /* support high speed hardware */ |
205 | if (gadget_is_dualspeed(c->cdev->gadget)) { | 182 | if (gadget_is_dualspeed(c->cdev->gadget)) { |
206 | hs_source_desc.bEndpointAddress = | 183 | hs_source_desc.bEndpointAddress = |
@@ -359,7 +336,6 @@ static void disable_source_sink(struct f_sourcesink *ss) | |||
359 | 336 | ||
360 | cdev = ss->function.config->cdev; | 337 | cdev = ss->function.config->cdev; |
361 | disable_endpoints(cdev, ss->in_ep, ss->out_ep); | 338 | disable_endpoints(cdev, ss->in_ep, ss->out_ep); |
362 | del_timer(&ss->resume); | ||
363 | VDBG(cdev, "%s disabled\n", ss->function.name); | 339 | VDBG(cdev, "%s disabled\n", ss->function.name); |
364 | } | 340 | } |
365 | 341 | ||
@@ -426,30 +402,6 @@ static void sourcesink_disable(struct usb_function *f) | |||
426 | disable_source_sink(ss); | 402 | disable_source_sink(ss); |
427 | } | 403 | } |
428 | 404 | ||
429 | static void sourcesink_suspend(struct usb_function *f) | ||
430 | { | ||
431 | struct f_sourcesink *ss = func_to_ss(f); | ||
432 | struct usb_composite_dev *cdev = f->config->cdev; | ||
433 | |||
434 | if (cdev->gadget->speed == USB_SPEED_UNKNOWN) | ||
435 | return; | ||
436 | |||
437 | if (autoresume) { | ||
438 | mod_timer(&ss->resume, jiffies + (HZ * autoresume)); | ||
439 | DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume); | ||
440 | } else | ||
441 | DBG(cdev, "%s\n", __func__); | ||
442 | } | ||
443 | |||
444 | static void sourcesink_resume(struct usb_function *f) | ||
445 | { | ||
446 | struct f_sourcesink *ss = func_to_ss(f); | ||
447 | struct usb_composite_dev *cdev = f->config->cdev; | ||
448 | |||
449 | DBG(cdev, "%s\n", __func__); | ||
450 | del_timer(&ss->resume); | ||
451 | } | ||
452 | |||
453 | /*-------------------------------------------------------------------------*/ | 405 | /*-------------------------------------------------------------------------*/ |
454 | 406 | ||
455 | static int __init sourcesink_bind_config(struct usb_configuration *c) | 407 | static int __init sourcesink_bind_config(struct usb_configuration *c) |
@@ -467,8 +419,6 @@ static int __init sourcesink_bind_config(struct usb_configuration *c) | |||
467 | ss->function.unbind = sourcesink_unbind; | 419 | ss->function.unbind = sourcesink_unbind; |
468 | ss->function.set_alt = sourcesink_set_alt; | 420 | ss->function.set_alt = sourcesink_set_alt; |
469 | ss->function.disable = sourcesink_disable; | 421 | ss->function.disable = sourcesink_disable; |
470 | ss->function.suspend = sourcesink_suspend; | ||
471 | ss->function.resume = sourcesink_resume; | ||
472 | 422 | ||
473 | status = usb_add_function(c, &ss->function); | 423 | status = usb_add_function(c, &ss->function); |
474 | if (status) | 424 | if (status) |
@@ -559,7 +509,7 @@ static struct usb_configuration sourcesink_driver = { | |||
559 | * sourcesink_add - add a source/sink testing configuration to a device | 509 | * sourcesink_add - add a source/sink testing configuration to a device |
560 | * @cdev: the device to support the configuration | 510 | * @cdev: the device to support the configuration |
561 | */ | 511 | */ |
562 | int __init sourcesink_add(struct usb_composite_dev *cdev) | 512 | int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume) |
563 | { | 513 | { |
564 | int id; | 514 | int id; |
565 | 515 | ||
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index fe1832875771..a9c98fdb626d 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c | |||
@@ -108,7 +108,7 @@ static struct usb_cdc_header_desc mdlm_header_desc __initdata = { | |||
108 | .bDescriptorType = USB_DT_CS_INTERFACE, | 108 | .bDescriptorType = USB_DT_CS_INTERFACE, |
109 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 109 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
110 | 110 | ||
111 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 111 | .bcdCDC = cpu_to_le16(0x0110), |
112 | }; | 112 | }; |
113 | 113 | ||
114 | static struct usb_cdc_mdlm_desc mdlm_desc __initdata = { | 114 | static struct usb_cdc_mdlm_desc mdlm_desc __initdata = { |
@@ -116,7 +116,7 @@ static struct usb_cdc_mdlm_desc mdlm_desc __initdata = { | |||
116 | .bDescriptorType = USB_DT_CS_INTERFACE, | 116 | .bDescriptorType = USB_DT_CS_INTERFACE, |
117 | .bDescriptorSubType = USB_CDC_MDLM_TYPE, | 117 | .bDescriptorSubType = USB_CDC_MDLM_TYPE, |
118 | 118 | ||
119 | .bcdVersion = __constant_cpu_to_le16(0x0100), | 119 | .bcdVersion = cpu_to_le16(0x0100), |
120 | .bGUID = { | 120 | .bGUID = { |
121 | 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, | 121 | 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, |
122 | 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, | 122 | 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, |
@@ -144,9 +144,9 @@ static struct usb_cdc_ether_desc ether_desc __initdata = { | |||
144 | 144 | ||
145 | /* this descriptor actually adds value, surprise! */ | 145 | /* this descriptor actually adds value, surprise! */ |
146 | /* .iMACAddress = DYNAMIC */ | 146 | /* .iMACAddress = DYNAMIC */ |
147 | .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */ | 147 | .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */ |
148 | .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN), | 148 | .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN), |
149 | .wNumberMCFilters = __constant_cpu_to_le16(0), | 149 | .wNumberMCFilters = cpu_to_le16(0), |
150 | .bNumberPowerFilters = 0, | 150 | .bNumberPowerFilters = 0, |
151 | }; | 151 | }; |
152 | 152 | ||
@@ -186,7 +186,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = { | |||
186 | .bDescriptorType = USB_DT_ENDPOINT, | 186 | .bDescriptorType = USB_DT_ENDPOINT, |
187 | 187 | ||
188 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 188 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
189 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 189 | .wMaxPacketSize = cpu_to_le16(512), |
190 | }; | 190 | }; |
191 | 191 | ||
192 | static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = { | 192 | static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = { |
@@ -194,7 +194,7 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = { | |||
194 | .bDescriptorType = USB_DT_ENDPOINT, | 194 | .bDescriptorType = USB_DT_ENDPOINT, |
195 | 195 | ||
196 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 196 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
197 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 197 | .wMaxPacketSize = cpu_to_le16(512), |
198 | }; | 198 | }; |
199 | 199 | ||
200 | static struct usb_descriptor_header *hs_eth_function[] __initdata = { | 200 | static struct usb_descriptor_header *hs_eth_function[] __initdata = { |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 1ab9dac7e12d..d3c2464dee82 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -847,13 +847,13 @@ device_desc = { | |||
847 | .bLength = sizeof device_desc, | 847 | .bLength = sizeof device_desc, |
848 | .bDescriptorType = USB_DT_DEVICE, | 848 | .bDescriptorType = USB_DT_DEVICE, |
849 | 849 | ||
850 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 850 | .bcdUSB = cpu_to_le16(0x0200), |
851 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 851 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
852 | 852 | ||
853 | /* The next three values can be overridden by module parameters */ | 853 | /* The next three values can be overridden by module parameters */ |
854 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID), | 854 | .idVendor = cpu_to_le16(DRIVER_VENDOR_ID), |
855 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID), | 855 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_ID), |
856 | .bcdDevice = __constant_cpu_to_le16(0xffff), | 856 | .bcdDevice = cpu_to_le16(0xffff), |
857 | 857 | ||
858 | .iManufacturer = STRING_MANUFACTURER, | 858 | .iManufacturer = STRING_MANUFACTURER, |
859 | .iProduct = STRING_PRODUCT, | 859 | .iProduct = STRING_PRODUCT, |
@@ -926,7 +926,7 @@ fs_intr_in_desc = { | |||
926 | 926 | ||
927 | .bEndpointAddress = USB_DIR_IN, | 927 | .bEndpointAddress = USB_DIR_IN, |
928 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 928 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
929 | .wMaxPacketSize = __constant_cpu_to_le16(2), | 929 | .wMaxPacketSize = cpu_to_le16(2), |
930 | .bInterval = 32, // frames -> 32 ms | 930 | .bInterval = 32, // frames -> 32 ms |
931 | }; | 931 | }; |
932 | 932 | ||
@@ -954,7 +954,7 @@ dev_qualifier = { | |||
954 | .bLength = sizeof dev_qualifier, | 954 | .bLength = sizeof dev_qualifier, |
955 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | 955 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, |
956 | 956 | ||
957 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 957 | .bcdUSB = cpu_to_le16(0x0200), |
958 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 958 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
959 | 959 | ||
960 | .bNumConfigurations = 1, | 960 | .bNumConfigurations = 1, |
@@ -967,7 +967,7 @@ hs_bulk_in_desc = { | |||
967 | 967 | ||
968 | /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ | 968 | /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ |
969 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 969 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
970 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 970 | .wMaxPacketSize = cpu_to_le16(512), |
971 | }; | 971 | }; |
972 | 972 | ||
973 | static struct usb_endpoint_descriptor | 973 | static struct usb_endpoint_descriptor |
@@ -977,7 +977,7 @@ hs_bulk_out_desc = { | |||
977 | 977 | ||
978 | /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ | 978 | /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ |
979 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 979 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
980 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 980 | .wMaxPacketSize = cpu_to_le16(512), |
981 | .bInterval = 1, // NAK every 1 uframe | 981 | .bInterval = 1, // NAK every 1 uframe |
982 | }; | 982 | }; |
983 | 983 | ||
@@ -988,7 +988,7 @@ hs_intr_in_desc = { | |||
988 | 988 | ||
989 | /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ | 989 | /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ |
990 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 990 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
991 | .wMaxPacketSize = __constant_cpu_to_le16(2), | 991 | .wMaxPacketSize = cpu_to_le16(2), |
992 | .bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms | 992 | .bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms |
993 | }; | 993 | }; |
994 | 994 | ||
@@ -2646,7 +2646,7 @@ static int send_status(struct fsg_dev *fsg) | |||
2646 | struct bulk_cs_wrap *csw = bh->buf; | 2646 | struct bulk_cs_wrap *csw = bh->buf; |
2647 | 2647 | ||
2648 | /* Store and send the Bulk-only CSW */ | 2648 | /* Store and send the Bulk-only CSW */ |
2649 | csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); | 2649 | csw->Signature = cpu_to_le32(USB_BULK_CS_SIG); |
2650 | csw->Tag = fsg->tag; | 2650 | csw->Tag = fsg->tag; |
2651 | csw->Residue = cpu_to_le32(fsg->residue); | 2651 | csw->Residue = cpu_to_le32(fsg->residue); |
2652 | csw->Status = status; | 2652 | csw->Status = status; |
@@ -3089,7 +3089,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
3089 | 3089 | ||
3090 | /* Is the CBW valid? */ | 3090 | /* Is the CBW valid? */ |
3091 | if (req->actual != USB_BULK_CB_WRAP_LEN || | 3091 | if (req->actual != USB_BULK_CB_WRAP_LEN || |
3092 | cbw->Signature != __constant_cpu_to_le32( | 3092 | cbw->Signature != cpu_to_le32( |
3093 | USB_BULK_CB_SIG)) { | 3093 | USB_BULK_CB_SIG)) { |
3094 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", | 3094 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", |
3095 | req->actual, | 3095 | req->actual, |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index d8d9a52a44b3..9d7b95d4e3d2 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -1802,7 +1802,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1802 | 1802 | ||
1803 | out: | 1803 | out: |
1804 | if (retval) | 1804 | if (retval) |
1805 | printk("gadget driver register failed %d\n", retval); | 1805 | printk(KERN_WARNING "gadget driver register failed %d\n", |
1806 | retval); | ||
1806 | return retval; | 1807 | return retval; |
1807 | } | 1808 | } |
1808 | EXPORT_SYMBOL(usb_gadget_register_driver); | 1809 | EXPORT_SYMBOL(usb_gadget_register_driver); |
@@ -1847,7 +1848,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1847 | udc_controller->gadget.dev.driver = NULL; | 1848 | udc_controller->gadget.dev.driver = NULL; |
1848 | udc_controller->driver = NULL; | 1849 | udc_controller->driver = NULL; |
1849 | 1850 | ||
1850 | printk("unregistered gadget driver '%s'\n", driver->driver.name); | 1851 | printk(KERN_WARNING "unregistered gadget driver '%s'\n", |
1852 | driver->driver.name); | ||
1851 | return 0; | 1853 | return 0; |
1852 | } | 1854 | } |
1853 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | 1855 | EXPORT_SYMBOL(usb_gadget_unregister_driver); |
@@ -2455,7 +2457,7 @@ module_init(udc_init); | |||
2455 | static void __exit udc_exit(void) | 2457 | static void __exit udc_exit(void) |
2456 | { | 2458 | { |
2457 | platform_driver_unregister(&udc_driver); | 2459 | platform_driver_unregister(&udc_driver); |
2458 | printk("%s unregistered\n", driver_desc); | 2460 | printk(KERN_WARNING "%s unregistered\n", driver_desc); |
2459 | } | 2461 | } |
2460 | 2462 | ||
2461 | module_exit(udc_exit); | 2463 | module_exit(udc_exit); |
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h index dd2f16ad5a88..e84b3c47ed3c 100644 --- a/drivers/usb/gadget/g_zero.h +++ b/drivers/usb/gadget/g_zero.h | |||
@@ -19,7 +19,7 @@ void disable_endpoints(struct usb_composite_dev *cdev, | |||
19 | struct usb_ep *in, struct usb_ep *out); | 19 | struct usb_ep *in, struct usb_ep *out); |
20 | 20 | ||
21 | /* configuration-specific linkup */ | 21 | /* configuration-specific linkup */ |
22 | int sourcesink_add(struct usb_composite_dev *cdev); | 22 | int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume); |
23 | int loopback_add(struct usb_composite_dev *cdev); | 23 | int loopback_add(struct usb_composite_dev *cdev, bool autoresume); |
24 | 24 | ||
25 | #endif /* __G_ZERO_H */ | 25 | #endif /* __G_ZERO_H */ |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 60d3f9e9b51f..b9312dc6e041 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -199,10 +199,10 @@ DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1); | |||
199 | static struct usb_device_descriptor device_desc = { | 199 | static struct usb_device_descriptor device_desc = { |
200 | .bLength = USB_DT_DEVICE_SIZE, | 200 | .bLength = USB_DT_DEVICE_SIZE, |
201 | .bDescriptorType = USB_DT_DEVICE, | 201 | .bDescriptorType = USB_DT_DEVICE, |
202 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 202 | .bcdUSB = cpu_to_le16(0x0200), |
203 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 203 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
204 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), | 204 | .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), |
205 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), | 205 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM), |
206 | .iManufacturer = STRING_MANUFACTURER, | 206 | .iManufacturer = STRING_MANUFACTURER, |
207 | .iProduct = STRING_PRODUCT, | 207 | .iProduct = STRING_PRODUCT, |
208 | .bNumConfigurations = 1, | 208 | .bNumConfigurations = 1, |
@@ -241,8 +241,8 @@ static const struct usb_ac_header_descriptor_1 ac_header_desc = { | |||
241 | .bLength = USB_DT_AC_HEADER_SIZE(1), | 241 | .bLength = USB_DT_AC_HEADER_SIZE(1), |
242 | .bDescriptorType = USB_DT_CS_INTERFACE, | 242 | .bDescriptorType = USB_DT_CS_INTERFACE, |
243 | .bDescriptorSubtype = USB_MS_HEADER, | 243 | .bDescriptorSubtype = USB_MS_HEADER, |
244 | .bcdADC = __constant_cpu_to_le16(0x0100), | 244 | .bcdADC = cpu_to_le16(0x0100), |
245 | .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)), | 245 | .wTotalLength = cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)), |
246 | .bInCollection = 1, | 246 | .bInCollection = 1, |
247 | .baInterfaceNr = { | 247 | .baInterfaceNr = { |
248 | [0] = GMIDI_MS_INTERFACE, | 248 | [0] = GMIDI_MS_INTERFACE, |
@@ -265,8 +265,8 @@ static const struct usb_ms_header_descriptor ms_header_desc = { | |||
265 | .bLength = USB_DT_MS_HEADER_SIZE, | 265 | .bLength = USB_DT_MS_HEADER_SIZE, |
266 | .bDescriptorType = USB_DT_CS_INTERFACE, | 266 | .bDescriptorType = USB_DT_CS_INTERFACE, |
267 | .bDescriptorSubtype = USB_MS_HEADER, | 267 | .bDescriptorSubtype = USB_MS_HEADER, |
268 | .bcdMSC = __constant_cpu_to_le16(0x0100), | 268 | .bcdMSC = cpu_to_le16(0x0100), |
269 | .wTotalLength = __constant_cpu_to_le16(USB_DT_MS_HEADER_SIZE | 269 | .wTotalLength = cpu_to_le16(USB_DT_MS_HEADER_SIZE |
270 | + 2*USB_DT_MIDI_IN_SIZE | 270 | + 2*USB_DT_MIDI_IN_SIZE |
271 | + 2*USB_DT_MIDI_OUT_SIZE(1)), | 271 | + 2*USB_DT_MIDI_OUT_SIZE(1)), |
272 | }; | 272 | }; |
@@ -1099,10 +1099,9 @@ static int gmidi_register_card(struct gmidi_device *dev) | |||
1099 | .dev_free = gmidi_snd_free, | 1099 | .dev_free = gmidi_snd_free, |
1100 | }; | 1100 | }; |
1101 | 1101 | ||
1102 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1102 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
1103 | if (!card) { | 1103 | if (err < 0) { |
1104 | ERROR(dev, "snd_card_new failed\n"); | 1104 | ERROR(dev, "snd_card_create failed\n"); |
1105 | err = -ENOMEM; | ||
1106 | goto fail; | 1105 | goto fail; |
1107 | } | 1106 | } |
1108 | dev->card = card; | 1107 | dev->card = card; |
@@ -1227,7 +1226,7 @@ autoconf_fail: | |||
1227 | */ | 1226 | */ |
1228 | pr_warning("%s: controller '%s' not recognized\n", | 1227 | pr_warning("%s: controller '%s' not recognized\n", |
1229 | shortname, gadget->name); | 1228 | shortname, gadget->name); |
1230 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | 1229 | device_desc.bcdDevice = cpu_to_le16(0x9999); |
1231 | } | 1230 | } |
1232 | 1231 | ||
1233 | 1232 | ||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 63419c4d503c..de010c939dbb 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1472,7 +1472,7 @@ static void ep0_setup(struct goku_udc *dev) | |||
1472 | /* active endpoint */ | 1472 | /* active endpoint */ |
1473 | if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0)) | 1473 | if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0)) |
1474 | goto stall; | 1474 | goto stall; |
1475 | if (ctrl.wIndex & __constant_cpu_to_le16( | 1475 | if (ctrl.wIndex & cpu_to_le16( |
1476 | USB_DIR_IN)) { | 1476 | USB_DIR_IN)) { |
1477 | if (!dev->ep[tmp].is_in) | 1477 | if (!dev->ep[tmp].is_in) |
1478 | goto stall; | 1478 | goto stall; |
@@ -1480,7 +1480,7 @@ static void ep0_setup(struct goku_udc *dev) | |||
1480 | if (dev->ep[tmp].is_in) | 1480 | if (dev->ep[tmp].is_in) |
1481 | goto stall; | 1481 | goto stall; |
1482 | } | 1482 | } |
1483 | if (ctrl.wValue != __constant_cpu_to_le16( | 1483 | if (ctrl.wValue != cpu_to_le16( |
1484 | USB_ENDPOINT_HALT)) | 1484 | USB_ENDPOINT_HALT)) |
1485 | goto stall; | 1485 | goto stall; |
1486 | if (tmp) | 1486 | if (tmp) |
@@ -1493,7 +1493,7 @@ succeed: | |||
1493 | return; | 1493 | return; |
1494 | case USB_RECIP_DEVICE: | 1494 | case USB_RECIP_DEVICE: |
1495 | /* device remote wakeup: always clear */ | 1495 | /* device remote wakeup: always clear */ |
1496 | if (ctrl.wValue != __constant_cpu_to_le16(1)) | 1496 | if (ctrl.wValue != cpu_to_le16(1)) |
1497 | goto stall; | 1497 | goto stall; |
1498 | VDBG(dev, "clear dev remote wakeup\n"); | 1498 | VDBG(dev, "clear dev remote wakeup\n"); |
1499 | goto succeed; | 1499 | goto succeed; |
@@ -1519,7 +1519,7 @@ succeed: | |||
1519 | dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION | 1519 | dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION |
1520 | && ctrl.bRequestType == USB_RECIP_DEVICE); | 1520 | && ctrl.bRequestType == USB_RECIP_DEVICE); |
1521 | if (unlikely(dev->req_config)) | 1521 | if (unlikely(dev->req_config)) |
1522 | dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0)); | 1522 | dev->configured = (ctrl.wValue != cpu_to_le16(0)); |
1523 | 1523 | ||
1524 | /* delegate everything to the gadget driver. | 1524 | /* delegate everything to the gadget driver. |
1525 | * it may respond after this irq handler returns. | 1525 | * it may respond after this irq handler returns. |
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 77c5d0a8a06e..168658b4b4e2 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * driver/usb/gadget/imx_udc.c | 2 | * driver/usb/gadget/imx_udc.c |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Mike Lee(eemike@gmail.com) | 4 | * Copyright (C) 2005 Mike Lee <eemike@gmail.com> |
5 | * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com> | 5 | * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/dma-mapping.h> | 28 | #include <linux/dma-mapping.h> |
29 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/timer.h> | ||
31 | 32 | ||
32 | #include <linux/usb/ch9.h> | 33 | #include <linux/usb/ch9.h> |
33 | #include <linux/usb/gadget.h> | 34 | #include <linux/usb/gadget.h> |
@@ -51,7 +52,8 @@ void ep0_chg_stat(const char *label, struct imx_udc_struct *imx_usb, | |||
51 | void imx_udc_enable(struct imx_udc_struct *imx_usb) | 52 | void imx_udc_enable(struct imx_udc_struct *imx_usb) |
52 | { | 53 | { |
53 | int temp = __raw_readl(imx_usb->base + USB_CTRL); | 54 | int temp = __raw_readl(imx_usb->base + USB_CTRL); |
54 | __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, imx_usb->base + USB_CTRL); | 55 | __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, |
56 | imx_usb->base + USB_CTRL); | ||
55 | imx_usb->gadget.speed = USB_SPEED_FULL; | 57 | imx_usb->gadget.speed = USB_SPEED_FULL; |
56 | } | 58 | } |
57 | 59 | ||
@@ -126,7 +128,8 @@ void imx_udc_config(struct imx_udc_struct *imx_usb) | |||
126 | for (j = 0; j < 5; j++) { | 128 | for (j = 0; j < 5; j++) { |
127 | __raw_writeb(ep_conf[j], | 129 | __raw_writeb(ep_conf[j], |
128 | imx_usb->base + USB_DDAT); | 130 | imx_usb->base + USB_DDAT); |
129 | do {} while (__raw_readl(imx_usb->base + USB_DADR) | 131 | do {} while (__raw_readl(imx_usb->base |
132 | + USB_DADR) | ||
130 | & DADR_BSY); | 133 | & DADR_BSY); |
131 | } | 134 | } |
132 | } | 135 | } |
@@ -183,7 +186,8 @@ void imx_udc_init_ep(struct imx_udc_struct *imx_usb) | |||
183 | temp = (EP_DIR(imx_ep) << 7) | (max << 5) | 186 | temp = (EP_DIR(imx_ep) << 7) | (max << 5) |
184 | | (imx_ep->bmAttributes << 3); | 187 | | (imx_ep->bmAttributes << 3); |
185 | __raw_writel(temp, imx_usb->base + USB_EP_STAT(i)); | 188 | __raw_writel(temp, imx_usb->base + USB_EP_STAT(i)); |
186 | __raw_writel(temp | EPSTAT_FLUSH, imx_usb->base + USB_EP_STAT(i)); | 189 | __raw_writel(temp | EPSTAT_FLUSH, |
190 | imx_usb->base + USB_EP_STAT(i)); | ||
187 | D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i, | 191 | D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i, |
188 | __raw_readl(imx_usb->base + USB_EP_STAT(i))); | 192 | __raw_readl(imx_usb->base + USB_EP_STAT(i))); |
189 | } | 193 | } |
@@ -278,15 +282,18 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep) | |||
278 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; | 282 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; |
279 | int temp, i; | 283 | int temp, i; |
280 | 284 | ||
281 | D_ERR(imx_usb->dev, "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name); | 285 | D_ERR(imx_usb->dev, |
286 | "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name); | ||
282 | 287 | ||
283 | imx_flush(imx_ep); | 288 | imx_flush(imx_ep); |
284 | 289 | ||
285 | /* Special care for ep0 */ | 290 | /* Special care for ep0 */ |
286 | if (EP_NO(imx_ep)) { | 291 | if (!EP_NO(imx_ep)) { |
287 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 292 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
288 | __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL); | 293 | __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, |
289 | do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER); | 294 | imx_usb->base + USB_CTRL); |
295 | do { } while (__raw_readl(imx_usb->base + USB_CTRL) | ||
296 | & CTRL_CMDOVER); | ||
290 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 297 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
291 | __raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL); | 298 | __raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL); |
292 | } | 299 | } |
@@ -296,12 +303,13 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep) | |||
296 | imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | 303 | imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); |
297 | 304 | ||
298 | for (i = 0; i < 100; i ++) { | 305 | for (i = 0; i < 100; i ++) { |
299 | temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | 306 | temp = __raw_readl(imx_usb->base |
307 | + USB_EP_STAT(EP_NO(imx_ep))); | ||
300 | if (!(temp & EPSTAT_STALL)) | 308 | if (!(temp & EPSTAT_STALL)) |
301 | break; | 309 | break; |
302 | udelay(20); | 310 | udelay(20); |
303 | } | 311 | } |
304 | if (i == 50) | 312 | if (i == 100) |
305 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", | 313 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", |
306 | __func__, imx_ep->ep.name); | 314 | __func__, imx_ep->ep.name); |
307 | } | 315 | } |
@@ -325,7 +333,8 @@ static int imx_udc_wakeup(struct usb_gadget *_gadget) | |||
325 | ******************************************************************************* | 333 | ******************************************************************************* |
326 | */ | 334 | */ |
327 | 335 | ||
328 | static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req) | 336 | static void ep_add_request(struct imx_ep_struct *imx_ep, |
337 | struct imx_request *req) | ||
329 | { | 338 | { |
330 | if (unlikely(!req)) | 339 | if (unlikely(!req)) |
331 | return; | 340 | return; |
@@ -334,7 +343,8 @@ static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req | |||
334 | list_add_tail(&req->queue, &imx_ep->queue); | 343 | list_add_tail(&req->queue, &imx_ep->queue); |
335 | } | 344 | } |
336 | 345 | ||
337 | static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req) | 346 | static void ep_del_request(struct imx_ep_struct *imx_ep, |
347 | struct imx_request *req) | ||
338 | { | 348 | { |
339 | if (unlikely(!req)) | 349 | if (unlikely(!req)) |
340 | return; | 350 | return; |
@@ -343,7 +353,8 @@ static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req | |||
343 | req->in_use = 0; | 353 | req->in_use = 0; |
344 | } | 354 | } |
345 | 355 | ||
346 | static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status) | 356 | static void done(struct imx_ep_struct *imx_ep, |
357 | struct imx_request *req, int status) | ||
347 | { | 358 | { |
348 | ep_del_request(imx_ep, req); | 359 | ep_del_request(imx_ep, req); |
349 | 360 | ||
@@ -494,7 +505,8 @@ static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req) | |||
494 | __func__, imx_ep->ep.name, req, | 505 | __func__, imx_ep->ep.name, req, |
495 | completed ? "completed" : "not completed"); | 506 | completed ? "completed" : "not completed"); |
496 | if (!EP_NO(imx_ep)) | 507 | if (!EP_NO(imx_ep)) |
497 | ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE); | 508 | ep0_chg_stat(__func__, |
509 | imx_ep->imx_usb, EP0_IDLE); | ||
498 | } | 510 | } |
499 | } | 511 | } |
500 | 512 | ||
@@ -539,10 +551,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep) | |||
539 | struct imx_request *req = NULL; | 551 | struct imx_request *req = NULL; |
540 | int ret = 0; | 552 | int ret = 0; |
541 | 553 | ||
542 | if (!list_empty(&imx_ep->queue)) | 554 | if (!list_empty(&imx_ep->queue)) { |
543 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); | 555 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); |
544 | 556 | ||
545 | if (req) { | ||
546 | switch (imx_ep->imx_usb->ep0state) { | 557 | switch (imx_ep->imx_usb->ep0state) { |
547 | 558 | ||
548 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ | 559 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ |
@@ -561,6 +572,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep) | |||
561 | } | 572 | } |
562 | } | 573 | } |
563 | 574 | ||
575 | else | ||
576 | D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n", | ||
577 | __func__, imx_ep->ep.name); | ||
578 | |||
564 | return ret; | 579 | return ret; |
565 | } | 580 | } |
566 | 581 | ||
@@ -583,7 +598,8 @@ static void handle_ep0_devreq(struct imx_udc_struct *imx_usb) | |||
583 | "<%s> no setup packet received\n", __func__); | 598 | "<%s> no setup packet received\n", __func__); |
584 | goto stall; | 599 | goto stall; |
585 | } | 600 | } |
586 | u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep))); | 601 | u.word[i] = __raw_readl(imx_usb->base |
602 | + USB_EP_FDAT(EP_NO(imx_ep))); | ||
587 | } | 603 | } |
588 | 604 | ||
589 | temp = imx_ep_empty(imx_ep); | 605 | temp = imx_ep_empty(imx_ep); |
@@ -759,7 +775,7 @@ static int imx_ep_queue | |||
759 | */ | 775 | */ |
760 | if (imx_usb->set_config && !EP_NO(imx_ep)) { | 776 | if (imx_usb->set_config && !EP_NO(imx_ep)) { |
761 | imx_usb->set_config = 0; | 777 | imx_usb->set_config = 0; |
762 | D_EPX(imx_usb->dev, | 778 | D_ERR(imx_usb->dev, |
763 | "<%s> gadget reply set config\n", __func__); | 779 | "<%s> gadget reply set config\n", __func__); |
764 | return 0; | 780 | return 0; |
765 | } | 781 | } |
@@ -779,28 +795,29 @@ static int imx_ep_queue | |||
779 | return -ESHUTDOWN; | 795 | return -ESHUTDOWN; |
780 | } | 796 | } |
781 | 797 | ||
782 | local_irq_save(flags); | ||
783 | |||
784 | /* Debug */ | 798 | /* Debug */ |
785 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", | 799 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", |
786 | __func__, EP_NO(imx_ep), | 800 | __func__, EP_NO(imx_ep), |
787 | ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE) | 801 | ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state |
788 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length); | 802 | == EP0_IN_DATA_PHASE) |
803 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) | ||
804 | ? "IN" : "OUT", usb_req->length); | ||
789 | dump_req(__func__, imx_ep, usb_req); | 805 | dump_req(__func__, imx_ep, usb_req); |
790 | 806 | ||
791 | if (imx_ep->stopped) { | 807 | if (imx_ep->stopped) { |
792 | usb_req->status = -ESHUTDOWN; | 808 | usb_req->status = -ESHUTDOWN; |
793 | ret = -ESHUTDOWN; | 809 | return -ESHUTDOWN; |
794 | goto out; | ||
795 | } | 810 | } |
796 | 811 | ||
797 | if (req->in_use) { | 812 | if (req->in_use) { |
798 | D_ERR(imx_usb->dev, | 813 | D_ERR(imx_usb->dev, |
799 | "<%s> refusing to queue req %p (already queued)\n", | 814 | "<%s> refusing to queue req %p (already queued)\n", |
800 | __func__, req); | 815 | __func__, req); |
801 | goto out; | 816 | return 0; |
802 | } | 817 | } |
803 | 818 | ||
819 | local_irq_save(flags); | ||
820 | |||
804 | usb_req->status = -EINPROGRESS; | 821 | usb_req->status = -EINPROGRESS; |
805 | usb_req->actual = 0; | 822 | usb_req->actual = 0; |
806 | 823 | ||
@@ -810,7 +827,7 @@ static int imx_ep_queue | |||
810 | ret = handle_ep0(imx_ep); | 827 | ret = handle_ep0(imx_ep); |
811 | else | 828 | else |
812 | ret = handle_ep(imx_ep); | 829 | ret = handle_ep(imx_ep); |
813 | out: | 830 | |
814 | local_irq_restore(flags); | 831 | local_irq_restore(flags); |
815 | return ret; | 832 | return ret; |
816 | } | 833 | } |
@@ -997,71 +1014,32 @@ static void udc_stop_activity(struct imx_udc_struct *imx_usb, | |||
997 | ******************************************************************************* | 1014 | ******************************************************************************* |
998 | */ | 1015 | */ |
999 | 1016 | ||
1000 | static irqreturn_t imx_udc_irq(int irq, void *dev) | 1017 | /* |
1018 | * Called when timer expires. | ||
1019 | * Timer is started when CFG_CHG is received. | ||
1020 | */ | ||
1021 | static void handle_config(unsigned long data) | ||
1001 | { | 1022 | { |
1002 | struct imx_udc_struct *imx_usb = dev; | 1023 | struct imx_udc_struct *imx_usb = (void *)data; |
1003 | struct usb_ctrlrequest u; | 1024 | struct usb_ctrlrequest u; |
1004 | int temp, cfg, intf, alt; | 1025 | int temp, cfg, intf, alt; |
1005 | int intr = __raw_readl(imx_usb->base + USB_INTR); | ||
1006 | 1026 | ||
1007 | if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START | 1027 | local_irq_disable(); |
1008 | | INTR_RESET_STOP | INTR_CFG_CHG)) { | ||
1009 | dump_intr(__func__, intr, imx_usb->dev); | ||
1010 | dump_usb_stat(__func__, imx_usb); | ||
1011 | } | ||
1012 | 1028 | ||
1013 | if (!imx_usb->driver) { | 1029 | temp = __raw_readl(imx_usb->base + USB_STAT); |
1014 | /*imx_udc_disable(imx_usb);*/ | 1030 | cfg = (temp & STAT_CFG) >> 5; |
1015 | goto end_irq; | 1031 | intf = (temp & STAT_INTF) >> 3; |
1016 | } | 1032 | alt = temp & STAT_ALTSET; |
1017 | 1033 | ||
1018 | if (intr & INTR_WAKEUP) { | 1034 | D_REQ(imx_usb->dev, |
1019 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | 1035 | "<%s> orig config C=%d, I=%d, A=%d / " |
1020 | && imx_usb->driver && imx_usb->driver->resume) | 1036 | "req config C=%d, I=%d, A=%d\n", |
1021 | imx_usb->driver->resume(&imx_usb->gadget); | 1037 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, |
1022 | imx_usb->set_config = 0; | 1038 | cfg, intf, alt); |
1023 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1024 | } | ||
1025 | |||
1026 | if (intr & INTR_SUSPEND) { | ||
1027 | if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN | ||
1028 | && imx_usb->driver && imx_usb->driver->suspend) | ||
1029 | imx_usb->driver->suspend(&imx_usb->gadget); | ||
1030 | imx_usb->set_config = 0; | ||
1031 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1032 | } | ||
1033 | |||
1034 | if (intr & INTR_RESET_START) { | ||
1035 | __raw_writel(intr, imx_usb->base + USB_INTR); | ||
1036 | udc_stop_activity(imx_usb, imx_usb->driver); | ||
1037 | imx_usb->set_config = 0; | ||
1038 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1039 | } | ||
1040 | 1039 | ||
1041 | if (intr & INTR_RESET_STOP) | 1040 | if (cfg == 1 || cfg == 2) { |
1042 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1043 | 1041 | ||
1044 | if (intr & INTR_CFG_CHG) { | ||
1045 | __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR); | ||
1046 | temp = __raw_readl(imx_usb->base + USB_STAT); | ||
1047 | cfg = (temp & STAT_CFG) >> 5; | ||
1048 | intf = (temp & STAT_INTF) >> 3; | ||
1049 | alt = temp & STAT_ALTSET; | ||
1050 | |||
1051 | D_REQ(imx_usb->dev, | ||
1052 | "<%s> orig config C=%d, I=%d, A=%d / " | ||
1053 | "req config C=%d, I=%d, A=%d\n", | ||
1054 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, | ||
1055 | cfg, intf, alt); | ||
1056 | |||
1057 | if (cfg != 1 && cfg != 2) | ||
1058 | goto end_irq; | ||
1059 | |||
1060 | imx_usb->set_config = 0; | ||
1061 | |||
1062 | /* Config setup */ | ||
1063 | if (imx_usb->cfg != cfg) { | 1042 | if (imx_usb->cfg != cfg) { |
1064 | D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__); | ||
1065 | u.bRequest = USB_REQ_SET_CONFIGURATION; | 1043 | u.bRequest = USB_REQ_SET_CONFIGURATION; |
1066 | u.bRequestType = USB_DIR_OUT | | 1044 | u.bRequestType = USB_DIR_OUT | |
1067 | USB_TYPE_STANDARD | | 1045 | USB_TYPE_STANDARD | |
@@ -1070,14 +1048,10 @@ static irqreturn_t imx_udc_irq(int irq, void *dev) | |||
1070 | u.wIndex = 0; | 1048 | u.wIndex = 0; |
1071 | u.wLength = 0; | 1049 | u.wLength = 0; |
1072 | imx_usb->cfg = cfg; | 1050 | imx_usb->cfg = cfg; |
1073 | imx_usb->set_config = 1; | ||
1074 | imx_usb->driver->setup(&imx_usb->gadget, &u); | 1051 | imx_usb->driver->setup(&imx_usb->gadget, &u); |
1075 | imx_usb->set_config = 0; | ||
1076 | D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__); | ||
1077 | 1052 | ||
1078 | } | 1053 | } |
1079 | if (imx_usb->intf != intf || imx_usb->alt != alt) { | 1054 | if (imx_usb->intf != intf || imx_usb->alt != alt) { |
1080 | D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__); | ||
1081 | u.bRequest = USB_REQ_SET_INTERFACE; | 1055 | u.bRequest = USB_REQ_SET_INTERFACE; |
1082 | u.bRequestType = USB_DIR_OUT | | 1056 | u.bRequestType = USB_DIR_OUT | |
1083 | USB_TYPE_STANDARD | | 1057 | USB_TYPE_STANDARD | |
@@ -1087,20 +1061,92 @@ static irqreturn_t imx_udc_irq(int irq, void *dev) | |||
1087 | u.wLength = 0; | 1061 | u.wLength = 0; |
1088 | imx_usb->intf = intf; | 1062 | imx_usb->intf = intf; |
1089 | imx_usb->alt = alt; | 1063 | imx_usb->alt = alt; |
1090 | imx_usb->set_config = 1; | ||
1091 | imx_usb->driver->setup(&imx_usb->gadget, &u); | 1064 | imx_usb->driver->setup(&imx_usb->gadget, &u); |
1092 | imx_usb->set_config = 0; | ||
1093 | D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__); | ||
1094 | } | 1065 | } |
1095 | } | 1066 | } |
1096 | 1067 | ||
1068 | imx_usb->set_config = 0; | ||
1069 | |||
1070 | local_irq_enable(); | ||
1071 | } | ||
1072 | |||
1073 | static irqreturn_t imx_udc_irq(int irq, void *dev) | ||
1074 | { | ||
1075 | struct imx_udc_struct *imx_usb = dev; | ||
1076 | int intr = __raw_readl(imx_usb->base + USB_INTR); | ||
1077 | int temp; | ||
1078 | |||
1079 | if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START | ||
1080 | | INTR_RESET_STOP | INTR_CFG_CHG)) { | ||
1081 | dump_intr(__func__, intr, imx_usb->dev); | ||
1082 | dump_usb_stat(__func__, imx_usb); | ||
1083 | } | ||
1084 | |||
1085 | if (!imx_usb->driver) | ||
1086 | goto end_irq; | ||
1087 | |||
1097 | if (intr & INTR_SOF) { | 1088 | if (intr & INTR_SOF) { |
1089 | /* Copy from Freescale BSP. | ||
1090 | We must enable SOF intr and set CMDOVER. | ||
1091 | Datasheet don't specifiy this action, but it | ||
1092 | is done in Freescale BSP, so just copy it. | ||
1093 | */ | ||
1098 | if (imx_usb->ep0state == EP0_IDLE) { | 1094 | if (imx_usb->ep0state == EP0_IDLE) { |
1099 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 1095 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
1100 | __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL); | 1096 | __raw_writel(temp | CTRL_CMDOVER, |
1097 | imx_usb->base + USB_CTRL); | ||
1101 | } | 1098 | } |
1102 | } | 1099 | } |
1103 | 1100 | ||
1101 | if (intr & INTR_CFG_CHG) { | ||
1102 | /* A workaround of serious IMX UDC bug. | ||
1103 | Handling of CFG_CHG should be delayed for some time, because | ||
1104 | IMX does not NACK the host when CFG_CHG interrupt is pending. | ||
1105 | There is no time to handle current CFG_CHG | ||
1106 | if next CFG_CHG or SETUP packed is send immediately. | ||
1107 | We have to clear CFG_CHG, start the timer and | ||
1108 | NACK the host by setting CTRL_CMDOVER | ||
1109 | if it sends any SETUP packet. | ||
1110 | When timer expires, handler is called to handle configuration | ||
1111 | changes. While CFG_CHG is not handled (set_config=1), | ||
1112 | we must NACK the host to every SETUP packed. | ||
1113 | This delay prevents from going out of sync with host. | ||
1114 | */ | ||
1115 | __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR); | ||
1116 | imx_usb->set_config = 1; | ||
1117 | mod_timer(&imx_usb->timer, jiffies + 5); | ||
1118 | goto end_irq; | ||
1119 | } | ||
1120 | |||
1121 | if (intr & INTR_WAKEUP) { | ||
1122 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | ||
1123 | && imx_usb->driver && imx_usb->driver->resume) | ||
1124 | imx_usb->driver->resume(&imx_usb->gadget); | ||
1125 | imx_usb->set_config = 0; | ||
1126 | del_timer(&imx_usb->timer); | ||
1127 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1128 | } | ||
1129 | |||
1130 | if (intr & INTR_SUSPEND) { | ||
1131 | if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN | ||
1132 | && imx_usb->driver && imx_usb->driver->suspend) | ||
1133 | imx_usb->driver->suspend(&imx_usb->gadget); | ||
1134 | imx_usb->set_config = 0; | ||
1135 | del_timer(&imx_usb->timer); | ||
1136 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1137 | } | ||
1138 | |||
1139 | if (intr & INTR_RESET_START) { | ||
1140 | __raw_writel(intr, imx_usb->base + USB_INTR); | ||
1141 | udc_stop_activity(imx_usb, imx_usb->driver); | ||
1142 | imx_usb->set_config = 0; | ||
1143 | del_timer(&imx_usb->timer); | ||
1144 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1145 | } | ||
1146 | |||
1147 | if (intr & INTR_RESET_STOP) | ||
1148 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1149 | |||
1104 | end_irq: | 1150 | end_irq: |
1105 | __raw_writel(intr, imx_usb->base + USB_INTR); | 1151 | __raw_writel(intr, imx_usb->base + USB_INTR); |
1106 | return IRQ_HANDLED; | 1152 | return IRQ_HANDLED; |
@@ -1109,6 +1155,7 @@ end_irq: | |||
1109 | static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) | 1155 | static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) |
1110 | { | 1156 | { |
1111 | struct imx_udc_struct *imx_usb = dev; | 1157 | struct imx_udc_struct *imx_usb = dev; |
1158 | struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0]; | ||
1112 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0)); | 1159 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0)); |
1113 | 1160 | ||
1114 | dump_ep_intr(__func__, 0, intr, imx_usb->dev); | 1161 | dump_ep_intr(__func__, 0, intr, imx_usb->dev); |
@@ -1118,16 +1165,15 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) | |||
1118 | return IRQ_HANDLED; | 1165 | return IRQ_HANDLED; |
1119 | } | 1166 | } |
1120 | 1167 | ||
1121 | /* DEVREQ IRQ has highest priority */ | 1168 | /* DEVREQ has highest priority */ |
1122 | if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ)) | 1169 | if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ)) |
1123 | handle_ep0_devreq(imx_usb); | 1170 | handle_ep0_devreq(imx_usb); |
1124 | /* Seem i.MX is missing EOF interrupt sometimes. | 1171 | /* Seem i.MX is missing EOF interrupt sometimes. |
1125 | * Therefore we monitor both EOF and FIFO_EMPTY interrups | 1172 | * Therefore we don't monitor EOF. |
1126 | * when transmiting, and both EOF and FIFO_FULL when | 1173 | * We call handle_ep0() only if a request is queued for ep0. |
1127 | * receiving data. | ||
1128 | */ | 1174 | */ |
1129 | else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL)) | 1175 | else if (!list_empty(&imx_ep->queue)) |
1130 | handle_ep0(&imx_usb->imx_ep[0]); | 1176 | handle_ep0(imx_ep); |
1131 | 1177 | ||
1132 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(0)); | 1178 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(0)); |
1133 | 1179 | ||
@@ -1186,8 +1232,8 @@ static struct imx_udc_struct controller = { | |||
1186 | .ep0 = &controller.imx_ep[0].ep, | 1232 | .ep0 = &controller.imx_ep[0].ep, |
1187 | .name = driver_name, | 1233 | .name = driver_name, |
1188 | .dev = { | 1234 | .dev = { |
1189 | .bus_id = "gadget", | 1235 | .init_name = "gadget", |
1190 | }, | 1236 | }, |
1191 | }, | 1237 | }, |
1192 | 1238 | ||
1193 | .imx_ep[0] = { | 1239 | .imx_ep[0] = { |
@@ -1318,6 +1364,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1318 | 1364 | ||
1319 | udc_stop_activity(imx_usb, driver); | 1365 | udc_stop_activity(imx_usb, driver); |
1320 | imx_udc_disable(imx_usb); | 1366 | imx_udc_disable(imx_usb); |
1367 | del_timer(&imx_usb->timer); | ||
1321 | 1368 | ||
1322 | driver->unbind(&imx_usb->gadget); | 1369 | driver->unbind(&imx_usb->gadget); |
1323 | imx_usb->gadget.dev.driver = NULL; | 1370 | imx_usb->gadget.dev.driver = NULL; |
@@ -1435,6 +1482,10 @@ static int __init imx_udc_probe(struct platform_device *pdev) | |||
1435 | usb_init_data(imx_usb); | 1482 | usb_init_data(imx_usb); |
1436 | imx_udc_init(imx_usb); | 1483 | imx_udc_init(imx_usb); |
1437 | 1484 | ||
1485 | init_timer(&imx_usb->timer); | ||
1486 | imx_usb->timer.function = handle_config; | ||
1487 | imx_usb->timer.data = (unsigned long)imx_usb; | ||
1488 | |||
1438 | return 0; | 1489 | return 0; |
1439 | 1490 | ||
1440 | fail3: | 1491 | fail3: |
@@ -1457,6 +1508,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev) | |||
1457 | int i; | 1508 | int i; |
1458 | 1509 | ||
1459 | imx_udc_disable(imx_usb); | 1510 | imx_udc_disable(imx_usb); |
1511 | del_timer(&imx_usb->timer); | ||
1460 | 1512 | ||
1461 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) | 1513 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) |
1462 | free_irq(imx_usb->usbd_int[i], imx_usb); | 1514 | free_irq(imx_usb->usbd_int[i], imx_usb); |
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h index 850076937d8d..b48ad59603d1 100644 --- a/drivers/usb/gadget/imx_udc.h +++ b/drivers/usb/gadget/imx_udc.h | |||
@@ -23,7 +23,8 @@ | |||
23 | /* Helper macros */ | 23 | /* Helper macros */ |
24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ | 24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ |
25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) | 25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) |
26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | 26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \ |
27 | ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | ||
27 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) | 28 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) |
28 | #define IMX_USB_NB_EP 6 | 29 | #define IMX_USB_NB_EP 6 |
29 | 30 | ||
@@ -58,6 +59,7 @@ struct imx_udc_struct { | |||
58 | struct device *dev; | 59 | struct device *dev; |
59 | struct imx_ep_struct imx_ep[IMX_USB_NB_EP]; | 60 | struct imx_ep_struct imx_ep[IMX_USB_NB_EP]; |
60 | struct clk *clk; | 61 | struct clk *clk; |
62 | struct timer_list timer; | ||
61 | enum ep0_state ep0state; | 63 | enum ep0_state ep0state; |
62 | struct resource *res; | 64 | struct resource *res; |
63 | void __iomem *base; | 65 | void __iomem *base; |
@@ -88,8 +90,8 @@ struct imx_udc_struct { | |||
88 | #define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */ | 90 | #define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */ |
89 | #define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */ | 91 | #define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */ |
90 | #define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */ | 92 | #define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */ |
91 | #define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */ | 93 | #define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last rd f. pointer */ |
92 | #define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */ | 94 | #define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last wr f. pointer */ |
93 | #define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */ | 95 | #define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */ |
94 | #define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */ | 96 | #define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */ |
95 | #define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */ | 97 | #define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */ |
@@ -170,7 +172,7 @@ struct imx_udc_struct { | |||
170 | /* #define DEBUG_IRQ */ | 172 | /* #define DEBUG_IRQ */ |
171 | /* #define DEBUG_EPIRQ */ | 173 | /* #define DEBUG_EPIRQ */ |
172 | /* #define DEBUG_DUMP */ | 174 | /* #define DEBUG_DUMP */ |
173 | #define DEBUG_ERR | 175 | /* #define DEBUG_ERR */ |
174 | 176 | ||
175 | #ifdef DEBUG_REQ | 177 | #ifdef DEBUG_REQ |
176 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) | 178 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) |
@@ -228,7 +230,8 @@ struct imx_udc_struct { | |||
228 | #endif /* DEBUG_IRQ */ | 230 | #endif /* DEBUG_IRQ */ |
229 | 231 | ||
230 | #ifdef DEBUG_EPIRQ | 232 | #ifdef DEBUG_EPIRQ |
231 | static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev) | 233 | static void dump_ep_intr(const char *label, int nr, int irqreg, |
234 | struct device *dev) | ||
232 | { | 235 | { |
233 | dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr, | 236 | dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr, |
234 | (irqreg & EPINTR_FIFO_FULL) ? " full" : "", | 237 | (irqreg & EPINTR_FIFO_FULL) ? " full" : "", |
@@ -246,7 +249,8 @@ struct imx_udc_struct { | |||
246 | #endif /* DEBUG_IRQ */ | 249 | #endif /* DEBUG_IRQ */ |
247 | 250 | ||
248 | #ifdef DEBUG_DUMP | 251 | #ifdef DEBUG_DUMP |
249 | static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb) | 252 | static void dump_usb_stat(const char *label, |
253 | struct imx_udc_struct *imx_usb) | ||
250 | { | 254 | { |
251 | int temp = __raw_readl(imx_usb->base + USB_STAT); | 255 | int temp = __raw_readl(imx_usb->base + USB_STAT); |
252 | 256 | ||
@@ -259,12 +263,15 @@ struct imx_udc_struct { | |||
259 | (temp & STAT_ALTSET)); | 263 | (temp & STAT_ALTSET)); |
260 | } | 264 | } |
261 | 265 | ||
262 | static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep) | 266 | static void dump_ep_stat(const char *label, |
267 | struct imx_ep_struct *imx_ep) | ||
263 | { | 268 | { |
264 | int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | 269 | int temp = __raw_readl(imx_ep->imx_usb->base |
270 | + USB_EP_INTR(EP_NO(imx_ep))); | ||
265 | 271 | ||
266 | dev_dbg(imx_ep->imx_usb->dev, | 272 | dev_dbg(imx_ep->imx_usb->dev, |
267 | "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep), | 273 | "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", |
274 | label, EP_NO(imx_ep), | ||
268 | (temp & EPINTR_FIFO_FULL) ? " full" : "", | 275 | (temp & EPINTR_FIFO_FULL) ? " full" : "", |
269 | (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "", | 276 | (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "", |
270 | (temp & EPINTR_FIFO_ERROR) ? " ferr" : "", | 277 | (temp & EPINTR_FIFO_ERROR) ? " ferr" : "", |
@@ -275,18 +282,22 @@ struct imx_udc_struct { | |||
275 | (temp & EPINTR_DEVREQ) ? " devreq" : "", | 282 | (temp & EPINTR_DEVREQ) ? " devreq" : "", |
276 | (temp & EPINTR_EOT) ? " eot" : ""); | 283 | (temp & EPINTR_EOT) ? " eot" : ""); |
277 | 284 | ||
278 | temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | 285 | temp = __raw_readl(imx_ep->imx_usb->base |
286 | + USB_EP_STAT(EP_NO(imx_ep))); | ||
279 | 287 | ||
280 | dev_dbg(imx_ep->imx_usb->dev, | 288 | dev_dbg(imx_ep->imx_usb->dev, |
281 | "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep), | 289 | "<%s> EP%d_STAT=[%s%s bcount=%d]\n", |
290 | label, EP_NO(imx_ep), | ||
282 | (temp & EPSTAT_SIP) ? " sip" : "", | 291 | (temp & EPSTAT_SIP) ? " sip" : "", |
283 | (temp & EPSTAT_STALL) ? " stall" : "", | 292 | (temp & EPSTAT_STALL) ? " stall" : "", |
284 | (temp & EPSTAT_BCOUNT) >> 16); | 293 | (temp & EPSTAT_BCOUNT) >> 16); |
285 | 294 | ||
286 | temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep))); | 295 | temp = __raw_readl(imx_ep->imx_usb->base |
296 | + USB_EP_FSTAT(EP_NO(imx_ep))); | ||
287 | 297 | ||
288 | dev_dbg(imx_ep->imx_usb->dev, | 298 | dev_dbg(imx_ep->imx_usb->dev, |
289 | "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep), | 299 | "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", |
300 | label, EP_NO(imx_ep), | ||
290 | (temp & FSTAT_ERR) ? " ferr" : "", | 301 | (temp & FSTAT_ERR) ? " ferr" : "", |
291 | (temp & FSTAT_UF) ? " funder" : "", | 302 | (temp & FSTAT_UF) ? " funder" : "", |
292 | (temp & FSTAT_OF) ? " fover" : "", | 303 | (temp & FSTAT_OF) ? " fover" : "", |
@@ -296,19 +307,23 @@ struct imx_udc_struct { | |||
296 | (temp & FSTAT_EMPTY) ? " fempty" : ""); | 307 | (temp & FSTAT_EMPTY) ? " fempty" : ""); |
297 | } | 308 | } |
298 | 309 | ||
299 | static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req) | 310 | static void dump_req(const char *label, struct imx_ep_struct *imx_ep, |
311 | struct usb_request *req) | ||
300 | { | 312 | { |
301 | int i; | 313 | int i; |
302 | 314 | ||
303 | if (!req || !req->buf) { | 315 | if (!req || !req->buf) { |
304 | dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label); | 316 | dev_dbg(imx_ep->imx_usb->dev, |
317 | "<%s> req or req buf is free\n", label); | ||
305 | return; | 318 | return; |
306 | } | 319 | } |
307 | 320 | ||
308 | if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE) | 321 | if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state |
322 | == EP0_IN_DATA_PHASE) | ||
309 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) { | 323 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) { |
310 | 324 | ||
311 | dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label); | 325 | dev_dbg(imx_ep->imx_usb->dev, |
326 | "<%s> request dump <", label); | ||
312 | for (i = 0; i < req->length; i++) | 327 | for (i = 0; i < req->length; i++) |
313 | printk("%02x-", *((u8 *)req->buf + i)); | 328 | printk("%02x-", *((u8 *)req->buf + i)); |
314 | printk(">\n"); | 329 | printk(">\n"); |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 317b48fdbf01..d20937f28a19 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1334,7 +1334,7 @@ static void make_qualifier (struct dev_data *dev) | |||
1334 | 1334 | ||
1335 | qual.bLength = sizeof qual; | 1335 | qual.bLength = sizeof qual; |
1336 | qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER; | 1336 | qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER; |
1337 | qual.bcdUSB = __constant_cpu_to_le16 (0x0200); | 1337 | qual.bcdUSB = cpu_to_le16 (0x0200); |
1338 | 1338 | ||
1339 | desc = dev->dev; | 1339 | desc = dev->dev; |
1340 | qual.bDeviceClass = desc->bDeviceClass; | 1340 | qual.bDeviceClass = desc->bDeviceClass; |
@@ -1908,7 +1908,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1908 | || dev->dev->bNumConfigurations != 1) | 1908 | || dev->dev->bNumConfigurations != 1) |
1909 | goto fail; | 1909 | goto fail; |
1910 | dev->dev->bNumConfigurations = 1; | 1910 | dev->dev->bNumConfigurations = 1; |
1911 | dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200); | 1911 | dev->dev->bcdUSB = cpu_to_le16 (0x0200); |
1912 | 1912 | ||
1913 | /* triggers gadgetfs_bind(); then we can enumerate. */ | 1913 | /* triggers gadgetfs_bind(); then we can enumerate. */ |
1914 | spin_unlock_irq (&dev->lock); | 1914 | spin_unlock_irq (&dev->lock); |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index d554b0895603..6cd3d54f5640 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -432,8 +432,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
432 | device_add(&dev->gadget.dev); | 432 | device_add(&dev->gadget.dev); |
433 | retval = driver->bind(&dev->gadget); | 433 | retval = driver->bind(&dev->gadget); |
434 | if (retval) { | 434 | if (retval) { |
435 | printk("%s: bind to driver %s --> error %d\n", dev->gadget.name, | 435 | printk(KERN_WARNING "%s: bind to driver %s --> error %d\n", |
436 | driver->driver.name, retval); | 436 | dev->gadget.name, driver->driver.name, retval); |
437 | device_del(&dev->gadget.dev); | 437 | device_del(&dev->gadget.dev); |
438 | 438 | ||
439 | dev->driver = 0; | 439 | dev->driver = 0; |
@@ -445,8 +445,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
445 | * for set_configuration as well as eventual disconnect. | 445 | * for set_configuration as well as eventual disconnect. |
446 | * NOTE: this shouldn't power up until later. | 446 | * NOTE: this shouldn't power up until later. |
447 | */ | 447 | */ |
448 | printk("%s: registered gadget driver '%s'\n", dev->gadget.name, | 448 | printk(KERN_WARNING "%s: registered gadget driver '%s'\n", |
449 | driver->driver.name); | 449 | dev->gadget.name, driver->driver.name); |
450 | 450 | ||
451 | udc_enable(dev); | 451 | udc_enable(dev); |
452 | 452 | ||
@@ -581,7 +581,8 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req) | |||
581 | * discard the extra data. | 581 | * discard the extra data. |
582 | */ | 582 | */ |
583 | if (req->req.status != -EOVERFLOW) | 583 | if (req->req.status != -EOVERFLOW) |
584 | printk("%s overflow %d\n", ep->ep.name, count); | 584 | printk(KERN_WARNING "%s overflow %d\n", |
585 | ep->ep.name, count); | ||
585 | req->req.status = -EOVERFLOW; | 586 | req->req.status = -EOVERFLOW; |
586 | } else { | 587 | } else { |
587 | *buf++ = byte; | 588 | *buf++ = byte; |
@@ -831,7 +832,8 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) | |||
831 | queue); | 832 | queue); |
832 | 833 | ||
833 | if (!req) { | 834 | if (!req) { |
834 | printk("%s: NULL REQ %d\n", | 835 | printk(KERN_WARNING |
836 | "%s: NULL REQ %d\n", | ||
835 | __func__, ep_idx); | 837 | __func__, ep_idx); |
836 | flush(ep); | 838 | flush(ep); |
837 | break; | 839 | break; |
@@ -844,7 +846,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) | |||
844 | 846 | ||
845 | } else { | 847 | } else { |
846 | /* Throw packet away.. */ | 848 | /* Throw packet away.. */ |
847 | printk("%s: No descriptor?!?\n", __func__); | 849 | printk(KERN_WARNING "%s: No descriptor?!?\n", __func__); |
848 | flush(ep); | 850 | flush(ep); |
849 | } | 851 | } |
850 | } | 852 | } |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 12c6d83b218c..9498be87a724 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -142,8 +142,8 @@ static char *type_string (u8 bmAttributes) | |||
142 | 142 | ||
143 | #include "net2280.h" | 143 | #include "net2280.h" |
144 | 144 | ||
145 | #define valid_bit __constant_cpu_to_le32 (1 << VALID_BIT) | 145 | #define valid_bit cpu_to_le32 (1 << VALID_BIT) |
146 | #define dma_done_ie __constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) | 146 | #define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) |
147 | 147 | ||
148 | /*-------------------------------------------------------------------------*/ | 148 | /*-------------------------------------------------------------------------*/ |
149 | 149 | ||
@@ -425,7 +425,7 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) | |||
425 | return NULL; | 425 | return NULL; |
426 | } | 426 | } |
427 | td->dmacount = 0; /* not VALID */ | 427 | td->dmacount = 0; /* not VALID */ |
428 | td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID); | 428 | td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID); |
429 | td->dmadesc = td->dmaaddr; | 429 | td->dmadesc = td->dmaaddr; |
430 | req->td = td; | 430 | req->td = td; |
431 | } | 431 | } |
@@ -775,7 +775,7 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req) | |||
775 | fill_dma_desc (ep, req, 1); | 775 | fill_dma_desc (ep, req, 1); |
776 | 776 | ||
777 | if (!use_dma_chaining) | 777 | if (!use_dma_chaining) |
778 | req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN); | 778 | req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN); |
779 | 779 | ||
780 | start_queue (ep, tmp, req->td_dma); | 780 | start_queue (ep, tmp, req->td_dma); |
781 | } | 781 | } |
@@ -2407,9 +2407,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2407 | 2407 | ||
2408 | if (readl (&e->regs->ep_rsp) | 2408 | if (readl (&e->regs->ep_rsp) |
2409 | & (1 << SET_ENDPOINT_HALT)) | 2409 | & (1 << SET_ENDPOINT_HALT)) |
2410 | status = __constant_cpu_to_le32 (1); | 2410 | status = cpu_to_le32 (1); |
2411 | else | 2411 | else |
2412 | status = __constant_cpu_to_le32 (0); | 2412 | status = cpu_to_le32 (0); |
2413 | 2413 | ||
2414 | /* don't bother with a request object! */ | 2414 | /* don't bother with a request object! */ |
2415 | writel (0, &dev->epregs [0].ep_irqenb); | 2415 | writel (0, &dev->epregs [0].ep_irqenb); |
@@ -2667,7 +2667,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) | |||
2667 | req = list_entry (ep->queue.next, | 2667 | req = list_entry (ep->queue.next, |
2668 | struct net2280_request, queue); | 2668 | struct net2280_request, queue); |
2669 | dmacount = req->td->dmacount; | 2669 | dmacount = req->td->dmacount; |
2670 | dmacount &= __constant_cpu_to_le32 ( | 2670 | dmacount &= cpu_to_le32 ( |
2671 | (1 << VALID_BIT) | 2671 | (1 << VALID_BIT) |
2672 | | DMA_BYTE_COUNT_MASK); | 2672 | | DMA_BYTE_COUNT_MASK); |
2673 | if (dmacount && (dmacount & valid_bit) == 0) | 2673 | if (dmacount && (dmacount & valid_bit) == 0) |
@@ -2881,7 +2881,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2881 | goto done; | 2881 | goto done; |
2882 | } | 2882 | } |
2883 | td->dmacount = 0; /* not VALID */ | 2883 | td->dmacount = 0; /* not VALID */ |
2884 | td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID); | 2884 | td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID); |
2885 | td->dmadesc = td->dmaaddr; | 2885 | td->dmadesc = td->dmaaddr; |
2886 | dev->ep [i].dummy = td; | 2886 | dev->ep [i].dummy = td; |
2887 | } | 2887 | } |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 5a3034fdfe47..29500154d00c 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -225,12 +225,12 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); | |||
225 | static struct usb_device_descriptor device_desc = { | 225 | static struct usb_device_descriptor device_desc = { |
226 | .bLength = sizeof device_desc, | 226 | .bLength = sizeof device_desc, |
227 | .bDescriptorType = USB_DT_DEVICE, | 227 | .bDescriptorType = USB_DT_DEVICE, |
228 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 228 | .bcdUSB = cpu_to_le16(0x0200), |
229 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 229 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
230 | .bDeviceSubClass = 0, | 230 | .bDeviceSubClass = 0, |
231 | .bDeviceProtocol = 0, | 231 | .bDeviceProtocol = 0, |
232 | .idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM), | 232 | .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM), |
233 | .idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM), | 233 | .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM), |
234 | .iManufacturer = STRING_MANUFACTURER, | 234 | .iManufacturer = STRING_MANUFACTURER, |
235 | .iProduct = STRING_PRODUCT, | 235 | .iProduct = STRING_PRODUCT, |
236 | .iSerialNumber = STRING_SERIALNUM, | 236 | .iSerialNumber = STRING_SERIALNUM, |
@@ -299,20 +299,20 @@ static struct usb_endpoint_descriptor hs_ep_in_desc = { | |||
299 | .bLength = USB_DT_ENDPOINT_SIZE, | 299 | .bLength = USB_DT_ENDPOINT_SIZE, |
300 | .bDescriptorType = USB_DT_ENDPOINT, | 300 | .bDescriptorType = USB_DT_ENDPOINT, |
301 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 301 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
302 | .wMaxPacketSize = __constant_cpu_to_le16(512) | 302 | .wMaxPacketSize = cpu_to_le16(512) |
303 | }; | 303 | }; |
304 | 304 | ||
305 | static struct usb_endpoint_descriptor hs_ep_out_desc = { | 305 | static struct usb_endpoint_descriptor hs_ep_out_desc = { |
306 | .bLength = USB_DT_ENDPOINT_SIZE, | 306 | .bLength = USB_DT_ENDPOINT_SIZE, |
307 | .bDescriptorType = USB_DT_ENDPOINT, | 307 | .bDescriptorType = USB_DT_ENDPOINT, |
308 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 308 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
309 | .wMaxPacketSize = __constant_cpu_to_le16(512) | 309 | .wMaxPacketSize = cpu_to_le16(512) |
310 | }; | 310 | }; |
311 | 311 | ||
312 | static struct usb_qualifier_descriptor dev_qualifier = { | 312 | static struct usb_qualifier_descriptor dev_qualifier = { |
313 | .bLength = sizeof dev_qualifier, | 313 | .bLength = sizeof dev_qualifier, |
314 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | 314 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, |
315 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 315 | .bcdUSB = cpu_to_le16(0x0200), |
316 | .bDeviceClass = USB_CLASS_PRINTER, | 316 | .bDeviceClass = USB_CLASS_PRINTER, |
317 | .bNumConfigurations = 1 | 317 | .bNumConfigurations = 1 |
318 | }; | 318 | }; |
@@ -1406,16 +1406,16 @@ printer_bind(struct usb_gadget *gadget) | |||
1406 | gadget->name); | 1406 | gadget->name); |
1407 | /* unrecognized, but safe unless bulk is REALLY quirky */ | 1407 | /* unrecognized, but safe unless bulk is REALLY quirky */ |
1408 | device_desc.bcdDevice = | 1408 | device_desc.bcdDevice = |
1409 | __constant_cpu_to_le16(0xFFFF); | 1409 | cpu_to_le16(0xFFFF); |
1410 | } | 1410 | } |
1411 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | 1411 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", |
1412 | init_utsname()->sysname, init_utsname()->release, | 1412 | init_utsname()->sysname, init_utsname()->release, |
1413 | gadget->name); | 1413 | gadget->name); |
1414 | 1414 | ||
1415 | device_desc.idVendor = | 1415 | device_desc.idVendor = |
1416 | __constant_cpu_to_le16(PRINTER_VENDOR_NUM); | 1416 | cpu_to_le16(PRINTER_VENDOR_NUM); |
1417 | device_desc.idProduct = | 1417 | device_desc.idProduct = |
1418 | __constant_cpu_to_le16(PRINTER_PRODUCT_NUM); | 1418 | cpu_to_le16(PRINTER_PRODUCT_NUM); |
1419 | 1419 | ||
1420 | /* support optional vendor/distro customization */ | 1420 | /* support optional vendor/distro customization */ |
1421 | if (idVendor) { | 1421 | if (idVendor) { |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 990f40f988d4..8cc676ecbb23 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/irq.h> | 32 | #include <linux/irq.h> |
33 | #include <linux/gpio.h> | ||
33 | 34 | ||
34 | #include <asm/byteorder.h> | 35 | #include <asm/byteorder.h> |
35 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
@@ -278,7 +279,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc) | |||
278 | goto err_queues; | 279 | goto err_queues; |
279 | eps = debugfs_create_file("epstate", 0400, root, udc, | 280 | eps = debugfs_create_file("epstate", 0400, root, udc, |
280 | &eps_dbg_fops); | 281 | &eps_dbg_fops); |
281 | if (!queues) | 282 | if (!eps) |
282 | goto err_eps; | 283 | goto err_eps; |
283 | 284 | ||
284 | udc->debugfs_root = root; | 285 | udc->debugfs_root = root; |
@@ -747,13 +748,13 @@ static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status) | |||
747 | } | 748 | } |
748 | 749 | ||
749 | /** | 750 | /** |
750 | * ep_end_out_req - Ends control endpoint in request | 751 | * ep_end_out_req - Ends endpoint OUT request |
751 | * @ep: physical endpoint | 752 | * @ep: physical endpoint |
752 | * @req: pxa request | 753 | * @req: pxa request |
753 | * | 754 | * |
754 | * Context: ep->lock held | 755 | * Context: ep->lock held |
755 | * | 756 | * |
756 | * Ends endpoint in request (completes usb request). | 757 | * Ends endpoint OUT request (completes usb request). |
757 | */ | 758 | */ |
758 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | 759 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) |
759 | { | 760 | { |
@@ -762,13 +763,13 @@ static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
762 | } | 763 | } |
763 | 764 | ||
764 | /** | 765 | /** |
765 | * ep0_end_out_req - Ends control endpoint in request (ends data stage) | 766 | * ep0_end_out_req - Ends control endpoint OUT request (ends data stage) |
766 | * @ep: physical endpoint | 767 | * @ep: physical endpoint |
767 | * @req: pxa request | 768 | * @req: pxa request |
768 | * | 769 | * |
769 | * Context: ep->lock held | 770 | * Context: ep->lock held |
770 | * | 771 | * |
771 | * Ends control endpoint in request (completes usb request), and puts | 772 | * Ends control endpoint OUT request (completes usb request), and puts |
772 | * control endpoint into idle state | 773 | * control endpoint into idle state |
773 | */ | 774 | */ |
774 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | 775 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) |
@@ -779,13 +780,13 @@ static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
779 | } | 780 | } |
780 | 781 | ||
781 | /** | 782 | /** |
782 | * ep_end_in_req - Ends endpoint out request | 783 | * ep_end_in_req - Ends endpoint IN request |
783 | * @ep: physical endpoint | 784 | * @ep: physical endpoint |
784 | * @req: pxa request | 785 | * @req: pxa request |
785 | * | 786 | * |
786 | * Context: ep->lock held | 787 | * Context: ep->lock held |
787 | * | 788 | * |
788 | * Ends endpoint out request (completes usb request). | 789 | * Ends endpoint IN request (completes usb request). |
789 | */ | 790 | */ |
790 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | 791 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) |
791 | { | 792 | { |
@@ -794,20 +795,18 @@ static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
794 | } | 795 | } |
795 | 796 | ||
796 | /** | 797 | /** |
797 | * ep0_end_in_req - Ends control endpoint out request (ends data stage) | 798 | * ep0_end_in_req - Ends control endpoint IN request (ends data stage) |
798 | * @ep: physical endpoint | 799 | * @ep: physical endpoint |
799 | * @req: pxa request | 800 | * @req: pxa request |
800 | * | 801 | * |
801 | * Context: ep->lock held | 802 | * Context: ep->lock held |
802 | * | 803 | * |
803 | * Ends control endpoint out request (completes usb request), and puts | 804 | * Ends control endpoint IN request (completes usb request), and puts |
804 | * control endpoint into status state | 805 | * control endpoint into status state |
805 | */ | 806 | */ |
806 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | 807 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) |
807 | { | 808 | { |
808 | struct pxa_udc *udc = ep->dev; | 809 | set_ep0state(ep->dev, IN_STATUS_STAGE); |
809 | |||
810 | set_ep0state(udc, IN_STATUS_STAGE); | ||
811 | ep_end_in_req(ep, req); | 810 | ep_end_in_req(ep, req); |
812 | } | 811 | } |
813 | 812 | ||
@@ -1167,7 +1166,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1167 | ep_end_in_req(ep, req); | 1166 | ep_end_in_req(ep, req); |
1168 | } else { | 1167 | } else { |
1169 | ep_err(ep, "got a request of %d bytes while" | 1168 | ep_err(ep, "got a request of %d bytes while" |
1170 | "in state WATI_ACK_SET_CONF_INTERF\n", | 1169 | "in state WAIT_ACK_SET_CONF_INTERF\n", |
1171 | length); | 1170 | length); |
1172 | ep_del_request(ep, req); | 1171 | ep_del_request(ep, req); |
1173 | rc = -EL2HLT; | 1172 | rc = -EL2HLT; |
@@ -1213,30 +1212,26 @@ static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1213 | struct udc_usb_ep *udc_usb_ep; | 1212 | struct udc_usb_ep *udc_usb_ep; |
1214 | struct pxa27x_request *req; | 1213 | struct pxa27x_request *req; |
1215 | unsigned long flags; | 1214 | unsigned long flags; |
1216 | int rc; | 1215 | int rc = -EINVAL; |
1217 | 1216 | ||
1218 | if (!_ep) | 1217 | if (!_ep) |
1219 | return -EINVAL; | 1218 | return rc; |
1220 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | 1219 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); |
1221 | ep = udc_usb_ep->pxa_ep; | 1220 | ep = udc_usb_ep->pxa_ep; |
1222 | if (!ep || is_ep0(ep)) | 1221 | if (!ep || is_ep0(ep)) |
1223 | return -EINVAL; | 1222 | return rc; |
1224 | 1223 | ||
1225 | spin_lock_irqsave(&ep->lock, flags); | 1224 | spin_lock_irqsave(&ep->lock, flags); |
1226 | 1225 | ||
1227 | /* make sure it's actually queued on this endpoint */ | 1226 | /* make sure it's actually queued on this endpoint */ |
1228 | list_for_each_entry(req, &ep->queue, queue) { | 1227 | list_for_each_entry(req, &ep->queue, queue) { |
1229 | if (&req->req == _req) | 1228 | if (&req->req == _req) { |
1229 | req_done(ep, req, -ECONNRESET); | ||
1230 | rc = 0; | ||
1230 | break; | 1231 | break; |
1232 | } | ||
1231 | } | 1233 | } |
1232 | 1234 | ||
1233 | rc = -EINVAL; | ||
1234 | if (&req->req != _req) | ||
1235 | goto out; | ||
1236 | |||
1237 | rc = 0; | ||
1238 | req_done(ep, req, -ECONNRESET); | ||
1239 | out: | ||
1240 | spin_unlock_irqrestore(&ep->lock, flags); | 1235 | spin_unlock_irqrestore(&ep->lock, flags); |
1241 | return rc; | 1236 | return rc; |
1242 | } | 1237 | } |
@@ -1471,6 +1466,32 @@ static struct usb_ep_ops pxa_ep_ops = { | |||
1471 | .fifo_flush = pxa_ep_fifo_flush, | 1466 | .fifo_flush = pxa_ep_fifo_flush, |
1472 | }; | 1467 | }; |
1473 | 1468 | ||
1469 | /** | ||
1470 | * dplus_pullup - Connect or disconnect pullup resistor to D+ pin | ||
1471 | * @udc: udc device | ||
1472 | * @on: 0 if disconnect pullup resistor, 1 otherwise | ||
1473 | * Context: any | ||
1474 | * | ||
1475 | * Handle D+ pullup resistor, make the device visible to the usb bus, and | ||
1476 | * declare it as a full speed usb device | ||
1477 | */ | ||
1478 | static void dplus_pullup(struct pxa_udc *udc, int on) | ||
1479 | { | ||
1480 | if (on) { | ||
1481 | if (gpio_is_valid(udc->mach->gpio_pullup)) | ||
1482 | gpio_set_value(udc->mach->gpio_pullup, | ||
1483 | !udc->mach->gpio_pullup_inverted); | ||
1484 | if (udc->mach->udc_command) | ||
1485 | udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | ||
1486 | } else { | ||
1487 | if (gpio_is_valid(udc->mach->gpio_pullup)) | ||
1488 | gpio_set_value(udc->mach->gpio_pullup, | ||
1489 | udc->mach->gpio_pullup_inverted); | ||
1490 | if (udc->mach->udc_command) | ||
1491 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | ||
1492 | } | ||
1493 | udc->pullup_on = on; | ||
1494 | } | ||
1474 | 1495 | ||
1475 | /** | 1496 | /** |
1476 | * pxa_udc_get_frame - Returns usb frame number | 1497 | * pxa_udc_get_frame - Returns usb frame number |
@@ -1500,21 +1521,145 @@ static int pxa_udc_wakeup(struct usb_gadget *_gadget) | |||
1500 | return 0; | 1521 | return 0; |
1501 | } | 1522 | } |
1502 | 1523 | ||
1524 | static void udc_enable(struct pxa_udc *udc); | ||
1525 | static void udc_disable(struct pxa_udc *udc); | ||
1526 | |||
1527 | /** | ||
1528 | * should_enable_udc - Tells if UDC should be enabled | ||
1529 | * @udc: udc device | ||
1530 | * Context: any | ||
1531 | * | ||
1532 | * The UDC should be enabled if : | ||
1533 | |||
1534 | * - the pullup resistor is connected | ||
1535 | * - and a gadget driver is bound | ||
1536 | * - and vbus is sensed (or no vbus sense is available) | ||
1537 | * | ||
1538 | * Returns 1 if UDC should be enabled, 0 otherwise | ||
1539 | */ | ||
1540 | static int should_enable_udc(struct pxa_udc *udc) | ||
1541 | { | ||
1542 | int put_on; | ||
1543 | |||
1544 | put_on = ((udc->pullup_on) && (udc->driver)); | ||
1545 | put_on &= ((udc->vbus_sensed) || (!udc->transceiver)); | ||
1546 | return put_on; | ||
1547 | } | ||
1548 | |||
1549 | /** | ||
1550 | * should_disable_udc - Tells if UDC should be disabled | ||
1551 | * @udc: udc device | ||
1552 | * Context: any | ||
1553 | * | ||
1554 | * The UDC should be disabled if : | ||
1555 | * - the pullup resistor is not connected | ||
1556 | * - or no gadget driver is bound | ||
1557 | * - or no vbus is sensed (when vbus sesing is available) | ||
1558 | * | ||
1559 | * Returns 1 if UDC should be disabled | ||
1560 | */ | ||
1561 | static int should_disable_udc(struct pxa_udc *udc) | ||
1562 | { | ||
1563 | int put_off; | ||
1564 | |||
1565 | put_off = ((!udc->pullup_on) || (!udc->driver)); | ||
1566 | put_off |= ((!udc->vbus_sensed) && (udc->transceiver)); | ||
1567 | return put_off; | ||
1568 | } | ||
1569 | |||
1570 | /** | ||
1571 | * pxa_udc_pullup - Offer manual D+ pullup control | ||
1572 | * @_gadget: usb gadget using the control | ||
1573 | * @is_active: 0 if disconnect, else connect D+ pullup resistor | ||
1574 | * Context: !in_interrupt() | ||
1575 | * | ||
1576 | * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup | ||
1577 | */ | ||
1578 | static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active) | ||
1579 | { | ||
1580 | struct pxa_udc *udc = to_gadget_udc(_gadget); | ||
1581 | |||
1582 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) | ||
1583 | return -EOPNOTSUPP; | ||
1584 | |||
1585 | dplus_pullup(udc, is_active); | ||
1586 | |||
1587 | if (should_enable_udc(udc)) | ||
1588 | udc_enable(udc); | ||
1589 | if (should_disable_udc(udc)) | ||
1590 | udc_disable(udc); | ||
1591 | return 0; | ||
1592 | } | ||
1593 | |||
1594 | static void udc_enable(struct pxa_udc *udc); | ||
1595 | static void udc_disable(struct pxa_udc *udc); | ||
1596 | |||
1597 | /** | ||
1598 | * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc | ||
1599 | * @_gadget: usb gadget | ||
1600 | * @is_active: 0 if should disable the udc, 1 if should enable | ||
1601 | * | ||
1602 | * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the | ||
1603 | * udc, and deactivates D+ pullup resistor. | ||
1604 | * | ||
1605 | * Returns 0 | ||
1606 | */ | ||
1607 | static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active) | ||
1608 | { | ||
1609 | struct pxa_udc *udc = to_gadget_udc(_gadget); | ||
1610 | |||
1611 | udc->vbus_sensed = is_active; | ||
1612 | if (should_enable_udc(udc)) | ||
1613 | udc_enable(udc); | ||
1614 | if (should_disable_udc(udc)) | ||
1615 | udc_disable(udc); | ||
1616 | |||
1617 | return 0; | ||
1618 | } | ||
1619 | |||
1620 | /** | ||
1621 | * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed | ||
1622 | * @_gadget: usb gadget | ||
1623 | * @mA: current drawn | ||
1624 | * | ||
1625 | * Context: !in_interrupt() | ||
1626 | * | ||
1627 | * Called after a configuration was chosen by a USB host, to inform how much | ||
1628 | * current can be drawn by the device from VBus line. | ||
1629 | * | ||
1630 | * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc | ||
1631 | */ | ||
1632 | static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | ||
1633 | { | ||
1634 | struct pxa_udc *udc; | ||
1635 | |||
1636 | udc = to_gadget_udc(_gadget); | ||
1637 | if (udc->transceiver) | ||
1638 | return otg_set_power(udc->transceiver, mA); | ||
1639 | return -EOPNOTSUPP; | ||
1640 | } | ||
1641 | |||
1503 | static const struct usb_gadget_ops pxa_udc_ops = { | 1642 | static const struct usb_gadget_ops pxa_udc_ops = { |
1504 | .get_frame = pxa_udc_get_frame, | 1643 | .get_frame = pxa_udc_get_frame, |
1505 | .wakeup = pxa_udc_wakeup, | 1644 | .wakeup = pxa_udc_wakeup, |
1506 | /* current versions must always be self-powered */ | 1645 | .pullup = pxa_udc_pullup, |
1646 | .vbus_session = pxa_udc_vbus_session, | ||
1647 | .vbus_draw = pxa_udc_vbus_draw, | ||
1507 | }; | 1648 | }; |
1508 | 1649 | ||
1509 | /** | 1650 | /** |
1510 | * udc_disable - disable udc device controller | 1651 | * udc_disable - disable udc device controller |
1511 | * @udc: udc device | 1652 | * @udc: udc device |
1653 | * Context: any | ||
1512 | * | 1654 | * |
1513 | * Disables the udc device : disables clocks, udc interrupts, control endpoint | 1655 | * Disables the udc device : disables clocks, udc interrupts, control endpoint |
1514 | * interrupts. | 1656 | * interrupts. |
1515 | */ | 1657 | */ |
1516 | static void udc_disable(struct pxa_udc *udc) | 1658 | static void udc_disable(struct pxa_udc *udc) |
1517 | { | 1659 | { |
1660 | if (!udc->enabled) | ||
1661 | return; | ||
1662 | |||
1518 | udc_writel(udc, UDCICR0, 0); | 1663 | udc_writel(udc, UDCICR0, 0); |
1519 | udc_writel(udc, UDCICR1, 0); | 1664 | udc_writel(udc, UDCICR1, 0); |
1520 | 1665 | ||
@@ -1523,8 +1668,8 @@ static void udc_disable(struct pxa_udc *udc) | |||
1523 | 1668 | ||
1524 | ep0_idle(udc); | 1669 | ep0_idle(udc); |
1525 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1670 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1526 | if (udc->mach->udc_command) | 1671 | |
1527 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | 1672 | udc->enabled = 0; |
1528 | } | 1673 | } |
1529 | 1674 | ||
1530 | /** | 1675 | /** |
@@ -1555,10 +1700,9 @@ static __init void udc_init_data(struct pxa_udc *dev) | |||
1555 | } | 1700 | } |
1556 | 1701 | ||
1557 | /* USB endpoints init */ | 1702 | /* USB endpoints init */ |
1558 | for (i = 0; i < NR_USB_ENDPOINTS; i++) | 1703 | for (i = 1; i < NR_USB_ENDPOINTS; i++) |
1559 | if (i != 0) | 1704 | list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, |
1560 | list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, | 1705 | &dev->gadget.ep_list); |
1561 | &dev->gadget.ep_list); | ||
1562 | } | 1706 | } |
1563 | 1707 | ||
1564 | /** | 1708 | /** |
@@ -1570,6 +1714,9 @@ static __init void udc_init_data(struct pxa_udc *dev) | |||
1570 | */ | 1714 | */ |
1571 | static void udc_enable(struct pxa_udc *udc) | 1715 | static void udc_enable(struct pxa_udc *udc) |
1572 | { | 1716 | { |
1717 | if (udc->enabled) | ||
1718 | return; | ||
1719 | |||
1573 | udc_writel(udc, UDCICR0, 0); | 1720 | udc_writel(udc, UDCICR0, 0); |
1574 | udc_writel(udc, UDCICR1, 0); | 1721 | udc_writel(udc, UDCICR1, 0); |
1575 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); | 1722 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); |
@@ -1598,9 +1745,7 @@ static void udc_enable(struct pxa_udc *udc) | |||
1598 | /* enable ep0 irqs */ | 1745 | /* enable ep0 irqs */ |
1599 | pio_irq_enable(&udc->pxa_ep[0]); | 1746 | pio_irq_enable(&udc->pxa_ep[0]); |
1600 | 1747 | ||
1601 | dev_info(udc->dev, "UDC connecting\n"); | 1748 | udc->enabled = 1; |
1602 | if (udc->mach->udc_command) | ||
1603 | udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | ||
1604 | } | 1749 | } |
1605 | 1750 | ||
1606 | /** | 1751 | /** |
@@ -1612,6 +1757,9 @@ static void udc_enable(struct pxa_udc *udc) | |||
1612 | * usb traffic follows until a disconnect is reported. Then a host may connect | 1757 | * usb traffic follows until a disconnect is reported. Then a host may connect |
1613 | * again, or the driver might get unbound. | 1758 | * again, or the driver might get unbound. |
1614 | * | 1759 | * |
1760 | * Note that the udc is not automatically enabled. Check function | ||
1761 | * should_enable_udc(). | ||
1762 | * | ||
1615 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise | 1763 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise |
1616 | */ | 1764 | */ |
1617 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | 1765 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) |
@@ -1630,6 +1778,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1630 | /* first hook up the driver ... */ | 1778 | /* first hook up the driver ... */ |
1631 | udc->driver = driver; | 1779 | udc->driver = driver; |
1632 | udc->gadget.dev.driver = &driver->driver; | 1780 | udc->gadget.dev.driver = &driver->driver; |
1781 | dplus_pullup(udc, 1); | ||
1633 | 1782 | ||
1634 | retval = device_add(&udc->gadget.dev); | 1783 | retval = device_add(&udc->gadget.dev); |
1635 | if (retval) { | 1784 | if (retval) { |
@@ -1645,9 +1794,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1645 | dev_dbg(udc->dev, "registered gadget driver '%s'\n", | 1794 | dev_dbg(udc->dev, "registered gadget driver '%s'\n", |
1646 | driver->driver.name); | 1795 | driver->driver.name); |
1647 | 1796 | ||
1648 | udc_enable(udc); | 1797 | if (udc->transceiver) { |
1798 | retval = otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
1799 | if (retval) { | ||
1800 | dev_err(udc->dev, "can't bind to transceiver\n"); | ||
1801 | goto transceiver_fail; | ||
1802 | } | ||
1803 | } | ||
1804 | |||
1805 | if (should_enable_udc(udc)) | ||
1806 | udc_enable(udc); | ||
1649 | return 0; | 1807 | return 0; |
1650 | 1808 | ||
1809 | transceiver_fail: | ||
1810 | if (driver->unbind) | ||
1811 | driver->unbind(&udc->gadget); | ||
1651 | bind_fail: | 1812 | bind_fail: |
1652 | device_del(&udc->gadget.dev); | 1813 | device_del(&udc->gadget.dev); |
1653 | add_fail: | 1814 | add_fail: |
@@ -1699,14 +1860,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1699 | 1860 | ||
1700 | stop_activity(udc, driver); | 1861 | stop_activity(udc, driver); |
1701 | udc_disable(udc); | 1862 | udc_disable(udc); |
1863 | dplus_pullup(udc, 0); | ||
1702 | 1864 | ||
1703 | driver->unbind(&udc->gadget); | 1865 | driver->unbind(&udc->gadget); |
1704 | udc->driver = NULL; | 1866 | udc->driver = NULL; |
1705 | 1867 | ||
1706 | device_del(&udc->gadget.dev); | 1868 | device_del(&udc->gadget.dev); |
1707 | |||
1708 | dev_info(udc->dev, "unregistered gadget driver '%s'\n", | 1869 | dev_info(udc->dev, "unregistered gadget driver '%s'\n", |
1709 | driver->driver.name); | 1870 | driver->driver.name); |
1871 | |||
1872 | if (udc->transceiver) | ||
1873 | return otg_set_peripheral(udc->transceiver, NULL); | ||
1710 | return 0; | 1874 | return 0; |
1711 | } | 1875 | } |
1712 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | 1876 | EXPORT_SYMBOL(usb_gadget_unregister_driver); |
@@ -1823,14 +1987,14 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq) | |||
1823 | struct pxa27x_request *req = NULL; | 1987 | struct pxa27x_request *req = NULL; |
1824 | int completed = 0; | 1988 | int completed = 0; |
1825 | 1989 | ||
1990 | if (!list_empty(&ep->queue)) | ||
1991 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | ||
1992 | |||
1826 | udccsr0 = udc_ep_readl(ep, UDCCSR); | 1993 | udccsr0 = udc_ep_readl(ep, UDCCSR); |
1827 | ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", | 1994 | ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", |
1828 | EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), | 1995 | EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), |
1829 | (fifo_irq << 1 | opc_irq)); | 1996 | (fifo_irq << 1 | opc_irq)); |
1830 | 1997 | ||
1831 | if (!list_empty(&ep->queue)) | ||
1832 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | ||
1833 | |||
1834 | if (udccsr0 & UDCCSR0_SST) { | 1998 | if (udccsr0 & UDCCSR0_SST) { |
1835 | ep_dbg(ep, "clearing stall status\n"); | 1999 | ep_dbg(ep, "clearing stall status\n"); |
1836 | nuke(ep, -EPIPE); | 2000 | nuke(ep, -EPIPE); |
@@ -2212,7 +2376,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
2212 | { | 2376 | { |
2213 | struct resource *regs; | 2377 | struct resource *regs; |
2214 | struct pxa_udc *udc = &memory; | 2378 | struct pxa_udc *udc = &memory; |
2215 | int retval; | 2379 | int retval = 0, gpio; |
2216 | 2380 | ||
2217 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2381 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2218 | if (!regs) | 2382 | if (!regs) |
@@ -2223,6 +2387,20 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
2223 | 2387 | ||
2224 | udc->dev = &pdev->dev; | 2388 | udc->dev = &pdev->dev; |
2225 | udc->mach = pdev->dev.platform_data; | 2389 | udc->mach = pdev->dev.platform_data; |
2390 | udc->transceiver = otg_get_transceiver(); | ||
2391 | |||
2392 | gpio = udc->mach->gpio_pullup; | ||
2393 | if (gpio_is_valid(gpio)) { | ||
2394 | retval = gpio_request(gpio, "USB D+ pullup"); | ||
2395 | if (retval == 0) | ||
2396 | gpio_direction_output(gpio, | ||
2397 | udc->mach->gpio_pullup_inverted); | ||
2398 | } | ||
2399 | if (retval) { | ||
2400 | dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n", | ||
2401 | gpio, retval); | ||
2402 | return retval; | ||
2403 | } | ||
2226 | 2404 | ||
2227 | udc->clk = clk_get(&pdev->dev, NULL); | 2405 | udc->clk = clk_get(&pdev->dev, NULL); |
2228 | if (IS_ERR(udc->clk)) { | 2406 | if (IS_ERR(udc->clk)) { |
@@ -2240,6 +2418,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
2240 | device_initialize(&udc->gadget.dev); | 2418 | device_initialize(&udc->gadget.dev); |
2241 | udc->gadget.dev.parent = &pdev->dev; | 2419 | udc->gadget.dev.parent = &pdev->dev; |
2242 | udc->gadget.dev.dma_mask = NULL; | 2420 | udc->gadget.dev.dma_mask = NULL; |
2421 | udc->vbus_sensed = 0; | ||
2243 | 2422 | ||
2244 | the_controller = udc; | 2423 | the_controller = udc; |
2245 | platform_set_drvdata(pdev, udc); | 2424 | platform_set_drvdata(pdev, udc); |
@@ -2273,14 +2452,21 @@ err_clk: | |||
2273 | static int __exit pxa_udc_remove(struct platform_device *_dev) | 2452 | static int __exit pxa_udc_remove(struct platform_device *_dev) |
2274 | { | 2453 | { |
2275 | struct pxa_udc *udc = platform_get_drvdata(_dev); | 2454 | struct pxa_udc *udc = platform_get_drvdata(_dev); |
2455 | int gpio = udc->mach->gpio_pullup; | ||
2276 | 2456 | ||
2277 | usb_gadget_unregister_driver(udc->driver); | 2457 | usb_gadget_unregister_driver(udc->driver); |
2278 | free_irq(udc->irq, udc); | 2458 | free_irq(udc->irq, udc); |
2279 | pxa_cleanup_debugfs(udc); | 2459 | pxa_cleanup_debugfs(udc); |
2460 | if (gpio_is_valid(gpio)) | ||
2461 | gpio_free(gpio); | ||
2462 | |||
2463 | otg_put_transceiver(udc->transceiver); | ||
2280 | 2464 | ||
2465 | udc->transceiver = NULL; | ||
2281 | platform_set_drvdata(_dev, NULL); | 2466 | platform_set_drvdata(_dev, NULL); |
2282 | the_controller = NULL; | 2467 | the_controller = NULL; |
2283 | clk_put(udc->clk); | 2468 | clk_put(udc->clk); |
2469 | iounmap(udc->regs); | ||
2284 | 2470 | ||
2285 | return 0; | 2471 | return 0; |
2286 | } | 2472 | } |
@@ -2319,6 +2505,8 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) | |||
2319 | } | 2505 | } |
2320 | 2506 | ||
2321 | udc_disable(udc); | 2507 | udc_disable(udc); |
2508 | udc->pullup_resume = udc->pullup_on; | ||
2509 | dplus_pullup(udc, 0); | ||
2322 | 2510 | ||
2323 | return 0; | 2511 | return 0; |
2324 | } | 2512 | } |
@@ -2346,7 +2534,9 @@ static int pxa_udc_resume(struct platform_device *_dev) | |||
2346 | ep->udccsr_value, ep->udccr_value); | 2534 | ep->udccsr_value, ep->udccr_value); |
2347 | } | 2535 | } |
2348 | 2536 | ||
2349 | udc_enable(udc); | 2537 | dplus_pullup(udc, udc->pullup_resume); |
2538 | if (should_enable_udc(udc)) | ||
2539 | udc_enable(udc); | ||
2350 | /* | 2540 | /* |
2351 | * We do not handle OTG yet. | 2541 | * We do not handle OTG yet. |
2352 | * | 2542 | * |
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h index 1d1b7936ee11..db58125331da 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/pxa27x_udc.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/usb/otg.h> | ||
29 | 30 | ||
30 | /* | 31 | /* |
31 | * Register definitions | 32 | * Register definitions |
@@ -421,10 +422,14 @@ struct udc_stats { | |||
421 | * @driver: bound gadget (zero, g_ether, g_file_storage, ...) | 422 | * @driver: bound gadget (zero, g_ether, g_file_storage, ...) |
422 | * @dev: device | 423 | * @dev: device |
423 | * @mach: machine info, used to activate specific GPIO | 424 | * @mach: machine info, used to activate specific GPIO |
425 | * @transceiver: external transceiver to handle vbus sense and D+ pullup | ||
424 | * @ep0state: control endpoint state machine state | 426 | * @ep0state: control endpoint state machine state |
425 | * @stats: statistics on udc usage | 427 | * @stats: statistics on udc usage |
426 | * @udc_usb_ep: array of usb endpoints offered by the gadget | 428 | * @udc_usb_ep: array of usb endpoints offered by the gadget |
427 | * @pxa_ep: array of pxa available endpoints | 429 | * @pxa_ep: array of pxa available endpoints |
430 | * @enabled: UDC was enabled by a previous udc_enable() | ||
431 | * @pullup_on: if pullup resistor connected to D+ pin | ||
432 | * @pullup_resume: if pullup resistor should be connected to D+ pin on resume | ||
428 | * @config: UDC active configuration | 433 | * @config: UDC active configuration |
429 | * @last_interface: UDC interface of the last SET_INTERFACE host request | 434 | * @last_interface: UDC interface of the last SET_INTERFACE host request |
430 | * @last_alternate: UDC altsetting of the last SET_INTERFACE host request | 435 | * @last_alternate: UDC altsetting of the last SET_INTERFACE host request |
@@ -443,6 +448,7 @@ struct pxa_udc { | |||
443 | struct usb_gadget_driver *driver; | 448 | struct usb_gadget_driver *driver; |
444 | struct device *dev; | 449 | struct device *dev; |
445 | struct pxa2xx_udc_mach_info *mach; | 450 | struct pxa2xx_udc_mach_info *mach; |
451 | struct otg_transceiver *transceiver; | ||
446 | 452 | ||
447 | enum ep0_state ep0state; | 453 | enum ep0_state ep0state; |
448 | struct udc_stats stats; | 454 | struct udc_stats stats; |
@@ -450,6 +456,10 @@ struct pxa_udc { | |||
450 | struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; | 456 | struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; |
451 | struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; | 457 | struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; |
452 | 458 | ||
459 | unsigned enabled:1; | ||
460 | unsigned pullup_on:1; | ||
461 | unsigned pullup_resume:1; | ||
462 | unsigned vbus_sensed:1; | ||
453 | unsigned config:2; | 463 | unsigned config:2; |
454 | unsigned last_interface:3; | 464 | unsigned last_interface:3; |
455 | unsigned last_alternate:3; | 465 | unsigned last_alternate:3; |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 37879af1c433..f46a60962dab 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -87,12 +87,12 @@ static struct usb_gadget_strings *dev_strings[] = { | |||
87 | static struct usb_device_descriptor device_desc = { | 87 | static struct usb_device_descriptor device_desc = { |
88 | .bLength = USB_DT_DEVICE_SIZE, | 88 | .bLength = USB_DT_DEVICE_SIZE, |
89 | .bDescriptorType = USB_DT_DEVICE, | 89 | .bDescriptorType = USB_DT_DEVICE, |
90 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 90 | .bcdUSB = cpu_to_le16(0x0200), |
91 | /* .bDeviceClass = f(use_acm) */ | 91 | /* .bDeviceClass = f(use_acm) */ |
92 | .bDeviceSubClass = 0, | 92 | .bDeviceSubClass = 0, |
93 | .bDeviceProtocol = 0, | 93 | .bDeviceProtocol = 0, |
94 | /* .bMaxPacketSize0 = f(hardware) */ | 94 | /* .bMaxPacketSize0 = f(hardware) */ |
95 | .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID), | 95 | .idVendor = cpu_to_le16(GS_VENDOR_ID), |
96 | /* .idProduct = f(use_acm) */ | 96 | /* .idProduct = f(use_acm) */ |
97 | /* .bcdDevice = f(hardware) */ | 97 | /* .bcdDevice = f(hardware) */ |
98 | /* .iManufacturer = DYNAMIC */ | 98 | /* .iManufacturer = DYNAMIC */ |
@@ -216,7 +216,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev) | |||
216 | pr_warning("gs_bind: controller '%s' not recognized\n", | 216 | pr_warning("gs_bind: controller '%s' not recognized\n", |
217 | gadget->name); | 217 | gadget->name); |
218 | device_desc.bcdDevice = | 218 | device_desc.bcdDevice = |
219 | __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099); | 219 | cpu_to_le16(GS_VERSION_NUM | 0x0099); |
220 | } | 220 | } |
221 | 221 | ||
222 | if (gadget_is_otg(cdev->gadget)) { | 222 | if (gadget_is_otg(cdev->gadget)) { |
@@ -255,19 +255,19 @@ static int __init init(void) | |||
255 | serial_config_driver.bConfigurationValue = 2; | 255 | serial_config_driver.bConfigurationValue = 2; |
256 | device_desc.bDeviceClass = USB_CLASS_COMM; | 256 | device_desc.bDeviceClass = USB_CLASS_COMM; |
257 | device_desc.idProduct = | 257 | device_desc.idProduct = |
258 | __constant_cpu_to_le16(GS_CDC_PRODUCT_ID); | 258 | cpu_to_le16(GS_CDC_PRODUCT_ID); |
259 | } else if (use_obex) { | 259 | } else if (use_obex) { |
260 | serial_config_driver.label = "CDC OBEX config"; | 260 | serial_config_driver.label = "CDC OBEX config"; |
261 | serial_config_driver.bConfigurationValue = 3; | 261 | serial_config_driver.bConfigurationValue = 3; |
262 | device_desc.bDeviceClass = USB_CLASS_COMM; | 262 | device_desc.bDeviceClass = USB_CLASS_COMM; |
263 | device_desc.idProduct = | 263 | device_desc.idProduct = |
264 | __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID); | 264 | cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID); |
265 | } else { | 265 | } else { |
266 | serial_config_driver.label = "Generic Serial config"; | 266 | serial_config_driver.label = "Generic Serial config"; |
267 | serial_config_driver.bConfigurationValue = 1; | 267 | serial_config_driver.bConfigurationValue = 1; |
268 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 268 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; |
269 | device_desc.idProduct = | 269 | device_desc.idProduct = |
270 | __constant_cpu_to_le16(GS_PRODUCT_ID); | 270 | cpu_to_le16(GS_PRODUCT_ID); |
271 | } | 271 | } |
272 | strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; | 272 | strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; |
273 | 273 | ||
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 53d59287f2bc..0a4d99ab40d8 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -1092,7 +1092,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count) | |||
1092 | gs_tty_driver->init_termios.c_ispeed = 9600; | 1092 | gs_tty_driver->init_termios.c_ispeed = 9600; |
1093 | gs_tty_driver->init_termios.c_ospeed = 9600; | 1093 | gs_tty_driver->init_termios.c_ospeed = 9600; |
1094 | 1094 | ||
1095 | coding.dwDTERate = __constant_cpu_to_le32(9600); | 1095 | coding.dwDTERate = cpu_to_le32(9600); |
1096 | coding.bCharFormat = 8; | 1096 | coding.bCharFormat = 8; |
1097 | coding.bParityType = USB_CDC_NO_PARITY; | 1097 | coding.bParityType = USB_CDC_NO_PARITY; |
1098 | coding.bDataBits = USB_CDC_1_STOP_BITS; | 1098 | coding.bDataBits = USB_CDC_1_STOP_BITS; |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 361d9659ac48..2d772401b7ad 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -102,22 +102,32 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR); | |||
102 | #ifndef CONFIG_USB_ZERO_HNPTEST | 102 | #ifndef CONFIG_USB_ZERO_HNPTEST |
103 | #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ | 103 | #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ |
104 | #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ | 104 | #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ |
105 | #define DEFAULT_AUTORESUME 0 | ||
105 | #else | 106 | #else |
106 | #define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ | 107 | #define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ |
107 | #define DRIVER_PRODUCT_NUM 0xbadd | 108 | #define DRIVER_PRODUCT_NUM 0xbadd |
109 | #define DEFAULT_AUTORESUME 5 | ||
108 | #endif | 110 | #endif |
109 | 111 | ||
112 | /* If the optional "autoresume" mode is enabled, it provides good | ||
113 | * functional coverage for the "USBCV" test harness from USB-IF. | ||
114 | * It's always set if OTG mode is enabled. | ||
115 | */ | ||
116 | unsigned autoresume = DEFAULT_AUTORESUME; | ||
117 | module_param(autoresume, uint, S_IRUGO); | ||
118 | MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup"); | ||
119 | |||
110 | /*-------------------------------------------------------------------------*/ | 120 | /*-------------------------------------------------------------------------*/ |
111 | 121 | ||
112 | static struct usb_device_descriptor device_desc = { | 122 | static struct usb_device_descriptor device_desc = { |
113 | .bLength = sizeof device_desc, | 123 | .bLength = sizeof device_desc, |
114 | .bDescriptorType = USB_DT_DEVICE, | 124 | .bDescriptorType = USB_DT_DEVICE, |
115 | 125 | ||
116 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 126 | .bcdUSB = cpu_to_le16(0x0200), |
117 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, | 127 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, |
118 | 128 | ||
119 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), | 129 | .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), |
120 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), | 130 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM), |
121 | .bNumConfigurations = 2, | 131 | .bNumConfigurations = 2, |
122 | }; | 132 | }; |
123 | 133 | ||
@@ -212,6 +222,47 @@ void disable_endpoints(struct usb_composite_dev *cdev, | |||
212 | 222 | ||
213 | /*-------------------------------------------------------------------------*/ | 223 | /*-------------------------------------------------------------------------*/ |
214 | 224 | ||
225 | static struct timer_list autoresume_timer; | ||
226 | |||
227 | static void zero_autoresume(unsigned long _c) | ||
228 | { | ||
229 | struct usb_composite_dev *cdev = (void *)_c; | ||
230 | struct usb_gadget *g = cdev->gadget; | ||
231 | |||
232 | /* unconfigured devices can't issue wakeups */ | ||
233 | if (!cdev->config) | ||
234 | return; | ||
235 | |||
236 | /* Normally the host would be woken up for something | ||
237 | * more significant than just a timer firing; likely | ||
238 | * because of some direct user request. | ||
239 | */ | ||
240 | if (g->speed != USB_SPEED_UNKNOWN) { | ||
241 | int status = usb_gadget_wakeup(g); | ||
242 | INFO(cdev, "%s --> %d\n", __func__, status); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | static void zero_suspend(struct usb_composite_dev *cdev) | ||
247 | { | ||
248 | if (cdev->gadget->speed == USB_SPEED_UNKNOWN) | ||
249 | return; | ||
250 | |||
251 | if (autoresume) { | ||
252 | mod_timer(&autoresume_timer, jiffies + (HZ * autoresume)); | ||
253 | DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume); | ||
254 | } else | ||
255 | DBG(cdev, "%s\n", __func__); | ||
256 | } | ||
257 | |||
258 | static void zero_resume(struct usb_composite_dev *cdev) | ||
259 | { | ||
260 | DBG(cdev, "%s\n", __func__); | ||
261 | del_timer(&autoresume_timer); | ||
262 | } | ||
263 | |||
264 | /*-------------------------------------------------------------------------*/ | ||
265 | |||
215 | static int __init zero_bind(struct usb_composite_dev *cdev) | 266 | static int __init zero_bind(struct usb_composite_dev *cdev) |
216 | { | 267 | { |
217 | int gcnum; | 268 | int gcnum; |
@@ -239,17 +290,19 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
239 | strings_dev[STRING_SERIAL_IDX].id = id; | 290 | strings_dev[STRING_SERIAL_IDX].id = id; |
240 | device_desc.iSerialNumber = id; | 291 | device_desc.iSerialNumber = id; |
241 | 292 | ||
293 | setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); | ||
294 | |||
242 | /* Register primary, then secondary configuration. Note that | 295 | /* Register primary, then secondary configuration. Note that |
243 | * SH3 only allows one config... | 296 | * SH3 only allows one config... |
244 | */ | 297 | */ |
245 | if (loopdefault) { | 298 | if (loopdefault) { |
246 | loopback_add(cdev); | 299 | loopback_add(cdev, autoresume != 0); |
247 | if (!gadget_is_sh(gadget)) | 300 | if (!gadget_is_sh(gadget)) |
248 | sourcesink_add(cdev); | 301 | sourcesink_add(cdev, autoresume != 0); |
249 | } else { | 302 | } else { |
250 | sourcesink_add(cdev); | 303 | sourcesink_add(cdev, autoresume != 0); |
251 | if (!gadget_is_sh(gadget)) | 304 | if (!gadget_is_sh(gadget)) |
252 | loopback_add(cdev); | 305 | loopback_add(cdev, autoresume != 0); |
253 | } | 306 | } |
254 | 307 | ||
255 | gcnum = usb_gadget_controller_number(gadget); | 308 | gcnum = usb_gadget_controller_number(gadget); |
@@ -265,7 +318,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
265 | */ | 318 | */ |
266 | pr_warning("%s: controller '%s' not recognized\n", | 319 | pr_warning("%s: controller '%s' not recognized\n", |
267 | longname, gadget->name); | 320 | longname, gadget->name); |
268 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | 321 | device_desc.bcdDevice = cpu_to_le16(0x9999); |
269 | } | 322 | } |
270 | 323 | ||
271 | 324 | ||
@@ -278,11 +331,20 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
278 | return 0; | 331 | return 0; |
279 | } | 332 | } |
280 | 333 | ||
334 | static int zero_unbind(struct usb_composite_dev *cdev) | ||
335 | { | ||
336 | del_timer_sync(&autoresume_timer); | ||
337 | return 0; | ||
338 | } | ||
339 | |||
281 | static struct usb_composite_driver zero_driver = { | 340 | static struct usb_composite_driver zero_driver = { |
282 | .name = "zero", | 341 | .name = "zero", |
283 | .dev = &device_desc, | 342 | .dev = &device_desc, |
284 | .strings = dev_strings, | 343 | .strings = dev_strings, |
285 | .bind = zero_bind, | 344 | .bind = zero_bind, |
345 | .unbind = zero_unbind, | ||
346 | .suspend = zero_suspend, | ||
347 | .resume = zero_resume, | ||
286 | }; | 348 | }; |
287 | 349 | ||
288 | MODULE_AUTHOR("David Brownell"); | 350 | MODULE_AUTHOR("David Brownell"); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2c63bfb1f8d9..845479f7c707 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -24,10 +24,7 @@ config USB_EHCI_HCD | |||
24 | The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 | 24 | The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 |
25 | "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. | 25 | "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. |
26 | If your USB host controller supports USB 2.0, you will likely want to | 26 | If your USB host controller supports USB 2.0, you will likely want to |
27 | configure this Host Controller Driver. At the time of this writing, | 27 | configure this Host Controller Driver. |
28 | the primary implementation of EHCI is a chip from NEC, widely available | ||
29 | in add-on PCI cards, but implementations are in the works from other | ||
30 | vendors including Intel and Philips. Motherboard support is appearing. | ||
31 | 28 | ||
32 | EHCI controllers are packaged with "companion" host controllers (OHCI | 29 | EHCI controllers are packaged with "companion" host controllers (OHCI |
33 | or UHCI) to handle USB 1.1 devices connected to root hub ports. Ports | 30 | or UHCI) to handle USB 1.1 devices connected to root hub ports. Ports |
@@ -123,7 +120,7 @@ config USB_ISP116X_HCD | |||
123 | 120 | ||
124 | config USB_ISP1760_HCD | 121 | config USB_ISP1760_HCD |
125 | tristate "ISP 1760 HCD support" | 122 | tristate "ISP 1760 HCD support" |
126 | depends on USB && EXPERIMENTAL && (PCI || PPC_OF) | 123 | depends on USB && EXPERIMENTAL |
127 | ---help--- | 124 | ---help--- |
128 | The ISP1760 chip is a USB 2.0 host controller. | 125 | The ISP1760 chip is a USB 2.0 host controller. |
129 | 126 | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index e551bb38852b..f2618d17710d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -110,6 +110,42 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); | |||
110 | 110 | ||
111 | /*-------------------------------------------------------------------------*/ | 111 | /*-------------------------------------------------------------------------*/ |
112 | 112 | ||
113 | static void | ||
114 | timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action) | ||
115 | { | ||
116 | /* Don't override timeouts which shrink or (later) disable | ||
117 | * the async ring; just the I/O watchdog. Note that if a | ||
118 | * SHRINK were pending, OFF would never be requested. | ||
119 | */ | ||
120 | if (timer_pending(&ehci->watchdog) | ||
121 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
122 | & ehci->actions)) | ||
123 | return; | ||
124 | |||
125 | if (!test_and_set_bit(action, &ehci->actions)) { | ||
126 | unsigned long t; | ||
127 | |||
128 | switch (action) { | ||
129 | case TIMER_IO_WATCHDOG: | ||
130 | t = EHCI_IO_JIFFIES; | ||
131 | break; | ||
132 | case TIMER_ASYNC_OFF: | ||
133 | t = EHCI_ASYNC_JIFFIES; | ||
134 | break; | ||
135 | /* case TIMER_ASYNC_SHRINK: */ | ||
136 | default: | ||
137 | /* add a jiffie since we synch against the | ||
138 | * 8 KHz uframe counter. | ||
139 | */ | ||
140 | t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; | ||
141 | break; | ||
142 | } | ||
143 | mod_timer(&ehci->watchdog, t + jiffies); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | /*-------------------------------------------------------------------------*/ | ||
148 | |||
113 | /* | 149 | /* |
114 | * handshake - spin reading hc until handshake completes or fails | 150 | * handshake - spin reading hc until handshake completes or fails |
115 | * @ptr: address of hc register to be read | 151 | * @ptr: address of hc register to be read |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index ecc9b66c03cd..1976b1b3778c 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -333,12 +333,40 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
333 | token = hc32_to_cpu(ehci, qtd->hw_token); | 333 | token = hc32_to_cpu(ehci, qtd->hw_token); |
334 | 334 | ||
335 | /* always clean up qtds the hc de-activated */ | 335 | /* always clean up qtds the hc de-activated */ |
336 | retry_xacterr: | ||
336 | if ((token & QTD_STS_ACTIVE) == 0) { | 337 | if ((token & QTD_STS_ACTIVE) == 0) { |
337 | 338 | ||
338 | /* on STALL, error, and short reads this urb must | 339 | /* on STALL, error, and short reads this urb must |
339 | * complete and all its qtds must be recycled. | 340 | * complete and all its qtds must be recycled. |
340 | */ | 341 | */ |
341 | if ((token & QTD_STS_HALT) != 0) { | 342 | if ((token & QTD_STS_HALT) != 0) { |
343 | |||
344 | /* retry transaction errors until we | ||
345 | * reach the software xacterr limit | ||
346 | */ | ||
347 | if ((token & QTD_STS_XACT) && | ||
348 | QTD_CERR(token) == 0 && | ||
349 | --qh->xacterrs > 0 && | ||
350 | !urb->unlinked) { | ||
351 | ehci_dbg(ehci, | ||
352 | "detected XactErr len %zu/%zu retry %d\n", | ||
353 | qtd->length - QTD_LENGTH(token), qtd->length, | ||
354 | QH_XACTERR_MAX - qh->xacterrs); | ||
355 | |||
356 | /* reset the token in the qtd and the | ||
357 | * qh overlay (which still contains | ||
358 | * the qtd) so that we pick up from | ||
359 | * where we left off | ||
360 | */ | ||
361 | token &= ~QTD_STS_HALT; | ||
362 | token |= QTD_STS_ACTIVE | | ||
363 | (EHCI_TUNE_CERR << 10); | ||
364 | qtd->hw_token = cpu_to_hc32(ehci, | ||
365 | token); | ||
366 | wmb(); | ||
367 | qh->hw_token = cpu_to_hc32(ehci, token); | ||
368 | goto retry_xacterr; | ||
369 | } | ||
342 | stopped = 1; | 370 | stopped = 1; |
343 | 371 | ||
344 | /* magic dummy for some short reads; qh won't advance. | 372 | /* magic dummy for some short reads; qh won't advance. |
@@ -421,6 +449,9 @@ halt: | |||
421 | /* remove qtd; it's recycled after possible urb completion */ | 449 | /* remove qtd; it's recycled after possible urb completion */ |
422 | list_del (&qtd->qtd_list); | 450 | list_del (&qtd->qtd_list); |
423 | last = qtd; | 451 | last = qtd; |
452 | |||
453 | /* reinit the xacterr counter for the next qtd */ | ||
454 | qh->xacterrs = QH_XACTERR_MAX; | ||
424 | } | 455 | } |
425 | 456 | ||
426 | /* last urb's completion might still need calling */ | 457 | /* last urb's completion might still need calling */ |
@@ -862,6 +893,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
862 | head->qh_next.qh = qh; | 893 | head->qh_next.qh = qh; |
863 | head->hw_next = dma; | 894 | head->hw_next = dma; |
864 | 895 | ||
896 | qh->xacterrs = QH_XACTERR_MAX; | ||
865 | qh->qh_state = QH_STATE_LINKED; | 897 | qh->qh_state = QH_STATE_LINKED; |
866 | /* qtd completions reported later by interrupt */ | 898 | /* qtd completions reported later by interrupt */ |
867 | } | 899 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 1d0b49e3f192..ada5d2ba297b 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -563,7 +563,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
563 | // and this qh is active in the current uframe | 563 | // and this qh is active in the current uframe |
564 | // (and overlay token SplitXstate is false?) | 564 | // (and overlay token SplitXstate is false?) |
565 | // THEN | 565 | // THEN |
566 | // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */); | 566 | // qh->hw_info1 |= cpu_to_hc32(1 << 7 /* "ignore" */); |
567 | 567 | ||
568 | /* high bandwidth, or otherwise part of every microframe */ | 568 | /* high bandwidth, or otherwise part of every microframe */ |
569 | if ((period = qh->period) == 0) | 569 | if ((period = qh->period) == 0) |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 262b00c9b334..6cff195e1a36 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -190,40 +190,6 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
190 | clear_bit (action, &ehci->actions); | 190 | clear_bit (action, &ehci->actions); |
191 | } | 191 | } |
192 | 192 | ||
193 | static inline void | ||
194 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | ||
195 | { | ||
196 | /* Don't override timeouts which shrink or (later) disable | ||
197 | * the async ring; just the I/O watchdog. Note that if a | ||
198 | * SHRINK were pending, OFF would never be requested. | ||
199 | */ | ||
200 | if (timer_pending(&ehci->watchdog) | ||
201 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
202 | & ehci->actions)) | ||
203 | return; | ||
204 | |||
205 | if (!test_and_set_bit (action, &ehci->actions)) { | ||
206 | unsigned long t; | ||
207 | |||
208 | switch (action) { | ||
209 | case TIMER_IO_WATCHDOG: | ||
210 | t = EHCI_IO_JIFFIES; | ||
211 | break; | ||
212 | case TIMER_ASYNC_OFF: | ||
213 | t = EHCI_ASYNC_JIFFIES; | ||
214 | break; | ||
215 | // case TIMER_ASYNC_SHRINK: | ||
216 | default: | ||
217 | /* add a jiffie since we synch against the | ||
218 | * 8 KHz uframe counter. | ||
219 | */ | ||
220 | t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; | ||
221 | break; | ||
222 | } | ||
223 | mod_timer(&ehci->watchdog, t + jiffies); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | static void free_cached_itd_list(struct ehci_hcd *ehci); | 193 | static void free_cached_itd_list(struct ehci_hcd *ehci); |
228 | 194 | ||
229 | /*-------------------------------------------------------------------------*/ | 195 | /*-------------------------------------------------------------------------*/ |
@@ -287,7 +253,7 @@ struct ehci_qtd { | |||
287 | 253 | ||
288 | /* | 254 | /* |
289 | * Now the following defines are not converted using the | 255 | * Now the following defines are not converted using the |
290 | * __constant_cpu_to_le32() macro anymore, since we have to support | 256 | * cpu_to_le32() macro anymore, since we have to support |
291 | * "dynamic" switching between be and le support, so that the driver | 257 | * "dynamic" switching between be and le support, so that the driver |
292 | * can be used on one system with SoC EHCI controller using big-endian | 258 | * can be used on one system with SoC EHCI controller using big-endian |
293 | * descriptors as well as a normal little-endian PCI EHCI controller. | 259 | * descriptors as well as a normal little-endian PCI EHCI controller. |
@@ -376,6 +342,9 @@ struct ehci_qh { | |||
376 | #define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ | 342 | #define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ |
377 | #define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ | 343 | #define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ |
378 | 344 | ||
345 | u8 xacterrs; /* XactErr retry counter */ | ||
346 | #define QH_XACTERR_MAX 32 /* XactErr retry limit */ | ||
347 | |||
379 | /* periodic schedule info */ | 348 | /* periodic schedule info */ |
380 | u8 usecs; /* intr bandwidth */ | 349 | u8 usecs; /* intr bandwidth */ |
381 | u8 gap_uf; /* uframes split/csplit gap */ | 350 | u8 gap_uf; /* uframes split/csplit gap */ |
diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c index 34e14edf390b..ea8a4255c5da 100644 --- a/drivers/usb/host/fhci-dbg.c +++ b/drivers/usb/host/fhci-dbg.c | |||
@@ -108,7 +108,7 @@ void fhci_dfs_create(struct fhci_hcd *fhci) | |||
108 | { | 108 | { |
109 | struct device *dev = fhci_to_hcd(fhci)->self.controller; | 109 | struct device *dev = fhci_to_hcd(fhci)->self.controller; |
110 | 110 | ||
111 | fhci->dfs_root = debugfs_create_dir(dev->bus_id, NULL); | 111 | fhci->dfs_root = debugfs_create_dir(dev_name(dev), NULL); |
112 | if (!fhci->dfs_root) { | 112 | if (!fhci->dfs_root) { |
113 | WARN_ON(1); | 113 | WARN_ON(1); |
114 | return; | 114 | return; |
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index ba622cc8a9ba..0951818ef93b 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c | |||
@@ -583,7 +583,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, | |||
583 | if (sprop && strcmp(sprop, "host")) | 583 | if (sprop && strcmp(sprop, "host")) |
584 | return -ENODEV; | 584 | return -ENODEV; |
585 | 585 | ||
586 | hcd = usb_create_hcd(&fhci_driver, dev, dev->bus_id); | 586 | hcd = usb_create_hcd(&fhci_driver, dev, dev_name(dev)); |
587 | if (!hcd) { | 587 | if (!hcd) { |
588 | dev_err(dev, "could not create hcd\n"); | 588 | dev_err(dev, "could not create hcd\n"); |
589 | return -ENOMEM; | 589 | return -ENOMEM; |
@@ -650,7 +650,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, | |||
650 | } | 650 | } |
651 | } | 651 | } |
652 | 652 | ||
653 | ret = gpio_request(gpio, dev->bus_id); | 653 | ret = gpio_request(gpio, dev_name(dev)); |
654 | if (ret) { | 654 | if (ret) { |
655 | dev_err(dev, "failed to request gpio %d", i); | 655 | dev_err(dev, "failed to request gpio %d", i); |
656 | goto err_gpios; | 656 | goto err_gpios; |
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 8582236e4cad..cbf30e515f29 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c | |||
@@ -464,8 +464,7 @@ static int __hwahc_dev_set_key(struct wusbhc *wusbhc, u8 port_idx, u32 tkid, | |||
464 | port_idx << 8 | iface_no, | 464 | port_idx << 8 | iface_no, |
465 | keyd, keyd_len, 1000 /* FIXME: arbitrary */); | 465 | keyd, keyd_len, 1000 /* FIXME: arbitrary */); |
466 | 466 | ||
467 | memset(keyd, 0, sizeof(*keyd)); /* clear keys etc. */ | 467 | kzfree(keyd); /* clear keys etc. */ |
468 | kfree(keyd); | ||
469 | return result; | 468 | return result; |
470 | } | 469 | } |
471 | 470 | ||
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 4dda31b26892..a2b305477afe 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -772,7 +772,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
772 | break; | 772 | break; |
773 | case PIPE_INTERRUPT: | 773 | case PIPE_INTERRUPT: |
774 | urb->interval = ep->period; | 774 | urb->interval = ep->period; |
775 | ep->length = min((int)ep->maxpacket, | 775 | ep->length = min_t(u32, ep->maxpacket, |
776 | urb->transfer_buffer_length); | 776 | urb->transfer_buffer_length); |
777 | 777 | ||
778 | /* urb submitted for already existing endpoint */ | 778 | /* urb submitted for already existing endpoint */ |
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index aa211bafcff9..12db961acdfb 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
@@ -563,7 +563,7 @@ static void urb_dbg(struct urb *urb, char *msg) | |||
563 | */ | 563 | */ |
564 | static inline void dump_ptd(struct ptd *ptd) | 564 | static inline void dump_ptd(struct ptd *ptd) |
565 | { | 565 | { |
566 | printk("td: %x %d%c%d %d,%d,%d %x %x%x%x\n", | 566 | printk(KERN_WARNING "td: %x %d%c%d %d,%d,%d %x %x%x%x\n", |
567 | PTD_GET_CC(ptd), PTD_GET_FA(ptd), | 567 | PTD_GET_CC(ptd), PTD_GET_FA(ptd), |
568 | PTD_DIR_STR(ptd), PTD_GET_EP(ptd), | 568 | PTD_DIR_STR(ptd), PTD_GET_EP(ptd), |
569 | PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd), | 569 | PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd), |
@@ -576,7 +576,7 @@ static inline void dump_ptd_out_data(struct ptd *ptd, u8 * buf) | |||
576 | int k; | 576 | int k; |
577 | 577 | ||
578 | if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) { | 578 | if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) { |
579 | printk("-> "); | 579 | printk(KERN_WARNING "-> "); |
580 | for (k = 0; k < PTD_GET_LEN(ptd); ++k) | 580 | for (k = 0; k < PTD_GET_LEN(ptd); ++k) |
581 | printk("%02x ", ((u8 *) buf)[k]); | 581 | printk("%02x ", ((u8 *) buf)[k]); |
582 | printk("\n"); | 582 | printk("\n"); |
@@ -588,13 +588,13 @@ static inline void dump_ptd_in_data(struct ptd *ptd, u8 * buf) | |||
588 | int k; | 588 | int k; |
589 | 589 | ||
590 | if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) { | 590 | if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) { |
591 | printk("<- "); | 591 | printk(KERN_WARNING "<- "); |
592 | for (k = 0; k < PTD_GET_COUNT(ptd); ++k) | 592 | for (k = 0; k < PTD_GET_COUNT(ptd); ++k) |
593 | printk("%02x ", ((u8 *) buf)[k]); | 593 | printk("%02x ", ((u8 *) buf)[k]); |
594 | printk("\n"); | 594 | printk("\n"); |
595 | } | 595 | } |
596 | if (PTD_GET_LAST(ptd)) | 596 | if (PTD_GET_LAST(ptd)) |
597 | printk("-\n"); | 597 | printk(KERN_WARNING "-\n"); |
598 | } | 598 | } |
599 | 599 | ||
600 | #else | 600 | #else |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index b899f1a59c26..cd07ea3f0c63 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -644,7 +644,7 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, | |||
644 | 644 | ||
645 | if (urb->dev->speed != USB_SPEED_HIGH) { | 645 | if (urb->dev->speed != USB_SPEED_HIGH) { |
646 | /* split */ | 646 | /* split */ |
647 | ptd->dw5 = __constant_cpu_to_le32(0x1c); | 647 | ptd->dw5 = cpu_to_le32(0x1c); |
648 | 648 | ||
649 | if (qh->period >= 32) | 649 | if (qh->period >= 32) |
650 | period = qh->period / 2; | 650 | period = qh->period / 2; |
@@ -819,6 +819,13 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
819 | u32 atl_regs, payload; | 819 | u32 atl_regs, payload; |
820 | u32 buffstatus; | 820 | u32 buffstatus; |
821 | 821 | ||
822 | /* | ||
823 | * When this function is called from the interrupt handler to enqueue | ||
824 | * a follow-up packet, the SKIP register gets written and read back | ||
825 | * almost immediately. With ISP1761, this register requires a delay of | ||
826 | * 195ns between a write and subsequent read (see section 15.1.1.3). | ||
827 | */ | ||
828 | ndelay(195); | ||
822 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); | 829 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); |
823 | 830 | ||
824 | BUG_ON(!skip_map); | 831 | BUG_ON(!skip_map); |
@@ -853,6 +860,13 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
853 | u32 int_regs, payload; | 860 | u32 int_regs, payload; |
854 | u32 buffstatus; | 861 | u32 buffstatus; |
855 | 862 | ||
863 | /* | ||
864 | * When this function is called from the interrupt handler to enqueue | ||
865 | * a follow-up packet, the SKIP register gets written and read back | ||
866 | * almost immediately. With ISP1761, this register requires a delay of | ||
867 | * 195ns between a write and subsequent read (see section 15.1.1.3). | ||
868 | */ | ||
869 | ndelay(195); | ||
856 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); | 870 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); |
857 | 871 | ||
858 | BUG_ON(!skip_map); | 872 | BUG_ON(!skip_map); |
@@ -1054,7 +1068,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd) | |||
1054 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + | 1068 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + |
1055 | atl_regs, sizeof(ptd)); | 1069 | atl_regs, sizeof(ptd)); |
1056 | 1070 | ||
1057 | ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID); | 1071 | ptd.dw0 |= cpu_to_le32(PTD_VALID); |
1058 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + | 1072 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + |
1059 | atl_regs, sizeof(ptd)); | 1073 | atl_regs, sizeof(ptd)); |
1060 | 1074 | ||
@@ -2235,9 +2249,10 @@ void deinit_kmem_cache(void) | |||
2235 | kmem_cache_destroy(qh_cachep); | 2249 | kmem_cache_destroy(qh_cachep); |
2236 | } | 2250 | } |
2237 | 2251 | ||
2238 | struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | 2252 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, |
2239 | u64 irqflags, struct device *dev, const char *busname, | 2253 | int irq, unsigned long irqflags, |
2240 | unsigned int devflags) | 2254 | struct device *dev, const char *busname, |
2255 | unsigned int devflags) | ||
2241 | { | 2256 | { |
2242 | struct usb_hcd *hcd; | 2257 | struct usb_hcd *hcd; |
2243 | struct isp1760_hcd *priv; | 2258 | struct isp1760_hcd *priv; |
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index a9daea587962..462f4943cb1b 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h | |||
@@ -2,9 +2,10 @@ | |||
2 | #define _ISP1760_HCD_H_ | 2 | #define _ISP1760_HCD_H_ |
3 | 3 | ||
4 | /* exports for if */ | 4 | /* exports for if */ |
5 | struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | 5 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, |
6 | u64 irqflags, struct device *dev, const char *busname, | 6 | int irq, unsigned long irqflags, |
7 | unsigned int devflags); | 7 | struct device *dev, const char *busname, |
8 | unsigned int devflags); | ||
8 | int init_kmem_once(void); | 9 | int init_kmem_once(void); |
9 | void deinit_kmem_cache(void); | 10 | void deinit_kmem_cache(void); |
10 | 11 | ||
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 4cf7ca428b33..3fa3a1702796 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/usb.h> | 11 | #include <linux/usb.h> |
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | #include <linux/platform_device.h> | ||
13 | 14 | ||
14 | #include "../core/hcd.h" | 15 | #include "../core/hcd.h" |
15 | #include "isp1760-hcd.h" | 16 | #include "isp1760-hcd.h" |
@@ -300,39 +301,101 @@ static struct pci_driver isp1761_pci_driver = { | |||
300 | }; | 301 | }; |
301 | #endif | 302 | #endif |
302 | 303 | ||
304 | static int __devinit isp1760_plat_probe(struct platform_device *pdev) | ||
305 | { | ||
306 | int ret = 0; | ||
307 | struct usb_hcd *hcd; | ||
308 | struct resource *mem_res; | ||
309 | struct resource *irq_res; | ||
310 | resource_size_t mem_size; | ||
311 | unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED; | ||
312 | |||
313 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
314 | if (!mem_res) { | ||
315 | pr_warning("isp1760: Memory resource not available\n"); | ||
316 | ret = -ENODEV; | ||
317 | goto out; | ||
318 | } | ||
319 | mem_size = resource_size(mem_res); | ||
320 | if (!request_mem_region(mem_res->start, mem_size, "isp1760")) { | ||
321 | pr_warning("isp1760: Cannot reserve the memory resource\n"); | ||
322 | ret = -EBUSY; | ||
323 | goto out; | ||
324 | } | ||
325 | |||
326 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
327 | if (!irq_res) { | ||
328 | pr_warning("isp1760: IRQ resource not available\n"); | ||
329 | return -ENODEV; | ||
330 | } | ||
331 | irqflags |= irq_res->flags & IRQF_TRIGGER_MASK; | ||
332 | |||
333 | hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, | ||
334 | irqflags, &pdev->dev, dev_name(&pdev->dev), 0); | ||
335 | if (IS_ERR(hcd)) { | ||
336 | pr_warning("isp1760: Failed to register the HCD device\n"); | ||
337 | ret = -ENODEV; | ||
338 | goto cleanup; | ||
339 | } | ||
340 | |||
341 | pr_info("ISP1760 USB device initialised\n"); | ||
342 | return ret; | ||
343 | |||
344 | cleanup: | ||
345 | release_mem_region(mem_res->start, mem_size); | ||
346 | out: | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | static int __devexit isp1760_plat_remove(struct platform_device *pdev) | ||
351 | { | ||
352 | struct resource *mem_res; | ||
353 | resource_size_t mem_size; | ||
354 | |||
355 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
356 | mem_size = resource_size(mem_res); | ||
357 | release_mem_region(mem_res->start, mem_size); | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static struct platform_driver isp1760_plat_driver = { | ||
363 | .probe = isp1760_plat_probe, | ||
364 | .remove = isp1760_plat_remove, | ||
365 | .driver = { | ||
366 | .name = "isp1760", | ||
367 | }, | ||
368 | }; | ||
369 | |||
303 | static int __init isp1760_init(void) | 370 | static int __init isp1760_init(void) |
304 | { | 371 | { |
305 | int ret; | 372 | int ret, any_ret = -ENODEV; |
306 | 373 | ||
307 | init_kmem_once(); | 374 | init_kmem_once(); |
308 | 375 | ||
376 | ret = platform_driver_register(&isp1760_plat_driver); | ||
377 | if (!ret) | ||
378 | any_ret = 0; | ||
309 | #ifdef CONFIG_PPC_OF | 379 | #ifdef CONFIG_PPC_OF |
310 | ret = of_register_platform_driver(&isp1760_of_driver); | 380 | ret = of_register_platform_driver(&isp1760_of_driver); |
311 | if (ret) { | 381 | if (!ret) |
312 | deinit_kmem_cache(); | 382 | any_ret = 0; |
313 | return ret; | ||
314 | } | ||
315 | #endif | 383 | #endif |
316 | #ifdef CONFIG_PCI | 384 | #ifdef CONFIG_PCI |
317 | ret = pci_register_driver(&isp1761_pci_driver); | 385 | ret = pci_register_driver(&isp1761_pci_driver); |
318 | if (ret) | 386 | if (!ret) |
319 | goto unreg_of; | 387 | any_ret = 0; |
320 | #endif | 388 | #endif |
321 | return ret; | ||
322 | 389 | ||
323 | #ifdef CONFIG_PCI | 390 | if (any_ret) |
324 | unreg_of: | 391 | deinit_kmem_cache(); |
325 | #endif | 392 | return any_ret; |
326 | #ifdef CONFIG_PPC_OF | ||
327 | of_unregister_platform_driver(&isp1760_of_driver); | ||
328 | #endif | ||
329 | deinit_kmem_cache(); | ||
330 | return ret; | ||
331 | } | 393 | } |
332 | module_init(isp1760_init); | 394 | module_init(isp1760_init); |
333 | 395 | ||
334 | static void __exit isp1760_exit(void) | 396 | static void __exit isp1760_exit(void) |
335 | { | 397 | { |
398 | platform_driver_unregister(&isp1760_plat_driver); | ||
336 | #ifdef CONFIG_PPC_OF | 399 | #ifdef CONFIG_PPC_OF |
337 | of_unregister_platform_driver(&isp1760_of_driver); | 400 | of_unregister_platform_driver(&isp1760_of_driver); |
338 | #endif | 401 | #endif |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 5cf5f1eca4f4..25db704f3a2a 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -997,7 +997,7 @@ MODULE_LICENSE ("GPL"); | |||
997 | #define SA1111_DRIVER ohci_hcd_sa1111_driver | 997 | #define SA1111_DRIVER ohci_hcd_sa1111_driver |
998 | #endif | 998 | #endif |
999 | 999 | ||
1000 | #ifdef CONFIG_ARCH_S3C2410 | 1000 | #if defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C64XX) |
1001 | #include "ohci-s3c2410.c" | 1001 | #include "ohci-s3c2410.c" |
1002 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver | 1002 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver |
1003 | #endif | 1003 | #endif |
@@ -1049,7 +1049,8 @@ MODULE_LICENSE ("GPL"); | |||
1049 | 1049 | ||
1050 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 1050 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
1051 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 1051 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
1052 | defined(CONFIG_CPU_SUBTYPE_SH7763) | 1052 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
1053 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
1053 | #include "ohci-sh.c" | 1054 | #include "ohci-sh.c" |
1054 | #define PLATFORM_DRIVER ohci_hcd_sh_driver | 1055 | #define PLATFORM_DRIVER ohci_hcd_sh_driver |
1055 | #endif | 1056 | #endif |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index f46af7a718d4..a68af2dd55ca 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -21,9 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | 24 | #include <plat/usb-control.h> | |
25 | #include <mach/hardware.h> | ||
26 | #include <mach/usb-control.h> | ||
27 | 25 | ||
28 | #define valid_port(idx) ((idx) == 1 || (idx) == 2) | 26 | #define valid_port(idx) ((idx) == 1 || (idx) == 2) |
29 | 27 | ||
@@ -372,7 +370,7 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, | |||
372 | 370 | ||
373 | usb_clk = clk_get(&dev->dev, "usb-bus-host"); | 371 | usb_clk = clk_get(&dev->dev, "usb-bus-host"); |
374 | if (IS_ERR(usb_clk)) { | 372 | if (IS_ERR(usb_clk)) { |
375 | dev_err(&dev->dev, "cannot get usb-host clock\n"); | 373 | dev_err(&dev->dev, "cannot get usb-bus-host clock\n"); |
376 | retval = -ENOENT; | 374 | retval = -ENOENT; |
377 | goto err_clk; | 375 | goto err_clk; |
378 | } | 376 | } |
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 75548f7c716b..5ac489ee3dab 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c | |||
@@ -845,14 +845,14 @@ static inline void qh_update(struct oxu_hcd *oxu, | |||
845 | is_out = !(qtd->hw_token & cpu_to_le32(1 << 8)); | 845 | is_out = !(qtd->hw_token & cpu_to_le32(1 << 8)); |
846 | epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f; | 846 | epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f; |
847 | if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) { | 847 | if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) { |
848 | qh->hw_token &= ~__constant_cpu_to_le32(QTD_TOGGLE); | 848 | qh->hw_token &= ~cpu_to_le32(QTD_TOGGLE); |
849 | usb_settoggle(qh->dev, epnum, is_out, 1); | 849 | usb_settoggle(qh->dev, epnum, is_out, 1); |
850 | } | 850 | } |
851 | } | 851 | } |
852 | 852 | ||
853 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ | 853 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ |
854 | wmb(); | 854 | wmb(); |
855 | qh->hw_token &= __constant_cpu_to_le32(QTD_TOGGLE | QTD_STS_PING); | 855 | qh->hw_token &= cpu_to_le32(QTD_TOGGLE | QTD_STS_PING); |
856 | } | 856 | } |
857 | 857 | ||
858 | /* If it weren't for a common silicon quirk (writing the dummy into the qh | 858 | /* If it weren't for a common silicon quirk (writing the dummy into the qh |
@@ -937,7 +937,7 @@ __acquires(oxu->lock) | |||
937 | struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; | 937 | struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; |
938 | 938 | ||
939 | /* S-mask in a QH means it's an interrupt urb */ | 939 | /* S-mask in a QH means it's an interrupt urb */ |
940 | if ((qh->hw_info2 & __constant_cpu_to_le32(QH_SMASK)) != 0) { | 940 | if ((qh->hw_info2 & cpu_to_le32(QH_SMASK)) != 0) { |
941 | 941 | ||
942 | /* ... update hc-wide periodic stats (for usbfs) */ | 942 | /* ... update hc-wide periodic stats (for usbfs) */ |
943 | oxu_to_hcd(oxu)->self.bandwidth_int_reqs--; | 943 | oxu_to_hcd(oxu)->self.bandwidth_int_reqs--; |
@@ -981,7 +981,7 @@ static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh); | |||
981 | static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh); | 981 | static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh); |
982 | static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh); | 982 | static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh); |
983 | 983 | ||
984 | #define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT) | 984 | #define HALT_BIT cpu_to_le32(QTD_STS_HALT) |
985 | 985 | ||
986 | /* Process and free completed qtds for a qh, returning URBs to drivers. | 986 | /* Process and free completed qtds for a qh, returning URBs to drivers. |
987 | * Chases up to qh->hw_current. Returns number of completions called, | 987 | * Chases up to qh->hw_current. Returns number of completions called, |
@@ -1160,7 +1160,7 @@ halt: | |||
1160 | /* should be rare for periodic transfers, | 1160 | /* should be rare for periodic transfers, |
1161 | * except maybe high bandwidth ... | 1161 | * except maybe high bandwidth ... |
1162 | */ | 1162 | */ |
1163 | if ((__constant_cpu_to_le32(QH_SMASK) | 1163 | if ((cpu_to_le32(QH_SMASK) |
1164 | & qh->hw_info2) != 0) { | 1164 | & qh->hw_info2) != 0) { |
1165 | intr_deschedule(oxu, qh); | 1165 | intr_deschedule(oxu, qh); |
1166 | (void) qh_schedule(oxu, qh); | 1166 | (void) qh_schedule(oxu, qh); |
@@ -1350,7 +1350,7 @@ static struct list_head *qh_urb_transaction(struct oxu_hcd *oxu, | |||
1350 | } | 1350 | } |
1351 | 1351 | ||
1352 | /* by default, enable interrupt on urb completion */ | 1352 | /* by default, enable interrupt on urb completion */ |
1353 | qtd->hw_token |= __constant_cpu_to_le32(QTD_IOC); | 1353 | qtd->hw_token |= cpu_to_le32(QTD_IOC); |
1354 | return head; | 1354 | return head; |
1355 | 1355 | ||
1356 | cleanup: | 1356 | cleanup: |
@@ -1539,7 +1539,7 @@ static void qh_link_async(struct oxu_hcd *oxu, struct ehci_qh *qh) | |||
1539 | /* qtd completions reported later by interrupt */ | 1539 | /* qtd completions reported later by interrupt */ |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | #define QH_ADDR_MASK __constant_cpu_to_le32(0x7f) | 1542 | #define QH_ADDR_MASK cpu_to_le32(0x7f) |
1543 | 1543 | ||
1544 | /* | 1544 | /* |
1545 | * For control/bulk/interrupt, return QH with these TDs appended. | 1545 | * For control/bulk/interrupt, return QH with these TDs appended. |
@@ -2012,7 +2012,7 @@ static void qh_unlink_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh) | |||
2012 | * and this qh is active in the current uframe | 2012 | * and this qh is active in the current uframe |
2013 | * (and overlay token SplitXstate is false?) | 2013 | * (and overlay token SplitXstate is false?) |
2014 | * THEN | 2014 | * THEN |
2015 | * qh->hw_info1 |= __constant_cpu_to_le32(1 << 7 "ignore"); | 2015 | * qh->hw_info1 |= cpu_to_le32(1 << 7 "ignore"); |
2016 | */ | 2016 | */ |
2017 | 2017 | ||
2018 | /* high bandwidth, or otherwise part of every microframe */ | 2018 | /* high bandwidth, or otherwise part of every microframe */ |
@@ -2057,7 +2057,7 @@ static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh) | |||
2057 | * active high speed queues may need bigger delays... | 2057 | * active high speed queues may need bigger delays... |
2058 | */ | 2058 | */ |
2059 | if (list_empty(&qh->qtd_list) | 2059 | if (list_empty(&qh->qtd_list) |
2060 | || (__constant_cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0) | 2060 | || (cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0) |
2061 | wait = 2; | 2061 | wait = 2; |
2062 | else | 2062 | else |
2063 | wait = 55; /* worst case: 3 * 1024 */ | 2063 | wait = 55; /* worst case: 3 * 1024 */ |
@@ -2183,10 +2183,10 @@ static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh) | |||
2183 | qh->start = frame; | 2183 | qh->start = frame; |
2184 | 2184 | ||
2185 | /* reset S-frame and (maybe) C-frame masks */ | 2185 | /* reset S-frame and (maybe) C-frame masks */ |
2186 | qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK)); | 2186 | qh->hw_info2 &= cpu_to_le32(~(QH_CMASK | QH_SMASK)); |
2187 | qh->hw_info2 |= qh->period | 2187 | qh->hw_info2 |= qh->period |
2188 | ? cpu_to_le32(1 << uframe) | 2188 | ? cpu_to_le32(1 << uframe) |
2189 | : __constant_cpu_to_le32(QH_SMASK); | 2189 | : cpu_to_le32(QH_SMASK); |
2190 | qh->hw_info2 |= c_mask; | 2190 | qh->hw_info2 |= c_mask; |
2191 | } else | 2191 | } else |
2192 | oxu_dbg(oxu, "reused qh %p schedule\n", qh); | 2192 | oxu_dbg(oxu, "reused qh %p schedule\n", qh); |
@@ -2684,7 +2684,7 @@ static int oxu_reset(struct usb_hcd *hcd) | |||
2684 | oxu->urb_len = 0; | 2684 | oxu->urb_len = 0; |
2685 | 2685 | ||
2686 | /* FIMXE */ | 2686 | /* FIMXE */ |
2687 | hcd->self.controller->dma_mask = 0UL; | 2687 | hcd->self.controller->dma_mask = NULL; |
2688 | 2688 | ||
2689 | if (oxu->is_otg) { | 2689 | if (oxu->is_otg) { |
2690 | oxu->caps = hcd->regs + OXU_OTG_CAP_OFFSET; | 2690 | oxu->caps = hcd->regs + OXU_OTG_CAP_OFFSET; |
diff --git a/drivers/usb/host/oxu210hp.h b/drivers/usb/host/oxu210hp.h index 8910e271cc7d..1c216ad9aad2 100644 --- a/drivers/usb/host/oxu210hp.h +++ b/drivers/usb/host/oxu210hp.h | |||
@@ -235,21 +235,21 @@ struct ehci_qtd { | |||
235 | } __attribute__ ((aligned(32))); | 235 | } __attribute__ ((aligned(32))); |
236 | 236 | ||
237 | /* mask NakCnt+T in qh->hw_alt_next */ | 237 | /* mask NakCnt+T in qh->hw_alt_next */ |
238 | #define QTD_MASK __constant_cpu_to_le32 (~0x1f) | 238 | #define QTD_MASK cpu_to_le32 (~0x1f) |
239 | 239 | ||
240 | #define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1) | 240 | #define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1) |
241 | 241 | ||
242 | /* Type tag from {qh, itd, sitd, fstn}->hw_next */ | 242 | /* Type tag from {qh, itd, sitd, fstn}->hw_next */ |
243 | #define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1)) | 243 | #define Q_NEXT_TYPE(dma) ((dma) & cpu_to_le32 (3 << 1)) |
244 | 244 | ||
245 | /* values for that type tag */ | 245 | /* values for that type tag */ |
246 | #define Q_TYPE_QH __constant_cpu_to_le32 (1 << 1) | 246 | #define Q_TYPE_QH cpu_to_le32 (1 << 1) |
247 | 247 | ||
248 | /* next async queue entry, or pointer to interrupt/periodic QH */ | 248 | /* next async queue entry, or pointer to interrupt/periodic QH */ |
249 | #define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH) | 249 | #define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH) |
250 | 250 | ||
251 | /* for periodic/async schedules and qtd lists, mark end of list */ | 251 | /* for periodic/async schedules and qtd lists, mark end of list */ |
252 | #define EHCI_LIST_END __constant_cpu_to_le32(1) /* "null pointer" to hw */ | 252 | #define EHCI_LIST_END cpu_to_le32(1) /* "null pointer" to hw */ |
253 | 253 | ||
254 | /* | 254 | /* |
255 | * Entries in periodic shadow table are pointers to one of four kinds | 255 | * Entries in periodic shadow table are pointers to one of four kinds |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 75b69847918e..033c2846ce59 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -234,7 +234,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
234 | */ | 234 | */ |
235 | hcc_params = readl(base + EHCI_HCC_PARAMS); | 235 | hcc_params = readl(base + EHCI_HCC_PARAMS); |
236 | offset = (hcc_params >> 8) & 0xff; | 236 | offset = (hcc_params >> 8) & 0xff; |
237 | while (offset && count--) { | 237 | while (offset && --count) { |
238 | u32 cap; | 238 | u32 cap; |
239 | int msec; | 239 | int msec; |
240 | 240 | ||
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 319041205b57..f1626e58c141 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -660,9 +660,9 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, | |||
660 | u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; | 660 | u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; |
661 | 661 | ||
662 | memset(array, 0, sizeof(array)); | 662 | memset(array, 0, sizeof(array)); |
663 | switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 663 | switch (usb_endpoint_type(ep)) { |
664 | case USB_ENDPOINT_XFER_BULK: | 664 | case USB_ENDPOINT_XFER_BULK: |
665 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 665 | if (usb_endpoint_dir_in(ep)) |
666 | array[i++] = 4; | 666 | array[i++] = 4; |
667 | else { | 667 | else { |
668 | array[i++] = 3; | 668 | array[i++] = 3; |
@@ -670,7 +670,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, | |||
670 | } | 670 | } |
671 | break; | 671 | break; |
672 | case USB_ENDPOINT_XFER_INT: | 672 | case USB_ENDPOINT_XFER_INT: |
673 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { | 673 | if (usb_endpoint_dir_in(ep)) { |
674 | array[i++] = 6; | 674 | array[i++] = 6; |
675 | array[i++] = 7; | 675 | array[i++] = 7; |
676 | array[i++] = 8; | 676 | array[i++] = 8; |
@@ -678,7 +678,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, | |||
678 | array[i++] = 9; | 678 | array[i++] = 9; |
679 | break; | 679 | break; |
680 | case USB_ENDPOINT_XFER_ISOC: | 680 | case USB_ENDPOINT_XFER_ISOC: |
681 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 681 | if (usb_endpoint_dir_in(ep)) |
682 | array[i++] = 2; | 682 | array[i++] = 2; |
683 | else | 683 | else |
684 | array[i++] = 1; | 684 | array[i++] = 1; |
@@ -928,10 +928,9 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, | |||
928 | 928 | ||
929 | info.pipenum = get_empty_pipenum(r8a66597, ep); | 929 | info.pipenum = get_empty_pipenum(r8a66597, ep); |
930 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); | 930 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); |
931 | info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 931 | info.epnum = usb_endpoint_num(ep); |
932 | info.maxpacket = le16_to_cpu(ep->wMaxPacketSize); | 932 | info.maxpacket = le16_to_cpu(ep->wMaxPacketSize); |
933 | info.type = get_r8a66597_type(ep->bmAttributes | 933 | info.type = get_r8a66597_type(usb_endpoint_type(ep)); |
934 | & USB_ENDPOINT_XFERTYPE_MASK); | ||
935 | info.bufnum = get_bufnum(info.pipenum); | 934 | info.bufnum = get_bufnum(info.pipenum); |
936 | info.buf_bsize = get_buf_bsize(info.pipenum); | 935 | info.buf_bsize = get_buf_bsize(info.pipenum); |
937 | if (info.type == R8A66597_BULK) { | 936 | if (info.type == R8A66597_BULK) { |
@@ -941,7 +940,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, | |||
941 | info.interval = get_interval(urb, ep->bInterval); | 940 | info.interval = get_interval(urb, ep->bInterval); |
942 | info.timer_interval = get_timer_interval(urb, ep->bInterval); | 941 | info.timer_interval = get_timer_interval(urb, ep->bInterval); |
943 | } | 942 | } |
944 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 943 | if (usb_endpoint_dir_in(ep)) |
945 | info.dir_in = 1; | 944 | info.dir_in = 1; |
946 | else | 945 | else |
947 | info.dir_in = 0; | 946 | info.dir_in = 0; |
@@ -1014,6 +1013,9 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, | |||
1014 | 1013 | ||
1015 | r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); | 1014 | r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); |
1016 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); | 1015 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); |
1016 | |||
1017 | if (r8a66597->bus_suspended) | ||
1018 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); | ||
1017 | } | 1019 | } |
1018 | 1020 | ||
1019 | /* this function must be called with interrupt disabled */ | 1021 | /* this function must be called with interrupt disabled */ |
@@ -1395,7 +1397,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | |||
1395 | (int)urb->iso_frame_desc[td->iso_cnt].length); | 1397 | (int)urb->iso_frame_desc[td->iso_cnt].length); |
1396 | } else { | 1398 | } else { |
1397 | buf = (u16 *)(urb->transfer_buffer + urb->actual_length); | 1399 | buf = (u16 *)(urb->transfer_buffer + urb->actual_length); |
1398 | size = min((int)bufsize, | 1400 | size = min_t(u32, bufsize, |
1399 | urb->transfer_buffer_length - urb->actual_length); | 1401 | urb->transfer_buffer_length - urb->actual_length); |
1400 | } | 1402 | } |
1401 | 1403 | ||
@@ -1615,6 +1617,11 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1615 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); | 1617 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); |
1616 | r8a66597_usb_disconnect(r8a66597, 1); | 1618 | r8a66597_usb_disconnect(r8a66597, 1); |
1617 | } | 1619 | } |
1620 | if (mask2 & BCHG) { | ||
1621 | r8a66597_write(r8a66597, ~BCHG, INTSTS2); | ||
1622 | r8a66597_bclr(r8a66597, BCHGE, INTENB2); | ||
1623 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); | ||
1624 | } | ||
1618 | } | 1625 | } |
1619 | 1626 | ||
1620 | if (mask1) { | 1627 | if (mask1) { |
@@ -1630,6 +1637,12 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1630 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); | 1637 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); |
1631 | r8a66597_usb_disconnect(r8a66597, 0); | 1638 | r8a66597_usb_disconnect(r8a66597, 0); |
1632 | } | 1639 | } |
1640 | if (mask1 & BCHG) { | ||
1641 | r8a66597_write(r8a66597, ~BCHG, INTSTS1); | ||
1642 | r8a66597_bclr(r8a66597, BCHGE, INTENB1); | ||
1643 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); | ||
1644 | } | ||
1645 | |||
1633 | if (mask1 & SIGN) { | 1646 | if (mask1 & SIGN) { |
1634 | r8a66597_write(r8a66597, ~SIGN, INTSTS1); | 1647 | r8a66597_write(r8a66597, ~SIGN, INTSTS1); |
1635 | status = get_urb_error(r8a66597, 0); | 1648 | status = get_urb_error(r8a66597, 0); |
@@ -2141,7 +2154,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2141 | 2154 | ||
2142 | switch (wValue) { | 2155 | switch (wValue) { |
2143 | case USB_PORT_FEAT_ENABLE: | 2156 | case USB_PORT_FEAT_ENABLE: |
2144 | rh->port &= (1 << USB_PORT_FEAT_POWER); | 2157 | rh->port &= ~(1 << USB_PORT_FEAT_POWER); |
2145 | break; | 2158 | break; |
2146 | case USB_PORT_FEAT_SUSPEND: | 2159 | case USB_PORT_FEAT_SUSPEND: |
2147 | break; | 2160 | break; |
@@ -2213,6 +2226,68 @@ error: | |||
2213 | return ret; | 2226 | return ret; |
2214 | } | 2227 | } |
2215 | 2228 | ||
2229 | #if defined(CONFIG_PM) | ||
2230 | static int r8a66597_bus_suspend(struct usb_hcd *hcd) | ||
2231 | { | ||
2232 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | ||
2233 | int port; | ||
2234 | |||
2235 | dbg("%s", __func__); | ||
2236 | |||
2237 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { | ||
2238 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | ||
2239 | unsigned long dvstctr_reg = get_dvstctr_reg(port); | ||
2240 | |||
2241 | if (!(rh->port & (1 << USB_PORT_FEAT_ENABLE))) | ||
2242 | continue; | ||
2243 | |||
2244 | dbg("suspend port = %d", port); | ||
2245 | r8a66597_bclr(r8a66597, UACT, dvstctr_reg); /* suspend */ | ||
2246 | rh->port |= 1 << USB_PORT_FEAT_SUSPEND; | ||
2247 | |||
2248 | if (rh->dev->udev->do_remote_wakeup) { | ||
2249 | msleep(3); /* waiting last SOF */ | ||
2250 | r8a66597_bset(r8a66597, RWUPE, dvstctr_reg); | ||
2251 | r8a66597_write(r8a66597, ~BCHG, get_intsts_reg(port)); | ||
2252 | r8a66597_bset(r8a66597, BCHGE, get_intenb_reg(port)); | ||
2253 | } | ||
2254 | } | ||
2255 | |||
2256 | r8a66597->bus_suspended = 1; | ||
2257 | |||
2258 | return 0; | ||
2259 | } | ||
2260 | |||
2261 | static int r8a66597_bus_resume(struct usb_hcd *hcd) | ||
2262 | { | ||
2263 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | ||
2264 | int port; | ||
2265 | |||
2266 | dbg("%s", __func__); | ||
2267 | |||
2268 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { | ||
2269 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | ||
2270 | unsigned long dvstctr_reg = get_dvstctr_reg(port); | ||
2271 | |||
2272 | if (!(rh->port & (1 << USB_PORT_FEAT_SUSPEND))) | ||
2273 | continue; | ||
2274 | |||
2275 | dbg("resume port = %d", port); | ||
2276 | rh->port &= ~(1 << USB_PORT_FEAT_SUSPEND); | ||
2277 | rh->port |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
2278 | r8a66597_mdfy(r8a66597, RESUME, RESUME | UACT, dvstctr_reg); | ||
2279 | msleep(50); | ||
2280 | r8a66597_mdfy(r8a66597, UACT, RESUME | UACT, dvstctr_reg); | ||
2281 | } | ||
2282 | |||
2283 | return 0; | ||
2284 | |||
2285 | } | ||
2286 | #else | ||
2287 | #define r8a66597_bus_suspend NULL | ||
2288 | #define r8a66597_bus_resume NULL | ||
2289 | #endif | ||
2290 | |||
2216 | static struct hc_driver r8a66597_hc_driver = { | 2291 | static struct hc_driver r8a66597_hc_driver = { |
2217 | .description = hcd_name, | 2292 | .description = hcd_name, |
2218 | .hcd_priv_size = sizeof(struct r8a66597), | 2293 | .hcd_priv_size = sizeof(struct r8a66597), |
@@ -2243,16 +2318,39 @@ static struct hc_driver r8a66597_hc_driver = { | |||
2243 | */ | 2318 | */ |
2244 | .hub_status_data = r8a66597_hub_status_data, | 2319 | .hub_status_data = r8a66597_hub_status_data, |
2245 | .hub_control = r8a66597_hub_control, | 2320 | .hub_control = r8a66597_hub_control, |
2321 | .bus_suspend = r8a66597_bus_suspend, | ||
2322 | .bus_resume = r8a66597_bus_resume, | ||
2246 | }; | 2323 | }; |
2247 | 2324 | ||
2248 | #if defined(CONFIG_PM) | 2325 | #if defined(CONFIG_PM) |
2249 | static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state) | 2326 | static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state) |
2250 | { | 2327 | { |
2328 | struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); | ||
2329 | int port; | ||
2330 | |||
2331 | dbg("%s", __func__); | ||
2332 | |||
2333 | disable_controller(r8a66597); | ||
2334 | |||
2335 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { | ||
2336 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | ||
2337 | |||
2338 | rh->port = 0x00000000; | ||
2339 | } | ||
2340 | |||
2251 | return 0; | 2341 | return 0; |
2252 | } | 2342 | } |
2253 | 2343 | ||
2254 | static int r8a66597_resume(struct platform_device *pdev) | 2344 | static int r8a66597_resume(struct platform_device *pdev) |
2255 | { | 2345 | { |
2346 | struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); | ||
2347 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); | ||
2348 | |||
2349 | dbg("%s", __func__); | ||
2350 | |||
2351 | enable_controller(r8a66597); | ||
2352 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
2353 | |||
2256 | return 0; | 2354 | return 0; |
2257 | } | 2355 | } |
2258 | #else /* if defined(CONFIG_PM) */ | 2356 | #else /* if defined(CONFIG_PM) */ |
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index ecacde4d69b0..f49208f1bb74 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h | |||
@@ -504,6 +504,8 @@ struct r8a66597 { | |||
504 | 504 | ||
505 | struct list_head child_device; | 505 | struct list_head child_device; |
506 | unsigned long child_connect_map[4]; | 506 | unsigned long child_connect_map[4]; |
507 | |||
508 | unsigned bus_suspended:1; | ||
507 | }; | 509 | }; |
508 | 510 | ||
509 | static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd) | 511 | static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd) |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index e106e9d48d4a..a949259f18b9 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -230,7 +230,7 @@ static void in_packet( | |||
230 | writeb(usb_pipedevice(urb->pipe), data_reg); | 230 | writeb(usb_pipedevice(urb->pipe), data_reg); |
231 | 231 | ||
232 | sl811_write(sl811, bank + SL11H_HOSTCTLREG, control); | 232 | sl811_write(sl811, bank + SL11H_HOSTCTLREG, control); |
233 | ep->length = min((int)len, | 233 | ep->length = min_t(u32, len, |
234 | urb->transfer_buffer_length - urb->actual_length); | 234 | urb->transfer_buffer_length - urb->actual_length); |
235 | PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", | 235 | PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", |
236 | !!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len); | 236 | !!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len); |
@@ -255,7 +255,7 @@ static void out_packet( | |||
255 | buf = urb->transfer_buffer + urb->actual_length; | 255 | buf = urb->transfer_buffer + urb->actual_length; |
256 | prefetch(buf); | 256 | prefetch(buf); |
257 | 257 | ||
258 | len = min((int)ep->maxpacket, | 258 | len = min_t(u32, ep->maxpacket, |
259 | urb->transfer_buffer_length - urb->actual_length); | 259 | urb->transfer_buffer_length - urb->actual_length); |
260 | 260 | ||
261 | if (!(control & SL11H_HCTLMASK_ISOCH) | 261 | if (!(control & SL11H_HCTLMASK_ISOCH) |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 20cc58b97807..e52b954dda47 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -118,7 +118,9 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); | 120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); |
121 | out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); | 121 | out += sprintf(out, " Actlen=%d%s", urbp->urb->actual_length, |
122 | (urbp->qh->type == USB_ENDPOINT_XFER_CONTROL ? | ||
123 | "-8" : "")); | ||
122 | 124 | ||
123 | if (urbp->urb->unlinked) | 125 | if (urbp->urb->unlinked) |
124 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); | 126 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 7d01c5677f92..26bd1b2bcbfc 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -73,11 +73,11 @@ | |||
73 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ | 73 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ |
74 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ | 74 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ |
75 | 75 | ||
76 | #define UHCI_PTR_BITS __constant_cpu_to_le32(0x000F) | 76 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) |
77 | #define UHCI_PTR_TERM __constant_cpu_to_le32(0x0001) | 77 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) |
78 | #define UHCI_PTR_QH __constant_cpu_to_le32(0x0002) | 78 | #define UHCI_PTR_QH cpu_to_le32(0x0002) |
79 | #define UHCI_PTR_DEPTH __constant_cpu_to_le32(0x0004) | 79 | #define UHCI_PTR_DEPTH cpu_to_le32(0x0004) |
80 | #define UHCI_PTR_BREADTH __constant_cpu_to_le32(0x0000) | 80 | #define UHCI_PTR_BREADTH cpu_to_le32(0x0000) |
81 | 81 | ||
82 | #define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ | 82 | #define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ |
83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 5631d89c8730..3e5807d14ffb 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -402,7 +402,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) | |||
402 | /* Otherwise all the toggles in the URB have to be switched */ | 402 | /* Otherwise all the toggles in the URB have to be switched */ |
403 | } else { | 403 | } else { |
404 | list_for_each_entry(td, &urbp->td_list, list) { | 404 | list_for_each_entry(td, &urbp->td_list, list) { |
405 | td->token ^= __constant_cpu_to_le32( | 405 | td->token ^= cpu_to_le32( |
406 | TD_TOKEN_TOGGLE); | 406 | TD_TOKEN_TOGGLE); |
407 | toggle ^= 1; | 407 | toggle ^= 1; |
408 | } | 408 | } |
@@ -883,7 +883,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
883 | 883 | ||
884 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); | 884 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); |
885 | wmb(); | 885 | wmb(); |
886 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); | 886 | qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE); |
887 | qh->dummy_td = td; | 887 | qh->dummy_td = td; |
888 | 888 | ||
889 | /* Low-speed transfers get a different queue, and won't hog the bus. | 889 | /* Low-speed transfers get a different queue, and won't hog the bus. |
@@ -899,8 +899,6 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
899 | } | 899 | } |
900 | if (qh->state != QH_STATE_ACTIVE) | 900 | if (qh->state != QH_STATE_ACTIVE) |
901 | qh->skel = skel; | 901 | qh->skel = skel; |
902 | |||
903 | urb->actual_length = -8; /* Account for the SETUP packet */ | ||
904 | return 0; | 902 | return 0; |
905 | 903 | ||
906 | nomem: | 904 | nomem: |
@@ -1003,7 +1001,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
1003 | * fast side but not enough to justify delaying an interrupt | 1001 | * fast side but not enough to justify delaying an interrupt |
1004 | * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT | 1002 | * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT |
1005 | * flag setting. */ | 1003 | * flag setting. */ |
1006 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); | 1004 | td->status |= cpu_to_le32(TD_CTRL_IOC); |
1007 | 1005 | ||
1008 | /* | 1006 | /* |
1009 | * Build the new dummy TD and activate the old one | 1007 | * Build the new dummy TD and activate the old one |
@@ -1015,7 +1013,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
1015 | 1013 | ||
1016 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); | 1014 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); |
1017 | wmb(); | 1015 | wmb(); |
1018 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); | 1016 | qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE); |
1019 | qh->dummy_td = td; | 1017 | qh->dummy_td = td; |
1020 | 1018 | ||
1021 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 1019 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
@@ -1317,7 +1315,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1317 | } | 1315 | } |
1318 | 1316 | ||
1319 | /* Set the interrupt-on-completion flag on the last packet. */ | 1317 | /* Set the interrupt-on-completion flag on the last packet. */ |
1320 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); | 1318 | td->status |= cpu_to_le32(TD_CTRL_IOC); |
1321 | 1319 | ||
1322 | /* Add the TDs to the frame list */ | 1320 | /* Add the TDs to the frame list */ |
1323 | frame = urb->start_frame; | 1321 | frame = urb->start_frame; |
@@ -1494,11 +1492,10 @@ __acquires(uhci->lock) | |||
1494 | 1492 | ||
1495 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { | 1493 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { |
1496 | 1494 | ||
1497 | /* urb->actual_length < 0 means the setup transaction didn't | 1495 | /* Subtract off the length of the SETUP packet from |
1498 | * complete successfully. Either it failed or the URB was | 1496 | * urb->actual_length. |
1499 | * unlinked first. Regardless, don't confuse people with a | 1497 | */ |
1500 | * negative length. */ | 1498 | urb->actual_length -= min_t(u32, 8, urb->actual_length); |
1501 | urb->actual_length = max(urb->actual_length, 0); | ||
1502 | } | 1499 | } |
1503 | 1500 | ||
1504 | /* When giving back the first URB in an Isochronous queue, | 1501 | /* When giving back the first URB in an Isochronous queue, |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 972f20b3406c..eca355dccf65 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -188,7 +188,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] = | |||
188 | .bDescriptorType = 0, | 188 | .bDescriptorType = 0, |
189 | .bEndpointAddress = 0x01, | 189 | .bEndpointAddress = 0x01, |
190 | .bmAttributes = 0x02, | 190 | .bmAttributes = 0x02, |
191 | .wMaxPacketSize = __constant_cpu_to_le16(8), | 191 | .wMaxPacketSize = cpu_to_le16(8), |
192 | .bInterval = 0, | 192 | .bInterval = 0, |
193 | .bRefresh = 0, | 193 | .bRefresh = 0, |
194 | .bSynchAddress = 0, | 194 | .bSynchAddress = 0, |
@@ -198,7 +198,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] = | |||
198 | .bDescriptorType = 0, | 198 | .bDescriptorType = 0, |
199 | .bEndpointAddress = 0x82, | 199 | .bEndpointAddress = 0x82, |
200 | .bmAttributes = 0x03, | 200 | .bmAttributes = 0x03, |
201 | .wMaxPacketSize = __constant_cpu_to_le16(8), | 201 | .wMaxPacketSize = cpu_to_le16(8), |
202 | .bInterval = 0, | 202 | .bInterval = 0, |
203 | .bRefresh = 0, | 203 | .bRefresh = 0, |
204 | .bSynchAddress = 0, | 204 | .bSynchAddress = 0, |
@@ -208,7 +208,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] = | |||
208 | .bDescriptorType = 0, | 208 | .bDescriptorType = 0, |
209 | .bEndpointAddress = 0x03, | 209 | .bEndpointAddress = 0x03, |
210 | .bmAttributes = 0x02, | 210 | .bmAttributes = 0x02, |
211 | .wMaxPacketSize = __constant_cpu_to_le16(64), | 211 | .wMaxPacketSize = cpu_to_le16(64), |
212 | .bInterval = 0, | 212 | .bInterval = 0, |
213 | .bRefresh = 0, | 213 | .bRefresh = 0, |
214 | .bSynchAddress = 0, | 214 | .bSynchAddress = 0, |
@@ -218,7 +218,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] = | |||
218 | .bDescriptorType = 0, | 218 | .bDescriptorType = 0, |
219 | .bEndpointAddress = 0x84, | 219 | .bEndpointAddress = 0x84, |
220 | .bmAttributes = 0x02, | 220 | .bmAttributes = 0x02, |
221 | .wMaxPacketSize = __constant_cpu_to_le16(64), | 221 | .wMaxPacketSize = cpu_to_le16(64), |
222 | .bInterval = 0, | 222 | .bInterval = 0, |
223 | .bRefresh = 0, | 223 | .bRefresh = 0, |
224 | .bSynchAddress = 0, | 224 | .bSynchAddress = 0, |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index e463db5d8188..a68d91a11bee 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -135,45 +135,6 @@ config USB_CYTHERM | |||
135 | To compile this driver as a module, choose M here: the | 135 | To compile this driver as a module, choose M here: the |
136 | module will be called cytherm. | 136 | module will be called cytherm. |
137 | 137 | ||
138 | config USB_PHIDGET | ||
139 | tristate "USB Phidgets drivers" | ||
140 | depends on USB | ||
141 | help | ||
142 | Say Y here to enable the various drivers for devices from | ||
143 | Phidgets inc. | ||
144 | |||
145 | config USB_PHIDGETKIT | ||
146 | tristate "USB PhidgetInterfaceKit support" | ||
147 | depends on USB_PHIDGET | ||
148 | help | ||
149 | Say Y here if you want to connect a PhidgetInterfaceKit USB device | ||
150 | from Phidgets Inc. | ||
151 | |||
152 | To compile this driver as a module, choose M here: the | ||
153 | module will be called phidgetkit. | ||
154 | |||
155 | config USB_PHIDGETMOTORCONTROL | ||
156 | tristate "USB PhidgetMotorControl support" | ||
157 | depends on USB_PHIDGET | ||
158 | help | ||
159 | Say Y here if you want to connect a PhidgetMotorControl USB device | ||
160 | from Phidgets Inc. | ||
161 | |||
162 | To compile this driver as a module, choose M here: the | ||
163 | module will be called phidgetmotorcontrol. | ||
164 | |||
165 | config USB_PHIDGETSERVO | ||
166 | tristate "USB PhidgetServo support" | ||
167 | depends on USB_PHIDGET | ||
168 | help | ||
169 | Say Y here if you want to connect an 1 or 4 Motor PhidgetServo | ||
170 | servo controller version 2.0 or 3.0. | ||
171 | |||
172 | Phidgets Inc. has a web page at <http://www.phidgets.com/>. | ||
173 | |||
174 | To compile this driver as a module, choose M here: the | ||
175 | module will be called phidgetservo. | ||
176 | |||
177 | config USB_IDMOUSE | 138 | config USB_IDMOUSE |
178 | tristate "Siemens ID USB Mouse Fingerprint sensor support" | 139 | tristate "Siemens ID USB Mouse Fingerprint sensor support" |
179 | depends on USB | 140 | depends on USB |
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 1334f7bdd7be..0826aab8303f 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -18,10 +18,6 @@ obj-$(CONFIG_USB_LCD) += usblcd.o | |||
18 | obj-$(CONFIG_USB_LD) += ldusb.o | 18 | obj-$(CONFIG_USB_LD) += ldusb.o |
19 | obj-$(CONFIG_USB_LED) += usbled.o | 19 | obj-$(CONFIG_USB_LED) += usbled.o |
20 | obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o | 20 | obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o |
21 | obj-$(CONFIG_USB_PHIDGET) += phidget.o | ||
22 | obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o | ||
23 | obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o | ||
24 | obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o | ||
25 | obj-$(CONFIG_USB_RIO500) += rio500.o | 21 | obj-$(CONFIG_USB_RIO500) += rio500.o |
26 | obj-$(CONFIG_USB_TEST) += usbtest.o | 22 | obj-$(CONFIG_USB_TEST) += usbtest.o |
27 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o | 23 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o |
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 79a7668ef264..9d0675ed0d4c 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -1568,7 +1568,7 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number, | |||
1568 | struct u132_target *target = &ftdi->target[ed]; | 1568 | struct u132_target *target = &ftdi->target[ed]; |
1569 | struct u132_command *command = &ftdi->command[ | 1569 | struct u132_command *command = &ftdi->command[ |
1570 | COMMAND_MASK & ftdi->command_next]; | 1570 | COMMAND_MASK & ftdi->command_next]; |
1571 | int remaining_length = urb->transfer_buffer_length - | 1571 | u32 remaining_length = urb->transfer_buffer_length - |
1572 | urb->actual_length; | 1572 | urb->actual_length; |
1573 | command->header = 0x82 | (ed << 5); | 1573 | command->header = 0x82 | (ed << 5); |
1574 | if (remaining_length == 0) { | 1574 | if (remaining_length == 0) { |
@@ -1702,7 +1702,7 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number, | |||
1702 | | (address << 0); | 1702 | | (address << 0); |
1703 | command->width = usb_maxpacket(urb->dev, urb->pipe, | 1703 | command->width = usb_maxpacket(urb->dev, urb->pipe, |
1704 | usb_pipeout(urb->pipe)); | 1704 | usb_pipeout(urb->pipe)); |
1705 | command->follows = min(1024, | 1705 | command->follows = min_t(u32, 1024, |
1706 | urb->transfer_buffer_length - | 1706 | urb->transfer_buffer_length - |
1707 | urb->actual_length); | 1707 | urb->actual_length); |
1708 | command->value = 0; | 1708 | command->value = 0; |
@@ -1766,7 +1766,7 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number, | |||
1766 | mutex_lock(&ftdi->u132_lock); | 1766 | mutex_lock(&ftdi->u132_lock); |
1767 | command_size = ftdi->command_next - ftdi->command_head; | 1767 | command_size = ftdi->command_next - ftdi->command_head; |
1768 | if (command_size < COMMAND_SIZE) { | 1768 | if (command_size < COMMAND_SIZE) { |
1769 | int remaining_length = urb->transfer_buffer_length - | 1769 | u32 remaining_length = urb->transfer_buffer_length - |
1770 | urb->actual_length; | 1770 | urb->actual_length; |
1771 | struct u132_target *target = &ftdi->target[ed]; | 1771 | struct u132_target *target = &ftdi->target[ed]; |
1772 | struct u132_command *command = &ftdi->command[ | 1772 | struct u132_command *command = &ftdi->command[ |
diff --git a/drivers/usb/misc/phidget.c b/drivers/usb/misc/phidget.c deleted file mode 100644 index 735ed33f4f7f..000000000000 --- a/drivers/usb/misc/phidget.c +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * USB Phidgets class | ||
3 | * | ||
4 | * Copyright (C) 2006 Sean Young <sean@mess.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/device.h> | ||
17 | |||
18 | struct class *phidget_class; | ||
19 | |||
20 | static int __init init_phidget(void) | ||
21 | { | ||
22 | phidget_class = class_create(THIS_MODULE, "phidget"); | ||
23 | |||
24 | if (IS_ERR(phidget_class)) | ||
25 | return PTR_ERR(phidget_class); | ||
26 | |||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | static void __exit cleanup_phidget(void) | ||
31 | { | ||
32 | class_destroy(phidget_class); | ||
33 | } | ||
34 | |||
35 | EXPORT_SYMBOL_GPL(phidget_class); | ||
36 | |||
37 | module_init(init_phidget); | ||
38 | module_exit(cleanup_phidget); | ||
39 | |||
40 | MODULE_LICENSE("GPL"); | ||
41 | MODULE_AUTHOR("Sean Young <sean@mess.org>"); | ||
42 | MODULE_DESCRIPTION("Container module for phidget class"); | ||
43 | |||
diff --git a/drivers/usb/misc/phidget.h b/drivers/usb/misc/phidget.h deleted file mode 100644 index c4011907d431..000000000000 --- a/drivers/usb/misc/phidget.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | /* | ||
2 | * USB Phidgets class | ||
3 | * | ||
4 | * Copyright (C) 2006 Sean Young <sean@mess.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | extern struct class *phidget_class; | ||
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c deleted file mode 100644 index cc8e0a926f99..000000000000 --- a/drivers/usb/misc/phidgetkit.c +++ /dev/null | |||
@@ -1,740 +0,0 @@ | |||
1 | /* | ||
2 | * USB PhidgetInterfaceKit driver 1.0 | ||
3 | * | ||
4 | * Copyright (C) 2004, 2006 Sean Young <sean@mess.org> | ||
5 | * Copyright (C) 2005 Daniel Saakes <daniel@saakes.net> | ||
6 | * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This is a driver for the USB PhidgetInterfaceKit. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/usb.h> | ||
22 | |||
23 | #include "phidget.h" | ||
24 | |||
25 | #define DRIVER_AUTHOR "Sean Young <sean@mess.org>" | ||
26 | #define DRIVER_DESC "USB PhidgetInterfaceKit Driver" | ||
27 | |||
28 | #define USB_VENDOR_ID_GLAB 0x06c2 | ||
29 | #define USB_DEVICE_ID_INTERFACEKIT004 0x0040 | ||
30 | #define USB_DEVICE_ID_INTERFACEKIT01616 0x0044 | ||
31 | #define USB_DEVICE_ID_INTERFACEKIT888 0x0045 | ||
32 | #define USB_DEVICE_ID_INTERFACEKIT047 0x0051 | ||
33 | #define USB_DEVICE_ID_INTERFACEKIT088 0x0053 | ||
34 | |||
35 | #define USB_VENDOR_ID_WISEGROUP 0x0925 | ||
36 | #define USB_DEVICE_ID_INTERFACEKIT884 0x8201 | ||
37 | |||
38 | #define MAX_INTERFACES 16 | ||
39 | |||
40 | #define URB_INT_SIZE 8 | ||
41 | |||
42 | struct driver_interfacekit { | ||
43 | int sensors; | ||
44 | int inputs; | ||
45 | int outputs; | ||
46 | int has_lcd; | ||
47 | int amnesiac; | ||
48 | }; | ||
49 | |||
50 | #define ifkit(_sensors, _inputs, _outputs, _lcd, _amnesiac) \ | ||
51 | { \ | ||
52 | .sensors = _sensors, \ | ||
53 | .inputs = _inputs, \ | ||
54 | .outputs = _outputs, \ | ||
55 | .has_lcd = _lcd, \ | ||
56 | .amnesiac = _amnesiac \ | ||
57 | }; | ||
58 | |||
59 | static const struct driver_interfacekit ph_004 = ifkit(0, 0, 4, 0, 0); | ||
60 | static const struct driver_interfacekit ph_888n = ifkit(8, 8, 8, 0, 1); | ||
61 | static const struct driver_interfacekit ph_888o = ifkit(8, 8, 8, 0, 0); | ||
62 | static const struct driver_interfacekit ph_047 = ifkit(0, 4, 7, 1, 0); | ||
63 | static const struct driver_interfacekit ph_884 = ifkit(8, 8, 4, 0, 0); | ||
64 | static const struct driver_interfacekit ph_088 = ifkit(0, 8, 8, 1, 0); | ||
65 | static const struct driver_interfacekit ph_01616 = ifkit(0, 16, 16, 0, 0); | ||
66 | |||
67 | static unsigned long device_no; | ||
68 | |||
69 | struct interfacekit { | ||
70 | struct usb_device *udev; | ||
71 | struct usb_interface *intf; | ||
72 | struct driver_interfacekit *ifkit; | ||
73 | struct device *dev; | ||
74 | unsigned long outputs; | ||
75 | int dev_no; | ||
76 | u8 inputs[MAX_INTERFACES]; | ||
77 | u16 sensors[MAX_INTERFACES]; | ||
78 | u8 lcd_files_on; | ||
79 | |||
80 | struct urb *irq; | ||
81 | unsigned char *data; | ||
82 | dma_addr_t data_dma; | ||
83 | |||
84 | struct delayed_work do_notify; | ||
85 | struct delayed_work do_resubmit; | ||
86 | unsigned long input_events; | ||
87 | unsigned long sensor_events; | ||
88 | }; | ||
89 | |||
90 | static struct usb_device_id id_table[] = { | ||
91 | {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT004), | ||
92 | .driver_info = (kernel_ulong_t)&ph_004}, | ||
93 | {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0, 0x814), | ||
94 | .driver_info = (kernel_ulong_t)&ph_888o}, | ||
95 | {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0x0815, 0xffff), | ||
96 | .driver_info = (kernel_ulong_t)&ph_888n}, | ||
97 | {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT047), | ||
98 | .driver_info = (kernel_ulong_t)&ph_047}, | ||
99 | {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088), | ||
100 | .driver_info = (kernel_ulong_t)&ph_088}, | ||
101 | {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT01616), | ||
102 | .driver_info = (kernel_ulong_t)&ph_01616}, | ||
103 | {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884), | ||
104 | .driver_info = (kernel_ulong_t)&ph_884}, | ||
105 | {} | ||
106 | }; | ||
107 | MODULE_DEVICE_TABLE(usb, id_table); | ||
108 | |||
109 | static int set_outputs(struct interfacekit *kit) | ||
110 | { | ||
111 | u8 *buffer; | ||
112 | int retval; | ||
113 | |||
114 | buffer = kzalloc(4, GFP_KERNEL); | ||
115 | if (!buffer) { | ||
116 | dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); | ||
117 | return -ENOMEM; | ||
118 | } | ||
119 | buffer[0] = (u8)kit->outputs; | ||
120 | buffer[1] = (u8)(kit->outputs >> 8); | ||
121 | |||
122 | dev_dbg(&kit->udev->dev, "sending data: 0x%04x\n", (u16)kit->outputs); | ||
123 | |||
124 | retval = usb_control_msg(kit->udev, | ||
125 | usb_sndctrlpipe(kit->udev, 0), | ||
126 | 0x09, 0x21, 0x0200, 0x0000, buffer, 4, 2000); | ||
127 | |||
128 | if (retval != 4) | ||
129 | dev_err(&kit->udev->dev, "usb_control_msg returned %d\n", | ||
130 | retval); | ||
131 | kfree(buffer); | ||
132 | |||
133 | if (kit->ifkit->amnesiac) | ||
134 | schedule_delayed_work(&kit->do_resubmit, HZ / 2); | ||
135 | |||
136 | return retval < 0 ? retval : 0; | ||
137 | } | ||
138 | |||
139 | static int change_string(struct interfacekit *kit, const char *display, unsigned char row) | ||
140 | { | ||
141 | unsigned char *buffer; | ||
142 | unsigned char *form_buffer; | ||
143 | int retval = -ENOMEM; | ||
144 | int i,j, len, buf_ptr; | ||
145 | |||
146 | buffer = kmalloc(8, GFP_KERNEL); | ||
147 | form_buffer = kmalloc(30, GFP_KERNEL); | ||
148 | if ((!buffer) || (!form_buffer)) { | ||
149 | dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); | ||
150 | goto exit; | ||
151 | } | ||
152 | |||
153 | len = strlen(display); | ||
154 | if (len > 20) | ||
155 | len = 20; | ||
156 | |||
157 | dev_dbg(&kit->udev->dev, "Setting LCD line %d to %s\n", row, display); | ||
158 | |||
159 | form_buffer[0] = row * 0x40 + 0x80; | ||
160 | form_buffer[1] = 0x02; | ||
161 | buf_ptr = 2; | ||
162 | for (i = 0; i<len; i++) | ||
163 | form_buffer[buf_ptr++] = display[i]; | ||
164 | |||
165 | for (i = 0; i < (20 - len); i++) | ||
166 | form_buffer[buf_ptr++] = 0x20; | ||
167 | form_buffer[buf_ptr++] = 0x01; | ||
168 | form_buffer[buf_ptr++] = row * 0x40 + 0x80 + strlen(display); | ||
169 | |||
170 | for (i = 0; i < buf_ptr; i += 7) { | ||
171 | if ((buf_ptr - i) > 7) | ||
172 | len = 7; | ||
173 | else | ||
174 | len = (buf_ptr - i); | ||
175 | for (j = 0; j < len; j++) | ||
176 | buffer[j] = form_buffer[i + j]; | ||
177 | buffer[7] = len; | ||
178 | |||
179 | retval = usb_control_msg(kit->udev, | ||
180 | usb_sndctrlpipe(kit->udev, 0), | ||
181 | 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000); | ||
182 | if (retval < 0) | ||
183 | goto exit; | ||
184 | } | ||
185 | |||
186 | retval = 0; | ||
187 | exit: | ||
188 | kfree(buffer); | ||
189 | kfree(form_buffer); | ||
190 | |||
191 | return retval; | ||
192 | } | ||
193 | |||
194 | #define set_lcd_line(number) \ | ||
195 | static ssize_t lcd_line_##number(struct device *dev, \ | ||
196 | struct device_attribute *attr, \ | ||
197 | const char *buf, size_t count) \ | ||
198 | { \ | ||
199 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
200 | change_string(kit, buf, number - 1); \ | ||
201 | return count; \ | ||
202 | } | ||
203 | |||
204 | #define lcd_line_attr(number) \ | ||
205 | __ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number) | ||
206 | |||
207 | set_lcd_line(1); | ||
208 | set_lcd_line(2); | ||
209 | |||
210 | static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | ||
211 | { | ||
212 | struct interfacekit *kit = dev_get_drvdata(dev); | ||
213 | int enabled; | ||
214 | unsigned char *buffer; | ||
215 | int retval = -ENOMEM; | ||
216 | |||
217 | buffer = kzalloc(8, GFP_KERNEL); | ||
218 | if (!buffer) { | ||
219 | dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); | ||
220 | goto exit; | ||
221 | } | ||
222 | |||
223 | if (sscanf(buf, "%d", &enabled) < 1) { | ||
224 | retval = -EINVAL; | ||
225 | goto exit; | ||
226 | } | ||
227 | if (enabled) | ||
228 | buffer[0] = 0x01; | ||
229 | buffer[7] = 0x11; | ||
230 | |||
231 | dev_dbg(&kit->udev->dev, "Setting backlight to %s\n", enabled ? "on" : "off"); | ||
232 | |||
233 | retval = usb_control_msg(kit->udev, | ||
234 | usb_sndctrlpipe(kit->udev, 0), | ||
235 | 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000); | ||
236 | if (retval < 0) | ||
237 | goto exit; | ||
238 | |||
239 | retval = count; | ||
240 | exit: | ||
241 | kfree(buffer); | ||
242 | return retval; | ||
243 | } | ||
244 | |||
245 | static struct device_attribute dev_lcd_line_attrs[] = { | ||
246 | lcd_line_attr(1), | ||
247 | lcd_line_attr(2), | ||
248 | __ATTR(backlight, S_IWUGO, NULL, set_backlight) | ||
249 | }; | ||
250 | |||
251 | static void remove_lcd_files(struct interfacekit *kit) | ||
252 | { | ||
253 | int i; | ||
254 | |||
255 | if (kit->lcd_files_on) { | ||
256 | dev_dbg(&kit->udev->dev, "Removing lcd files\n"); | ||
257 | |||
258 | for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) | ||
259 | device_remove_file(kit->dev, &dev_lcd_line_attrs[i]); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | ||
264 | { | ||
265 | struct interfacekit *kit = dev_get_drvdata(dev); | ||
266 | int enable; | ||
267 | int i, rc; | ||
268 | |||
269 | if (kit->ifkit->has_lcd == 0) | ||
270 | return -ENODEV; | ||
271 | |||
272 | if (sscanf(buf, "%d", &enable) < 1) | ||
273 | return -EINVAL; | ||
274 | |||
275 | if (enable) { | ||
276 | if (!kit->lcd_files_on) { | ||
277 | dev_dbg(&kit->udev->dev, "Adding lcd files\n"); | ||
278 | for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) { | ||
279 | rc = device_create_file(kit->dev, | ||
280 | &dev_lcd_line_attrs[i]); | ||
281 | if (rc) | ||
282 | goto out; | ||
283 | } | ||
284 | kit->lcd_files_on = 1; | ||
285 | } | ||
286 | } else { | ||
287 | if (kit->lcd_files_on) { | ||
288 | remove_lcd_files(kit); | ||
289 | kit->lcd_files_on = 0; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | return count; | ||
294 | out: | ||
295 | while (i-- > 0) | ||
296 | device_remove_file(kit->dev, &dev_lcd_line_attrs[i]); | ||
297 | |||
298 | return rc; | ||
299 | } | ||
300 | |||
301 | static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); | ||
302 | |||
303 | static void interfacekit_irq(struct urb *urb) | ||
304 | { | ||
305 | struct interfacekit *kit = urb->context; | ||
306 | unsigned char *buffer = kit->data; | ||
307 | int i, level, sensor; | ||
308 | int retval; | ||
309 | int status = urb->status; | ||
310 | |||
311 | switch (status) { | ||
312 | case 0: /* success */ | ||
313 | break; | ||
314 | case -ECONNRESET: /* unlink */ | ||
315 | case -ENOENT: | ||
316 | case -ESHUTDOWN: | ||
317 | return; | ||
318 | /* -EPIPE: should clear the halt */ | ||
319 | default: /* error */ | ||
320 | goto resubmit; | ||
321 | } | ||
322 | |||
323 | /* digital inputs */ | ||
324 | if (kit->ifkit->inputs == 16) { | ||
325 | for (i=0; i < 8; i++) { | ||
326 | level = (buffer[0] >> i) & 1; | ||
327 | if (kit->inputs[i] != level) { | ||
328 | kit->inputs[i] = level; | ||
329 | set_bit(i, &kit->input_events); | ||
330 | } | ||
331 | level = (buffer[1] >> i) & 1; | ||
332 | if (kit->inputs[8 + i] != level) { | ||
333 | kit->inputs[8 + i] = level; | ||
334 | set_bit(8 + i, &kit->input_events); | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | else if (kit->ifkit->inputs == 8) { | ||
339 | for (i=0; i < 8; i++) { | ||
340 | level = (buffer[1] >> i) & 1; | ||
341 | if (kit->inputs[i] != level) { | ||
342 | kit->inputs[i] = level; | ||
343 | set_bit(i, &kit->input_events); | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | |||
348 | /* analog inputs */ | ||
349 | if (kit->ifkit->sensors) { | ||
350 | sensor = (buffer[0] & 1) ? 4 : 0; | ||
351 | |||
352 | level = buffer[2] + (buffer[3] & 0x0f) * 256; | ||
353 | if (level != kit->sensors[sensor]) { | ||
354 | kit->sensors[sensor] = level; | ||
355 | set_bit(sensor, &kit->sensor_events); | ||
356 | } | ||
357 | sensor++; | ||
358 | level = buffer[4] + (buffer[3] & 0xf0) * 16; | ||
359 | if (level != kit->sensors[sensor]) { | ||
360 | kit->sensors[sensor] = level; | ||
361 | set_bit(sensor, &kit->sensor_events); | ||
362 | } | ||
363 | sensor++; | ||
364 | level = buffer[5] + (buffer[6] & 0x0f) * 256; | ||
365 | if (level != kit->sensors[sensor]) { | ||
366 | kit->sensors[sensor] = level; | ||
367 | set_bit(sensor, &kit->sensor_events); | ||
368 | } | ||
369 | sensor++; | ||
370 | level = buffer[7] + (buffer[6] & 0xf0) * 16; | ||
371 | if (level != kit->sensors[sensor]) { | ||
372 | kit->sensors[sensor] = level; | ||
373 | set_bit(sensor, &kit->sensor_events); | ||
374 | } | ||
375 | } | ||
376 | |||
377 | if (kit->input_events || kit->sensor_events) | ||
378 | schedule_delayed_work(&kit->do_notify, 0); | ||
379 | |||
380 | resubmit: | ||
381 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
382 | if (retval) | ||
383 | err("can't resubmit intr, %s-%s/interfacekit0, retval %d", | ||
384 | kit->udev->bus->bus_name, | ||
385 | kit->udev->devpath, retval); | ||
386 | } | ||
387 | |||
388 | static void do_notify(struct work_struct *work) | ||
389 | { | ||
390 | struct interfacekit *kit = | ||
391 | container_of(work, struct interfacekit, do_notify.work); | ||
392 | int i; | ||
393 | char sysfs_file[8]; | ||
394 | |||
395 | for (i=0; i<kit->ifkit->inputs; i++) { | ||
396 | if (test_and_clear_bit(i, &kit->input_events)) { | ||
397 | sprintf(sysfs_file, "input%d", i + 1); | ||
398 | sysfs_notify(&kit->dev->kobj, NULL, sysfs_file); | ||
399 | } | ||
400 | } | ||
401 | |||
402 | for (i=0; i<kit->ifkit->sensors; i++) { | ||
403 | if (test_and_clear_bit(i, &kit->sensor_events)) { | ||
404 | sprintf(sysfs_file, "sensor%d", i + 1); | ||
405 | sysfs_notify(&kit->dev->kobj, NULL, sysfs_file); | ||
406 | } | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void do_resubmit(struct work_struct *work) | ||
411 | { | ||
412 | struct interfacekit *kit = | ||
413 | container_of(work, struct interfacekit, do_resubmit.work); | ||
414 | set_outputs(kit); | ||
415 | } | ||
416 | |||
417 | #define show_set_output(value) \ | ||
418 | static ssize_t set_output##value(struct device *dev, \ | ||
419 | struct device_attribute *attr, \ | ||
420 | const char *buf, size_t count) \ | ||
421 | { \ | ||
422 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
423 | int enable; \ | ||
424 | int retval; \ | ||
425 | \ | ||
426 | if (sscanf(buf, "%d", &enable) < 1) \ | ||
427 | return -EINVAL; \ | ||
428 | \ | ||
429 | if (enable) \ | ||
430 | set_bit(value - 1, &kit->outputs); \ | ||
431 | else \ | ||
432 | clear_bit(value - 1, &kit->outputs); \ | ||
433 | \ | ||
434 | retval = set_outputs(kit); \ | ||
435 | \ | ||
436 | return retval ? retval : count; \ | ||
437 | } \ | ||
438 | \ | ||
439 | static ssize_t show_output##value(struct device *dev, \ | ||
440 | struct device_attribute *attr, \ | ||
441 | char *buf) \ | ||
442 | { \ | ||
443 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
444 | \ | ||
445 | return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ | ||
446 | } | ||
447 | |||
448 | #define output_attr(value) \ | ||
449 | __ATTR(output##value, S_IWUGO | S_IRUGO, \ | ||
450 | show_output##value, set_output##value) | ||
451 | |||
452 | show_set_output(1); | ||
453 | show_set_output(2); | ||
454 | show_set_output(3); | ||
455 | show_set_output(4); | ||
456 | show_set_output(5); | ||
457 | show_set_output(6); | ||
458 | show_set_output(7); | ||
459 | show_set_output(8); | ||
460 | show_set_output(9); | ||
461 | show_set_output(10); | ||
462 | show_set_output(11); | ||
463 | show_set_output(12); | ||
464 | show_set_output(13); | ||
465 | show_set_output(14); | ||
466 | show_set_output(15); | ||
467 | show_set_output(16); | ||
468 | |||
469 | static struct device_attribute dev_output_attrs[] = { | ||
470 | output_attr(1), output_attr(2), output_attr(3), output_attr(4), | ||
471 | output_attr(5), output_attr(6), output_attr(7), output_attr(8), | ||
472 | output_attr(9), output_attr(10), output_attr(11), output_attr(12), | ||
473 | output_attr(13), output_attr(14), output_attr(15), output_attr(16) | ||
474 | }; | ||
475 | |||
476 | #define show_input(value) \ | ||
477 | static ssize_t show_input##value(struct device *dev, \ | ||
478 | struct device_attribute *attr, char *buf) \ | ||
479 | { \ | ||
480 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
481 | \ | ||
482 | return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ | ||
483 | } | ||
484 | |||
485 | #define input_attr(value) \ | ||
486 | __ATTR(input##value, S_IRUGO, show_input##value, NULL) | ||
487 | |||
488 | show_input(1); | ||
489 | show_input(2); | ||
490 | show_input(3); | ||
491 | show_input(4); | ||
492 | show_input(5); | ||
493 | show_input(6); | ||
494 | show_input(7); | ||
495 | show_input(8); | ||
496 | show_input(9); | ||
497 | show_input(10); | ||
498 | show_input(11); | ||
499 | show_input(12); | ||
500 | show_input(13); | ||
501 | show_input(14); | ||
502 | show_input(15); | ||
503 | show_input(16); | ||
504 | |||
505 | static struct device_attribute dev_input_attrs[] = { | ||
506 | input_attr(1), input_attr(2), input_attr(3), input_attr(4), | ||
507 | input_attr(5), input_attr(6), input_attr(7), input_attr(8), | ||
508 | input_attr(9), input_attr(10), input_attr(11), input_attr(12), | ||
509 | input_attr(13), input_attr(14), input_attr(15), input_attr(16) | ||
510 | }; | ||
511 | |||
512 | #define show_sensor(value) \ | ||
513 | static ssize_t show_sensor##value(struct device *dev, \ | ||
514 | struct device_attribute *attr, \ | ||
515 | char *buf) \ | ||
516 | { \ | ||
517 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
518 | \ | ||
519 | return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ | ||
520 | } | ||
521 | |||
522 | #define sensor_attr(value) \ | ||
523 | __ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL) | ||
524 | |||
525 | show_sensor(1); | ||
526 | show_sensor(2); | ||
527 | show_sensor(3); | ||
528 | show_sensor(4); | ||
529 | show_sensor(5); | ||
530 | show_sensor(6); | ||
531 | show_sensor(7); | ||
532 | show_sensor(8); | ||
533 | |||
534 | static struct device_attribute dev_sensor_attrs[] = { | ||
535 | sensor_attr(1), sensor_attr(2), sensor_attr(3), sensor_attr(4), | ||
536 | sensor_attr(5), sensor_attr(6), sensor_attr(7), sensor_attr(8) | ||
537 | }; | ||
538 | |||
539 | static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
540 | { | ||
541 | struct usb_device *dev = interface_to_usbdev(intf); | ||
542 | struct usb_host_interface *interface; | ||
543 | struct usb_endpoint_descriptor *endpoint; | ||
544 | struct interfacekit *kit; | ||
545 | struct driver_interfacekit *ifkit; | ||
546 | int pipe, maxp, rc = -ENOMEM; | ||
547 | int bit, value, i; | ||
548 | |||
549 | ifkit = (struct driver_interfacekit *)id->driver_info; | ||
550 | if (!ifkit) | ||
551 | return -ENODEV; | ||
552 | |||
553 | interface = intf->cur_altsetting; | ||
554 | if (interface->desc.bNumEndpoints != 1) | ||
555 | return -ENODEV; | ||
556 | |||
557 | endpoint = &interface->endpoint[0].desc; | ||
558 | if (!usb_endpoint_dir_in(endpoint)) | ||
559 | return -ENODEV; | ||
560 | /* | ||
561 | * bmAttributes | ||
562 | */ | ||
563 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | ||
564 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | ||
565 | |||
566 | kit = kzalloc(sizeof(*kit), GFP_KERNEL); | ||
567 | if (!kit) | ||
568 | goto out; | ||
569 | |||
570 | kit->dev_no = -1; | ||
571 | kit->ifkit = ifkit; | ||
572 | kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &kit->data_dma); | ||
573 | if (!kit->data) | ||
574 | goto out; | ||
575 | |||
576 | kit->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
577 | if (!kit->irq) | ||
578 | goto out; | ||
579 | |||
580 | kit->udev = usb_get_dev(dev); | ||
581 | kit->intf = intf; | ||
582 | INIT_DELAYED_WORK(&kit->do_notify, do_notify); | ||
583 | INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit); | ||
584 | usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, | ||
585 | maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, | ||
586 | interfacekit_irq, kit, endpoint->bInterval); | ||
587 | kit->irq->transfer_dma = kit->data_dma; | ||
588 | kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
589 | |||
590 | usb_set_intfdata(intf, kit); | ||
591 | |||
592 | do { | ||
593 | bit = find_first_zero_bit(&device_no, sizeof(device_no)); | ||
594 | value = test_and_set_bit(bit, &device_no); | ||
595 | } while(value); | ||
596 | kit->dev_no = bit; | ||
597 | |||
598 | kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0), | ||
599 | kit, "interfacekit%d", kit->dev_no); | ||
600 | if (IS_ERR(kit->dev)) { | ||
601 | rc = PTR_ERR(kit->dev); | ||
602 | kit->dev = NULL; | ||
603 | goto out; | ||
604 | } | ||
605 | |||
606 | if (usb_submit_urb(kit->irq, GFP_KERNEL)) { | ||
607 | rc = -EIO; | ||
608 | goto out; | ||
609 | } | ||
610 | |||
611 | for (i=0; i<ifkit->outputs; i++ ) { | ||
612 | rc = device_create_file(kit->dev, &dev_output_attrs[i]); | ||
613 | if (rc) | ||
614 | goto out2; | ||
615 | } | ||
616 | |||
617 | for (i=0; i<ifkit->inputs; i++ ) { | ||
618 | rc = device_create_file(kit->dev, &dev_input_attrs[i]); | ||
619 | if (rc) | ||
620 | goto out3; | ||
621 | } | ||
622 | |||
623 | for (i=0; i<ifkit->sensors; i++ ) { | ||
624 | rc = device_create_file(kit->dev, &dev_sensor_attrs[i]); | ||
625 | if (rc) | ||
626 | goto out4; | ||
627 | } | ||
628 | |||
629 | if (ifkit->has_lcd) { | ||
630 | rc = device_create_file(kit->dev, &dev_attr_lcd); | ||
631 | if (rc) | ||
632 | goto out4; | ||
633 | |||
634 | } | ||
635 | |||
636 | dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", | ||
637 | ifkit->sensors, ifkit->inputs, ifkit->outputs); | ||
638 | |||
639 | return 0; | ||
640 | |||
641 | out4: | ||
642 | while (i-- > 0) | ||
643 | device_remove_file(kit->dev, &dev_sensor_attrs[i]); | ||
644 | |||
645 | i = ifkit->inputs; | ||
646 | out3: | ||
647 | while (i-- > 0) | ||
648 | device_remove_file(kit->dev, &dev_input_attrs[i]); | ||
649 | |||
650 | i = ifkit->outputs; | ||
651 | out2: | ||
652 | while (i-- > 0) | ||
653 | device_remove_file(kit->dev, &dev_output_attrs[i]); | ||
654 | out: | ||
655 | if (kit) { | ||
656 | usb_free_urb(kit->irq); | ||
657 | if (kit->data) | ||
658 | usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma); | ||
659 | if (kit->dev) | ||
660 | device_unregister(kit->dev); | ||
661 | if (kit->dev_no >= 0) | ||
662 | clear_bit(kit->dev_no, &device_no); | ||
663 | |||
664 | kfree(kit); | ||
665 | } | ||
666 | |||
667 | return rc; | ||
668 | } | ||
669 | |||
670 | static void interfacekit_disconnect(struct usb_interface *interface) | ||
671 | { | ||
672 | struct interfacekit *kit; | ||
673 | int i; | ||
674 | |||
675 | kit = usb_get_intfdata(interface); | ||
676 | usb_set_intfdata(interface, NULL); | ||
677 | if (!kit) | ||
678 | return; | ||
679 | |||
680 | usb_kill_urb(kit->irq); | ||
681 | usb_free_urb(kit->irq); | ||
682 | usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma); | ||
683 | |||
684 | cancel_delayed_work(&kit->do_notify); | ||
685 | cancel_delayed_work(&kit->do_resubmit); | ||
686 | |||
687 | for (i=0; i<kit->ifkit->outputs; i++) | ||
688 | device_remove_file(kit->dev, &dev_output_attrs[i]); | ||
689 | |||
690 | for (i=0; i<kit->ifkit->inputs; i++) | ||
691 | device_remove_file(kit->dev, &dev_input_attrs[i]); | ||
692 | |||
693 | for (i=0; i<kit->ifkit->sensors; i++) | ||
694 | device_remove_file(kit->dev, &dev_sensor_attrs[i]); | ||
695 | |||
696 | if (kit->ifkit->has_lcd) { | ||
697 | device_remove_file(kit->dev, &dev_attr_lcd); | ||
698 | remove_lcd_files(kit); | ||
699 | } | ||
700 | |||
701 | device_unregister(kit->dev); | ||
702 | |||
703 | dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", | ||
704 | kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); | ||
705 | |||
706 | usb_put_dev(kit->udev); | ||
707 | clear_bit(kit->dev_no, &device_no); | ||
708 | |||
709 | kfree(kit); | ||
710 | } | ||
711 | |||
712 | static struct usb_driver interfacekit_driver = { | ||
713 | .name = "phidgetkit", | ||
714 | .probe = interfacekit_probe, | ||
715 | .disconnect = interfacekit_disconnect, | ||
716 | .id_table = id_table | ||
717 | }; | ||
718 | |||
719 | static int __init interfacekit_init(void) | ||
720 | { | ||
721 | int retval = 0; | ||
722 | |||
723 | retval = usb_register(&interfacekit_driver); | ||
724 | if (retval) | ||
725 | err("usb_register failed. Error number %d", retval); | ||
726 | |||
727 | return retval; | ||
728 | } | ||
729 | |||
730 | static void __exit interfacekit_exit(void) | ||
731 | { | ||
732 | usb_deregister(&interfacekit_driver); | ||
733 | } | ||
734 | |||
735 | module_init(interfacekit_init); | ||
736 | module_exit(interfacekit_exit); | ||
737 | |||
738 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
739 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
740 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c deleted file mode 100644 index 38088b44349e..000000000000 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ /dev/null | |||
@@ -1,465 +0,0 @@ | |||
1 | /* | ||
2 | * USB Phidget MotorControl driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Sean Young <sean@mess.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/usb.h> | ||
17 | |||
18 | #include "phidget.h" | ||
19 | |||
20 | #define DRIVER_AUTHOR "Sean Young <sean@mess.org>" | ||
21 | #define DRIVER_DESC "USB PhidgetMotorControl Driver" | ||
22 | |||
23 | #define USB_VENDOR_ID_GLAB 0x06c2 | ||
24 | #define USB_DEVICE_ID_MOTORCONTROL 0x0058 | ||
25 | |||
26 | #define URB_INT_SIZE 8 | ||
27 | |||
28 | static unsigned long device_no; | ||
29 | |||
30 | struct motorcontrol { | ||
31 | struct usb_device *udev; | ||
32 | struct usb_interface *intf; | ||
33 | struct device *dev; | ||
34 | int dev_no; | ||
35 | u8 inputs[4]; | ||
36 | s8 desired_speed[2]; | ||
37 | s8 speed[2]; | ||
38 | s16 _current[2]; | ||
39 | s8 acceleration[2]; | ||
40 | struct urb *irq; | ||
41 | unsigned char *data; | ||
42 | dma_addr_t data_dma; | ||
43 | |||
44 | struct delayed_work do_notify; | ||
45 | unsigned long input_events; | ||
46 | unsigned long speed_events; | ||
47 | unsigned long exceed_events; | ||
48 | }; | ||
49 | |||
50 | static struct usb_device_id id_table[] = { | ||
51 | { USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_MOTORCONTROL) }, | ||
52 | {} | ||
53 | }; | ||
54 | MODULE_DEVICE_TABLE(usb, id_table); | ||
55 | |||
56 | static int set_motor(struct motorcontrol *mc, int motor) | ||
57 | { | ||
58 | u8 *buffer; | ||
59 | int speed, speed2, acceleration; | ||
60 | int retval; | ||
61 | |||
62 | buffer = kzalloc(8, GFP_KERNEL); | ||
63 | if (!buffer) { | ||
64 | dev_err(&mc->intf->dev, "%s - out of memory\n", __func__); | ||
65 | return -ENOMEM; | ||
66 | } | ||
67 | |||
68 | acceleration = mc->acceleration[motor] * 10; | ||
69 | /* -127 <= speed <= 127 */ | ||
70 | speed = (mc->desired_speed[motor] * 127) / 100; | ||
71 | /* -0x7300 <= speed2 <= 0x7300 */ | ||
72 | speed2 = (mc->desired_speed[motor] * 230 * 128) / 100; | ||
73 | |||
74 | buffer[0] = motor; | ||
75 | buffer[1] = speed; | ||
76 | buffer[2] = acceleration >> 8; | ||
77 | buffer[3] = acceleration; | ||
78 | buffer[4] = speed2 >> 8; | ||
79 | buffer[5] = speed2; | ||
80 | |||
81 | retval = usb_control_msg(mc->udev, | ||
82 | usb_sndctrlpipe(mc->udev, 0), | ||
83 | 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000); | ||
84 | |||
85 | if (retval != 8) | ||
86 | dev_err(&mc->intf->dev, "usb_control_msg returned %d\n", | ||
87 | retval); | ||
88 | kfree(buffer); | ||
89 | |||
90 | return retval < 0 ? retval : 0; | ||
91 | } | ||
92 | |||
93 | static void motorcontrol_irq(struct urb *urb) | ||
94 | { | ||
95 | struct motorcontrol *mc = urb->context; | ||
96 | unsigned char *buffer = mc->data; | ||
97 | int i, level; | ||
98 | int retval; | ||
99 | int status = urb->status;; | ||
100 | |||
101 | switch (status) { | ||
102 | case 0: /* success */ | ||
103 | break; | ||
104 | case -ECONNRESET: /* unlink */ | ||
105 | case -ENOENT: | ||
106 | case -ESHUTDOWN: | ||
107 | return; | ||
108 | /* -EPIPE: should clear the halt */ | ||
109 | default: /* error */ | ||
110 | goto resubmit; | ||
111 | } | ||
112 | |||
113 | /* digital inputs */ | ||
114 | for (i=0; i<4; i++) { | ||
115 | level = (buffer[0] >> i) & 1; | ||
116 | if (mc->inputs[i] != level) { | ||
117 | mc->inputs[i] = level; | ||
118 | set_bit(i, &mc->input_events); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | /* motor speed */ | ||
123 | if (buffer[2] == 0) { | ||
124 | for (i=0; i<2; i++) { | ||
125 | level = ((s8)buffer[4+i]) * 100 / 127; | ||
126 | if (mc->speed[i] != level) { | ||
127 | mc->speed[i] = level; | ||
128 | set_bit(i, &mc->speed_events); | ||
129 | } | ||
130 | } | ||
131 | } else { | ||
132 | int index = buffer[3] & 1; | ||
133 | |||
134 | level = ((s8)buffer[4] << 8) | buffer[5]; | ||
135 | level = level * 100 / 29440; | ||
136 | if (mc->speed[index] != level) { | ||
137 | mc->speed[index] = level; | ||
138 | set_bit(index, &mc->speed_events); | ||
139 | } | ||
140 | |||
141 | level = ((s8)buffer[6] << 8) | buffer[7]; | ||
142 | mc->_current[index] = level * 100 / 1572; | ||
143 | } | ||
144 | |||
145 | if (buffer[1] & 1) | ||
146 | set_bit(0, &mc->exceed_events); | ||
147 | |||
148 | if (buffer[1] & 2) | ||
149 | set_bit(1, &mc->exceed_events); | ||
150 | |||
151 | if (mc->input_events || mc->exceed_events || mc->speed_events) | ||
152 | schedule_delayed_work(&mc->do_notify, 0); | ||
153 | |||
154 | resubmit: | ||
155 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
156 | if (retval) | ||
157 | dev_err(&mc->intf->dev, | ||
158 | "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n", | ||
159 | mc->udev->bus->bus_name, | ||
160 | mc->udev->devpath, retval); | ||
161 | } | ||
162 | |||
163 | static void do_notify(struct work_struct *work) | ||
164 | { | ||
165 | struct motorcontrol *mc = | ||
166 | container_of(work, struct motorcontrol, do_notify.work); | ||
167 | int i; | ||
168 | char sysfs_file[8]; | ||
169 | |||
170 | for (i=0; i<4; i++) { | ||
171 | if (test_and_clear_bit(i, &mc->input_events)) { | ||
172 | sprintf(sysfs_file, "input%d", i); | ||
173 | sysfs_notify(&mc->dev->kobj, NULL, sysfs_file); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | for (i=0; i<2; i++) { | ||
178 | if (test_and_clear_bit(i, &mc->speed_events)) { | ||
179 | sprintf(sysfs_file, "speed%d", i); | ||
180 | sysfs_notify(&mc->dev->kobj, NULL, sysfs_file); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | for (i=0; i<2; i++) { | ||
185 | if (test_and_clear_bit(i, &mc->exceed_events)) | ||
186 | dev_warn(&mc->intf->dev, | ||
187 | "motor #%d exceeds 1.5 Amp current limit\n", i); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | #define show_set_speed(value) \ | ||
192 | static ssize_t set_speed##value(struct device *dev, \ | ||
193 | struct device_attribute *attr, \ | ||
194 | const char *buf, size_t count) \ | ||
195 | { \ | ||
196 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
197 | int speed; \ | ||
198 | int retval; \ | ||
199 | \ | ||
200 | if (sscanf(buf, "%d", &speed) < 1) \ | ||
201 | return -EINVAL; \ | ||
202 | \ | ||
203 | if (speed < -100 || speed > 100) \ | ||
204 | return -EINVAL; \ | ||
205 | \ | ||
206 | mc->desired_speed[value] = speed; \ | ||
207 | \ | ||
208 | retval = set_motor(mc, value); \ | ||
209 | \ | ||
210 | return retval ? retval : count; \ | ||
211 | } \ | ||
212 | \ | ||
213 | static ssize_t show_speed##value(struct device *dev, \ | ||
214 | struct device_attribute *attr, \ | ||
215 | char *buf) \ | ||
216 | { \ | ||
217 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
218 | \ | ||
219 | return sprintf(buf, "%d\n", mc->speed[value]); \ | ||
220 | } | ||
221 | |||
222 | #define speed_attr(value) \ | ||
223 | __ATTR(speed##value, S_IWUGO | S_IRUGO, \ | ||
224 | show_speed##value, set_speed##value) | ||
225 | |||
226 | show_set_speed(0); | ||
227 | show_set_speed(1); | ||
228 | |||
229 | #define show_set_acceleration(value) \ | ||
230 | static ssize_t set_acceleration##value(struct device *dev, \ | ||
231 | struct device_attribute *attr, \ | ||
232 | const char *buf, size_t count) \ | ||
233 | { \ | ||
234 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
235 | int acceleration; \ | ||
236 | int retval; \ | ||
237 | \ | ||
238 | if (sscanf(buf, "%d", &acceleration) < 1) \ | ||
239 | return -EINVAL; \ | ||
240 | \ | ||
241 | if (acceleration < 0 || acceleration > 100) \ | ||
242 | return -EINVAL; \ | ||
243 | \ | ||
244 | mc->acceleration[value] = acceleration; \ | ||
245 | \ | ||
246 | retval = set_motor(mc, value); \ | ||
247 | \ | ||
248 | return retval ? retval : count; \ | ||
249 | } \ | ||
250 | \ | ||
251 | static ssize_t show_acceleration##value(struct device *dev, \ | ||
252 | struct device_attribute *attr, \ | ||
253 | char *buf) \ | ||
254 | { \ | ||
255 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
256 | \ | ||
257 | return sprintf(buf, "%d\n", mc->acceleration[value]); \ | ||
258 | } | ||
259 | |||
260 | #define acceleration_attr(value) \ | ||
261 | __ATTR(acceleration##value, S_IWUGO | S_IRUGO, \ | ||
262 | show_acceleration##value, set_acceleration##value) | ||
263 | |||
264 | show_set_acceleration(0); | ||
265 | show_set_acceleration(1); | ||
266 | |||
267 | #define show_current(value) \ | ||
268 | static ssize_t show_current##value(struct device *dev, \ | ||
269 | struct device_attribute *attr, \ | ||
270 | char *buf) \ | ||
271 | { \ | ||
272 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
273 | \ | ||
274 | return sprintf(buf, "%dmA\n", (int)mc->_current[value]); \ | ||
275 | } | ||
276 | |||
277 | #define current_attr(value) \ | ||
278 | __ATTR(current##value, S_IRUGO, show_current##value, NULL) | ||
279 | |||
280 | show_current(0); | ||
281 | show_current(1); | ||
282 | |||
283 | #define show_input(value) \ | ||
284 | static ssize_t show_input##value(struct device *dev, \ | ||
285 | struct device_attribute *attr, \ | ||
286 | char *buf) \ | ||
287 | { \ | ||
288 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
289 | \ | ||
290 | return sprintf(buf, "%d\n", (int)mc->inputs[value]); \ | ||
291 | } | ||
292 | |||
293 | #define input_attr(value) \ | ||
294 | __ATTR(input##value, S_IRUGO, show_input##value, NULL) | ||
295 | |||
296 | show_input(0); | ||
297 | show_input(1); | ||
298 | show_input(2); | ||
299 | show_input(3); | ||
300 | |||
301 | static struct device_attribute dev_attrs[] = { | ||
302 | input_attr(0), | ||
303 | input_attr(1), | ||
304 | input_attr(2), | ||
305 | input_attr(3), | ||
306 | speed_attr(0), | ||
307 | speed_attr(1), | ||
308 | acceleration_attr(0), | ||
309 | acceleration_attr(1), | ||
310 | current_attr(0), | ||
311 | current_attr(1) | ||
312 | }; | ||
313 | |||
314 | static int motorcontrol_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
315 | { | ||
316 | struct usb_device *dev = interface_to_usbdev(intf); | ||
317 | struct usb_host_interface *interface; | ||
318 | struct usb_endpoint_descriptor *endpoint; | ||
319 | struct motorcontrol *mc; | ||
320 | int pipe, maxp, rc = -ENOMEM; | ||
321 | int bit, value, i; | ||
322 | |||
323 | interface = intf->cur_altsetting; | ||
324 | if (interface->desc.bNumEndpoints != 1) | ||
325 | return -ENODEV; | ||
326 | |||
327 | endpoint = &interface->endpoint[0].desc; | ||
328 | if (!usb_endpoint_dir_in(endpoint)) | ||
329 | return -ENODEV; | ||
330 | |||
331 | /* | ||
332 | * bmAttributes | ||
333 | */ | ||
334 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | ||
335 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | ||
336 | |||
337 | mc = kzalloc(sizeof(*mc), GFP_KERNEL); | ||
338 | if (!mc) | ||
339 | goto out; | ||
340 | |||
341 | mc->dev_no = -1; | ||
342 | mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &mc->data_dma); | ||
343 | if (!mc->data) | ||
344 | goto out; | ||
345 | |||
346 | mc->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
347 | if (!mc->irq) | ||
348 | goto out; | ||
349 | |||
350 | mc->udev = usb_get_dev(dev); | ||
351 | mc->intf = intf; | ||
352 | mc->acceleration[0] = mc->acceleration[1] = 10; | ||
353 | INIT_DELAYED_WORK(&mc->do_notify, do_notify); | ||
354 | usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data, | ||
355 | maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, | ||
356 | motorcontrol_irq, mc, endpoint->bInterval); | ||
357 | mc->irq->transfer_dma = mc->data_dma; | ||
358 | mc->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
359 | |||
360 | usb_set_intfdata(intf, mc); | ||
361 | |||
362 | do { | ||
363 | bit = find_first_zero_bit(&device_no, sizeof(device_no)); | ||
364 | value = test_and_set_bit(bit, &device_no); | ||
365 | } while(value); | ||
366 | mc->dev_no = bit; | ||
367 | |||
368 | mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc, | ||
369 | "motorcontrol%d", mc->dev_no); | ||
370 | if (IS_ERR(mc->dev)) { | ||
371 | rc = PTR_ERR(mc->dev); | ||
372 | mc->dev = NULL; | ||
373 | goto out; | ||
374 | } | ||
375 | |||
376 | if (usb_submit_urb(mc->irq, GFP_KERNEL)) { | ||
377 | rc = -EIO; | ||
378 | goto out; | ||
379 | } | ||
380 | |||
381 | for (i=0; i<ARRAY_SIZE(dev_attrs); i++) { | ||
382 | rc = device_create_file(mc->dev, &dev_attrs[i]); | ||
383 | if (rc) | ||
384 | goto out2; | ||
385 | } | ||
386 | |||
387 | dev_info(&intf->dev, "USB PhidgetMotorControl attached\n"); | ||
388 | |||
389 | return 0; | ||
390 | out2: | ||
391 | while (i-- > 0) | ||
392 | device_remove_file(mc->dev, &dev_attrs[i]); | ||
393 | out: | ||
394 | if (mc) { | ||
395 | usb_free_urb(mc->irq); | ||
396 | if (mc->data) | ||
397 | usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma); | ||
398 | if (mc->dev) | ||
399 | device_unregister(mc->dev); | ||
400 | if (mc->dev_no >= 0) | ||
401 | clear_bit(mc->dev_no, &device_no); | ||
402 | |||
403 | kfree(mc); | ||
404 | } | ||
405 | |||
406 | return rc; | ||
407 | } | ||
408 | |||
409 | static void motorcontrol_disconnect(struct usb_interface *interface) | ||
410 | { | ||
411 | struct motorcontrol *mc; | ||
412 | int i; | ||
413 | |||
414 | mc = usb_get_intfdata(interface); | ||
415 | usb_set_intfdata(interface, NULL); | ||
416 | if (!mc) | ||
417 | return; | ||
418 | |||
419 | usb_kill_urb(mc->irq); | ||
420 | usb_free_urb(mc->irq); | ||
421 | usb_buffer_free(mc->udev, URB_INT_SIZE, mc->data, mc->data_dma); | ||
422 | |||
423 | cancel_delayed_work(&mc->do_notify); | ||
424 | |||
425 | for (i=0; i<ARRAY_SIZE(dev_attrs); i++) | ||
426 | device_remove_file(mc->dev, &dev_attrs[i]); | ||
427 | |||
428 | device_unregister(mc->dev); | ||
429 | |||
430 | usb_put_dev(mc->udev); | ||
431 | clear_bit(mc->dev_no, &device_no); | ||
432 | kfree(mc); | ||
433 | |||
434 | dev_info(&interface->dev, "USB PhidgetMotorControl detached\n"); | ||
435 | } | ||
436 | |||
437 | static struct usb_driver motorcontrol_driver = { | ||
438 | .name = "phidgetmotorcontrol", | ||
439 | .probe = motorcontrol_probe, | ||
440 | .disconnect = motorcontrol_disconnect, | ||
441 | .id_table = id_table | ||
442 | }; | ||
443 | |||
444 | static int __init motorcontrol_init(void) | ||
445 | { | ||
446 | int retval = 0; | ||
447 | |||
448 | retval = usb_register(&motorcontrol_driver); | ||
449 | if (retval) | ||
450 | err("usb_register failed. Error number %d", retval); | ||
451 | |||
452 | return retval; | ||
453 | } | ||
454 | |||
455 | static void __exit motorcontrol_exit(void) | ||
456 | { | ||
457 | usb_deregister(&motorcontrol_driver); | ||
458 | } | ||
459 | |||
460 | module_init(motorcontrol_init); | ||
461 | module_exit(motorcontrol_exit); | ||
462 | |||
463 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
464 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
465 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c deleted file mode 100644 index bef6fe16364b..000000000000 --- a/drivers/usb/misc/phidgetservo.c +++ /dev/null | |||
@@ -1,375 +0,0 @@ | |||
1 | /* | ||
2 | * USB PhidgetServo driver 1.0 | ||
3 | * | ||
4 | * Copyright (C) 2004, 2006 Sean Young <sean@mess.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This is a driver for the USB PhidgetServo version 2.0 and 3.0 servo | ||
12 | * controllers available at: http://www.phidgets.com/ | ||
13 | * | ||
14 | * Note that the driver takes input as: degrees.minutes | ||
15 | * | ||
16 | * CAUTION: Generally you should use 0 < degrees < 180 as anything else | ||
17 | * is probably beyond the range of your servo and may damage it. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/usb.h> | ||
26 | |||
27 | #include "phidget.h" | ||
28 | |||
29 | #define DRIVER_AUTHOR "Sean Young <sean@mess.org>" | ||
30 | #define DRIVER_DESC "USB PhidgetServo Driver" | ||
31 | |||
32 | #define VENDOR_ID_GLAB 0x06c2 | ||
33 | #define DEVICE_ID_GLAB_PHIDGETSERVO_QUAD 0x0038 | ||
34 | #define DEVICE_ID_GLAB_PHIDGETSERVO_UNI 0x0039 | ||
35 | |||
36 | #define VENDOR_ID_WISEGROUP 0x0925 | ||
37 | #define VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD 0x8101 | ||
38 | #define VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI 0x8104 | ||
39 | |||
40 | #define SERVO_VERSION_30 0x01 | ||
41 | #define SERVO_COUNT_QUAD 0x02 | ||
42 | |||
43 | static struct usb_device_id id_table[] = { | ||
44 | { | ||
45 | USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_QUAD), | ||
46 | .driver_info = SERVO_VERSION_30 | SERVO_COUNT_QUAD | ||
47 | }, | ||
48 | { | ||
49 | USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_UNI), | ||
50 | .driver_info = SERVO_VERSION_30 | ||
51 | }, | ||
52 | { | ||
53 | USB_DEVICE(VENDOR_ID_WISEGROUP, | ||
54 | VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD), | ||
55 | .driver_info = SERVO_COUNT_QUAD | ||
56 | }, | ||
57 | { | ||
58 | USB_DEVICE(VENDOR_ID_WISEGROUP, | ||
59 | VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI), | ||
60 | .driver_info = 0 | ||
61 | }, | ||
62 | {} | ||
63 | }; | ||
64 | |||
65 | MODULE_DEVICE_TABLE(usb, id_table); | ||
66 | |||
67 | static int unsigned long device_no; | ||
68 | |||
69 | struct phidget_servo { | ||
70 | struct usb_device *udev; | ||
71 | struct device *dev; | ||
72 | int dev_no; | ||
73 | ulong type; | ||
74 | int pulse[4]; | ||
75 | int degrees[4]; | ||
76 | int minutes[4]; | ||
77 | }; | ||
78 | |||
79 | static int | ||
80 | change_position_v30(struct phidget_servo *servo, int servo_no, int degrees, | ||
81 | int minutes) | ||
82 | { | ||
83 | int retval; | ||
84 | unsigned char *buffer; | ||
85 | |||
86 | if (degrees < -23 || degrees > 362) | ||
87 | return -EINVAL; | ||
88 | |||
89 | buffer = kmalloc(6, GFP_KERNEL); | ||
90 | if (!buffer) { | ||
91 | dev_err(&servo->udev->dev, "%s - out of memory\n", | ||
92 | __func__); | ||
93 | return -ENOMEM; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * pulse = 0 - 4095 | ||
98 | * angle = 0 - 180 degrees | ||
99 | * | ||
100 | * pulse = angle * 10.6 + 243.8 | ||
101 | */ | ||
102 | servo->pulse[servo_no] = ((degrees*60 + minutes)*106 + 2438*60)/600; | ||
103 | servo->degrees[servo_no]= degrees; | ||
104 | servo->minutes[servo_no]= minutes; | ||
105 | |||
106 | /* | ||
107 | * The PhidgetServo v3.0 is controlled by sending 6 bytes, | ||
108 | * 4 * 12 bits for each servo. | ||
109 | * | ||
110 | * low = lower 8 bits pulse | ||
111 | * high = higher 4 bits pulse | ||
112 | * | ||
113 | * offset bits | ||
114 | * +---+-----------------+ | ||
115 | * | 0 | low 0 | | ||
116 | * +---+--------+--------+ | ||
117 | * | 1 | high 1 | high 0 | | ||
118 | * +---+--------+--------+ | ||
119 | * | 2 | low 1 | | ||
120 | * +---+-----------------+ | ||
121 | * | 3 | low 2 | | ||
122 | * +---+--------+--------+ | ||
123 | * | 4 | high 3 | high 2 | | ||
124 | * +---+--------+--------+ | ||
125 | * | 5 | low 3 | | ||
126 | * +---+-----------------+ | ||
127 | */ | ||
128 | |||
129 | buffer[0] = servo->pulse[0] & 0xff; | ||
130 | buffer[1] = (servo->pulse[0] >> 8 & 0x0f) | ||
131 | | (servo->pulse[1] >> 4 & 0xf0); | ||
132 | buffer[2] = servo->pulse[1] & 0xff; | ||
133 | buffer[3] = servo->pulse[2] & 0xff; | ||
134 | buffer[4] = (servo->pulse[2] >> 8 & 0x0f) | ||
135 | | (servo->pulse[3] >> 4 & 0xf0); | ||
136 | buffer[5] = servo->pulse[3] & 0xff; | ||
137 | |||
138 | dev_dbg(&servo->udev->dev, | ||
139 | "data: %02x %02x %02x %02x %02x %02x\n", | ||
140 | buffer[0], buffer[1], buffer[2], | ||
141 | buffer[3], buffer[4], buffer[5]); | ||
142 | |||
143 | retval = usb_control_msg(servo->udev, | ||
144 | usb_sndctrlpipe(servo->udev, 0), | ||
145 | 0x09, 0x21, 0x0200, 0x0000, buffer, 6, 2000); | ||
146 | |||
147 | kfree(buffer); | ||
148 | |||
149 | return retval; | ||
150 | } | ||
151 | |||
152 | static int | ||
153 | change_position_v20(struct phidget_servo *servo, int servo_no, int degrees, | ||
154 | int minutes) | ||
155 | { | ||
156 | int retval; | ||
157 | unsigned char *buffer; | ||
158 | |||
159 | if (degrees < -23 || degrees > 278) | ||
160 | return -EINVAL; | ||
161 | |||
162 | buffer = kmalloc(2, GFP_KERNEL); | ||
163 | if (!buffer) { | ||
164 | dev_err(&servo->udev->dev, "%s - out of memory\n", | ||
165 | __func__); | ||
166 | return -ENOMEM; | ||
167 | } | ||
168 | |||
169 | /* | ||
170 | * angle = 0 - 180 degrees | ||
171 | * pulse = angle + 23 | ||
172 | */ | ||
173 | servo->pulse[servo_no]= degrees + 23; | ||
174 | servo->degrees[servo_no]= degrees; | ||
175 | servo->minutes[servo_no]= 0; | ||
176 | |||
177 | /* | ||
178 | * The PhidgetServo v2.0 is controlled by sending two bytes. The | ||
179 | * first byte is the servo number xor'ed with 2: | ||
180 | * | ||
181 | * servo 0 = 2 | ||
182 | * servo 1 = 3 | ||
183 | * servo 2 = 0 | ||
184 | * servo 3 = 1 | ||
185 | * | ||
186 | * The second byte is the position. | ||
187 | */ | ||
188 | |||
189 | buffer[0] = servo_no ^ 2; | ||
190 | buffer[1] = servo->pulse[servo_no]; | ||
191 | |||
192 | dev_dbg(&servo->udev->dev, "data: %02x %02x\n", buffer[0], buffer[1]); | ||
193 | |||
194 | retval = usb_control_msg(servo->udev, | ||
195 | usb_sndctrlpipe(servo->udev, 0), | ||
196 | 0x09, 0x21, 0x0200, 0x0000, buffer, 2, 2000); | ||
197 | |||
198 | kfree(buffer); | ||
199 | |||
200 | return retval; | ||
201 | } | ||
202 | |||
203 | #define show_set(value) \ | ||
204 | static ssize_t set_servo##value (struct device *dev, \ | ||
205 | struct device_attribute *attr, \ | ||
206 | const char *buf, size_t count) \ | ||
207 | { \ | ||
208 | int degrees, minutes, retval; \ | ||
209 | struct phidget_servo *servo = dev_get_drvdata(dev); \ | ||
210 | \ | ||
211 | minutes = 0; \ | ||
212 | /* must at least convert degrees */ \ | ||
213 | if (sscanf(buf, "%d.%d", °rees, &minutes) < 1) { \ | ||
214 | return -EINVAL; \ | ||
215 | } \ | ||
216 | \ | ||
217 | if (minutes < 0 || minutes > 59) \ | ||
218 | return -EINVAL; \ | ||
219 | \ | ||
220 | if (servo->type & SERVO_VERSION_30) \ | ||
221 | retval = change_position_v30(servo, value, degrees, \ | ||
222 | minutes); \ | ||
223 | else \ | ||
224 | retval = change_position_v20(servo, value, degrees, \ | ||
225 | minutes); \ | ||
226 | \ | ||
227 | return retval < 0 ? retval : count; \ | ||
228 | } \ | ||
229 | \ | ||
230 | static ssize_t show_servo##value (struct device *dev, \ | ||
231 | struct device_attribute *attr, \ | ||
232 | char *buf) \ | ||
233 | { \ | ||
234 | struct phidget_servo *servo = dev_get_drvdata(dev); \ | ||
235 | \ | ||
236 | return sprintf(buf, "%d.%02d\n", servo->degrees[value], \ | ||
237 | servo->minutes[value]); \ | ||
238 | } | ||
239 | |||
240 | #define servo_attr(value) \ | ||
241 | __ATTR(servo##value, S_IWUGO | S_IRUGO, \ | ||
242 | show_servo##value, set_servo##value) | ||
243 | show_set(0); | ||
244 | show_set(1); | ||
245 | show_set(2); | ||
246 | show_set(3); | ||
247 | |||
248 | static struct device_attribute dev_attrs[] = { | ||
249 | servo_attr(0), servo_attr(1), servo_attr(2), servo_attr(3) | ||
250 | }; | ||
251 | |||
252 | static int | ||
253 | servo_probe(struct usb_interface *interface, const struct usb_device_id *id) | ||
254 | { | ||
255 | struct usb_device *udev = interface_to_usbdev(interface); | ||
256 | struct phidget_servo *dev; | ||
257 | int bit, value, rc; | ||
258 | int servo_count, i; | ||
259 | |||
260 | dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL); | ||
261 | if (dev == NULL) { | ||
262 | dev_err(&interface->dev, "%s - out of memory\n", __func__); | ||
263 | rc = -ENOMEM; | ||
264 | goto out; | ||
265 | } | ||
266 | |||
267 | dev->udev = usb_get_dev(udev); | ||
268 | dev->type = id->driver_info; | ||
269 | dev->dev_no = -1; | ||
270 | usb_set_intfdata(interface, dev); | ||
271 | |||
272 | do { | ||
273 | bit = find_first_zero_bit(&device_no, sizeof(device_no)); | ||
274 | value = test_and_set_bit(bit, &device_no); | ||
275 | } while (value); | ||
276 | dev->dev_no = bit; | ||
277 | |||
278 | dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0), | ||
279 | dev, "servo%d", dev->dev_no); | ||
280 | if (IS_ERR(dev->dev)) { | ||
281 | rc = PTR_ERR(dev->dev); | ||
282 | dev->dev = NULL; | ||
283 | goto out; | ||
284 | } | ||
285 | |||
286 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; | ||
287 | |||
288 | for (i=0; i<servo_count; i++) { | ||
289 | rc = device_create_file(dev->dev, &dev_attrs[i]); | ||
290 | if (rc) | ||
291 | goto out2; | ||
292 | } | ||
293 | |||
294 | dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n", | ||
295 | servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2); | ||
296 | |||
297 | if (!(dev->type & SERVO_VERSION_30)) | ||
298 | dev_info(&interface->dev, | ||
299 | "WARNING: v2.0 not tested! Please report if it works.\n"); | ||
300 | |||
301 | return 0; | ||
302 | out2: | ||
303 | while (i-- > 0) | ||
304 | device_remove_file(dev->dev, &dev_attrs[i]); | ||
305 | out: | ||
306 | if (dev) { | ||
307 | if (dev->dev) | ||
308 | device_unregister(dev->dev); | ||
309 | if (dev->dev_no >= 0) | ||
310 | clear_bit(dev->dev_no, &device_no); | ||
311 | |||
312 | kfree(dev); | ||
313 | } | ||
314 | |||
315 | return rc; | ||
316 | } | ||
317 | |||
318 | static void | ||
319 | servo_disconnect(struct usb_interface *interface) | ||
320 | { | ||
321 | struct phidget_servo *dev; | ||
322 | int servo_count, i; | ||
323 | |||
324 | dev = usb_get_intfdata(interface); | ||
325 | usb_set_intfdata(interface, NULL); | ||
326 | |||
327 | if (!dev) | ||
328 | return; | ||
329 | |||
330 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; | ||
331 | |||
332 | for (i=0; i<servo_count; i++) | ||
333 | device_remove_file(dev->dev, &dev_attrs[i]); | ||
334 | |||
335 | device_unregister(dev->dev); | ||
336 | usb_put_dev(dev->udev); | ||
337 | |||
338 | dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n", | ||
339 | servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2); | ||
340 | |||
341 | clear_bit(dev->dev_no, &device_no); | ||
342 | kfree(dev); | ||
343 | } | ||
344 | |||
345 | static struct usb_driver servo_driver = { | ||
346 | .name = "phidgetservo", | ||
347 | .probe = servo_probe, | ||
348 | .disconnect = servo_disconnect, | ||
349 | .id_table = id_table | ||
350 | }; | ||
351 | |||
352 | static int __init | ||
353 | phidget_servo_init(void) | ||
354 | { | ||
355 | int retval; | ||
356 | |||
357 | retval = usb_register(&servo_driver); | ||
358 | if (retval) | ||
359 | err("usb_register failed. Error number %d", retval); | ||
360 | |||
361 | return retval; | ||
362 | } | ||
363 | |||
364 | static void __exit | ||
365 | phidget_servo_exit(void) | ||
366 | { | ||
367 | usb_deregister(&servo_driver); | ||
368 | } | ||
369 | |||
370 | module_init(phidget_servo_init); | ||
371 | module_exit(phidget_servo_exit); | ||
372 | |||
373 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
374 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
375 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 4cf27c72423e..f8d9045d668a 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -37,10 +37,13 @@ | |||
37 | #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) | 37 | #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) |
38 | #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) | 38 | #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) |
39 | #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) | 39 | #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) |
40 | /* #9 was MON_IOCT_SETAPI */ | ||
41 | #define MON_IOCX_GETX _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get) | ||
40 | 42 | ||
41 | #ifdef CONFIG_COMPAT | 43 | #ifdef CONFIG_COMPAT |
42 | #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) | 44 | #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) |
43 | #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) | 45 | #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) |
46 | #define MON_IOCX_GETX32 _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get32) | ||
44 | #endif | 47 | #endif |
45 | 48 | ||
46 | /* | 49 | /* |
@@ -92,7 +95,29 @@ struct mon_bin_hdr { | |||
92 | int status; | 95 | int status; |
93 | unsigned int len_urb; /* Length of data (submitted or actual) */ | 96 | unsigned int len_urb; /* Length of data (submitted or actual) */ |
94 | unsigned int len_cap; /* Delivered length */ | 97 | unsigned int len_cap; /* Delivered length */ |
95 | unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ | 98 | union { |
99 | unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ | ||
100 | struct iso_rec { | ||
101 | int error_count; | ||
102 | int numdesc; | ||
103 | } iso; | ||
104 | } s; | ||
105 | int interval; | ||
106 | int start_frame; | ||
107 | unsigned int xfer_flags; | ||
108 | unsigned int ndesc; /* Actual number of ISO descriptors */ | ||
109 | }; | ||
110 | |||
111 | /* | ||
112 | * ISO vector, packed into the head of data stream. | ||
113 | * This has to take 16 bytes to make sure that the end of buffer | ||
114 | * wrap is not happening in the middle of a descriptor. | ||
115 | */ | ||
116 | struct mon_bin_isodesc { | ||
117 | int iso_status; | ||
118 | unsigned int iso_off; | ||
119 | unsigned int iso_len; | ||
120 | u32 _pad; | ||
96 | }; | 121 | }; |
97 | 122 | ||
98 | /* per file statistic */ | 123 | /* per file statistic */ |
@@ -102,7 +127,7 @@ struct mon_bin_stats { | |||
102 | }; | 127 | }; |
103 | 128 | ||
104 | struct mon_bin_get { | 129 | struct mon_bin_get { |
105 | struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */ | 130 | struct mon_bin_hdr __user *hdr; /* Can be 48 bytes or 64. */ |
106 | void __user *data; | 131 | void __user *data; |
107 | size_t alloc; /* Length of data (can be zero) */ | 132 | size_t alloc; /* Length of data (can be zero) */ |
108 | }; | 133 | }; |
@@ -131,6 +156,11 @@ struct mon_bin_mfetch32 { | |||
131 | #define PKT_ALIGN 64 | 156 | #define PKT_ALIGN 64 |
132 | #define PKT_SIZE 64 | 157 | #define PKT_SIZE 64 |
133 | 158 | ||
159 | #define PKT_SZ_API0 48 /* API 0 (2.6.20) size */ | ||
160 | #define PKT_SZ_API1 64 /* API 1 size: extra fields */ | ||
161 | |||
162 | #define ISODESC_MAX 128 /* Same number as usbfs allows, 2048 bytes. */ | ||
163 | |||
134 | /* max number of USB bus supported */ | 164 | /* max number of USB bus supported */ |
135 | #define MON_BIN_MAX_MINOR 128 | 165 | #define MON_BIN_MAX_MINOR 128 |
136 | 166 | ||
@@ -360,12 +390,8 @@ static inline char mon_bin_get_setup(unsigned char *setupb, | |||
360 | const struct urb *urb, char ev_type) | 390 | const struct urb *urb, char ev_type) |
361 | { | 391 | { |
362 | 392 | ||
363 | if (!usb_endpoint_xfer_control(&urb->ep->desc) || ev_type != 'S') | ||
364 | return '-'; | ||
365 | |||
366 | if (urb->setup_packet == NULL) | 393 | if (urb->setup_packet == NULL) |
367 | return 'Z'; | 394 | return 'Z'; |
368 | |||
369 | memcpy(setupb, urb->setup_packet, SETUP_LEN); | 395 | memcpy(setupb, urb->setup_packet, SETUP_LEN); |
370 | return 0; | 396 | return 0; |
371 | } | 397 | } |
@@ -387,6 +413,26 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp, | |||
387 | return 0; | 413 | return 0; |
388 | } | 414 | } |
389 | 415 | ||
416 | static void mon_bin_get_isodesc(const struct mon_reader_bin *rp, | ||
417 | unsigned int offset, struct urb *urb, char ev_type, unsigned int ndesc) | ||
418 | { | ||
419 | struct mon_bin_isodesc *dp; | ||
420 | struct usb_iso_packet_descriptor *fp; | ||
421 | |||
422 | fp = urb->iso_frame_desc; | ||
423 | while (ndesc-- != 0) { | ||
424 | dp = (struct mon_bin_isodesc *) | ||
425 | (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE); | ||
426 | dp->iso_status = fp->status; | ||
427 | dp->iso_off = fp->offset; | ||
428 | dp->iso_len = (ev_type == 'S') ? fp->length : fp->actual_length; | ||
429 | dp->_pad = 0; | ||
430 | if ((offset += sizeof(struct mon_bin_isodesc)) >= rp->b_size) | ||
431 | offset = 0; | ||
432 | fp++; | ||
433 | } | ||
434 | } | ||
435 | |||
390 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | 436 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, |
391 | char ev_type, int status) | 437 | char ev_type, int status) |
392 | { | 438 | { |
@@ -396,6 +442,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
396 | unsigned int urb_length; | 442 | unsigned int urb_length; |
397 | unsigned int offset; | 443 | unsigned int offset; |
398 | unsigned int length; | 444 | unsigned int length; |
445 | unsigned int ndesc, lendesc; | ||
399 | unsigned char dir; | 446 | unsigned char dir; |
400 | struct mon_bin_hdr *ep; | 447 | struct mon_bin_hdr *ep; |
401 | char data_tag = 0; | 448 | char data_tag = 0; |
@@ -407,6 +454,19 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
407 | /* | 454 | /* |
408 | * Find the maximum allowable length, then allocate space. | 455 | * Find the maximum allowable length, then allocate space. |
409 | */ | 456 | */ |
457 | if (usb_endpoint_xfer_isoc(epd)) { | ||
458 | if (urb->number_of_packets < 0) { | ||
459 | ndesc = 0; | ||
460 | } else if (urb->number_of_packets >= ISODESC_MAX) { | ||
461 | ndesc = ISODESC_MAX; | ||
462 | } else { | ||
463 | ndesc = urb->number_of_packets; | ||
464 | } | ||
465 | } else { | ||
466 | ndesc = 0; | ||
467 | } | ||
468 | lendesc = ndesc*sizeof(struct mon_bin_isodesc); | ||
469 | |||
410 | urb_length = (ev_type == 'S') ? | 470 | urb_length = (ev_type == 'S') ? |
411 | urb->transfer_buffer_length : urb->actual_length; | 471 | urb->transfer_buffer_length : urb->actual_length; |
412 | length = urb_length; | 472 | length = urb_length; |
@@ -429,10 +489,12 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
429 | dir = 0; | 489 | dir = 0; |
430 | } | 490 | } |
431 | 491 | ||
432 | if (rp->mmap_active) | 492 | if (rp->mmap_active) { |
433 | offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE); | 493 | offset = mon_buff_area_alloc_contiguous(rp, |
434 | else | 494 | length + PKT_SIZE + lendesc); |
435 | offset = mon_buff_area_alloc(rp, length + PKT_SIZE); | 495 | } else { |
496 | offset = mon_buff_area_alloc(rp, length + PKT_SIZE + lendesc); | ||
497 | } | ||
436 | if (offset == ~0) { | 498 | if (offset == ~0) { |
437 | rp->cnt_lost++; | 499 | rp->cnt_lost++; |
438 | spin_unlock_irqrestore(&rp->b_lock, flags); | 500 | spin_unlock_irqrestore(&rp->b_lock, flags); |
@@ -456,9 +518,31 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
456 | ep->ts_usec = ts.tv_usec; | 518 | ep->ts_usec = ts.tv_usec; |
457 | ep->status = status; | 519 | ep->status = status; |
458 | ep->len_urb = urb_length; | 520 | ep->len_urb = urb_length; |
459 | ep->len_cap = length; | 521 | ep->len_cap = length + lendesc; |
522 | ep->xfer_flags = urb->transfer_flags; | ||
523 | |||
524 | if (usb_endpoint_xfer_int(epd)) { | ||
525 | ep->interval = urb->interval; | ||
526 | } else if (usb_endpoint_xfer_isoc(epd)) { | ||
527 | ep->interval = urb->interval; | ||
528 | ep->start_frame = urb->start_frame; | ||
529 | ep->s.iso.error_count = urb->error_count; | ||
530 | ep->s.iso.numdesc = urb->number_of_packets; | ||
531 | } | ||
532 | |||
533 | if (usb_endpoint_xfer_control(epd) && ev_type == 'S') { | ||
534 | ep->flag_setup = mon_bin_get_setup(ep->s.setup, urb, ev_type); | ||
535 | } else { | ||
536 | ep->flag_setup = '-'; | ||
537 | } | ||
538 | |||
539 | if (ndesc != 0) { | ||
540 | ep->ndesc = ndesc; | ||
541 | mon_bin_get_isodesc(rp, offset, urb, ev_type, ndesc); | ||
542 | if ((offset += lendesc) >= rp->b_size) | ||
543 | offset -= rp->b_size; | ||
544 | } | ||
460 | 545 | ||
461 | ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type); | ||
462 | if (length != 0) { | 546 | if (length != 0) { |
463 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); | 547 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); |
464 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ | 548 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ |
@@ -592,7 +676,8 @@ err_alloc: | |||
592 | * Returns zero or error. | 676 | * Returns zero or error. |
593 | */ | 677 | */ |
594 | static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, | 678 | static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, |
595 | struct mon_bin_hdr __user *hdr, void __user *data, unsigned int nbytes) | 679 | struct mon_bin_hdr __user *hdr, unsigned int hdrbytes, |
680 | void __user *data, unsigned int nbytes) | ||
596 | { | 681 | { |
597 | unsigned long flags; | 682 | unsigned long flags; |
598 | struct mon_bin_hdr *ep; | 683 | struct mon_bin_hdr *ep; |
@@ -609,7 +694,7 @@ static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, | |||
609 | 694 | ||
610 | ep = MON_OFF2HDR(rp, rp->b_out); | 695 | ep = MON_OFF2HDR(rp, rp->b_out); |
611 | 696 | ||
612 | if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) { | 697 | if (copy_to_user(hdr, ep, hdrbytes)) { |
613 | mutex_unlock(&rp->fetch_lock); | 698 | mutex_unlock(&rp->fetch_lock); |
614 | return -EFAULT; | 699 | return -EFAULT; |
615 | } | 700 | } |
@@ -657,6 +742,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
657 | size_t nbytes, loff_t *ppos) | 742 | size_t nbytes, loff_t *ppos) |
658 | { | 743 | { |
659 | struct mon_reader_bin *rp = file->private_data; | 744 | struct mon_reader_bin *rp = file->private_data; |
745 | unsigned int hdrbytes = PKT_SZ_API0; | ||
660 | unsigned long flags; | 746 | unsigned long flags; |
661 | struct mon_bin_hdr *ep; | 747 | struct mon_bin_hdr *ep; |
662 | unsigned int offset; | 748 | unsigned int offset; |
@@ -674,8 +760,8 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
674 | 760 | ||
675 | ep = MON_OFF2HDR(rp, rp->b_out); | 761 | ep = MON_OFF2HDR(rp, rp->b_out); |
676 | 762 | ||
677 | if (rp->b_read < sizeof(struct mon_bin_hdr)) { | 763 | if (rp->b_read < hdrbytes) { |
678 | step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read); | 764 | step_len = min(nbytes, (size_t)(hdrbytes - rp->b_read)); |
679 | ptr = ((char *)ep) + rp->b_read; | 765 | ptr = ((char *)ep) + rp->b_read; |
680 | if (step_len && copy_to_user(buf, ptr, step_len)) { | 766 | if (step_len && copy_to_user(buf, ptr, step_len)) { |
681 | mutex_unlock(&rp->fetch_lock); | 767 | mutex_unlock(&rp->fetch_lock); |
@@ -687,13 +773,13 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
687 | done += step_len; | 773 | done += step_len; |
688 | } | 774 | } |
689 | 775 | ||
690 | if (rp->b_read >= sizeof(struct mon_bin_hdr)) { | 776 | if (rp->b_read >= hdrbytes) { |
691 | step_len = ep->len_cap; | 777 | step_len = ep->len_cap; |
692 | step_len -= rp->b_read - sizeof(struct mon_bin_hdr); | 778 | step_len -= rp->b_read - hdrbytes; |
693 | if (step_len > nbytes) | 779 | if (step_len > nbytes) |
694 | step_len = nbytes; | 780 | step_len = nbytes; |
695 | offset = rp->b_out + PKT_SIZE; | 781 | offset = rp->b_out + PKT_SIZE; |
696 | offset += rp->b_read - sizeof(struct mon_bin_hdr); | 782 | offset += rp->b_read - hdrbytes; |
697 | if (offset >= rp->b_size) | 783 | if (offset >= rp->b_size) |
698 | offset -= rp->b_size; | 784 | offset -= rp->b_size; |
699 | if (copy_from_buf(rp, offset, buf, step_len)) { | 785 | if (copy_from_buf(rp, offset, buf, step_len)) { |
@@ -709,7 +795,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
709 | /* | 795 | /* |
710 | * Check if whole packet was read, and if so, jump to the next one. | 796 | * Check if whole packet was read, and if so, jump to the next one. |
711 | */ | 797 | */ |
712 | if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) { | 798 | if (rp->b_read >= hdrbytes + ep->len_cap) { |
713 | spin_lock_irqsave(&rp->b_lock, flags); | 799 | spin_lock_irqsave(&rp->b_lock, flags); |
714 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | 800 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); |
715 | spin_unlock_irqrestore(&rp->b_lock, flags); | 801 | spin_unlock_irqrestore(&rp->b_lock, flags); |
@@ -908,6 +994,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | |||
908 | break; | 994 | break; |
909 | 995 | ||
910 | case MON_IOCX_GET: | 996 | case MON_IOCX_GET: |
997 | case MON_IOCX_GETX: | ||
911 | { | 998 | { |
912 | struct mon_bin_get getb; | 999 | struct mon_bin_get getb; |
913 | 1000 | ||
@@ -917,8 +1004,9 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | |||
917 | 1004 | ||
918 | if (getb.alloc > 0x10000000) /* Want to cast to u32 */ | 1005 | if (getb.alloc > 0x10000000) /* Want to cast to u32 */ |
919 | return -EINVAL; | 1006 | return -EINVAL; |
920 | ret = mon_bin_get_event(file, rp, | 1007 | ret = mon_bin_get_event(file, rp, getb.hdr, |
921 | getb.hdr, getb.data, (unsigned int)getb.alloc); | 1008 | (cmd == MON_IOCX_GET)? PKT_SZ_API0: PKT_SZ_API1, |
1009 | getb.data, (unsigned int)getb.alloc); | ||
922 | } | 1010 | } |
923 | break; | 1011 | break; |
924 | 1012 | ||
@@ -984,16 +1072,18 @@ static long mon_bin_compat_ioctl(struct file *file, | |||
984 | 1072 | ||
985 | switch (cmd) { | 1073 | switch (cmd) { |
986 | 1074 | ||
987 | case MON_IOCX_GET32: { | 1075 | case MON_IOCX_GET32: |
1076 | case MON_IOCX_GETX32: | ||
1077 | { | ||
988 | struct mon_bin_get32 getb; | 1078 | struct mon_bin_get32 getb; |
989 | 1079 | ||
990 | if (copy_from_user(&getb, (void __user *)arg, | 1080 | if (copy_from_user(&getb, (void __user *)arg, |
991 | sizeof(struct mon_bin_get32))) | 1081 | sizeof(struct mon_bin_get32))) |
992 | return -EFAULT; | 1082 | return -EFAULT; |
993 | 1083 | ||
994 | ret = mon_bin_get_event(file, rp, | 1084 | ret = mon_bin_get_event(file, rp, compat_ptr(getb.hdr32), |
995 | compat_ptr(getb.hdr32), compat_ptr(getb.data32), | 1085 | (cmd == MON_IOCX_GET32)? PKT_SZ_API0: PKT_SZ_API1, |
996 | getb.alloc32); | 1086 | compat_ptr(getb.data32), getb.alloc32); |
997 | if (ret < 0) | 1087 | if (ret < 0) |
998 | return ret; | 1088 | return ret; |
999 | } | 1089 | } |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 9985db08e7db..b66e8544d8b9 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -20,8 +20,8 @@ config USB_MUSB_HDRC | |||
20 | it's being used with, including the USB peripheral role, | 20 | it's being used with, including the USB peripheral role, |
21 | or the USB host role, or both. | 21 | or the USB host role, or both. |
22 | 22 | ||
23 | Texas Instruments parts using this IP include DaVinci 644x, | 23 | Texas Instruments familiies using this IP include DaVinci |
24 | OMAP 243x, OMAP 343x, and TUSB 6010. | 24 | (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010. |
25 | 25 | ||
26 | Analog Devices parts using this IP include Blackfin BF54x, | 26 | Analog Devices parts using this IP include Blackfin BF54x, |
27 | BF525 and BF527. | 27 | BF525 and BF527. |
@@ -40,7 +40,7 @@ config USB_MUSB_SOC | |||
40 | default y if (BF54x && !BF544) | 40 | default y if (BF54x && !BF544) |
41 | default y if (BF52x && !BF522 && !BF523) | 41 | default y if (BF52x && !BF522 && !BF523) |
42 | 42 | ||
43 | comment "DaVinci 644x USB support" | 43 | comment "DaVinci 35x and 644x USB support" |
44 | depends on USB_MUSB_HDRC && ARCH_DAVINCI | 44 | depends on USB_MUSB_HDRC && ARCH_DAVINCI |
45 | 45 | ||
46 | comment "OMAP 243x high speed USB support" | 46 | comment "OMAP 243x high speed USB support" |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 2dc7606f319c..10d11ab113ab 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -48,6 +48,9 @@ | |||
48 | #include "cppi_dma.h" | 48 | #include "cppi_dma.h" |
49 | 49 | ||
50 | 50 | ||
51 | #define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) | ||
52 | #define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) | ||
53 | |||
51 | /* REVISIT (PM) we should be able to keep the PHY in low power mode most | 54 | /* REVISIT (PM) we should be able to keep the PHY in low power mode most |
52 | * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 | 55 | * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 |
53 | * and, when in host mode, autosuspending idle root ports... PHYPLLON | 56 | * and, when in host mode, autosuspending idle root ports... PHYPLLON |
@@ -56,20 +59,26 @@ | |||
56 | 59 | ||
57 | static inline void phy_on(void) | 60 | static inline void phy_on(void) |
58 | { | 61 | { |
59 | /* start the on-chip PHY and its PLL */ | 62 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); |
60 | __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON, | 63 | |
61 | (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR)); | 64 | /* power everything up; start the on-chip PHY and its PLL */ |
62 | while ((__raw_readl((void __force __iomem *) | 65 | phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN); |
63 | IO_ADDRESS(USBPHY_CTL_PADDR)) | 66 | phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON; |
64 | & USBPHY_PHYCLKGD) == 0) | 67 | __raw_writel(phy_ctrl, USB_PHY_CTRL); |
68 | |||
69 | /* wait for PLL to lock before proceeding */ | ||
70 | while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0) | ||
65 | cpu_relax(); | 71 | cpu_relax(); |
66 | } | 72 | } |
67 | 73 | ||
68 | static inline void phy_off(void) | 74 | static inline void phy_off(void) |
69 | { | 75 | { |
70 | /* powerdown the on-chip PHY and its oscillator */ | 76 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); |
71 | __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *) | 77 | |
72 | IO_ADDRESS(USBPHY_CTL_PADDR)); | 78 | /* powerdown the on-chip PHY, its PLL, and the OTG block */ |
79 | phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON); | ||
80 | phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN; | ||
81 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | ||
73 | } | 82 | } |
74 | 83 | ||
75 | static int dma_off = 1; | 84 | static int dma_off = 1; |
@@ -126,10 +135,6 @@ void musb_platform_disable(struct musb *musb) | |||
126 | } | 135 | } |
127 | 136 | ||
128 | 137 | ||
129 | /* REVISIT it's not clear whether DaVinci can support full OTG. */ | ||
130 | |||
131 | static int vbus_state = -1; | ||
132 | |||
133 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 138 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
134 | #define portstate(stmt) stmt | 139 | #define portstate(stmt) stmt |
135 | #else | 140 | #else |
@@ -137,10 +142,19 @@ static int vbus_state = -1; | |||
137 | #endif | 142 | #endif |
138 | 143 | ||
139 | 144 | ||
140 | /* VBUS SWITCHING IS BOARD-SPECIFIC */ | 145 | /* |
146 | * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM, | ||
147 | * which doesn't wire DRVVBUS to the FET that switches it. Unclear | ||
148 | * if that's a problem with the DM6446 chip or just with that board. | ||
149 | * | ||
150 | * In either case, the DM355 EVM automates DRVVBUS the normal way, | ||
151 | * when J10 is out, and TI documents it as handling OTG. | ||
152 | */ | ||
141 | 153 | ||
142 | #ifdef CONFIG_MACH_DAVINCI_EVM | 154 | #ifdef CONFIG_MACH_DAVINCI_EVM |
143 | 155 | ||
156 | static int vbus_state = -1; | ||
157 | |||
144 | /* I2C operations are always synchronous, and require a task context. | 158 | /* I2C operations are always synchronous, and require a task context. |
145 | * With unloaded systems, using the shared workqueue seems to suffice | 159 | * With unloaded systems, using the shared workqueue seems to suffice |
146 | * to satisfy the 100msec A_WAIT_VRISE timeout... | 160 | * to satisfy the 100msec A_WAIT_VRISE timeout... |
@@ -150,12 +164,12 @@ static void evm_deferred_drvvbus(struct work_struct *ignored) | |||
150 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); | 164 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); |
151 | vbus_state = !vbus_state; | 165 | vbus_state = !vbus_state; |
152 | } | 166 | } |
153 | static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); | ||
154 | 167 | ||
155 | #endif /* EVM */ | 168 | #endif /* EVM */ |
156 | 169 | ||
157 | static void davinci_source_power(struct musb *musb, int is_on, int immediate) | 170 | static void davinci_source_power(struct musb *musb, int is_on, int immediate) |
158 | { | 171 | { |
172 | #ifdef CONFIG_MACH_DAVINCI_EVM | ||
159 | if (is_on) | 173 | if (is_on) |
160 | is_on = 1; | 174 | is_on = 1; |
161 | 175 | ||
@@ -163,16 +177,17 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate) | |||
163 | return; | 177 | return; |
164 | vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ | 178 | vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ |
165 | 179 | ||
166 | #ifdef CONFIG_MACH_DAVINCI_EVM | ||
167 | if (machine_is_davinci_evm()) { | 180 | if (machine_is_davinci_evm()) { |
181 | static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); | ||
182 | |||
168 | if (immediate) | 183 | if (immediate) |
169 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); | 184 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); |
170 | else | 185 | else |
171 | schedule_work(&evm_vbus_work); | 186 | schedule_work(&evm_vbus_work); |
172 | } | 187 | } |
173 | #endif | ||
174 | if (immediate) | 188 | if (immediate) |
175 | vbus_state = is_on; | 189 | vbus_state = is_on; |
190 | #endif | ||
176 | } | 191 | } |
177 | 192 | ||
178 | static void davinci_set_vbus(struct musb *musb, int is_on) | 193 | static void davinci_set_vbus(struct musb *musb, int is_on) |
@@ -391,6 +406,17 @@ int __init musb_platform_init(struct musb *musb) | |||
391 | musb->board_set_vbus = davinci_set_vbus; | 406 | musb->board_set_vbus = davinci_set_vbus; |
392 | davinci_source_power(musb, 0, 1); | 407 | davinci_source_power(musb, 0, 1); |
393 | 408 | ||
409 | /* dm355 EVM swaps D+/D- for signal integrity, and | ||
410 | * is clocked from the main 24 MHz crystal. | ||
411 | */ | ||
412 | if (machine_is_davinci_dm355_evm()) { | ||
413 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); | ||
414 | |||
415 | phy_ctrl &= ~(3 << 9); | ||
416 | phy_ctrl |= USBPHY_DATAPOL; | ||
417 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | ||
418 | } | ||
419 | |||
394 | /* reset the controller */ | 420 | /* reset the controller */ |
395 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); | 421 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); |
396 | 422 | ||
@@ -401,8 +427,7 @@ int __init musb_platform_init(struct musb *musb) | |||
401 | 427 | ||
402 | /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ | 428 | /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ |
403 | pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", | 429 | pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", |
404 | revision, __raw_readl((void __force __iomem *) | 430 | revision, __raw_readl(USB_PHY_CTRL), |
405 | IO_ADDRESS(USBPHY_CTL_PADDR)), | ||
406 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); | 431 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); |
407 | 432 | ||
408 | musb->isr = davinci_interrupt; | 433 | musb->isr = davinci_interrupt; |
diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h index 7fb6238e270f..046c84433cad 100644 --- a/drivers/usb/musb/davinci.h +++ b/drivers/usb/musb/davinci.h | |||
@@ -15,14 +15,21 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* Integrated highspeed/otg PHY */ | 17 | /* Integrated highspeed/otg PHY */ |
18 | #define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) | 18 | #define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) |
19 | #define USBPHY_PHYCLKGD (1 << 8) | 19 | #define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */ |
20 | #define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */ | 20 | #define USBPHY_PHYCLKGD BIT(8) |
21 | #define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */ | 21 | #define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */ |
22 | #define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */ | 22 | #define USBPHY_VBDTCTEN BIT(6) /* v(bus) comparator */ |
23 | #define USBPHY_CLKO1SEL (1 << 3) | 23 | #define USBPHY_VBUSSENS BIT(5) /* (dm355,ro) is vbus > 0.5V */ |
24 | #define USBPHY_OSCPDWN (1 << 2) | 24 | #define USBPHY_PHYPLLON BIT(4) /* override pll suspend */ |
25 | #define USBPHY_PHYPDWN (1 << 0) | 25 | #define USBPHY_CLKO1SEL BIT(3) |
26 | #define USBPHY_OSCPDWN BIT(2) | ||
27 | #define USBPHY_OTGPDWN BIT(1) | ||
28 | #define USBPHY_PHYPDWN BIT(0) | ||
29 | |||
30 | #define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48) | ||
31 | #define DRVVBUS_FORCE BIT(2) | ||
32 | #define DRVVBUS_OVERRIDE BIT(1) | ||
26 | 33 | ||
27 | /* For now include usb OTG module registers here */ | 34 | /* For now include usb OTG module registers here */ |
28 | #define DAVINCI_USB_VERSION_REG 0x00 | 35 | #define DAVINCI_USB_VERSION_REG 0x00 |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index af77e4659006..338cd1611ab3 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -769,7 +769,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | |||
769 | case OTG_STATE_A_SUSPEND: | 769 | case OTG_STATE_A_SUSPEND: |
770 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | 770 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); |
771 | musb_root_disconnect(musb); | 771 | musb_root_disconnect(musb); |
772 | if (musb->a_wait_bcon != 0) | 772 | if (musb->a_wait_bcon != 0 && is_otg_enabled(musb)) |
773 | musb_platform_try_idle(musb, jiffies | 773 | musb_platform_try_idle(musb, jiffies |
774 | + msecs_to_jiffies(musb->a_wait_bcon)); | 774 | + msecs_to_jiffies(musb->a_wait_bcon)); |
775 | break; | 775 | break; |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 630946a2d9fc..efb39b5e55b5 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -331,7 +331,6 @@ struct musb { | |||
331 | struct list_head control; /* of musb_qh */ | 331 | struct list_head control; /* of musb_qh */ |
332 | struct list_head in_bulk; /* of musb_qh */ | 332 | struct list_head in_bulk; /* of musb_qh */ |
333 | struct list_head out_bulk; /* of musb_qh */ | 333 | struct list_head out_bulk; /* of musb_qh */ |
334 | struct musb_qh *periodic[32]; /* tree of interrupt+iso */ | ||
335 | #endif | 334 | #endif |
336 | 335 | ||
337 | /* called with IRQs blocked; ON/nonzero implies starting a session, | 336 | /* called with IRQs blocked; ON/nonzero implies starting a session, |
@@ -479,10 +478,11 @@ static inline void musb_configure_ep0(struct musb *musb) | |||
479 | static inline int musb_read_fifosize(struct musb *musb, | 478 | static inline int musb_read_fifosize(struct musb *musb, |
480 | struct musb_hw_ep *hw_ep, u8 epnum) | 479 | struct musb_hw_ep *hw_ep, u8 epnum) |
481 | { | 480 | { |
481 | void *mbase = musb->mregs; | ||
482 | u8 reg = 0; | 482 | u8 reg = 0; |
483 | 483 | ||
484 | /* read from core using indexed model */ | 484 | /* read from core using indexed model */ |
485 | reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE); | 485 | reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE)); |
486 | /* 0's returned when no more endpoints */ | 486 | /* 0's returned when no more endpoints */ |
487 | if (!reg) | 487 | if (!reg) |
488 | return -ENODEV; | 488 | return -ENODEV; |
@@ -509,6 +509,7 @@ static inline void musb_configure_ep0(struct musb *musb) | |||
509 | { | 509 | { |
510 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; | 510 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; |
511 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; | 511 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; |
512 | musb->endpoints[0].is_shared_fifo = true; | ||
512 | } | 513 | } |
513 | #endif /* CONFIG_BLACKFIN */ | 514 | #endif /* CONFIG_BLACKFIN */ |
514 | 515 | ||
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 6dbbd0786a6a..499c431a6d62 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -64,11 +64,8 @@ | |||
64 | * | 64 | * |
65 | * - DMA (Mentor/OMAP) ...has at least toggle update problems | 65 | * - DMA (Mentor/OMAP) ...has at least toggle update problems |
66 | * | 66 | * |
67 | * - Still no traffic scheduling code to make NAKing for bulk or control | 67 | * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet |
68 | * transfers unable to starve other requests; or to make efficient use | 68 | * starvation ... nothing yet for TX, interrupt, or bulk. |
69 | * of hardware with periodic transfers. (Note that network drivers | ||
70 | * commonly post bulk reads that stay pending for a long time; these | ||
71 | * would make very visible trouble.) | ||
72 | * | 69 | * |
73 | * - Not tested with HNP, but some SRP paths seem to behave. | 70 | * - Not tested with HNP, but some SRP paths seem to behave. |
74 | * | 71 | * |
@@ -88,11 +85,8 @@ | |||
88 | * | 85 | * |
89 | * CONTROL transfers all go through ep0. BULK ones go through dedicated IN | 86 | * CONTROL transfers all go through ep0. BULK ones go through dedicated IN |
90 | * and OUT endpoints ... hardware is dedicated for those "async" queue(s). | 87 | * and OUT endpoints ... hardware is dedicated for those "async" queue(s). |
91 | * | ||
92 | * (Yes, bulk _could_ use more of the endpoints than that, and would even | 88 | * (Yes, bulk _could_ use more of the endpoints than that, and would even |
93 | * benefit from it ... one remote device may easily be NAKing while others | 89 | * benefit from it.) |
94 | * need to perform transfers in that same direction. The same thing could | ||
95 | * be done in software though, assuming dma cooperates.) | ||
96 | * | 90 | * |
97 | * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints. | 91 | * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints. |
98 | * So far that scheduling is both dumb and optimistic: the endpoint will be | 92 | * So far that scheduling is both dumb and optimistic: the endpoint will be |
@@ -201,8 +195,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
201 | len = urb->iso_frame_desc[0].length; | 195 | len = urb->iso_frame_desc[0].length; |
202 | break; | 196 | break; |
203 | default: /* bulk, interrupt */ | 197 | default: /* bulk, interrupt */ |
204 | buf = urb->transfer_buffer; | 198 | /* actual_length may be nonzero on retry paths */ |
205 | len = urb->transfer_buffer_length; | 199 | buf = urb->transfer_buffer + urb->actual_length; |
200 | len = urb->transfer_buffer_length - urb->actual_length; | ||
206 | } | 201 | } |
207 | 202 | ||
208 | DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n", | 203 | DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n", |
@@ -395,7 +390,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | |||
395 | * de-allocated if it's tracked and allocated; | 390 | * de-allocated if it's tracked and allocated; |
396 | * and where we'd update the schedule tree... | 391 | * and where we'd update the schedule tree... |
397 | */ | 392 | */ |
398 | musb->periodic[ep->epnum] = NULL; | ||
399 | kfree(qh); | 393 | kfree(qh); |
400 | qh = NULL; | 394 | qh = NULL; |
401 | break; | 395 | break; |
@@ -1045,7 +1039,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
1045 | 1039 | ||
1046 | /* NOTE: this code path would be a good place to PAUSE a | 1040 | /* NOTE: this code path would be a good place to PAUSE a |
1047 | * control transfer, if another one is queued, so that | 1041 | * control transfer, if another one is queued, so that |
1048 | * ep0 is more likely to stay busy. | 1042 | * ep0 is more likely to stay busy. That's already done |
1043 | * for bulk RX transfers. | ||
1049 | * | 1044 | * |
1050 | * if (qh->ring.next != &musb->control), then | 1045 | * if (qh->ring.next != &musb->control), then |
1051 | * we have a candidate... NAKing is *NOT* an error | 1046 | * we have a candidate... NAKing is *NOT* an error |
@@ -1197,6 +1192,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1197 | /* NOTE: this code path would be a good place to PAUSE a | 1192 | /* NOTE: this code path would be a good place to PAUSE a |
1198 | * transfer, if there's some other (nonperiodic) tx urb | 1193 | * transfer, if there's some other (nonperiodic) tx urb |
1199 | * that could use this fifo. (dma complicates it...) | 1194 | * that could use this fifo. (dma complicates it...) |
1195 | * That's already done for bulk RX transfers. | ||
1200 | * | 1196 | * |
1201 | * if (bulk && qh->ring.next != &musb->out_bulk), then | 1197 | * if (bulk && qh->ring.next != &musb->out_bulk), then |
1202 | * we have a candidate... NAKing is *NOT* an error | 1198 | * we have a candidate... NAKing is *NOT* an error |
@@ -1358,6 +1354,50 @@ finish: | |||
1358 | 1354 | ||
1359 | #endif | 1355 | #endif |
1360 | 1356 | ||
1357 | /* Schedule next QH from musb->in_bulk and move the current qh to | ||
1358 | * the end; avoids starvation for other endpoints. | ||
1359 | */ | ||
1360 | static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep) | ||
1361 | { | ||
1362 | struct dma_channel *dma; | ||
1363 | struct urb *urb; | ||
1364 | void __iomem *mbase = musb->mregs; | ||
1365 | void __iomem *epio = ep->regs; | ||
1366 | struct musb_qh *cur_qh, *next_qh; | ||
1367 | u16 rx_csr; | ||
1368 | |||
1369 | musb_ep_select(mbase, ep->epnum); | ||
1370 | dma = is_dma_capable() ? ep->rx_channel : NULL; | ||
1371 | |||
1372 | /* clear nak timeout bit */ | ||
1373 | rx_csr = musb_readw(epio, MUSB_RXCSR); | ||
1374 | rx_csr |= MUSB_RXCSR_H_WZC_BITS; | ||
1375 | rx_csr &= ~MUSB_RXCSR_DATAERROR; | ||
1376 | musb_writew(epio, MUSB_RXCSR, rx_csr); | ||
1377 | |||
1378 | cur_qh = first_qh(&musb->in_bulk); | ||
1379 | if (cur_qh) { | ||
1380 | urb = next_urb(cur_qh); | ||
1381 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | ||
1382 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; | ||
1383 | musb->dma_controller->channel_abort(dma); | ||
1384 | urb->actual_length += dma->actual_len; | ||
1385 | dma->actual_len = 0L; | ||
1386 | } | ||
1387 | musb_save_toggle(ep, 1, urb); | ||
1388 | |||
1389 | /* move cur_qh to end of queue */ | ||
1390 | list_move_tail(&cur_qh->ring, &musb->in_bulk); | ||
1391 | |||
1392 | /* get the next qh from musb->in_bulk */ | ||
1393 | next_qh = first_qh(&musb->in_bulk); | ||
1394 | |||
1395 | /* set rx_reinit and schedule the next qh */ | ||
1396 | ep->rx_reinit = 1; | ||
1397 | musb_start_urb(musb, 1, next_qh); | ||
1398 | } | ||
1399 | } | ||
1400 | |||
1361 | /* | 1401 | /* |
1362 | * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso, | 1402 | * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso, |
1363 | * and high-bandwidth IN transfer cases. | 1403 | * and high-bandwidth IN transfer cases. |
@@ -1421,18 +1461,26 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1421 | } else if (rx_csr & MUSB_RXCSR_DATAERROR) { | 1461 | } else if (rx_csr & MUSB_RXCSR_DATAERROR) { |
1422 | 1462 | ||
1423 | if (USB_ENDPOINT_XFER_ISOC != qh->type) { | 1463 | if (USB_ENDPOINT_XFER_ISOC != qh->type) { |
1424 | /* NOTE this code path would be a good place to PAUSE a | 1464 | DBG(6, "RX end %d NAK timeout\n", epnum); |
1425 | * transfer, if there's some other (nonperiodic) rx urb | 1465 | |
1426 | * that could use this fifo. (dma complicates it...) | 1466 | /* NOTE: NAKing is *NOT* an error, so we want to |
1467 | * continue. Except ... if there's a request for | ||
1468 | * another QH, use that instead of starving it. | ||
1427 | * | 1469 | * |
1428 | * if (bulk && qh->ring.next != &musb->in_bulk), then | 1470 | * Devices like Ethernet and serial adapters keep |
1429 | * we have a candidate... NAKing is *NOT* an error | 1471 | * reads posted at all times, which will starve |
1472 | * other devices without this logic. | ||
1430 | */ | 1473 | */ |
1431 | DBG(6, "RX end %d NAK timeout\n", epnum); | 1474 | if (usb_pipebulk(urb->pipe) |
1475 | && qh->mux == 1 | ||
1476 | && !list_is_singular(&musb->in_bulk)) { | ||
1477 | musb_bulk_rx_nak_timeout(musb, hw_ep); | ||
1478 | return; | ||
1479 | } | ||
1432 | musb_ep_select(mbase, epnum); | 1480 | musb_ep_select(mbase, epnum); |
1433 | musb_writew(epio, MUSB_RXCSR, | 1481 | rx_csr |= MUSB_RXCSR_H_WZC_BITS; |
1434 | MUSB_RXCSR_H_WZC_BITS | 1482 | rx_csr &= ~MUSB_RXCSR_DATAERROR; |
1435 | | MUSB_RXCSR_H_REQPKT); | 1483 | musb_writew(epio, MUSB_RXCSR, rx_csr); |
1436 | 1484 | ||
1437 | goto finish; | 1485 | goto finish; |
1438 | } else { | 1486 | } else { |
@@ -1711,31 +1759,27 @@ static int musb_schedule( | |||
1711 | 1759 | ||
1712 | /* else, periodic transfers get muxed to other endpoints */ | 1760 | /* else, periodic transfers get muxed to other endpoints */ |
1713 | 1761 | ||
1714 | /* FIXME this doesn't consider direction, so it can only | 1762 | /* |
1715 | * work for one half of the endpoint hardware, and assumes | 1763 | * We know this qh hasn't been scheduled, so all we need to do |
1716 | * the previous cases handled all non-shared endpoints... | ||
1717 | */ | ||
1718 | |||
1719 | /* we know this qh hasn't been scheduled, so all we need to do | ||
1720 | * is choose which hardware endpoint to put it on ... | 1764 | * is choose which hardware endpoint to put it on ... |
1721 | * | 1765 | * |
1722 | * REVISIT what we really want here is a regular schedule tree | 1766 | * REVISIT what we really want here is a regular schedule tree |
1723 | * like e.g. OHCI uses, but for now musb->periodic is just an | 1767 | * like e.g. OHCI uses. |
1724 | * array of the _single_ logical endpoint associated with a | ||
1725 | * given physical one (identity mapping logical->physical). | ||
1726 | * | ||
1727 | * that simplistic approach makes TT scheduling a lot simpler; | ||
1728 | * there is none, and thus none of its complexity... | ||
1729 | */ | 1768 | */ |
1730 | best_diff = 4096; | 1769 | best_diff = 4096; |
1731 | best_end = -1; | 1770 | best_end = -1; |
1732 | 1771 | ||
1733 | for (epnum = 1; epnum < musb->nr_endpoints; epnum++) { | 1772 | for (epnum = 1, hw_ep = musb->endpoints + 1; |
1773 | epnum < musb->nr_endpoints; | ||
1774 | epnum++, hw_ep++) { | ||
1734 | int diff; | 1775 | int diff; |
1735 | 1776 | ||
1736 | if (musb->periodic[epnum]) | 1777 | if (is_in || hw_ep->is_shared_fifo) { |
1778 | if (hw_ep->in_qh != NULL) | ||
1779 | continue; | ||
1780 | } else if (hw_ep->out_qh != NULL) | ||
1737 | continue; | 1781 | continue; |
1738 | hw_ep = &musb->endpoints[epnum]; | 1782 | |
1739 | if (hw_ep == musb->bulk_ep) | 1783 | if (hw_ep == musb->bulk_ep) |
1740 | continue; | 1784 | continue; |
1741 | 1785 | ||
@@ -1756,6 +1800,17 @@ static int musb_schedule( | |||
1756 | head = &musb->in_bulk; | 1800 | head = &musb->in_bulk; |
1757 | else | 1801 | else |
1758 | head = &musb->out_bulk; | 1802 | head = &musb->out_bulk; |
1803 | |||
1804 | /* Enable bulk RX NAK timeout scheme when bulk requests are | ||
1805 | * multiplexed. This scheme doen't work in high speed to full | ||
1806 | * speed scenario as NAK interrupts are not coming from a | ||
1807 | * full speed device connected to a high speed device. | ||
1808 | * NAK timeout interval is 8 (128 uframe or 16ms) for HS and | ||
1809 | * 4 (8 frame or 8ms) for FS device. | ||
1810 | */ | ||
1811 | if (is_in && qh->dev) | ||
1812 | qh->intv_reg = | ||
1813 | (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4; | ||
1759 | goto success; | 1814 | goto success; |
1760 | } else if (best_end < 0) { | 1815 | } else if (best_end < 0) { |
1761 | return -ENOSPC; | 1816 | return -ENOSPC; |
@@ -1764,7 +1819,6 @@ static int musb_schedule( | |||
1764 | idle = 1; | 1819 | idle = 1; |
1765 | qh->mux = 0; | 1820 | qh->mux = 0; |
1766 | hw_ep = musb->endpoints + best_end; | 1821 | hw_ep = musb->endpoints + best_end; |
1767 | musb->periodic[best_end] = qh; | ||
1768 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); | 1822 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); |
1769 | success: | 1823 | success: |
1770 | if (head) { | 1824 | if (head) { |
@@ -1888,13 +1942,11 @@ static int musb_urb_enqueue( | |||
1888 | * | 1942 | * |
1889 | * The downside of disabling this is that transfer scheduling | 1943 | * The downside of disabling this is that transfer scheduling |
1890 | * gets VERY unfair for nonperiodic transfers; a misbehaving | 1944 | * gets VERY unfair for nonperiodic transfers; a misbehaving |
1891 | * peripheral could make that hurt. Or for reads, one that's | 1945 | * peripheral could make that hurt. That's perfectly normal |
1892 | * perfectly normal: network and other drivers keep reads | 1946 | * for reads from network or serial adapters ... so we have |
1893 | * posted at all times, having one pending for a week should | 1947 | * partial NAKlimit support for bulk RX. |
1894 | * be perfectly safe. | ||
1895 | * | 1948 | * |
1896 | * The upside of disabling it is avoidng transfer scheduling | 1949 | * The upside of disabling it is simpler transfer scheduling. |
1897 | * code to put this aside for while. | ||
1898 | */ | 1950 | */ |
1899 | interval = 0; | 1951 | interval = 0; |
1900 | } | 1952 | } |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index e0e9ce584175..bf677acc83db 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -285,7 +285,7 @@ int musb_hub_control( | |||
285 | desc->bDescLength = 9; | 285 | desc->bDescLength = 9; |
286 | desc->bDescriptorType = 0x29; | 286 | desc->bDescriptorType = 0x29; |
287 | desc->bNbrPorts = 1; | 287 | desc->bNbrPorts = 1; |
288 | desc->wHubCharacteristics = __constant_cpu_to_le16( | 288 | desc->wHubCharacteristics = cpu_to_le16( |
289 | 0x0001 /* per-port power switching */ | 289 | 0x0001 /* per-port power switching */ |
290 | | 0x0010 /* no overcurrent reporting */ | 290 | | 0x0010 /* no overcurrent reporting */ |
291 | ); | 291 | ); |
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index ee55b449ffde..aa884d072f0b 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
@@ -43,7 +43,7 @@ config ISP1301_OMAP | |||
43 | 43 | ||
44 | config TWL4030_USB | 44 | config TWL4030_USB |
45 | tristate "TWL4030 USB Transceiver Driver" | 45 | tristate "TWL4030 USB Transceiver Driver" |
46 | depends on TWL4030_CORE | 46 | depends on TWL4030_CORE && REGULATOR_TWL4030 |
47 | select USB_OTG_UTILS | 47 | select USB_OTG_UTILS |
48 | help | 48 | help |
49 | Enable this to support the USB OTG transceiver on TWL4030 | 49 | Enable this to support the USB OTG transceiver on TWL4030 |
@@ -51,4 +51,12 @@ config TWL4030_USB | |||
51 | This transceiver supports high and full speed devices plus, | 51 | This transceiver supports high and full speed devices plus, |
52 | in host mode, low speed. | 52 | in host mode, low speed. |
53 | 53 | ||
54 | config NOP_USB_XCEIV | ||
55 | tristate "NOP USB Transceiver Driver" | ||
56 | select USB_OTG_UTILS | ||
57 | help | ||
58 | this driver is to be used by all the usb transceiver which are either | ||
59 | built-in with usb ip or which are autonomous and doesn't require any | ||
60 | phy programming such as ISP1x04 etc. | ||
61 | |||
54 | endif # USB || OTG | 62 | endif # USB || OTG |
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index d73c7cf5e2f7..208167856529 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o | |||
9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o | 9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o |
10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o | 10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o |
11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o | 11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o |
12 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o | ||
12 | 13 | ||
13 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG | 14 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG |
14 | ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG | 15 | ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG |
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 63a6036f04be..1c26c94513e9 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/gpio.h> | 13 | #include <linux/gpio.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/workqueue.h> | ||
16 | 17 | ||
17 | #include <linux/regulator/consumer.h> | 18 | #include <linux/regulator/consumer.h> |
18 | 19 | ||
@@ -34,6 +35,7 @@ struct gpio_vbus_data { | |||
34 | struct regulator *vbus_draw; | 35 | struct regulator *vbus_draw; |
35 | int vbus_draw_enabled; | 36 | int vbus_draw_enabled; |
36 | unsigned mA; | 37 | unsigned mA; |
38 | struct work_struct work; | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | 41 | ||
@@ -76,24 +78,26 @@ static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA) | |||
76 | gpio_vbus->mA = mA; | 78 | gpio_vbus->mA = mA; |
77 | } | 79 | } |
78 | 80 | ||
79 | /* VBUS change IRQ handler */ | 81 | static int is_vbus_powered(struct gpio_vbus_mach_info *pdata) |
80 | static irqreturn_t gpio_vbus_irq(int irq, void *data) | ||
81 | { | 82 | { |
82 | struct platform_device *pdev = data; | 83 | int vbus; |
83 | struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; | ||
84 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | ||
85 | int gpio, vbus; | ||
86 | 84 | ||
87 | vbus = gpio_get_value(pdata->gpio_vbus); | 85 | vbus = gpio_get_value(pdata->gpio_vbus); |
88 | if (pdata->gpio_vbus_inverted) | 86 | if (pdata->gpio_vbus_inverted) |
89 | vbus = !vbus; | 87 | vbus = !vbus; |
90 | 88 | ||
91 | dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", | 89 | return vbus; |
92 | vbus ? "supplied" : "inactive", | 90 | } |
93 | gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); | 91 | |
92 | static void gpio_vbus_work(struct work_struct *work) | ||
93 | { | ||
94 | struct gpio_vbus_data *gpio_vbus = | ||
95 | container_of(work, struct gpio_vbus_data, work); | ||
96 | struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; | ||
97 | int gpio; | ||
94 | 98 | ||
95 | if (!gpio_vbus->otg.gadget) | 99 | if (!gpio_vbus->otg.gadget) |
96 | return IRQ_HANDLED; | 100 | return; |
97 | 101 | ||
98 | /* Peripheral controllers which manage the pullup themselves won't have | 102 | /* Peripheral controllers which manage the pullup themselves won't have |
99 | * gpio_pullup configured here. If it's configured here, we'll do what | 103 | * gpio_pullup configured here. If it's configured here, we'll do what |
@@ -101,7 +105,7 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data) | |||
101 | * that may complicate usb_gadget_{,dis}connect() support. | 105 | * that may complicate usb_gadget_{,dis}connect() support. |
102 | */ | 106 | */ |
103 | gpio = pdata->gpio_pullup; | 107 | gpio = pdata->gpio_pullup; |
104 | if (vbus) { | 108 | if (is_vbus_powered(pdata)) { |
105 | gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL; | 109 | gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL; |
106 | usb_gadget_vbus_connect(gpio_vbus->otg.gadget); | 110 | usb_gadget_vbus_connect(gpio_vbus->otg.gadget); |
107 | 111 | ||
@@ -121,6 +125,21 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data) | |||
121 | usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget); | 125 | usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget); |
122 | gpio_vbus->otg.state = OTG_STATE_B_IDLE; | 126 | gpio_vbus->otg.state = OTG_STATE_B_IDLE; |
123 | } | 127 | } |
128 | } | ||
129 | |||
130 | /* VBUS change IRQ handler */ | ||
131 | static irqreturn_t gpio_vbus_irq(int irq, void *data) | ||
132 | { | ||
133 | struct platform_device *pdev = data; | ||
134 | struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; | ||
135 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | ||
136 | |||
137 | dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", | ||
138 | is_vbus_powered(pdata) ? "supplied" : "inactive", | ||
139 | gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); | ||
140 | |||
141 | if (gpio_vbus->otg.gadget) | ||
142 | schedule_work(&gpio_vbus->work); | ||
124 | 143 | ||
125 | return IRQ_HANDLED; | 144 | return IRQ_HANDLED; |
126 | } | 145 | } |
@@ -257,6 +276,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) | |||
257 | irq, err); | 276 | irq, err); |
258 | goto err_irq; | 277 | goto err_irq; |
259 | } | 278 | } |
279 | INIT_WORK(&gpio_vbus->work, gpio_vbus_work); | ||
260 | 280 | ||
261 | /* only active when a gadget is registered */ | 281 | /* only active when a gadget is registered */ |
262 | err = otg_set_transceiver(&gpio_vbus->otg); | 282 | err = otg_set_transceiver(&gpio_vbus->otg); |
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c new file mode 100644 index 000000000000..4b933f646f2e --- /dev/null +++ b/drivers/usb/otg/nop-usb-xceiv.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * drivers/usb/otg/nop-usb-xceiv.c | ||
3 | * | ||
4 | * NOP USB transceiver for all USB transceiver which are either built-in | ||
5 | * into USB IP or which are mostly autonomous. | ||
6 | * | ||
7 | * Copyright (C) 2009 Texas Instruments Inc | ||
8 | * Author: Ajay Kumar Gupta <ajay.gupta@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * Current status: | ||
25 | * this is to add "nop" transceiver for all those phy which is | ||
26 | * autonomous such as isp1504 etc. | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/usb/otg.h> | ||
33 | |||
34 | struct nop_usb_xceiv { | ||
35 | struct otg_transceiver otg; | ||
36 | struct device *dev; | ||
37 | }; | ||
38 | |||
39 | static u64 nop_xceiv_dmamask = DMA_32BIT_MASK; | ||
40 | |||
41 | static struct platform_device nop_xceiv_device = { | ||
42 | .name = "nop_usb_xceiv", | ||
43 | .id = -1, | ||
44 | .dev = { | ||
45 | .dma_mask = &nop_xceiv_dmamask, | ||
46 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
47 | .platform_data = NULL, | ||
48 | }, | ||
49 | }; | ||
50 | |||
51 | void usb_nop_xceiv_register(void) | ||
52 | { | ||
53 | if (platform_device_register(&nop_xceiv_device) < 0) { | ||
54 | printk(KERN_ERR "Unable to register usb nop transceiver\n"); | ||
55 | return; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | void usb_nop_xceiv_unregister(void) | ||
60 | { | ||
61 | platform_device_unregister(&nop_xceiv_device); | ||
62 | } | ||
63 | |||
64 | static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x) | ||
65 | { | ||
66 | return container_of(x, struct nop_usb_xceiv, otg); | ||
67 | } | ||
68 | |||
69 | static int nop_set_suspend(struct otg_transceiver *x, int suspend) | ||
70 | { | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int nop_set_peripheral(struct otg_transceiver *x, | ||
75 | struct usb_gadget *gadget) | ||
76 | { | ||
77 | struct nop_usb_xceiv *nop; | ||
78 | |||
79 | if (!x) | ||
80 | return -ENODEV; | ||
81 | |||
82 | nop = xceiv_to_nop(x); | ||
83 | |||
84 | if (!gadget) { | ||
85 | nop->otg.gadget = NULL; | ||
86 | return -ENODEV; | ||
87 | } | ||
88 | |||
89 | nop->otg.gadget = gadget; | ||
90 | nop->otg.state = OTG_STATE_B_IDLE; | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int nop_set_host(struct otg_transceiver *x, struct usb_bus *host) | ||
95 | { | ||
96 | struct nop_usb_xceiv *nop; | ||
97 | |||
98 | if (!x) | ||
99 | return -ENODEV; | ||
100 | |||
101 | nop = xceiv_to_nop(x); | ||
102 | |||
103 | if (!host) { | ||
104 | nop->otg.host = NULL; | ||
105 | return -ENODEV; | ||
106 | } | ||
107 | |||
108 | nop->otg.host = host; | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) | ||
113 | { | ||
114 | struct nop_usb_xceiv *nop; | ||
115 | int err; | ||
116 | |||
117 | nop = kzalloc(sizeof *nop, GFP_KERNEL); | ||
118 | if (!nop) | ||
119 | return -ENOMEM; | ||
120 | |||
121 | nop->dev = &pdev->dev; | ||
122 | nop->otg.dev = nop->dev; | ||
123 | nop->otg.label = "nop-xceiv"; | ||
124 | nop->otg.state = OTG_STATE_UNDEFINED; | ||
125 | nop->otg.set_host = nop_set_host; | ||
126 | nop->otg.set_peripheral = nop_set_peripheral; | ||
127 | nop->otg.set_suspend = nop_set_suspend; | ||
128 | |||
129 | err = otg_set_transceiver(&nop->otg); | ||
130 | if (err) { | ||
131 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", | ||
132 | err); | ||
133 | goto exit; | ||
134 | } | ||
135 | |||
136 | platform_set_drvdata(pdev, nop); | ||
137 | |||
138 | return 0; | ||
139 | exit: | ||
140 | kfree(nop); | ||
141 | return err; | ||
142 | } | ||
143 | |||
144 | static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev) | ||
145 | { | ||
146 | struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); | ||
147 | |||
148 | otg_set_transceiver(NULL); | ||
149 | |||
150 | platform_set_drvdata(pdev, NULL); | ||
151 | kfree(nop); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static struct platform_driver nop_usb_xceiv_driver = { | ||
157 | .probe = nop_usb_xceiv_probe, | ||
158 | .remove = __devexit_p(nop_usb_xceiv_remove), | ||
159 | .driver = { | ||
160 | .name = "nop_usb_xceiv", | ||
161 | .owner = THIS_MODULE, | ||
162 | }, | ||
163 | }; | ||
164 | |||
165 | static int __init nop_usb_xceiv_init(void) | ||
166 | { | ||
167 | return platform_driver_register(&nop_usb_xceiv_driver); | ||
168 | } | ||
169 | subsys_initcall(nop_usb_xceiv_init); | ||
170 | |||
171 | static void __exit nop_usb_xceiv_exit(void) | ||
172 | { | ||
173 | platform_driver_unregister(&nop_usb_xceiv_driver); | ||
174 | } | ||
175 | module_exit(nop_usb_xceiv_exit); | ||
176 | |||
177 | MODULE_ALIAS("platform:nop_usb_xceiv"); | ||
178 | MODULE_AUTHOR("Texas Instruments Inc"); | ||
179 | MODULE_DESCRIPTION("NOP USB Transceiver driver"); | ||
180 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 416e4410be02..d9478d0e1c8b 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/usb/otg.h> | 35 | #include <linux/usb/otg.h> |
36 | #include <linux/i2c/twl4030.h> | 36 | #include <linux/i2c/twl4030.h> |
37 | #include <linux/regulator/consumer.h> | ||
38 | #include <linux/err.h> | ||
37 | 39 | ||
38 | 40 | ||
39 | /* Register defines */ | 41 | /* Register defines */ |
@@ -246,6 +248,11 @@ struct twl4030_usb { | |||
246 | struct otg_transceiver otg; | 248 | struct otg_transceiver otg; |
247 | struct device *dev; | 249 | struct device *dev; |
248 | 250 | ||
251 | /* TWL4030 internal USB regulator supplies */ | ||
252 | struct regulator *usb1v5; | ||
253 | struct regulator *usb1v8; | ||
254 | struct regulator *usb3v1; | ||
255 | |||
249 | /* for vbus reporting with irqs disabled */ | 256 | /* for vbus reporting with irqs disabled */ |
250 | spinlock_t lock; | 257 | spinlock_t lock; |
251 | 258 | ||
@@ -434,6 +441,18 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) | |||
434 | 441 | ||
435 | pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); | 442 | pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); |
436 | if (on) { | 443 | if (on) { |
444 | regulator_enable(twl->usb3v1); | ||
445 | regulator_enable(twl->usb1v8); | ||
446 | /* | ||
447 | * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP | ||
448 | * in twl4030) resets the VUSB_DEDICATED2 register. This reset | ||
449 | * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to | ||
450 | * SLEEP. We work around this by clearing the bit after usv3v1 | ||
451 | * is re-activated. This ensures that VUSB3V1 is really active. | ||
452 | */ | ||
453 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, | ||
454 | VUSB_DEDICATED2); | ||
455 | regulator_enable(twl->usb1v5); | ||
437 | pwr &= ~PHY_PWR_PHYPWD; | 456 | pwr &= ~PHY_PWR_PHYPWD; |
438 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); | 457 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); |
439 | twl4030_usb_write(twl, PHY_CLK_CTRL, | 458 | twl4030_usb_write(twl, PHY_CLK_CTRL, |
@@ -443,6 +462,9 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) | |||
443 | } else { | 462 | } else { |
444 | pwr |= PHY_PWR_PHYPWD; | 463 | pwr |= PHY_PWR_PHYPWD; |
445 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); | 464 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); |
465 | regulator_disable(twl->usb1v5); | ||
466 | regulator_disable(twl->usb1v8); | ||
467 | regulator_disable(twl->usb3v1); | ||
446 | } | 468 | } |
447 | } | 469 | } |
448 | 470 | ||
@@ -468,7 +490,7 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) | |||
468 | twl->asleep = 0; | 490 | twl->asleep = 0; |
469 | } | 491 | } |
470 | 492 | ||
471 | static void twl4030_usb_ldo_init(struct twl4030_usb *twl) | 493 | static int twl4030_usb_ldo_init(struct twl4030_usb *twl) |
472 | { | 494 | { |
473 | /* Enable writing to power configuration registers */ | 495 | /* Enable writing to power configuration registers */ |
474 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); | 496 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); |
@@ -480,20 +502,45 @@ static void twl4030_usb_ldo_init(struct twl4030_usb *twl) | |||
480 | /* input to VUSB3V1 LDO is from VBAT, not VBUS */ | 502 | /* input to VUSB3V1 LDO is from VBAT, not VBUS */ |
481 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); | 503 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); |
482 | 504 | ||
483 | /* turn on 3.1V regulator */ | 505 | /* Initialize 3.1V regulator */ |
484 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB3V1_DEV_GRP); | 506 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); |
507 | |||
508 | twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); | ||
509 | if (IS_ERR(twl->usb3v1)) | ||
510 | return -ENODEV; | ||
511 | |||
485 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); | 512 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); |
486 | 513 | ||
487 | /* turn on 1.5V regulator */ | 514 | /* Initialize 1.5V regulator */ |
488 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V5_DEV_GRP); | 515 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); |
516 | |||
517 | twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); | ||
518 | if (IS_ERR(twl->usb1v5)) | ||
519 | goto fail1; | ||
520 | |||
489 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); | 521 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); |
490 | 522 | ||
491 | /* turn on 1.8V regulator */ | 523 | /* Initialize 1.8V regulator */ |
492 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V8_DEV_GRP); | 524 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); |
525 | |||
526 | twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); | ||
527 | if (IS_ERR(twl->usb1v8)) | ||
528 | goto fail2; | ||
529 | |||
493 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); | 530 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); |
494 | 531 | ||
495 | /* disable access to power configuration registers */ | 532 | /* disable access to power configuration registers */ |
496 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); | 533 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); |
534 | |||
535 | return 0; | ||
536 | |||
537 | fail2: | ||
538 | regulator_put(twl->usb1v5); | ||
539 | twl->usb1v5 = NULL; | ||
540 | fail1: | ||
541 | regulator_put(twl->usb3v1); | ||
542 | twl->usb3v1 = NULL; | ||
543 | return -ENODEV; | ||
497 | } | 544 | } |
498 | 545 | ||
499 | static ssize_t twl4030_usb_vbus_show(struct device *dev, | 546 | static ssize_t twl4030_usb_vbus_show(struct device *dev, |
@@ -598,7 +645,7 @@ static int __init twl4030_usb_probe(struct platform_device *pdev) | |||
598 | { | 645 | { |
599 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; | 646 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; |
600 | struct twl4030_usb *twl; | 647 | struct twl4030_usb *twl; |
601 | int status; | 648 | int status, err; |
602 | 649 | ||
603 | if (!pdata) { | 650 | if (!pdata) { |
604 | dev_dbg(&pdev->dev, "platform_data not available\n"); | 651 | dev_dbg(&pdev->dev, "platform_data not available\n"); |
@@ -622,7 +669,12 @@ static int __init twl4030_usb_probe(struct platform_device *pdev) | |||
622 | /* init spinlock for workqueue */ | 669 | /* init spinlock for workqueue */ |
623 | spin_lock_init(&twl->lock); | 670 | spin_lock_init(&twl->lock); |
624 | 671 | ||
625 | twl4030_usb_ldo_init(twl); | 672 | err = twl4030_usb_ldo_init(twl); |
673 | if (err) { | ||
674 | dev_err(&pdev->dev, "ldo init failed\n"); | ||
675 | kfree(twl); | ||
676 | return err; | ||
677 | } | ||
626 | otg_set_transceiver(&twl->otg); | 678 | otg_set_transceiver(&twl->otg); |
627 | 679 | ||
628 | platform_set_drvdata(pdev, twl); | 680 | platform_set_drvdata(pdev, twl); |
@@ -688,6 +740,9 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) | |||
688 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); | 740 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); |
689 | 741 | ||
690 | twl4030_phy_power(twl, 0); | 742 | twl4030_phy_power(twl, 0); |
743 | regulator_put(twl->usb1v5); | ||
744 | regulator_put(twl->usb1v8); | ||
745 | regulator_put(twl->usb3v1); | ||
691 | 746 | ||
692 | kfree(twl); | 747 | kfree(twl); |
693 | 748 | ||
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index b361f05cafac..a65f9196b0a0 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -116,14 +116,14 @@ config USB_SERIAL_DIGI_ACCELEPORT | |||
116 | To compile this driver as a module, choose M here: the | 116 | To compile this driver as a module, choose M here: the |
117 | module will be called digi_acceleport. | 117 | module will be called digi_acceleport. |
118 | 118 | ||
119 | config USB_SERIAL_CP2101 | 119 | config USB_SERIAL_CP210X |
120 | tristate "USB CP2101 UART Bridge Controller" | 120 | tristate "USB CP210x family of UART Bridge Controllers" |
121 | help | 121 | help |
122 | Say Y here if you want to use a CP2101/CP2102 based USB to RS232 | 122 | Say Y here if you want to use a CP2101/CP2102/CP2103 based USB |
123 | converter. | 123 | to RS232 converters. |
124 | 124 | ||
125 | To compile this driver as a module, choose M here: the | 125 | To compile this driver as a module, choose M here: the |
126 | module will be called cp2101. | 126 | module will be called cp210x. |
127 | 127 | ||
128 | config USB_SERIAL_CYPRESS_M8 | 128 | config USB_SERIAL_CYPRESS_M8 |
129 | tristate "USB Cypress M8 USB Serial Driver" | 129 | tristate "USB Cypress M8 USB Serial Driver" |
@@ -472,6 +472,15 @@ config USB_SERIAL_OTI6858 | |||
472 | To compile this driver as a module, choose M here: the | 472 | To compile this driver as a module, choose M here: the |
473 | module will be called oti6858. | 473 | module will be called oti6858. |
474 | 474 | ||
475 | config USB_SERIAL_QUALCOMM | ||
476 | tristate "USB Qualcomm Serial modem" | ||
477 | help | ||
478 | Say Y here if you have a Qualcomm USB modem device. These are | ||
479 | usually wireless cellular modems. | ||
480 | |||
481 | To compile this driver as a module, choose M here: the | ||
482 | module will be called qcserial. | ||
483 | |||
475 | config USB_SERIAL_SPCP8X5 | 484 | config USB_SERIAL_SPCP8X5 |
476 | tristate "USB SPCP8x5 USB To Serial Driver" | 485 | tristate "USB SPCP8x5 USB To Serial Driver" |
477 | help | 486 | help |
@@ -515,6 +524,15 @@ config USB_SERIAL_SIERRAWIRELESS | |||
515 | To compile this driver as a module, choose M here: the | 524 | To compile this driver as a module, choose M here: the |
516 | module will be called sierra. | 525 | module will be called sierra. |
517 | 526 | ||
527 | config USB_SERIAL_SYMBOL | ||
528 | tristate "USB Symbol Barcode driver (serial mode)" | ||
529 | help | ||
530 | Say Y here if you want to use a Symbol USB Barcode device | ||
531 | in serial emulation mode. | ||
532 | |||
533 | To compile this driver as a module, choose M here: the | ||
534 | module will be called symbolserial. | ||
535 | |||
518 | config USB_SERIAL_TI | 536 | config USB_SERIAL_TI |
519 | tristate "USB TI 3410/5052 Serial Driver" | 537 | tristate "USB TI 3410/5052 Serial Driver" |
520 | help | 538 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index b75be91eb8f1..66619beb6cc0 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -15,7 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o | |||
15 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o | 15 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o |
16 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o | 16 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o |
17 | obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o | 17 | obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o |
18 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o | 18 | obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o |
19 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o | 19 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o |
20 | obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o | 20 | obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o |
21 | obj-$(CONFIG_USB_SERIAL_DEBUG) += usb_debug.o | 21 | obj-$(CONFIG_USB_SERIAL_DEBUG) += usb_debug.o |
@@ -45,10 +45,12 @@ obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o | |||
45 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | 45 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o |
46 | obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o | 46 | obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o |
47 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 47 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
48 | obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o | ||
48 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o | 49 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o |
49 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o | 50 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o |
50 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o | 51 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o |
51 | obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o | 52 | obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o |
53 | obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o | ||
52 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o | 54 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o |
53 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o | 55 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o |
54 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o | 56 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index f61e3ca64305..ab4cc277aa65 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> | 2 | * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> |
3 | * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de> | ||
4 | * Copyright 2009, Boris Hajduk <boris@hajduk.org> | ||
3 | * | 5 | * |
4 | * ch341.c implements a serial port driver for the Winchiphead CH341. | 6 | * ch341.c implements a serial port driver for the Winchiphead CH341. |
5 | * | 7 | * |
@@ -21,9 +23,39 @@ | |||
21 | #include <linux/usb/serial.h> | 23 | #include <linux/usb/serial.h> |
22 | #include <linux/serial.h> | 24 | #include <linux/serial.h> |
23 | 25 | ||
24 | #define DEFAULT_BAUD_RATE 2400 | 26 | #define DEFAULT_BAUD_RATE 9600 |
25 | #define DEFAULT_TIMEOUT 1000 | 27 | #define DEFAULT_TIMEOUT 1000 |
26 | 28 | ||
29 | /* flags for IO-Bits */ | ||
30 | #define CH341_BIT_RTS (1 << 6) | ||
31 | #define CH341_BIT_DTR (1 << 5) | ||
32 | |||
33 | /******************************/ | ||
34 | /* interrupt pipe definitions */ | ||
35 | /******************************/ | ||
36 | /* always 4 interrupt bytes */ | ||
37 | /* first irq byte normally 0x08 */ | ||
38 | /* second irq byte base 0x7d + below */ | ||
39 | /* third irq byte base 0x94 + below */ | ||
40 | /* fourth irq byte normally 0xee */ | ||
41 | |||
42 | /* second interrupt byte */ | ||
43 | #define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */ | ||
44 | |||
45 | /* status returned in third interrupt answer byte, inverted in data | ||
46 | from irq */ | ||
47 | #define CH341_BIT_CTS 0x01 | ||
48 | #define CH341_BIT_DSR 0x02 | ||
49 | #define CH341_BIT_RI 0x04 | ||
50 | #define CH341_BIT_DCD 0x08 | ||
51 | #define CH341_BITS_MODEM_STAT 0x0f /* all bits */ | ||
52 | |||
53 | /*******************************/ | ||
54 | /* baudrate calculation factor */ | ||
55 | /*******************************/ | ||
56 | #define CH341_BAUDBASE_FACTOR 1532620800 | ||
57 | #define CH341_BAUDBASE_DIVMAX 3 | ||
58 | |||
27 | static int debug; | 59 | static int debug; |
28 | 60 | ||
29 | static struct usb_device_id id_table [] = { | 61 | static struct usb_device_id id_table [] = { |
@@ -34,9 +66,12 @@ static struct usb_device_id id_table [] = { | |||
34 | MODULE_DEVICE_TABLE(usb, id_table); | 66 | MODULE_DEVICE_TABLE(usb, id_table); |
35 | 67 | ||
36 | struct ch341_private { | 68 | struct ch341_private { |
37 | unsigned baud_rate; | 69 | spinlock_t lock; /* access lock */ |
38 | u8 dtr; | 70 | wait_queue_head_t delta_msr_wait; /* wait queue for modem status */ |
39 | u8 rts; | 71 | unsigned baud_rate; /* set baud rate */ |
72 | u8 line_control; /* set line control value RTS/DTR */ | ||
73 | u8 line_status; /* active status of modem control inputs */ | ||
74 | u8 multi_status_change; /* status changed multiple since last call */ | ||
40 | }; | 75 | }; |
41 | 76 | ||
42 | static int ch341_control_out(struct usb_device *dev, u8 request, | 77 | static int ch341_control_out(struct usb_device *dev, u8 request, |
@@ -72,37 +107,28 @@ static int ch341_set_baudrate(struct usb_device *dev, | |||
72 | { | 107 | { |
73 | short a, b; | 108 | short a, b; |
74 | int r; | 109 | int r; |
110 | unsigned long factor; | ||
111 | short divisor; | ||
75 | 112 | ||
76 | dbg("ch341_set_baudrate(%d)", priv->baud_rate); | 113 | dbg("ch341_set_baudrate(%d)", priv->baud_rate); |
77 | switch (priv->baud_rate) { | 114 | |
78 | case 2400: | 115 | if (!priv->baud_rate) |
79 | a = 0xd901; | ||
80 | b = 0x0038; | ||
81 | break; | ||
82 | case 4800: | ||
83 | a = 0x6402; | ||
84 | b = 0x001f; | ||
85 | break; | ||
86 | case 9600: | ||
87 | a = 0xb202; | ||
88 | b = 0x0013; | ||
89 | break; | ||
90 | case 19200: | ||
91 | a = 0xd902; | ||
92 | b = 0x000d; | ||
93 | break; | ||
94 | case 38400: | ||
95 | a = 0x6403; | ||
96 | b = 0x000a; | ||
97 | break; | ||
98 | case 115200: | ||
99 | a = 0xcc03; | ||
100 | b = 0x0008; | ||
101 | break; | ||
102 | default: | ||
103 | return -EINVAL; | 116 | return -EINVAL; |
117 | factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate); | ||
118 | divisor = CH341_BAUDBASE_DIVMAX; | ||
119 | |||
120 | while ((factor > 0xfff0) && divisor) { | ||
121 | factor >>= 3; | ||
122 | divisor--; | ||
104 | } | 123 | } |
105 | 124 | ||
125 | if (factor > 0xfff0) | ||
126 | return -EINVAL; | ||
127 | |||
128 | factor = 0x10000 - factor; | ||
129 | a = (factor & 0xff00) | divisor; | ||
130 | b = factor & 0xff; | ||
131 | |||
106 | r = ch341_control_out(dev, 0x9a, 0x1312, a); | 132 | r = ch341_control_out(dev, 0x9a, 0x1312, a); |
107 | if (!r) | 133 | if (!r) |
108 | r = ch341_control_out(dev, 0x9a, 0x0f2c, b); | 134 | r = ch341_control_out(dev, 0x9a, 0x0f2c, b); |
@@ -110,19 +136,18 @@ static int ch341_set_baudrate(struct usb_device *dev, | |||
110 | return r; | 136 | return r; |
111 | } | 137 | } |
112 | 138 | ||
113 | static int ch341_set_handshake(struct usb_device *dev, | 139 | static int ch341_set_handshake(struct usb_device *dev, u8 control) |
114 | struct ch341_private *priv) | ||
115 | { | 140 | { |
116 | dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts); | 141 | dbg("ch341_set_handshake(0x%02x)", control); |
117 | return ch341_control_out(dev, 0xa4, | 142 | return ch341_control_out(dev, 0xa4, ~control, 0); |
118 | ~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0); | ||
119 | } | 143 | } |
120 | 144 | ||
121 | static int ch341_get_status(struct usb_device *dev) | 145 | static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv) |
122 | { | 146 | { |
123 | char *buffer; | 147 | char *buffer; |
124 | int r; | 148 | int r; |
125 | const unsigned size = 8; | 149 | const unsigned size = 8; |
150 | unsigned long flags; | ||
126 | 151 | ||
127 | dbg("ch341_get_status()"); | 152 | dbg("ch341_get_status()"); |
128 | 153 | ||
@@ -134,10 +159,15 @@ static int ch341_get_status(struct usb_device *dev) | |||
134 | if (r < 0) | 159 | if (r < 0) |
135 | goto out; | 160 | goto out; |
136 | 161 | ||
137 | /* Not having the datasheet for the CH341, we ignore the bytes returned | 162 | /* setup the private status if available */ |
138 | * from the device. Return error if the device did not respond in time. | 163 | if (r == 2) { |
139 | */ | 164 | r = 0; |
140 | r = 0; | 165 | spin_lock_irqsave(&priv->lock, flags); |
166 | priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT; | ||
167 | priv->multi_status_change = 0; | ||
168 | spin_unlock_irqrestore(&priv->lock, flags); | ||
169 | } else | ||
170 | r = -EPROTO; | ||
141 | 171 | ||
142 | out: kfree(buffer); | 172 | out: kfree(buffer); |
143 | return r; | 173 | return r; |
@@ -180,7 +210,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) | |||
180 | goto out; | 210 | goto out; |
181 | 211 | ||
182 | /* expect 0xff 0xee */ | 212 | /* expect 0xff 0xee */ |
183 | r = ch341_get_status(dev); | 213 | r = ch341_get_status(dev, priv); |
184 | if (r < 0) | 214 | if (r < 0) |
185 | goto out; | 215 | goto out; |
186 | 216 | ||
@@ -192,12 +222,12 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) | |||
192 | if (r < 0) | 222 | if (r < 0) |
193 | goto out; | 223 | goto out; |
194 | 224 | ||
195 | r = ch341_set_handshake(dev, priv); | 225 | r = ch341_set_handshake(dev, priv->line_control); |
196 | if (r < 0) | 226 | if (r < 0) |
197 | goto out; | 227 | goto out; |
198 | 228 | ||
199 | /* expect 0x9f 0xee */ | 229 | /* expect 0x9f 0xee */ |
200 | r = ch341_get_status(dev); | 230 | r = ch341_get_status(dev, priv); |
201 | 231 | ||
202 | out: kfree(buffer); | 232 | out: kfree(buffer); |
203 | return r; | 233 | return r; |
@@ -216,9 +246,10 @@ static int ch341_attach(struct usb_serial *serial) | |||
216 | if (!priv) | 246 | if (!priv) |
217 | return -ENOMEM; | 247 | return -ENOMEM; |
218 | 248 | ||
249 | spin_lock_init(&priv->lock); | ||
250 | init_waitqueue_head(&priv->delta_msr_wait); | ||
219 | priv->baud_rate = DEFAULT_BAUD_RATE; | 251 | priv->baud_rate = DEFAULT_BAUD_RATE; |
220 | priv->dtr = 1; | 252 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; |
221 | priv->rts = 1; | ||
222 | 253 | ||
223 | r = ch341_configure(serial->dev, priv); | 254 | r = ch341_configure(serial->dev, priv); |
224 | if (r < 0) | 255 | if (r < 0) |
@@ -231,6 +262,35 @@ error: kfree(priv); | |||
231 | return r; | 262 | return r; |
232 | } | 263 | } |
233 | 264 | ||
265 | static void ch341_close(struct tty_struct *tty, struct usb_serial_port *port, | ||
266 | struct file *filp) | ||
267 | { | ||
268 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
269 | unsigned long flags; | ||
270 | unsigned int c_cflag; | ||
271 | |||
272 | dbg("%s - port %d", __func__, port->number); | ||
273 | |||
274 | /* shutdown our urbs */ | ||
275 | dbg("%s - shutting down urbs", __func__); | ||
276 | usb_kill_urb(port->write_urb); | ||
277 | usb_kill_urb(port->read_urb); | ||
278 | usb_kill_urb(port->interrupt_in_urb); | ||
279 | |||
280 | if (tty) { | ||
281 | c_cflag = tty->termios->c_cflag; | ||
282 | if (c_cflag & HUPCL) { | ||
283 | /* drop DTR and RTS */ | ||
284 | spin_lock_irqsave(&priv->lock, flags); | ||
285 | priv->line_control = 0; | ||
286 | spin_unlock_irqrestore(&priv->lock, flags); | ||
287 | ch341_set_handshake(port->serial->dev, 0); | ||
288 | } | ||
289 | } | ||
290 | wake_up_interruptible(&priv->delta_msr_wait); | ||
291 | } | ||
292 | |||
293 | |||
234 | /* open this device, set default parameters */ | 294 | /* open this device, set default parameters */ |
235 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, | 295 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, |
236 | struct file *filp) | 296 | struct file *filp) |
@@ -242,14 +302,13 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
242 | dbg("ch341_open()"); | 302 | dbg("ch341_open()"); |
243 | 303 | ||
244 | priv->baud_rate = DEFAULT_BAUD_RATE; | 304 | priv->baud_rate = DEFAULT_BAUD_RATE; |
245 | priv->dtr = 1; | 305 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; |
246 | priv->rts = 1; | ||
247 | 306 | ||
248 | r = ch341_configure(serial->dev, priv); | 307 | r = ch341_configure(serial->dev, priv); |
249 | if (r) | 308 | if (r) |
250 | goto out; | 309 | goto out; |
251 | 310 | ||
252 | r = ch341_set_handshake(serial->dev, priv); | 311 | r = ch341_set_handshake(serial->dev, priv->line_control); |
253 | if (r) | 312 | if (r) |
254 | goto out; | 313 | goto out; |
255 | 314 | ||
@@ -257,6 +316,16 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
257 | if (r) | 316 | if (r) |
258 | goto out; | 317 | goto out; |
259 | 318 | ||
319 | dbg("%s - submitting interrupt urb", __func__); | ||
320 | port->interrupt_in_urb->dev = serial->dev; | ||
321 | r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | ||
322 | if (r) { | ||
323 | dev_err(&port->dev, "%s - failed submitting interrupt urb," | ||
324 | " error %d\n", __func__, r); | ||
325 | ch341_close(tty, port, NULL); | ||
326 | return -EPROTO; | ||
327 | } | ||
328 | |||
260 | r = usb_serial_generic_open(tty, port, filp); | 329 | r = usb_serial_generic_open(tty, port, filp); |
261 | 330 | ||
262 | out: return r; | 331 | out: return r; |
@@ -270,46 +339,224 @@ static void ch341_set_termios(struct tty_struct *tty, | |||
270 | { | 339 | { |
271 | struct ch341_private *priv = usb_get_serial_port_data(port); | 340 | struct ch341_private *priv = usb_get_serial_port_data(port); |
272 | unsigned baud_rate; | 341 | unsigned baud_rate; |
342 | unsigned long flags; | ||
273 | 343 | ||
274 | dbg("ch341_set_termios()"); | 344 | dbg("ch341_set_termios()"); |
275 | 345 | ||
346 | if (!tty || !tty->termios) | ||
347 | return; | ||
348 | |||
276 | baud_rate = tty_get_baud_rate(tty); | 349 | baud_rate = tty_get_baud_rate(tty); |
277 | 350 | ||
278 | switch (baud_rate) { | 351 | priv->baud_rate = baud_rate; |
279 | case 2400: | 352 | |
280 | case 4800: | 353 | if (baud_rate) { |
281 | case 9600: | 354 | spin_lock_irqsave(&priv->lock, flags); |
282 | case 19200: | 355 | priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS); |
283 | case 38400: | 356 | spin_unlock_irqrestore(&priv->lock, flags); |
284 | case 115200: | 357 | ch341_set_baudrate(port->serial->dev, priv); |
285 | priv->baud_rate = baud_rate; | 358 | } else { |
286 | break; | 359 | spin_lock_irqsave(&priv->lock, flags); |
287 | default: | 360 | priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS); |
288 | dbg("Rate %d not supported, using %d", | 361 | spin_unlock_irqrestore(&priv->lock, flags); |
289 | baud_rate, DEFAULT_BAUD_RATE); | ||
290 | priv->baud_rate = DEFAULT_BAUD_RATE; | ||
291 | } | 362 | } |
292 | 363 | ||
293 | ch341_set_baudrate(port->serial->dev, priv); | 364 | ch341_set_handshake(port->serial->dev, priv->line_control); |
294 | 365 | ||
295 | /* Unimplemented: | 366 | /* Unimplemented: |
296 | * (cflag & CSIZE) : data bits [5, 8] | 367 | * (cflag & CSIZE) : data bits [5, 8] |
297 | * (cflag & PARENB) : parity {NONE, EVEN, ODD} | 368 | * (cflag & PARENB) : parity {NONE, EVEN, ODD} |
298 | * (cflag & CSTOPB) : stop bits [1, 2] | 369 | * (cflag & CSTOPB) : stop bits [1, 2] |
299 | */ | 370 | */ |
371 | } | ||
372 | |||
373 | static int ch341_tiocmset(struct tty_struct *tty, struct file *file, | ||
374 | unsigned int set, unsigned int clear) | ||
375 | { | ||
376 | struct usb_serial_port *port = tty->driver_data; | ||
377 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
378 | unsigned long flags; | ||
379 | u8 control; | ||
380 | |||
381 | spin_lock_irqsave(&priv->lock, flags); | ||
382 | if (set & TIOCM_RTS) | ||
383 | priv->line_control |= CH341_BIT_RTS; | ||
384 | if (set & TIOCM_DTR) | ||
385 | priv->line_control |= CH341_BIT_DTR; | ||
386 | if (clear & TIOCM_RTS) | ||
387 | priv->line_control &= ~CH341_BIT_RTS; | ||
388 | if (clear & TIOCM_DTR) | ||
389 | priv->line_control &= ~CH341_BIT_DTR; | ||
390 | control = priv->line_control; | ||
391 | spin_unlock_irqrestore(&priv->lock, flags); | ||
392 | |||
393 | return ch341_set_handshake(port->serial->dev, control); | ||
394 | } | ||
395 | |||
396 | static void ch341_read_int_callback(struct urb *urb) | ||
397 | { | ||
398 | struct usb_serial_port *port = (struct usb_serial_port *) urb->context; | ||
399 | unsigned char *data = urb->transfer_buffer; | ||
400 | unsigned int actual_length = urb->actual_length; | ||
401 | int status; | ||
402 | |||
403 | dbg("%s (%d)", __func__, port->number); | ||
404 | |||
405 | switch (urb->status) { | ||
406 | case 0: | ||
407 | /* success */ | ||
408 | break; | ||
409 | case -ECONNRESET: | ||
410 | case -ENOENT: | ||
411 | case -ESHUTDOWN: | ||
412 | /* this urb is terminated, clean up */ | ||
413 | dbg("%s - urb shutting down with status: %d", __func__, | ||
414 | urb->status); | ||
415 | return; | ||
416 | default: | ||
417 | dbg("%s - nonzero urb status received: %d", __func__, | ||
418 | urb->status); | ||
419 | goto exit; | ||
420 | } | ||
300 | 421 | ||
301 | /* Copy back the old hardware settings */ | 422 | usb_serial_debug_data(debug, &port->dev, __func__, |
302 | tty_termios_copy_hw(tty->termios, old_termios); | 423 | urb->actual_length, urb->transfer_buffer); |
303 | /* And re-encode with the new baud */ | 424 | |
304 | tty_encode_baud_rate(tty, baud_rate, baud_rate); | 425 | if (actual_length >= 4) { |
426 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
427 | unsigned long flags; | ||
428 | |||
429 | spin_lock_irqsave(&priv->lock, flags); | ||
430 | priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT; | ||
431 | if ((data[1] & CH341_MULT_STAT)) | ||
432 | priv->multi_status_change = 1; | ||
433 | spin_unlock_irqrestore(&priv->lock, flags); | ||
434 | wake_up_interruptible(&priv->delta_msr_wait); | ||
435 | } | ||
436 | |||
437 | exit: | ||
438 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
439 | if (status) | ||
440 | dev_err(&urb->dev->dev, | ||
441 | "%s - usb_submit_urb failed with result %d\n", | ||
442 | __func__, status); | ||
443 | } | ||
444 | |||
445 | static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | ||
446 | { | ||
447 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
448 | unsigned long flags; | ||
449 | u8 prevstatus; | ||
450 | u8 status; | ||
451 | u8 changed; | ||
452 | u8 multi_change = 0; | ||
453 | |||
454 | spin_lock_irqsave(&priv->lock, flags); | ||
455 | prevstatus = priv->line_status; | ||
456 | priv->multi_status_change = 0; | ||
457 | spin_unlock_irqrestore(&priv->lock, flags); | ||
458 | |||
459 | while (!multi_change) { | ||
460 | interruptible_sleep_on(&priv->delta_msr_wait); | ||
461 | /* see if a signal did it */ | ||
462 | if (signal_pending(current)) | ||
463 | return -ERESTARTSYS; | ||
464 | |||
465 | spin_lock_irqsave(&priv->lock, flags); | ||
466 | status = priv->line_status; | ||
467 | multi_change = priv->multi_status_change; | ||
468 | spin_unlock_irqrestore(&priv->lock, flags); | ||
469 | |||
470 | changed = prevstatus ^ status; | ||
471 | |||
472 | if (((arg & TIOCM_RNG) && (changed & CH341_BIT_RI)) || | ||
473 | ((arg & TIOCM_DSR) && (changed & CH341_BIT_DSR)) || | ||
474 | ((arg & TIOCM_CD) && (changed & CH341_BIT_DCD)) || | ||
475 | ((arg & TIOCM_CTS) && (changed & CH341_BIT_CTS))) { | ||
476 | return 0; | ||
477 | } | ||
478 | prevstatus = status; | ||
479 | } | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | /*static int ch341_ioctl(struct usb_serial_port *port, struct file *file,*/ | ||
485 | static int ch341_ioctl(struct tty_struct *tty, struct file *file, | ||
486 | unsigned int cmd, unsigned long arg) | ||
487 | { | ||
488 | struct usb_serial_port *port = tty->driver_data; | ||
489 | dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); | ||
490 | |||
491 | switch (cmd) { | ||
492 | case TIOCMIWAIT: | ||
493 | dbg("%s (%d) TIOCMIWAIT", __func__, port->number); | ||
494 | return wait_modem_info(port, arg); | ||
495 | |||
496 | default: | ||
497 | dbg("%s not supported = 0x%04x", __func__, cmd); | ||
498 | break; | ||
499 | } | ||
500 | |||
501 | return -ENOIOCTLCMD; | ||
502 | } | ||
503 | |||
504 | static int ch341_tiocmget(struct tty_struct *tty, struct file *file) | ||
505 | { | ||
506 | struct usb_serial_port *port = tty->driver_data; | ||
507 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
508 | unsigned long flags; | ||
509 | u8 mcr; | ||
510 | u8 status; | ||
511 | unsigned int result; | ||
512 | |||
513 | dbg("%s (%d)", __func__, port->number); | ||
514 | |||
515 | spin_lock_irqsave(&priv->lock, flags); | ||
516 | mcr = priv->line_control; | ||
517 | status = priv->line_status; | ||
518 | spin_unlock_irqrestore(&priv->lock, flags); | ||
519 | |||
520 | result = ((mcr & CH341_BIT_DTR) ? TIOCM_DTR : 0) | ||
521 | | ((mcr & CH341_BIT_RTS) ? TIOCM_RTS : 0) | ||
522 | | ((status & CH341_BIT_CTS) ? TIOCM_CTS : 0) | ||
523 | | ((status & CH341_BIT_DSR) ? TIOCM_DSR : 0) | ||
524 | | ((status & CH341_BIT_RI) ? TIOCM_RI : 0) | ||
525 | | ((status & CH341_BIT_DCD) ? TIOCM_CD : 0); | ||
526 | |||
527 | dbg("%s - result = %x", __func__, result); | ||
528 | |||
529 | return result; | ||
530 | } | ||
531 | |||
532 | |||
533 | static int ch341_reset_resume(struct usb_interface *intf) | ||
534 | { | ||
535 | struct usb_device *dev = interface_to_usbdev(intf); | ||
536 | struct usb_serial *serial = NULL; | ||
537 | struct ch341_private *priv; | ||
538 | |||
539 | serial = usb_get_intfdata(intf); | ||
540 | priv = usb_get_serial_port_data(serial->port[0]); | ||
541 | |||
542 | /*reconfigure ch341 serial port after bus-reset*/ | ||
543 | ch341_configure(dev, priv); | ||
544 | |||
545 | usb_serial_resume(intf); | ||
546 | |||
547 | return 0; | ||
305 | } | 548 | } |
306 | 549 | ||
307 | static struct usb_driver ch341_driver = { | 550 | static struct usb_driver ch341_driver = { |
308 | .name = "ch341", | 551 | .name = "ch341", |
309 | .probe = usb_serial_probe, | 552 | .probe = usb_serial_probe, |
310 | .disconnect = usb_serial_disconnect, | 553 | .disconnect = usb_serial_disconnect, |
554 | .suspend = usb_serial_suspend, | ||
555 | .resume = usb_serial_resume, | ||
556 | .reset_resume = ch341_reset_resume, | ||
311 | .id_table = id_table, | 557 | .id_table = id_table, |
312 | .no_dynamic_id = 1, | 558 | .no_dynamic_id = 1, |
559 | .supports_autosuspend = 1, | ||
313 | }; | 560 | }; |
314 | 561 | ||
315 | static struct usb_serial_driver ch341_device = { | 562 | static struct usb_serial_driver ch341_device = { |
@@ -317,12 +564,17 @@ static struct usb_serial_driver ch341_device = { | |||
317 | .owner = THIS_MODULE, | 564 | .owner = THIS_MODULE, |
318 | .name = "ch341-uart", | 565 | .name = "ch341-uart", |
319 | }, | 566 | }, |
320 | .id_table = id_table, | 567 | .id_table = id_table, |
321 | .usb_driver = &ch341_driver, | 568 | .usb_driver = &ch341_driver, |
322 | .num_ports = 1, | 569 | .num_ports = 1, |
323 | .open = ch341_open, | 570 | .open = ch341_open, |
324 | .set_termios = ch341_set_termios, | 571 | .close = ch341_close, |
325 | .attach = ch341_attach, | 572 | .ioctl = ch341_ioctl, |
573 | .set_termios = ch341_set_termios, | ||
574 | .tiocmget = ch341_tiocmget, | ||
575 | .tiocmset = ch341_tiocmset, | ||
576 | .read_int_callback = ch341_read_int_callback, | ||
577 | .attach = ch341_attach, | ||
326 | }; | 578 | }; |
327 | 579 | ||
328 | static int __init ch341_init(void) | 580 | static int __init ch341_init(void) |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp210x.c index 9b4082b58c5b..e8d5133ce9c8 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -11,10 +11,6 @@ | |||
11 | * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow | 11 | * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow |
12 | * control thanks to Munir Nassar nassarmu@real-time.com | 12 | * control thanks to Munir Nassar nassarmu@real-time.com |
13 | * | 13 | * |
14 | * Outstanding Issues: | ||
15 | * Buffers are not flushed when the port is opened. | ||
16 | * Multiple calls to write() may fail with "Resource temporarily unavailable" | ||
17 | * | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
@@ -31,7 +27,7 @@ | |||
31 | /* | 27 | /* |
32 | * Version Information | 28 | * Version Information |
33 | */ | 29 | */ |
34 | #define DRIVER_VERSION "v0.07" | 30 | #define DRIVER_VERSION "v0.08" |
35 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" | 31 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" |
36 | 32 | ||
37 | /* | 33 | /* |
@@ -42,17 +38,21 @@ static int cp2101_open(struct tty_struct *, struct usb_serial_port *, | |||
42 | static void cp2101_cleanup(struct usb_serial_port *); | 38 | static void cp2101_cleanup(struct usb_serial_port *); |
43 | static void cp2101_close(struct tty_struct *, struct usb_serial_port *, | 39 | static void cp2101_close(struct tty_struct *, struct usb_serial_port *, |
44 | struct file*); | 40 | struct file*); |
45 | static void cp2101_get_termios(struct tty_struct *); | 41 | static void cp2101_get_termios(struct tty_struct *, |
42 | struct usb_serial_port *port); | ||
43 | static void cp2101_get_termios_port(struct usb_serial_port *port, | ||
44 | unsigned int *cflagp, unsigned int *baudp); | ||
46 | static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *, | 45 | static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *, |
47 | struct ktermios*); | 46 | struct ktermios*); |
48 | static int cp2101_tiocmget(struct tty_struct *, struct file *); | 47 | static int cp2101_tiocmget(struct tty_struct *, struct file *); |
49 | static int cp2101_tiocmset(struct tty_struct *, struct file *, | 48 | static int cp2101_tiocmset(struct tty_struct *, struct file *, |
50 | unsigned int, unsigned int); | 49 | unsigned int, unsigned int); |
50 | static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *, | ||
51 | unsigned int, unsigned int); | ||
51 | static void cp2101_break_ctl(struct tty_struct *, int); | 52 | static void cp2101_break_ctl(struct tty_struct *, int); |
52 | static int cp2101_startup(struct usb_serial *); | 53 | static int cp2101_startup(struct usb_serial *); |
53 | static void cp2101_shutdown(struct usb_serial *); | 54 | static void cp2101_shutdown(struct usb_serial *); |
54 | 55 | ||
55 | |||
56 | static int debug; | 56 | static int debug; |
57 | 57 | ||
58 | static struct usb_device_id id_table [] = { | 58 | static struct usb_device_id id_table [] = { |
@@ -91,6 +91,7 @@ static struct usb_device_id id_table [] = { | |||
91 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ | 91 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ |
92 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ | 92 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ |
93 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ | 93 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ |
94 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | ||
94 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 95 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
95 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 96 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
96 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ | 97 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ |
@@ -225,7 +226,7 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request, | |||
225 | kfree(buf); | 226 | kfree(buf); |
226 | 227 | ||
227 | if (result != size) { | 228 | if (result != size) { |
228 | dev_err(&port->dev, "%s - Unable to send config request, " | 229 | dbg("%s - Unable to send config request, " |
229 | "request=0x%x size=%d result=%d\n", | 230 | "request=0x%x size=%d result=%d\n", |
230 | __func__, request, size, result); | 231 | __func__, request, size, result); |
231 | return -EPROTO; | 232 | return -EPROTO; |
@@ -276,7 +277,7 @@ static int cp2101_set_config(struct usb_serial_port *port, u8 request, | |||
276 | kfree(buf); | 277 | kfree(buf); |
277 | 278 | ||
278 | if ((size > 2 && result != size) || result < 0) { | 279 | if ((size > 2 && result != size) || result < 0) { |
279 | dev_err(&port->dev, "%s - Unable to send request, " | 280 | dbg("%s - Unable to send request, " |
280 | "request=0x%x size=%d result=%d\n", | 281 | "request=0x%x size=%d result=%d\n", |
281 | __func__, request, size, result); | 282 | __func__, request, size, result); |
282 | return -EPROTO; | 283 | return -EPROTO; |
@@ -301,6 +302,47 @@ static inline int cp2101_set_config_single(struct usb_serial_port *port, | |||
301 | return cp2101_set_config(port, request, &data, 2); | 302 | return cp2101_set_config(port, request, &data, 2); |
302 | } | 303 | } |
303 | 304 | ||
305 | /* | ||
306 | * cp2101_quantise_baudrate | ||
307 | * Quantises the baud rate as per AN205 Table 1 | ||
308 | */ | ||
309 | static unsigned int cp2101_quantise_baudrate(unsigned int baud) { | ||
310 | if (baud <= 56) baud = 0; | ||
311 | else if (baud <= 300) baud = 300; | ||
312 | else if (baud <= 600) baud = 600; | ||
313 | else if (baud <= 1200) baud = 1200; | ||
314 | else if (baud <= 1800) baud = 1800; | ||
315 | else if (baud <= 2400) baud = 2400; | ||
316 | else if (baud <= 4000) baud = 4000; | ||
317 | else if (baud <= 4803) baud = 4800; | ||
318 | else if (baud <= 7207) baud = 7200; | ||
319 | else if (baud <= 9612) baud = 9600; | ||
320 | else if (baud <= 14428) baud = 14400; | ||
321 | else if (baud <= 16062) baud = 16000; | ||
322 | else if (baud <= 19250) baud = 19200; | ||
323 | else if (baud <= 28912) baud = 28800; | ||
324 | else if (baud <= 38601) baud = 38400; | ||
325 | else if (baud <= 51558) baud = 51200; | ||
326 | else if (baud <= 56280) baud = 56000; | ||
327 | else if (baud <= 58053) baud = 57600; | ||
328 | else if (baud <= 64111) baud = 64000; | ||
329 | else if (baud <= 77608) baud = 76800; | ||
330 | else if (baud <= 117028) baud = 115200; | ||
331 | else if (baud <= 129347) baud = 128000; | ||
332 | else if (baud <= 156868) baud = 153600; | ||
333 | else if (baud <= 237832) baud = 230400; | ||
334 | else if (baud <= 254234) baud = 250000; | ||
335 | else if (baud <= 273066) baud = 256000; | ||
336 | else if (baud <= 491520) baud = 460800; | ||
337 | else if (baud <= 567138) baud = 500000; | ||
338 | else if (baud <= 670254) baud = 576000; | ||
339 | else if (baud <= 1053257) baud = 921600; | ||
340 | else if (baud <= 1474560) baud = 1228800; | ||
341 | else if (baud <= 2457600) baud = 1843200; | ||
342 | else baud = 3686400; | ||
343 | return baud; | ||
344 | } | ||
345 | |||
304 | static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | 346 | static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, |
305 | struct file *filp) | 347 | struct file *filp) |
306 | { | 348 | { |
@@ -331,10 +373,12 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
331 | } | 373 | } |
332 | 374 | ||
333 | /* Configure the termios structure */ | 375 | /* Configure the termios structure */ |
334 | cp2101_get_termios(tty); | 376 | cp2101_get_termios(tty, port); |
335 | 377 | ||
336 | /* Set the DTR and RTS pins low */ | 378 | /* Set the DTR and RTS pins low */ |
337 | cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0); | 379 | cp2101_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data |
380 | : port, | ||
381 | NULL, TIOCM_DTR | TIOCM_RTS, 0); | ||
338 | 382 | ||
339 | return 0; | 383 | return 0; |
340 | } | 384 | } |
@@ -376,9 +420,31 @@ static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
376 | * from the device, corrects any unsupported values, and configures the | 420 | * from the device, corrects any unsupported values, and configures the |
377 | * termios structure to reflect the state of the device | 421 | * termios structure to reflect the state of the device |
378 | */ | 422 | */ |
379 | static void cp2101_get_termios (struct tty_struct *tty) | 423 | static void cp2101_get_termios(struct tty_struct *tty, |
424 | struct usb_serial_port *port) | ||
425 | { | ||
426 | unsigned int baud; | ||
427 | |||
428 | if (tty) { | ||
429 | cp2101_get_termios_port(tty->driver_data, | ||
430 | &tty->termios->c_cflag, &baud); | ||
431 | tty_encode_baud_rate(tty, baud, baud); | ||
432 | } | ||
433 | |||
434 | else { | ||
435 | unsigned int cflag; | ||
436 | cflag = 0; | ||
437 | cp2101_get_termios_port(port, &cflag, &baud); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * cp2101_get_termios_port | ||
443 | * This is the heart of cp2101_get_termios which always uses a &usb_serial_port. | ||
444 | */ | ||
445 | static void cp2101_get_termios_port(struct usb_serial_port *port, | ||
446 | unsigned int *cflagp, unsigned int *baudp) | ||
380 | { | 447 | { |
381 | struct usb_serial_port *port = tty->driver_data; | ||
382 | unsigned int cflag, modem_ctl[4]; | 448 | unsigned int cflag, modem_ctl[4]; |
383 | unsigned int baud; | 449 | unsigned int baud; |
384 | unsigned int bits; | 450 | unsigned int bits; |
@@ -388,12 +454,12 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
388 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); | 454 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); |
389 | /* Convert to baudrate */ | 455 | /* Convert to baudrate */ |
390 | if (baud) | 456 | if (baud) |
391 | baud = BAUD_RATE_GEN_FREQ / baud; | 457 | baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); |
392 | 458 | ||
393 | dbg("%s - baud rate = %d", __func__, baud); | 459 | dbg("%s - baud rate = %d", __func__, baud); |
460 | *baudp = baud; | ||
394 | 461 | ||
395 | tty_encode_baud_rate(tty, baud, baud); | 462 | cflag = *cflagp; |
396 | cflag = tty->termios->c_cflag; | ||
397 | 463 | ||
398 | cp2101_get_config(port, CP2101_BITS, &bits, 2); | 464 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
399 | cflag &= ~CSIZE; | 465 | cflag &= ~CSIZE; |
@@ -499,7 +565,7 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
499 | cflag &= ~CRTSCTS; | 565 | cflag &= ~CRTSCTS; |
500 | } | 566 | } |
501 | 567 | ||
502 | tty->termios->c_cflag = cflag; | 568 | *cflagp = cflag; |
503 | } | 569 | } |
504 | 570 | ||
505 | static void cp2101_set_termios(struct tty_struct *tty, | 571 | static void cp2101_set_termios(struct tty_struct *tty, |
@@ -517,46 +583,16 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
517 | tty->termios->c_cflag &= ~CMSPAR; | 583 | tty->termios->c_cflag &= ~CMSPAR; |
518 | cflag = tty->termios->c_cflag; | 584 | cflag = tty->termios->c_cflag; |
519 | old_cflag = old_termios->c_cflag; | 585 | old_cflag = old_termios->c_cflag; |
520 | baud = tty_get_baud_rate(tty); | 586 | baud = cp2101_quantise_baudrate(tty_get_baud_rate(tty)); |
521 | 587 | ||
522 | /* If the baud rate is to be updated*/ | 588 | /* If the baud rate is to be updated*/ |
523 | if (baud != tty_termios_baud_rate(old_termios)) { | 589 | if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { |
524 | switch (baud) { | 590 | dbg("%s - Setting baud rate to %d baud", __func__, |
525 | case 0: | 591 | baud); |
526 | case 600: | 592 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, |
527 | case 1200: | 593 | ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { |
528 | case 1800: | 594 | dbg("Baud rate requested not supported by device\n"); |
529 | case 2400: | 595 | baud = tty_termios_baud_rate(old_termios); |
530 | case 4800: | ||
531 | case 7200: | ||
532 | case 9600: | ||
533 | case 14400: | ||
534 | case 19200: | ||
535 | case 28800: | ||
536 | case 38400: | ||
537 | case 55854: | ||
538 | case 57600: | ||
539 | case 115200: | ||
540 | case 127117: | ||
541 | case 230400: | ||
542 | case 460800: | ||
543 | case 921600: | ||
544 | case 3686400: | ||
545 | break; | ||
546 | default: | ||
547 | baud = 9600; | ||
548 | break; | ||
549 | } | ||
550 | |||
551 | if (baud) { | ||
552 | dbg("%s - Setting baud rate to %d baud", __func__, | ||
553 | baud); | ||
554 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, | ||
555 | (BAUD_RATE_GEN_FREQ / baud))) { | ||
556 | dev_err(&port->dev, "Baud rate requested not " | ||
557 | "supported by device\n"); | ||
558 | baud = tty_termios_baud_rate(old_termios); | ||
559 | } | ||
560 | } | 596 | } |
561 | } | 597 | } |
562 | /* Report back the resulting baud rate */ | 598 | /* Report back the resulting baud rate */ |
@@ -588,14 +624,14 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
588 | dbg("%s - data bits = 9", __func__); | 624 | dbg("%s - data bits = 9", __func__); |
589 | break;*/ | 625 | break;*/ |
590 | default: | 626 | default: |
591 | dev_err(&port->dev, "cp2101 driver does not " | 627 | dbg("cp2101 driver does not " |
592 | "support the number of bits requested," | 628 | "support the number of bits requested," |
593 | " using 8 bit mode\n"); | 629 | " using 8 bit mode\n"); |
594 | bits |= BITS_DATA_8; | 630 | bits |= BITS_DATA_8; |
595 | break; | 631 | break; |
596 | } | 632 | } |
597 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 633 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
598 | dev_err(&port->dev, "Number of data bits requested " | 634 | dbg("Number of data bits requested " |
599 | "not supported by device\n"); | 635 | "not supported by device\n"); |
600 | } | 636 | } |
601 | 637 | ||
@@ -612,7 +648,7 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
612 | } | 648 | } |
613 | } | 649 | } |
614 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 650 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
615 | dev_err(&port->dev, "Parity mode not supported " | 651 | dbg("Parity mode not supported " |
616 | "by device\n"); | 652 | "by device\n"); |
617 | } | 653 | } |
618 | 654 | ||
@@ -627,7 +663,7 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
627 | dbg("%s - stop bits = 1", __func__); | 663 | dbg("%s - stop bits = 1", __func__); |
628 | } | 664 | } |
629 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 665 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
630 | dev_err(&port->dev, "Number of stop bits requested " | 666 | dbg("Number of stop bits requested " |
631 | "not supported by device\n"); | 667 | "not supported by device\n"); |
632 | } | 668 | } |
633 | 669 | ||
@@ -661,6 +697,12 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | |||
661 | unsigned int set, unsigned int clear) | 697 | unsigned int set, unsigned int clear) |
662 | { | 698 | { |
663 | struct usb_serial_port *port = tty->driver_data; | 699 | struct usb_serial_port *port = tty->driver_data; |
700 | return cp2101_tiocmset_port(port, file, set, clear); | ||
701 | } | ||
702 | |||
703 | static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *file, | ||
704 | unsigned int set, unsigned int clear) | ||
705 | { | ||
664 | unsigned int control = 0; | 706 | unsigned int control = 0; |
665 | 707 | ||
666 | dbg("%s - port %d", __func__, port->number); | 708 | dbg("%s - port %d", __func__, port->number); |
@@ -685,7 +727,6 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | |||
685 | dbg("%s - control = 0x%.4x", __func__, control); | 727 | dbg("%s - control = 0x%.4x", __func__, control); |
686 | 728 | ||
687 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); | 729 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); |
688 | |||
689 | } | 730 | } |
690 | 731 | ||
691 | static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) | 732 | static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ae84c326a540..dcc87aaa8628 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1938,18 +1938,16 @@ static void ftdi_process_read(struct work_struct *work) | |||
1938 | /* Compare new line status to the old one, signal if different/ | 1938 | /* Compare new line status to the old one, signal if different/ |
1939 | N.B. packet may be processed more than once, but differences | 1939 | N.B. packet may be processed more than once, but differences |
1940 | are only processed once. */ | 1940 | are only processed once. */ |
1941 | if (priv != NULL) { | 1941 | char new_status = data[packet_offset + 0] & |
1942 | char new_status = data[packet_offset + 0] & | 1942 | FTDI_STATUS_B0_MASK; |
1943 | FTDI_STATUS_B0_MASK; | 1943 | if (new_status != priv->prev_status) { |
1944 | if (new_status != priv->prev_status) { | 1944 | priv->diff_status |= |
1945 | priv->diff_status |= | 1945 | new_status ^ priv->prev_status; |
1946 | new_status ^ priv->prev_status; | 1946 | wake_up_interruptible(&priv->delta_msr_wait); |
1947 | wake_up_interruptible(&priv->delta_msr_wait); | 1947 | priv->prev_status = new_status; |
1948 | priv->prev_status = new_status; | ||
1949 | } | ||
1950 | } | 1948 | } |
1951 | 1949 | ||
1952 | length = min(PKTSZ, urb->actual_length-packet_offset)-2; | 1950 | length = min_t(u32, PKTSZ, urb->actual_length-packet_offset)-2; |
1953 | if (length < 0) { | 1951 | if (length < 0) { |
1954 | dev_err(&port->dev, "%s - bad packet length: %d\n", | 1952 | dev_err(&port->dev, "%s - bad packet length: %d\n", |
1955 | __func__, length+2); | 1953 | __func__, length+2); |
@@ -2294,11 +2292,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2294 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | 2292 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, |
2295 | 0, 0, | 2293 | 0, 0, |
2296 | buf, 1, WDR_TIMEOUT); | 2294 | buf, 1, WDR_TIMEOUT); |
2297 | if (ret < 0) { | 2295 | if (ret < 0) |
2298 | dbg("%s Could not get modem status of device - err: %d", __func__, | ||
2299 | ret); | ||
2300 | return ret; | 2296 | return ret; |
2301 | } | ||
2302 | break; | 2297 | break; |
2303 | case FT8U232AM: | 2298 | case FT8U232AM: |
2304 | case FT232BM: | 2299 | case FT232BM: |
@@ -2313,15 +2308,11 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2313 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | 2308 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, |
2314 | 0, priv->interface, | 2309 | 0, priv->interface, |
2315 | buf, 2, WDR_TIMEOUT); | 2310 | buf, 2, WDR_TIMEOUT); |
2316 | if (ret < 0) { | 2311 | if (ret < 0) |
2317 | dbg("%s Could not get modem status of device - err: %d", __func__, | ||
2318 | ret); | ||
2319 | return ret; | 2312 | return ret; |
2320 | } | ||
2321 | break; | 2313 | break; |
2322 | default: | 2314 | default: |
2323 | return -EFAULT; | 2315 | return -EFAULT; |
2324 | break; | ||
2325 | } | 2316 | } |
2326 | 2317 | ||
2327 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | 2318 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 814909f1ee63..9d57cace3731 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -177,14 +177,6 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
177 | struct usb_serial_port *port; | 177 | struct usb_serial_port *port; |
178 | int i, c = 0, r; | 178 | int i, c = 0, r; |
179 | 179 | ||
180 | #ifdef CONFIG_PM | ||
181 | /* | ||
182 | * If this is an autoresume, don't submit URBs. | ||
183 | * They will be submitted in the open function instead. | ||
184 | */ | ||
185 | if (serial->dev->auto_pm) | ||
186 | return 0; | ||
187 | #endif | ||
188 | for (i = 0; i < serial->num_ports; i++) { | 180 | for (i = 0; i < serial->num_ports; i++) { |
189 | port = serial->port[i]; | 181 | port = serial->port[i]; |
190 | if (port->port.count && port->read_urb) { | 182 | if (port->port.count && port->read_urb) { |
@@ -196,6 +188,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
196 | 188 | ||
197 | return c ? -EIO : 0; | 189 | return c ? -EIO : 0; |
198 | } | 190 | } |
191 | EXPORT_SYMBOL_GPL(usb_serial_generic_resume); | ||
199 | 192 | ||
200 | void usb_serial_generic_close(struct tty_struct *tty, | 193 | void usb_serial_generic_close(struct tty_struct *tty, |
201 | struct usb_serial_port *port, struct file *filp) | 194 | struct usb_serial_port *port, struct file *filp) |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 132be74d2b89..ef92095b0732 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -78,6 +78,7 @@ static int ipaq_open(struct tty_struct *tty, | |||
78 | struct usb_serial_port *port, struct file *filp); | 78 | struct usb_serial_port *port, struct file *filp); |
79 | static void ipaq_close(struct tty_struct *tty, | 79 | static void ipaq_close(struct tty_struct *tty, |
80 | struct usb_serial_port *port, struct file *filp); | 80 | struct usb_serial_port *port, struct file *filp); |
81 | static int ipaq_calc_num_ports(struct usb_serial *serial); | ||
81 | static int ipaq_startup(struct usb_serial *serial); | 82 | static int ipaq_startup(struct usb_serial *serial); |
82 | static void ipaq_shutdown(struct usb_serial *serial); | 83 | static void ipaq_shutdown(struct usb_serial *serial); |
83 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, | 84 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, |
@@ -572,15 +573,10 @@ static struct usb_serial_driver ipaq_device = { | |||
572 | .description = "PocketPC PDA", | 573 | .description = "PocketPC PDA", |
573 | .usb_driver = &ipaq_driver, | 574 | .usb_driver = &ipaq_driver, |
574 | .id_table = ipaq_id_table, | 575 | .id_table = ipaq_id_table, |
575 | /* | ||
576 | * some devices have an extra endpoint, which | ||
577 | * must be ignored as it would make the core | ||
578 | * create a second port which oopses when used | ||
579 | */ | ||
580 | .num_ports = 1, | ||
581 | .open = ipaq_open, | 576 | .open = ipaq_open, |
582 | .close = ipaq_close, | 577 | .close = ipaq_close, |
583 | .attach = ipaq_startup, | 578 | .attach = ipaq_startup, |
579 | .calc_num_ports = ipaq_calc_num_ports, | ||
584 | .shutdown = ipaq_shutdown, | 580 | .shutdown = ipaq_shutdown, |
585 | .write = ipaq_write, | 581 | .write = ipaq_write, |
586 | .write_room = ipaq_write_room, | 582 | .write_room = ipaq_write_room, |
@@ -956,14 +952,49 @@ static void ipaq_destroy_lists(struct usb_serial_port *port) | |||
956 | } | 952 | } |
957 | 953 | ||
958 | 954 | ||
955 | static int ipaq_calc_num_ports(struct usb_serial *serial) | ||
956 | { | ||
957 | /* | ||
958 | * some devices have 3 endpoints, the 3rd of which | ||
959 | * must be ignored as it would make the core | ||
960 | * create a second port which oopses when used | ||
961 | */ | ||
962 | int ipaq_num_ports = 1; | ||
963 | |||
964 | dbg("%s - numberofendpoints: %d", __FUNCTION__, | ||
965 | (int)serial->interface->cur_altsetting->desc.bNumEndpoints); | ||
966 | |||
967 | /* | ||
968 | * a few devices have 4 endpoints, seemingly Yakuma devices, | ||
969 | * and we need the second pair, so let them have 2 ports | ||
970 | * | ||
971 | * TODO: can we drop port 1 ? | ||
972 | */ | ||
973 | if (serial->interface->cur_altsetting->desc.bNumEndpoints > 3) { | ||
974 | ipaq_num_ports = 2; | ||
975 | } | ||
976 | |||
977 | return ipaq_num_ports; | ||
978 | } | ||
979 | |||
980 | |||
959 | static int ipaq_startup(struct usb_serial *serial) | 981 | static int ipaq_startup(struct usb_serial *serial) |
960 | { | 982 | { |
961 | dbg("%s", __func__); | 983 | dbg("%s", __func__); |
962 | if (serial->dev->actconfig->desc.bConfigurationValue != 1) { | 984 | if (serial->dev->actconfig->desc.bConfigurationValue != 1) { |
985 | /* | ||
986 | * FIXME: HP iPaq rx3715, possibly others, have 1 config that | ||
987 | * is labeled as 2 | ||
988 | */ | ||
989 | |||
963 | dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", | 990 | dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", |
964 | serial->dev->actconfig->desc.bConfigurationValue); | 991 | serial->dev->actconfig->desc.bConfigurationValue); |
965 | return -ENODEV; | 992 | return -ENODEV; |
966 | } | 993 | } |
994 | |||
995 | dbg("%s - iPAQ module configured for %d ports", | ||
996 | __FUNCTION__, serial->num_ports); | ||
997 | |||
967 | return usb_reset_configuration(serial->dev); | 998 | return usb_reset_configuration(serial->dev); |
968 | } | 999 | } |
969 | 1000 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 9878c0fb3859..00daa8f7759a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -1507,7 +1507,7 @@ static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint, | |||
1507 | } else { | 1507 | } else { |
1508 | dev_warn(&serial->interface->dev, | 1508 | dev_warn(&serial->interface->dev, |
1509 | "unsupported endpoint type %x\n", | 1509 | "unsupported endpoint type %x\n", |
1510 | ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | 1510 | usb_endpoint_type(ep_desc)); |
1511 | usb_free_urb(urb); | 1511 | usb_free_urb(urb); |
1512 | return NULL; | 1512 | return NULL; |
1513 | } | 1513 | } |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index cea326f1f105..839583dc8b6a 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Opticon USB barcode to serial driver | 2 | * Opticon USB barcode to serial driver |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de> | 4 | * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de> |
5 | * Copyright (C) 2008 Novell Inc. | 5 | * Copyright (C) 2008 - 2009 Novell Inc. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License version | 8 | * modify it under the terms of the GNU General Public License version |
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <linux/tty_driver.h> | 15 | #include <linux/tty_driver.h> |
16 | #include <linux/tty_flip.h> | 16 | #include <linux/tty_flip.h> |
17 | #include <linux/serial.h> | ||
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
18 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
19 | #include <linux/usb/serial.h> | 20 | #include <linux/usb/serial.h> |
@@ -40,8 +41,12 @@ struct opticon_private { | |||
40 | bool throttled; | 41 | bool throttled; |
41 | bool actually_throttled; | 42 | bool actually_throttled; |
42 | bool rts; | 43 | bool rts; |
44 | int outstanding_urbs; | ||
43 | }; | 45 | }; |
44 | 46 | ||
47 | /* max number of write urbs in flight */ | ||
48 | #define URB_UPPER_LIMIT 4 | ||
49 | |||
45 | static void opticon_bulk_callback(struct urb *urb) | 50 | static void opticon_bulk_callback(struct urb *urb) |
46 | { | 51 | { |
47 | struct opticon_private *priv = urb->context; | 52 | struct opticon_private *priv = urb->context; |
@@ -106,7 +111,6 @@ static void opticon_bulk_callback(struct urb *urb) | |||
106 | priv->rts = false; | 111 | priv->rts = false; |
107 | else | 112 | else |
108 | priv->rts = true; | 113 | priv->rts = true; |
109 | /* FIXME change the RTS level */ | ||
110 | } else { | 114 | } else { |
111 | dev_dbg(&priv->udev->dev, | 115 | dev_dbg(&priv->udev->dev, |
112 | "Unknown data packet received from the device:" | 116 | "Unknown data packet received from the device:" |
@@ -188,6 +192,120 @@ static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
188 | usb_kill_urb(priv->bulk_read_urb); | 192 | usb_kill_urb(priv->bulk_read_urb); |
189 | } | 193 | } |
190 | 194 | ||
195 | static void opticon_write_bulk_callback(struct urb *urb) | ||
196 | { | ||
197 | struct opticon_private *priv = urb->context; | ||
198 | int status = urb->status; | ||
199 | unsigned long flags; | ||
200 | |||
201 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | ||
202 | kfree(urb->transfer_buffer); | ||
203 | |||
204 | if (status) | ||
205 | dbg("%s - nonzero write bulk status received: %d", | ||
206 | __func__, status); | ||
207 | |||
208 | spin_lock_irqsave(&priv->lock, flags); | ||
209 | --priv->outstanding_urbs; | ||
210 | spin_unlock_irqrestore(&priv->lock, flags); | ||
211 | |||
212 | usb_serial_port_softint(priv->port); | ||
213 | } | ||
214 | |||
215 | static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
216 | const unsigned char *buf, int count) | ||
217 | { | ||
218 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
219 | struct usb_serial *serial = port->serial; | ||
220 | struct urb *urb; | ||
221 | unsigned char *buffer; | ||
222 | unsigned long flags; | ||
223 | int status; | ||
224 | |||
225 | dbg("%s - port %d", __func__, port->number); | ||
226 | |||
227 | spin_lock_irqsave(&priv->lock, flags); | ||
228 | if (priv->outstanding_urbs > URB_UPPER_LIMIT) { | ||
229 | spin_unlock_irqrestore(&priv->lock, flags); | ||
230 | dbg("%s - write limit hit\n", __func__); | ||
231 | return 0; | ||
232 | } | ||
233 | priv->outstanding_urbs++; | ||
234 | spin_unlock_irqrestore(&priv->lock, flags); | ||
235 | |||
236 | buffer = kmalloc(count, GFP_ATOMIC); | ||
237 | if (!buffer) { | ||
238 | dev_err(&port->dev, "out of memory\n"); | ||
239 | count = -ENOMEM; | ||
240 | goto error_no_buffer; | ||
241 | } | ||
242 | |||
243 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
244 | if (!urb) { | ||
245 | dev_err(&port->dev, "no more free urbs\n"); | ||
246 | count = -ENOMEM; | ||
247 | goto error_no_urb; | ||
248 | } | ||
249 | |||
250 | memcpy(buffer, buf, count); | ||
251 | |||
252 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); | ||
253 | |||
254 | usb_fill_bulk_urb(urb, serial->dev, | ||
255 | usb_sndbulkpipe(serial->dev, | ||
256 | port->bulk_out_endpointAddress), | ||
257 | buffer, count, opticon_write_bulk_callback, priv); | ||
258 | |||
259 | /* send it down the pipe */ | ||
260 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
261 | if (status) { | ||
262 | dev_err(&port->dev, | ||
263 | "%s - usb_submit_urb(write bulk) failed with status = %d\n", | ||
264 | __func__, status); | ||
265 | count = status; | ||
266 | goto error; | ||
267 | } | ||
268 | |||
269 | /* we are done with this urb, so let the host driver | ||
270 | * really free it when it is finished with it */ | ||
271 | usb_free_urb(urb); | ||
272 | |||
273 | return count; | ||
274 | error: | ||
275 | usb_free_urb(urb); | ||
276 | error_no_urb: | ||
277 | kfree(buffer); | ||
278 | error_no_buffer: | ||
279 | spin_lock_irqsave(&priv->lock, flags); | ||
280 | --priv->outstanding_urbs; | ||
281 | spin_unlock_irqrestore(&priv->lock, flags); | ||
282 | return count; | ||
283 | } | ||
284 | |||
285 | static int opticon_write_room(struct tty_struct *tty) | ||
286 | { | ||
287 | struct usb_serial_port *port = tty->driver_data; | ||
288 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
289 | unsigned long flags; | ||
290 | |||
291 | dbg("%s - port %d", __func__, port->number); | ||
292 | |||
293 | /* | ||
294 | * We really can take almost anything the user throws at us | ||
295 | * but let's pick a nice big number to tell the tty | ||
296 | * layer that we have lots of free space, unless we don't. | ||
297 | */ | ||
298 | spin_lock_irqsave(&priv->lock, flags); | ||
299 | if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { | ||
300 | spin_unlock_irqrestore(&priv->lock, flags); | ||
301 | dbg("%s - write limit hit\n", __func__); | ||
302 | return 0; | ||
303 | } | ||
304 | spin_unlock_irqrestore(&priv->lock, flags); | ||
305 | |||
306 | return 2048; | ||
307 | } | ||
308 | |||
191 | static void opticon_throttle(struct tty_struct *tty) | 309 | static void opticon_throttle(struct tty_struct *tty) |
192 | { | 310 | { |
193 | struct usb_serial_port *port = tty->driver_data; | 311 | struct usb_serial_port *port = tty->driver_data; |
@@ -223,6 +341,67 @@ static void opticon_unthrottle(struct tty_struct *tty) | |||
223 | __func__, result); | 341 | __func__, result); |
224 | } | 342 | } |
225 | 343 | ||
344 | static int opticon_tiocmget(struct tty_struct *tty, struct file *file) | ||
345 | { | ||
346 | struct usb_serial_port *port = tty->driver_data; | ||
347 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
348 | unsigned long flags; | ||
349 | int result = 0; | ||
350 | |||
351 | dbg("%s - port %d", __func__, port->number); | ||
352 | |||
353 | spin_lock_irqsave(&priv->lock, flags); | ||
354 | if (priv->rts) | ||
355 | result = TIOCM_RTS; | ||
356 | spin_unlock_irqrestore(&priv->lock, flags); | ||
357 | |||
358 | dbg("%s - %x", __func__, result); | ||
359 | return result; | ||
360 | } | ||
361 | |||
362 | static int get_serial_info(struct opticon_private *priv, | ||
363 | struct serial_struct __user *serial) | ||
364 | { | ||
365 | struct serial_struct tmp; | ||
366 | |||
367 | if (!serial) | ||
368 | return -EFAULT; | ||
369 | |||
370 | memset(&tmp, 0x00, sizeof(tmp)); | ||
371 | |||
372 | /* fake emulate a 16550 uart to make userspace code happy */ | ||
373 | tmp.type = PORT_16550A; | ||
374 | tmp.line = priv->serial->minor; | ||
375 | tmp.port = 0; | ||
376 | tmp.irq = 0; | ||
377 | tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | ||
378 | tmp.xmit_fifo_size = 1024; | ||
379 | tmp.baud_base = 9600; | ||
380 | tmp.close_delay = 5*HZ; | ||
381 | tmp.closing_wait = 30*HZ; | ||
382 | |||
383 | if (copy_to_user(serial, &tmp, sizeof(*serial))) | ||
384 | return -EFAULT; | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int opticon_ioctl(struct tty_struct *tty, struct file *file, | ||
389 | unsigned int cmd, unsigned long arg) | ||
390 | { | ||
391 | struct usb_serial_port *port = tty->driver_data; | ||
392 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
393 | |||
394 | dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); | ||
395 | |||
396 | switch (cmd) { | ||
397 | case TIOCGSERIAL: | ||
398 | return get_serial_info(priv, | ||
399 | (struct serial_struct __user *)arg); | ||
400 | } | ||
401 | |||
402 | return -ENOIOCTLCMD; | ||
403 | } | ||
404 | |||
226 | static int opticon_startup(struct usb_serial *serial) | 405 | static int opticon_startup(struct usb_serial *serial) |
227 | { | 406 | { |
228 | struct opticon_private *priv; | 407 | struct opticon_private *priv; |
@@ -306,11 +485,37 @@ static void opticon_shutdown(struct usb_serial *serial) | |||
306 | usb_set_serial_data(serial, NULL); | 485 | usb_set_serial_data(serial, NULL); |
307 | } | 486 | } |
308 | 487 | ||
488 | static int opticon_suspend(struct usb_interface *intf, pm_message_t message) | ||
489 | { | ||
490 | struct usb_serial *serial = usb_get_intfdata(intf); | ||
491 | struct opticon_private *priv = usb_get_serial_data(serial); | ||
492 | |||
493 | usb_kill_urb(priv->bulk_read_urb); | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static int opticon_resume(struct usb_interface *intf) | ||
498 | { | ||
499 | struct usb_serial *serial = usb_get_intfdata(intf); | ||
500 | struct opticon_private *priv = usb_get_serial_data(serial); | ||
501 | struct usb_serial_port *port = serial->port[0]; | ||
502 | int result; | ||
503 | |||
504 | mutex_lock(&port->mutex); | ||
505 | if (port->port.count) | ||
506 | result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO); | ||
507 | else | ||
508 | result = 0; | ||
509 | mutex_unlock(&port->mutex); | ||
510 | return result; | ||
511 | } | ||
309 | 512 | ||
310 | static struct usb_driver opticon_driver = { | 513 | static struct usb_driver opticon_driver = { |
311 | .name = "opticon", | 514 | .name = "opticon", |
312 | .probe = usb_serial_probe, | 515 | .probe = usb_serial_probe, |
313 | .disconnect = usb_serial_disconnect, | 516 | .disconnect = usb_serial_disconnect, |
517 | .suspend = opticon_suspend, | ||
518 | .resume = opticon_resume, | ||
314 | .id_table = id_table, | 519 | .id_table = id_table, |
315 | .no_dynamic_id = 1, | 520 | .no_dynamic_id = 1, |
316 | }; | 521 | }; |
@@ -326,9 +531,13 @@ static struct usb_serial_driver opticon_device = { | |||
326 | .attach = opticon_startup, | 531 | .attach = opticon_startup, |
327 | .open = opticon_open, | 532 | .open = opticon_open, |
328 | .close = opticon_close, | 533 | .close = opticon_close, |
534 | .write = opticon_write, | ||
535 | .write_room = opticon_write_room, | ||
329 | .shutdown = opticon_shutdown, | 536 | .shutdown = opticon_shutdown, |
330 | .throttle = opticon_throttle, | 537 | .throttle = opticon_throttle, |
331 | .unthrottle = opticon_unthrottle, | 538 | .unthrottle = opticon_unthrottle, |
539 | .ioctl = opticon_ioctl, | ||
540 | .tiocmget = opticon_tiocmget, | ||
332 | }; | 541 | }; |
333 | 542 | ||
334 | static int __init opticon_init(void) | 543 | static int __init opticon_init(void) |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 61ebddc48497..d560c0b54e6e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -62,6 +62,8 @@ static int option_tiocmget(struct tty_struct *tty, struct file *file); | |||
62 | static int option_tiocmset(struct tty_struct *tty, struct file *file, | 62 | static int option_tiocmset(struct tty_struct *tty, struct file *file, |
63 | unsigned int set, unsigned int clear); | 63 | unsigned int set, unsigned int clear); |
64 | static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port); | 64 | static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port); |
65 | static int option_suspend(struct usb_serial *serial, pm_message_t message); | ||
66 | static int option_resume(struct usb_serial *serial); | ||
65 | 67 | ||
66 | /* Vendor and product IDs */ | 68 | /* Vendor and product IDs */ |
67 | #define OPTION_VENDOR_ID 0x0AF0 | 69 | #define OPTION_VENDOR_ID 0x0AF0 |
@@ -523,6 +525,8 @@ static struct usb_driver option_driver = { | |||
523 | .name = "option", | 525 | .name = "option", |
524 | .probe = usb_serial_probe, | 526 | .probe = usb_serial_probe, |
525 | .disconnect = usb_serial_disconnect, | 527 | .disconnect = usb_serial_disconnect, |
528 | .suspend = usb_serial_suspend, | ||
529 | .resume = usb_serial_resume, | ||
526 | .id_table = option_ids, | 530 | .id_table = option_ids, |
527 | .no_dynamic_id = 1, | 531 | .no_dynamic_id = 1, |
528 | }; | 532 | }; |
@@ -551,6 +555,8 @@ static struct usb_serial_driver option_1port_device = { | |||
551 | .attach = option_startup, | 555 | .attach = option_startup, |
552 | .shutdown = option_shutdown, | 556 | .shutdown = option_shutdown, |
553 | .read_int_callback = option_instat_callback, | 557 | .read_int_callback = option_instat_callback, |
558 | .suspend = option_suspend, | ||
559 | .resume = option_resume, | ||
554 | }; | 560 | }; |
555 | 561 | ||
556 | static int debug; | 562 | static int debug; |
@@ -821,10 +827,10 @@ static void option_instat_callback(struct urb *urb) | |||
821 | req_pkt->bRequestType, req_pkt->bRequest); | 827 | req_pkt->bRequestType, req_pkt->bRequest); |
822 | } | 828 | } |
823 | } else | 829 | } else |
824 | dbg("%s: error %d", __func__, status); | 830 | err("%s: error %d", __func__, status); |
825 | 831 | ||
826 | /* Resubmit urb so we continue receiving IRQ data */ | 832 | /* Resubmit urb so we continue receiving IRQ data */ |
827 | if (status != -ESHUTDOWN) { | 833 | if (status != -ESHUTDOWN && status != -ENOENT) { |
828 | urb->dev = serial->dev; | 834 | urb->dev = serial->dev; |
829 | err = usb_submit_urb(urb, GFP_ATOMIC); | 835 | err = usb_submit_urb(urb, GFP_ATOMIC); |
830 | if (err) | 836 | if (err) |
@@ -843,7 +849,6 @@ static int option_write_room(struct tty_struct *tty) | |||
843 | 849 | ||
844 | portdata = usb_get_serial_port_data(port); | 850 | portdata = usb_get_serial_port_data(port); |
845 | 851 | ||
846 | |||
847 | for (i = 0; i < N_OUT_URB; i++) { | 852 | for (i = 0; i < N_OUT_URB; i++) { |
848 | this_urb = portdata->out_urbs[i]; | 853 | this_urb = portdata->out_urbs[i]; |
849 | if (this_urb && !test_bit(i, &portdata->out_busy)) | 854 | if (this_urb && !test_bit(i, &portdata->out_busy)) |
@@ -1105,14 +1110,12 @@ bail_out_error: | |||
1105 | return 1; | 1110 | return 1; |
1106 | } | 1111 | } |
1107 | 1112 | ||
1108 | static void option_shutdown(struct usb_serial *serial) | 1113 | static void stop_read_write_urbs(struct usb_serial *serial) |
1109 | { | 1114 | { |
1110 | int i, j; | 1115 | int i, j; |
1111 | struct usb_serial_port *port; | 1116 | struct usb_serial_port *port; |
1112 | struct option_port_private *portdata; | 1117 | struct option_port_private *portdata; |
1113 | 1118 | ||
1114 | dbg("%s", __func__); | ||
1115 | |||
1116 | /* Stop reading/writing urbs */ | 1119 | /* Stop reading/writing urbs */ |
1117 | for (i = 0; i < serial->num_ports; ++i) { | 1120 | for (i = 0; i < serial->num_ports; ++i) { |
1118 | port = serial->port[i]; | 1121 | port = serial->port[i]; |
@@ -1122,6 +1125,17 @@ static void option_shutdown(struct usb_serial *serial) | |||
1122 | for (j = 0; j < N_OUT_URB; j++) | 1125 | for (j = 0; j < N_OUT_URB; j++) |
1123 | usb_kill_urb(portdata->out_urbs[j]); | 1126 | usb_kill_urb(portdata->out_urbs[j]); |
1124 | } | 1127 | } |
1128 | } | ||
1129 | |||
1130 | static void option_shutdown(struct usb_serial *serial) | ||
1131 | { | ||
1132 | int i, j; | ||
1133 | struct usb_serial_port *port; | ||
1134 | struct option_port_private *portdata; | ||
1135 | |||
1136 | dbg("%s", __func__); | ||
1137 | |||
1138 | stop_read_write_urbs(serial); | ||
1125 | 1139 | ||
1126 | /* Now free them */ | 1140 | /* Now free them */ |
1127 | for (i = 0; i < serial->num_ports; ++i) { | 1141 | for (i = 0; i < serial->num_ports; ++i) { |
@@ -1152,6 +1166,66 @@ static void option_shutdown(struct usb_serial *serial) | |||
1152 | } | 1166 | } |
1153 | } | 1167 | } |
1154 | 1168 | ||
1169 | static int option_suspend(struct usb_serial *serial, pm_message_t message) | ||
1170 | { | ||
1171 | dbg("%s entered", __func__); | ||
1172 | stop_read_write_urbs(serial); | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
1177 | static int option_resume(struct usb_serial *serial) | ||
1178 | { | ||
1179 | int err, i, j; | ||
1180 | struct usb_serial_port *port; | ||
1181 | struct urb *urb; | ||
1182 | struct option_port_private *portdata; | ||
1183 | |||
1184 | dbg("%s entered", __func__); | ||
1185 | /* get the interrupt URBs resubmitted unconditionally */ | ||
1186 | for (i = 0; i < serial->num_ports; i++) { | ||
1187 | port = serial->port[i]; | ||
1188 | if (!port->interrupt_in_urb) { | ||
1189 | dbg("%s: No interrupt URB for port %d\n", __func__, i); | ||
1190 | continue; | ||
1191 | } | ||
1192 | port->interrupt_in_urb->dev = serial->dev; | ||
1193 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); | ||
1194 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); | ||
1195 | if (err < 0) { | ||
1196 | err("%s: Error %d for interrupt URB of port%d", | ||
1197 | __func__, err, i); | ||
1198 | return err; | ||
1199 | } | ||
1200 | } | ||
1201 | |||
1202 | for (i = 0; i < serial->num_ports; i++) { | ||
1203 | /* walk all ports */ | ||
1204 | port = serial->port[i]; | ||
1205 | portdata = usb_get_serial_port_data(port); | ||
1206 | mutex_lock(&port->mutex); | ||
1207 | |||
1208 | /* skip closed ports */ | ||
1209 | if (!port->port.count) { | ||
1210 | mutex_unlock(&port->mutex); | ||
1211 | continue; | ||
1212 | } | ||
1213 | |||
1214 | for (j = 0; j < N_IN_URB; j++) { | ||
1215 | urb = portdata->in_urbs[j]; | ||
1216 | err = usb_submit_urb(urb, GFP_NOIO); | ||
1217 | if (err < 0) { | ||
1218 | mutex_unlock(&port->mutex); | ||
1219 | err("%s: Error %d for bulk URB %d", | ||
1220 | __func__, err, i); | ||
1221 | return err; | ||
1222 | } | ||
1223 | } | ||
1224 | mutex_unlock(&port->mutex); | ||
1225 | } | ||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1155 | MODULE_AUTHOR(DRIVER_AUTHOR); | 1229 | MODULE_AUTHOR(DRIVER_AUTHOR); |
1156 | MODULE_DESCRIPTION(DRIVER_DESC); | 1230 | MODULE_DESCRIPTION(DRIVER_DESC); |
1157 | MODULE_VERSION(DRIVER_VERSION); | 1231 | MODULE_VERSION(DRIVER_VERSION); |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c new file mode 100644 index 000000000000..e6d6b0c17fd9 --- /dev/null +++ b/drivers/usb/serial/qcserial.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /* | ||
2 | * Qualcomm Serial USB driver | ||
3 | * | ||
4 | * Copyright (c) 2008 QUALCOMM Incorporated. | ||
5 | * Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de> | ||
6 | * Copyright (c) 2009 Novell Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/tty.h> | ||
15 | #include <linux/tty_flip.h> | ||
16 | #include <linux/usb.h> | ||
17 | #include <linux/usb/serial.h> | ||
18 | |||
19 | #define DRIVER_AUTHOR "Qualcomm Inc" | ||
20 | #define DRIVER_DESC "Qualcomm USB Serial driver" | ||
21 | |||
22 | static int debug; | ||
23 | |||
24 | static struct usb_device_id id_table[] = { | ||
25 | {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */ | ||
26 | {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | ||
27 | {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | ||
28 | {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ | ||
29 | { } /* Terminating entry */ | ||
30 | }; | ||
31 | MODULE_DEVICE_TABLE(usb, id_table); | ||
32 | |||
33 | static struct usb_driver qcdriver = { | ||
34 | .name = "qcserial", | ||
35 | .probe = usb_serial_probe, | ||
36 | .disconnect = usb_serial_disconnect, | ||
37 | .id_table = id_table, | ||
38 | .suspend = usb_serial_suspend, | ||
39 | .resume = usb_serial_resume, | ||
40 | .supports_autosuspend = true, | ||
41 | }; | ||
42 | |||
43 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | ||
44 | { | ||
45 | int retval = -ENODEV; | ||
46 | __u8 nintf; | ||
47 | __u8 ifnum; | ||
48 | |||
49 | dbg("%s", __func__); | ||
50 | |||
51 | nintf = serial->dev->actconfig->desc.bNumInterfaces; | ||
52 | dbg("Num Interfaces = %d", nintf); | ||
53 | ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | ||
54 | dbg("This Interface = %d", ifnum); | ||
55 | |||
56 | switch (nintf) { | ||
57 | case 1: | ||
58 | /* QDL mode */ | ||
59 | if (serial->interface->num_altsetting == 2) { | ||
60 | struct usb_host_interface *intf; | ||
61 | |||
62 | intf = &serial->interface->altsetting[1]; | ||
63 | if (intf->desc.bNumEndpoints == 2) { | ||
64 | if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && | ||
65 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { | ||
66 | dbg("QDL port found"); | ||
67 | retval = usb_set_interface(serial->dev, ifnum, 1); | ||
68 | if (retval < 0) { | ||
69 | dev_err(&serial->dev->dev, | ||
70 | "Could not set interface, error %d\n", | ||
71 | retval); | ||
72 | retval = -ENODEV; | ||
73 | } | ||
74 | return retval; | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | break; | ||
79 | |||
80 | case 4: | ||
81 | /* Composite mode */ | ||
82 | if (ifnum == 2) { | ||
83 | dbg("Modem port found"); | ||
84 | retval = usb_set_interface(serial->dev, ifnum, 0); | ||
85 | if (retval < 0) { | ||
86 | dev_err(&serial->dev->dev, | ||
87 | "Could not set interface, error %d\n", | ||
88 | retval); | ||
89 | retval = -ENODEV; | ||
90 | } | ||
91 | return retval; | ||
92 | } | ||
93 | break; | ||
94 | |||
95 | default: | ||
96 | dev_err(&serial->dev->dev, | ||
97 | "unknown number of interfaces: %d\n", nintf); | ||
98 | return -ENODEV; | ||
99 | } | ||
100 | |||
101 | return retval; | ||
102 | } | ||
103 | |||
104 | static struct usb_serial_driver qcdevice = { | ||
105 | .driver = { | ||
106 | .owner = THIS_MODULE, | ||
107 | .name = "qcserial", | ||
108 | }, | ||
109 | .description = "Qualcomm USB modem", | ||
110 | .id_table = id_table, | ||
111 | .usb_driver = &qcdriver, | ||
112 | .num_ports = 1, | ||
113 | .probe = qcprobe, | ||
114 | }; | ||
115 | |||
116 | static int __init qcinit(void) | ||
117 | { | ||
118 | int retval; | ||
119 | |||
120 | retval = usb_serial_register(&qcdevice); | ||
121 | if (retval) | ||
122 | return retval; | ||
123 | |||
124 | retval = usb_register(&qcdriver); | ||
125 | if (retval) { | ||
126 | usb_serial_deregister(&qcdevice); | ||
127 | return retval; | ||
128 | } | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static void __exit qcexit(void) | ||
134 | { | ||
135 | usb_deregister(&qcdriver); | ||
136 | usb_serial_deregister(&qcdevice); | ||
137 | } | ||
138 | |||
139 | module_init(qcinit); | ||
140 | module_exit(qcexit); | ||
141 | |||
142 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
143 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
144 | MODULE_LICENSE("GPL v2"); | ||
145 | |||
146 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
147 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c new file mode 100644 index 000000000000..8b3cbc87adc7 --- /dev/null +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -0,0 +1,399 @@ | |||
1 | /* | ||
2 | * Symbol USB barcode to serial driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Greg Kroah-Hartman <gregkh@suse.de> | ||
5 | * Copyright (C) 2009 Novell Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/tty.h> | ||
15 | #include <linux/tty_driver.h> | ||
16 | #include <linux/tty_flip.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/usb.h> | ||
19 | #include <linux/usb/serial.h> | ||
20 | #include <linux/uaccess.h> | ||
21 | |||
22 | static int debug; | ||
23 | |||
24 | static struct usb_device_id id_table[] = { | ||
25 | { USB_DEVICE(0x05e0, 0x0600) }, | ||
26 | { }, | ||
27 | }; | ||
28 | MODULE_DEVICE_TABLE(usb, id_table); | ||
29 | |||
30 | /* This structure holds all of the individual device information */ | ||
31 | struct symbol_private { | ||
32 | struct usb_device *udev; | ||
33 | struct usb_serial *serial; | ||
34 | struct usb_serial_port *port; | ||
35 | unsigned char *int_buffer; | ||
36 | struct urb *int_urb; | ||
37 | int buffer_size; | ||
38 | u8 bInterval; | ||
39 | u8 int_address; | ||
40 | spinlock_t lock; /* protects the following flags */ | ||
41 | bool throttled; | ||
42 | bool actually_throttled; | ||
43 | bool rts; | ||
44 | }; | ||
45 | |||
46 | static void symbol_int_callback(struct urb *urb) | ||
47 | { | ||
48 | struct symbol_private *priv = urb->context; | ||
49 | unsigned char *data = urb->transfer_buffer; | ||
50 | struct usb_serial_port *port = priv->port; | ||
51 | int status = urb->status; | ||
52 | struct tty_struct *tty; | ||
53 | int result; | ||
54 | int available_room = 0; | ||
55 | int data_length; | ||
56 | |||
57 | dbg("%s - port %d", __func__, port->number); | ||
58 | |||
59 | switch (status) { | ||
60 | case 0: | ||
61 | /* success */ | ||
62 | break; | ||
63 | case -ECONNRESET: | ||
64 | case -ENOENT: | ||
65 | case -ESHUTDOWN: | ||
66 | /* this urb is terminated, clean up */ | ||
67 | dbg("%s - urb shutting down with status: %d", | ||
68 | __func__, status); | ||
69 | return; | ||
70 | default: | ||
71 | dbg("%s - nonzero urb status received: %d", | ||
72 | __func__, status); | ||
73 | goto exit; | ||
74 | } | ||
75 | |||
76 | usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, | ||
77 | data); | ||
78 | |||
79 | if (urb->actual_length > 1) { | ||
80 | data_length = urb->actual_length - 1; | ||
81 | |||
82 | /* | ||
83 | * Data from the device comes with a 1 byte header: | ||
84 | * | ||
85 | * <size of data>data... | ||
86 | * This is real data to be sent to the tty layer | ||
87 | * we pretty much just ignore the size and send everything | ||
88 | * else to the tty layer. | ||
89 | */ | ||
90 | tty = tty_port_tty_get(&port->port); | ||
91 | if (tty) { | ||
92 | available_room = tty_buffer_request_room(tty, | ||
93 | data_length); | ||
94 | if (available_room) { | ||
95 | tty_insert_flip_string(tty, &data[1], | ||
96 | available_room); | ||
97 | tty_flip_buffer_push(tty); | ||
98 | } | ||
99 | tty_kref_put(tty); | ||
100 | } | ||
101 | } else { | ||
102 | dev_dbg(&priv->udev->dev, | ||
103 | "Improper ammount of data received from the device, " | ||
104 | "%d bytes", urb->actual_length); | ||
105 | } | ||
106 | |||
107 | exit: | ||
108 | spin_lock(&priv->lock); | ||
109 | |||
110 | /* Continue trying to always read if we should */ | ||
111 | if (!priv->throttled) { | ||
112 | usb_fill_int_urb(priv->int_urb, priv->udev, | ||
113 | usb_rcvintpipe(priv->udev, | ||
114 | priv->int_address), | ||
115 | priv->int_buffer, priv->buffer_size, | ||
116 | symbol_int_callback, priv, priv->bInterval); | ||
117 | result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); | ||
118 | if (result) | ||
119 | dev_err(&port->dev, | ||
120 | "%s - failed resubmitting read urb, error %d\n", | ||
121 | __func__, result); | ||
122 | } else | ||
123 | priv->actually_throttled = true; | ||
124 | spin_unlock(&priv->lock); | ||
125 | } | ||
126 | |||
127 | static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port, | ||
128 | struct file *filp) | ||
129 | { | ||
130 | struct symbol_private *priv = usb_get_serial_data(port->serial); | ||
131 | unsigned long flags; | ||
132 | int result = 0; | ||
133 | |||
134 | dbg("%s - port %d", __func__, port->number); | ||
135 | |||
136 | spin_lock_irqsave(&priv->lock, flags); | ||
137 | priv->throttled = false; | ||
138 | priv->actually_throttled = false; | ||
139 | priv->port = port; | ||
140 | spin_unlock_irqrestore(&priv->lock, flags); | ||
141 | |||
142 | /* | ||
143 | * Force low_latency on so that our tty_push actually forces the data | ||
144 | * through, otherwise it is scheduled, and with high data rates (like | ||
145 | * with OHCI) data can get lost. | ||
146 | */ | ||
147 | if (tty) | ||
148 | tty->low_latency = 1; | ||
149 | |||
150 | /* Start reading from the device */ | ||
151 | usb_fill_int_urb(priv->int_urb, priv->udev, | ||
152 | usb_rcvintpipe(priv->udev, priv->int_address), | ||
153 | priv->int_buffer, priv->buffer_size, | ||
154 | symbol_int_callback, priv, priv->bInterval); | ||
155 | result = usb_submit_urb(priv->int_urb, GFP_KERNEL); | ||
156 | if (result) | ||
157 | dev_err(&port->dev, | ||
158 | "%s - failed resubmitting read urb, error %d\n", | ||
159 | __func__, result); | ||
160 | return result; | ||
161 | } | ||
162 | |||
163 | static void symbol_close(struct tty_struct *tty, struct usb_serial_port *port, | ||
164 | struct file *filp) | ||
165 | { | ||
166 | struct symbol_private *priv = usb_get_serial_data(port->serial); | ||
167 | |||
168 | dbg("%s - port %d", __func__, port->number); | ||
169 | |||
170 | /* shutdown our urbs */ | ||
171 | usb_kill_urb(priv->int_urb); | ||
172 | } | ||
173 | |||
174 | static void symbol_throttle(struct tty_struct *tty) | ||
175 | { | ||
176 | struct usb_serial_port *port = tty->driver_data; | ||
177 | struct symbol_private *priv = usb_get_serial_data(port->serial); | ||
178 | unsigned long flags; | ||
179 | |||
180 | dbg("%s - port %d", __func__, port->number); | ||
181 | spin_lock_irqsave(&priv->lock, flags); | ||
182 | priv->throttled = true; | ||
183 | spin_unlock_irqrestore(&priv->lock, flags); | ||
184 | } | ||
185 | |||
186 | static void symbol_unthrottle(struct tty_struct *tty) | ||
187 | { | ||
188 | struct usb_serial_port *port = tty->driver_data; | ||
189 | struct symbol_private *priv = usb_get_serial_data(port->serial); | ||
190 | unsigned long flags; | ||
191 | int result; | ||
192 | |||
193 | dbg("%s - port %d", __func__, port->number); | ||
194 | |||
195 | spin_lock_irqsave(&priv->lock, flags); | ||
196 | priv->throttled = false; | ||
197 | priv->actually_throttled = false; | ||
198 | spin_unlock_irqrestore(&priv->lock, flags); | ||
199 | |||
200 | priv->int_urb->dev = port->serial->dev; | ||
201 | result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); | ||
202 | if (result) | ||
203 | dev_err(&port->dev, | ||
204 | "%s - failed submitting read urb, error %d\n", | ||
205 | __func__, result); | ||
206 | } | ||
207 | |||
208 | static int symbol_ioctl(struct tty_struct *tty, struct file *file, | ||
209 | unsigned int cmd, unsigned long arg) | ||
210 | { | ||
211 | struct usb_serial_port *port = tty->driver_data; | ||
212 | struct device *dev = &port->dev; | ||
213 | |||
214 | /* | ||
215 | * Right now we need to figure out what commands | ||
216 | * most userspace tools want to see for this driver, | ||
217 | * so just log the things. | ||
218 | */ | ||
219 | switch (cmd) { | ||
220 | case TIOCSERGETLSR: | ||
221 | dev_info(dev, "%s: TIOCSERGETLSR\n", __func__); | ||
222 | break; | ||
223 | |||
224 | case TIOCGSERIAL: | ||
225 | dev_info(dev, "%s: TIOCGSERIAL\n", __func__); | ||
226 | break; | ||
227 | |||
228 | case TIOCMIWAIT: | ||
229 | dev_info(dev, "%s: TIOCMIWAIT\n", __func__); | ||
230 | break; | ||
231 | |||
232 | case TIOCGICOUNT: | ||
233 | dev_info(dev, "%s: TIOCGICOUNT\n", __func__); | ||
234 | break; | ||
235 | default: | ||
236 | dev_info(dev, "%s: unknown (%d)\n", __func__, cmd); | ||
237 | } | ||
238 | return -ENOIOCTLCMD; | ||
239 | } | ||
240 | |||
241 | static int symbol_tiocmget(struct tty_struct *tty, struct file *file) | ||
242 | { | ||
243 | struct usb_serial_port *port = tty->driver_data; | ||
244 | struct device *dev = &port->dev; | ||
245 | |||
246 | /* TODO */ | ||
247 | /* probably just need to shadow whatever was sent to us here */ | ||
248 | dev_info(dev, "%s\n", __func__); | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static int symbol_tiocmset(struct tty_struct *tty, struct file *file, | ||
253 | unsigned int set, unsigned int clear) | ||
254 | { | ||
255 | struct usb_serial_port *port = tty->driver_data; | ||
256 | struct device *dev = &port->dev; | ||
257 | |||
258 | /* TODO */ | ||
259 | /* probably just need to shadow whatever was sent to us here */ | ||
260 | dev_info(dev, "%s\n", __func__); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int symbol_startup(struct usb_serial *serial) | ||
265 | { | ||
266 | struct symbol_private *priv; | ||
267 | struct usb_host_interface *intf; | ||
268 | int i; | ||
269 | int retval = -ENOMEM; | ||
270 | bool int_in_found = false; | ||
271 | |||
272 | /* create our private serial structure */ | ||
273 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
274 | if (priv == NULL) { | ||
275 | dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); | ||
276 | return -ENOMEM; | ||
277 | } | ||
278 | spin_lock_init(&priv->lock); | ||
279 | priv->serial = serial; | ||
280 | priv->port = serial->port[0]; | ||
281 | priv->udev = serial->dev; | ||
282 | |||
283 | /* find our interrupt endpoint */ | ||
284 | intf = serial->interface->altsetting; | ||
285 | for (i = 0; i < intf->desc.bNumEndpoints; ++i) { | ||
286 | struct usb_endpoint_descriptor *endpoint; | ||
287 | |||
288 | endpoint = &intf->endpoint[i].desc; | ||
289 | if (!usb_endpoint_is_int_in(endpoint)) | ||
290 | continue; | ||
291 | |||
292 | priv->int_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
293 | if (!priv->int_urb) { | ||
294 | dev_err(&priv->udev->dev, "out of memory\n"); | ||
295 | goto error; | ||
296 | } | ||
297 | |||
298 | priv->buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2; | ||
299 | priv->int_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); | ||
300 | if (!priv->int_buffer) { | ||
301 | dev_err(&priv->udev->dev, "out of memory\n"); | ||
302 | goto error; | ||
303 | } | ||
304 | |||
305 | priv->int_address = endpoint->bEndpointAddress; | ||
306 | priv->bInterval = endpoint->bInterval; | ||
307 | |||
308 | /* set up our int urb */ | ||
309 | usb_fill_int_urb(priv->int_urb, priv->udev, | ||
310 | usb_rcvintpipe(priv->udev, | ||
311 | endpoint->bEndpointAddress), | ||
312 | priv->int_buffer, priv->buffer_size, | ||
313 | symbol_int_callback, priv, priv->bInterval); | ||
314 | |||
315 | int_in_found = true; | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | if (!int_in_found) { | ||
320 | dev_err(&priv->udev->dev, | ||
321 | "Error - the proper endpoints were not found!\n"); | ||
322 | goto error; | ||
323 | } | ||
324 | |||
325 | usb_set_serial_data(serial, priv); | ||
326 | return 0; | ||
327 | |||
328 | error: | ||
329 | usb_free_urb(priv->int_urb); | ||
330 | kfree(priv->int_buffer); | ||
331 | kfree(priv); | ||
332 | return retval; | ||
333 | } | ||
334 | |||
335 | static void symbol_shutdown(struct usb_serial *serial) | ||
336 | { | ||
337 | struct symbol_private *priv = usb_get_serial_data(serial); | ||
338 | |||
339 | dbg("%s", __func__); | ||
340 | |||
341 | usb_kill_urb(priv->int_urb); | ||
342 | usb_free_urb(priv->int_urb); | ||
343 | kfree(priv->int_buffer); | ||
344 | kfree(priv); | ||
345 | usb_set_serial_data(serial, NULL); | ||
346 | } | ||
347 | |||
348 | static struct usb_driver symbol_driver = { | ||
349 | .name = "symbol", | ||
350 | .probe = usb_serial_probe, | ||
351 | .disconnect = usb_serial_disconnect, | ||
352 | .id_table = id_table, | ||
353 | .no_dynamic_id = 1, | ||
354 | }; | ||
355 | |||
356 | static struct usb_serial_driver symbol_device = { | ||
357 | .driver = { | ||
358 | .owner = THIS_MODULE, | ||
359 | .name = "symbol", | ||
360 | }, | ||
361 | .id_table = id_table, | ||
362 | .usb_driver = &symbol_driver, | ||
363 | .num_ports = 1, | ||
364 | .attach = symbol_startup, | ||
365 | .open = symbol_open, | ||
366 | .close = symbol_close, | ||
367 | .shutdown = symbol_shutdown, | ||
368 | .throttle = symbol_throttle, | ||
369 | .unthrottle = symbol_unthrottle, | ||
370 | .ioctl = symbol_ioctl, | ||
371 | .tiocmget = symbol_tiocmget, | ||
372 | .tiocmset = symbol_tiocmset, | ||
373 | }; | ||
374 | |||
375 | static int __init symbol_init(void) | ||
376 | { | ||
377 | int retval; | ||
378 | |||
379 | retval = usb_serial_register(&symbol_device); | ||
380 | if (retval) | ||
381 | return retval; | ||
382 | retval = usb_register(&symbol_driver); | ||
383 | if (retval) | ||
384 | usb_serial_deregister(&symbol_device); | ||
385 | return retval; | ||
386 | } | ||
387 | |||
388 | static void __exit symbol_exit(void) | ||
389 | { | ||
390 | usb_deregister(&symbol_driver); | ||
391 | usb_serial_deregister(&symbol_device); | ||
392 | } | ||
393 | |||
394 | module_init(symbol_init); | ||
395 | module_exit(symbol_exit); | ||
396 | MODULE_LICENSE("GPL"); | ||
397 | |||
398 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
399 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index cfcfd5ab06ce..742a5bc44be8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -204,6 +204,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
204 | goto bailout_kref_put; | 204 | goto bailout_kref_put; |
205 | } | 205 | } |
206 | 206 | ||
207 | if (port->serial->disconnected) { | ||
208 | retval = -ENODEV; | ||
209 | goto bailout_kref_put; | ||
210 | } | ||
211 | |||
207 | if (mutex_lock_interruptible(&port->mutex)) { | 212 | if (mutex_lock_interruptible(&port->mutex)) { |
208 | retval = -ERESTARTSYS; | 213 | retval = -ERESTARTSYS; |
209 | goto bailout_kref_put; | 214 | goto bailout_kref_put; |
@@ -1067,6 +1072,8 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) | |||
1067 | struct usb_serial_port *port; | 1072 | struct usb_serial_port *port; |
1068 | int i, r = 0; | 1073 | int i, r = 0; |
1069 | 1074 | ||
1075 | serial->suspending = 1; | ||
1076 | |||
1070 | for (i = 0; i < serial->num_ports; ++i) { | 1077 | for (i = 0; i < serial->num_ports; ++i) { |
1071 | port = serial->port[i]; | 1078 | port = serial->port[i]; |
1072 | if (port) | 1079 | if (port) |
@@ -1083,10 +1090,15 @@ EXPORT_SYMBOL(usb_serial_suspend); | |||
1083 | int usb_serial_resume(struct usb_interface *intf) | 1090 | int usb_serial_resume(struct usb_interface *intf) |
1084 | { | 1091 | { |
1085 | struct usb_serial *serial = usb_get_intfdata(intf); | 1092 | struct usb_serial *serial = usb_get_intfdata(intf); |
1093 | int rv; | ||
1086 | 1094 | ||
1095 | serial->suspending = 0; | ||
1087 | if (serial->type->resume) | 1096 | if (serial->type->resume) |
1088 | return serial->type->resume(serial); | 1097 | rv = serial->type->resume(serial); |
1089 | return 0; | 1098 | else |
1099 | rv = usb_serial_generic_resume(serial); | ||
1100 | |||
1101 | return rv; | ||
1090 | } | 1102 | } |
1091 | EXPORT_SYMBOL(usb_serial_resume); | 1103 | EXPORT_SYMBOL(usb_serial_resume); |
1092 | 1104 | ||
@@ -1222,7 +1234,6 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
1222 | set_to_generic_if_null(device, read_bulk_callback); | 1234 | set_to_generic_if_null(device, read_bulk_callback); |
1223 | set_to_generic_if_null(device, write_bulk_callback); | 1235 | set_to_generic_if_null(device, write_bulk_callback); |
1224 | set_to_generic_if_null(device, shutdown); | 1236 | set_to_generic_if_null(device, shutdown); |
1225 | set_to_generic_if_null(device, resume); | ||
1226 | } | 1237 | } |
1227 | 1238 | ||
1228 | int usb_serial_register(struct usb_serial_driver *driver) | 1239 | int usb_serial_register(struct usb_serial_driver *driver) |
@@ -1230,6 +1241,9 @@ int usb_serial_register(struct usb_serial_driver *driver) | |||
1230 | /* must be called with BKL held */ | 1241 | /* must be called with BKL held */ |
1231 | int retval; | 1242 | int retval; |
1232 | 1243 | ||
1244 | if (usb_disabled()) | ||
1245 | return -ENODEV; | ||
1246 | |||
1233 | fixup_generic(driver); | 1247 | fixup_generic(driver); |
1234 | 1248 | ||
1235 | if (!driver->description) | 1249 | if (!driver->description) |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 9df6887b91f6..8a372bac0e43 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -2,8 +2,8 @@ | |||
2 | # USB Storage driver configuration | 2 | # USB Storage driver configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;" | 5 | comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may" |
6 | comment "see USB_STORAGE Help for more information" | 6 | comment "also be needed; see USB_STORAGE Help for more info" |
7 | depends on USB | 7 | depends on USB |
8 | 8 | ||
9 | config USB_STORAGE | 9 | config USB_STORAGE |
@@ -32,21 +32,25 @@ config USB_STORAGE_DEBUG | |||
32 | verbose debugging messages. | 32 | verbose debugging messages. |
33 | 33 | ||
34 | config USB_STORAGE_DATAFAB | 34 | config USB_STORAGE_DATAFAB |
35 | bool "Datafab Compact Flash Reader support" | 35 | tristate "Datafab Compact Flash Reader support" |
36 | depends on USB_STORAGE | 36 | depends on USB_STORAGE |
37 | help | 37 | help |
38 | Support for certain Datafab CompactFlash readers. | 38 | Support for certain Datafab CompactFlash readers. |
39 | Datafab has a web page at <http://www.datafabusa.com/>. | 39 | Datafab has a web page at <http://www.datafabusa.com/>. |
40 | 40 | ||
41 | If this driver is compiled as a module, it will be named ums-datafab. | ||
42 | |||
41 | config USB_STORAGE_FREECOM | 43 | config USB_STORAGE_FREECOM |
42 | bool "Freecom USB/ATAPI Bridge support" | 44 | tristate "Freecom USB/ATAPI Bridge support" |
43 | depends on USB_STORAGE | 45 | depends on USB_STORAGE |
44 | help | 46 | help |
45 | Support for the Freecom USB to IDE/ATAPI adaptor. | 47 | Support for the Freecom USB to IDE/ATAPI adaptor. |
46 | Freecom has a web page at <http://www.freecom.de/>. | 48 | Freecom has a web page at <http://www.freecom.de/>. |
47 | 49 | ||
50 | If this driver is compiled as a module, it will be named ums-freecom. | ||
51 | |||
48 | config USB_STORAGE_ISD200 | 52 | config USB_STORAGE_ISD200 |
49 | bool "ISD-200 USB/ATA Bridge support" | 53 | tristate "ISD-200 USB/ATA Bridge support" |
50 | depends on USB_STORAGE | 54 | depends on USB_STORAGE |
51 | ---help--- | 55 | ---help--- |
52 | Say Y here if you want to use USB Mass Store devices based | 56 | Say Y here if you want to use USB Mass Store devices based |
@@ -61,8 +65,10 @@ config USB_STORAGE_ISD200 | |||
61 | - CyQ've CQ8060A CDRW drive | 65 | - CyQ've CQ8060A CDRW drive |
62 | - Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U) | 66 | - Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U) |
63 | 67 | ||
68 | If this driver is compiled as a module, it will be named ums-isd200. | ||
69 | |||
64 | config USB_STORAGE_USBAT | 70 | config USB_STORAGE_USBAT |
65 | bool "USBAT/USBAT02-based storage support" | 71 | tristate "USBAT/USBAT02-based storage support" |
66 | depends on USB_STORAGE | 72 | depends on USB_STORAGE |
67 | help | 73 | help |
68 | Say Y here to include additional code to support storage devices | 74 | Say Y here to include additional code to support storage devices |
@@ -82,30 +88,38 @@ config USB_STORAGE_USBAT | |||
82 | - RCA LYRA MP3 portable | 88 | - RCA LYRA MP3 portable |
83 | - Sandisk ImageMate SDDR-05b | 89 | - Sandisk ImageMate SDDR-05b |
84 | 90 | ||
91 | If this driver is compiled as a module, it will be named ums-usbat. | ||
92 | |||
85 | config USB_STORAGE_SDDR09 | 93 | config USB_STORAGE_SDDR09 |
86 | bool "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support" | 94 | tristate "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support" |
87 | depends on USB_STORAGE | 95 | depends on USB_STORAGE |
88 | help | 96 | help |
89 | Say Y here to include additional code to support the Sandisk SDDR-09 | 97 | Say Y here to include additional code to support the Sandisk SDDR-09 |
90 | SmartMedia reader in the USB Mass Storage driver. | 98 | SmartMedia reader in the USB Mass Storage driver. |
91 | Also works for the Microtech Zio! CompactFlash/SmartMedia reader. | 99 | Also works for the Microtech Zio! CompactFlash/SmartMedia reader. |
92 | 100 | ||
101 | If this driver is compiled as a module, it will be named ums-sddr09. | ||
102 | |||
93 | config USB_STORAGE_SDDR55 | 103 | config USB_STORAGE_SDDR55 |
94 | bool "SanDisk SDDR-55 SmartMedia support" | 104 | tristate "SanDisk SDDR-55 SmartMedia support" |
95 | depends on USB_STORAGE | 105 | depends on USB_STORAGE |
96 | help | 106 | help |
97 | Say Y here to include additional code to support the Sandisk SDDR-55 | 107 | Say Y here to include additional code to support the Sandisk SDDR-55 |
98 | SmartMedia reader in the USB Mass Storage driver. | 108 | SmartMedia reader in the USB Mass Storage driver. |
99 | 109 | ||
110 | If this driver is compiled as a module, it will be named ums-sddr55. | ||
111 | |||
100 | config USB_STORAGE_JUMPSHOT | 112 | config USB_STORAGE_JUMPSHOT |
101 | bool "Lexar Jumpshot Compact Flash Reader" | 113 | tristate "Lexar Jumpshot Compact Flash Reader" |
102 | depends on USB_STORAGE | 114 | depends on USB_STORAGE |
103 | help | 115 | help |
104 | Say Y here to include additional code to support the Lexar Jumpshot | 116 | Say Y here to include additional code to support the Lexar Jumpshot |
105 | USB CompactFlash reader. | 117 | USB CompactFlash reader. |
106 | 118 | ||
119 | If this driver is compiled as a module, it will be named ums-jumpshot. | ||
120 | |||
107 | config USB_STORAGE_ALAUDA | 121 | config USB_STORAGE_ALAUDA |
108 | bool "Olympus MAUSB-10/Fuji DPC-R1 support" | 122 | tristate "Olympus MAUSB-10/Fuji DPC-R1 support" |
109 | depends on USB_STORAGE | 123 | depends on USB_STORAGE |
110 | help | 124 | help |
111 | Say Y here to include additional code to support the Olympus MAUSB-10 | 125 | Say Y here to include additional code to support the Olympus MAUSB-10 |
@@ -114,8 +128,10 @@ config USB_STORAGE_ALAUDA | |||
114 | These devices are based on the Alauda chip and support both | 128 | These devices are based on the Alauda chip and support both |
115 | XD and SmartMedia cards. | 129 | XD and SmartMedia cards. |
116 | 130 | ||
131 | If this driver is compiled as a module, it will be named ums-alauda. | ||
132 | |||
117 | config USB_STORAGE_ONETOUCH | 133 | config USB_STORAGE_ONETOUCH |
118 | bool "Support OneTouch Button on Maxtor Hard Drives" | 134 | tristate "Support OneTouch Button on Maxtor Hard Drives" |
119 | depends on USB_STORAGE | 135 | depends on USB_STORAGE |
120 | depends on INPUT=y || INPUT=USB_STORAGE | 136 | depends on INPUT=y || INPUT=USB_STORAGE |
121 | help | 137 | help |
@@ -127,8 +143,10 @@ config USB_STORAGE_ONETOUCH | |||
127 | this input in any keybinding software. (e.g. gnome's keyboard short- | 143 | this input in any keybinding software. (e.g. gnome's keyboard short- |
128 | cuts) | 144 | cuts) |
129 | 145 | ||
146 | If this driver is compiled as a module, it will be named ums-onetouch. | ||
147 | |||
130 | config USB_STORAGE_KARMA | 148 | config USB_STORAGE_KARMA |
131 | bool "Support for Rio Karma music player" | 149 | tristate "Support for Rio Karma music player" |
132 | depends on USB_STORAGE | 150 | depends on USB_STORAGE |
133 | help | 151 | help |
134 | Say Y here to include additional code to support the Rio Karma | 152 | Say Y here to include additional code to support the Rio Karma |
@@ -139,8 +157,10 @@ config USB_STORAGE_KARMA | |||
139 | on the resulting scsi device node returns the Karma to normal | 157 | on the resulting scsi device node returns the Karma to normal |
140 | operation. | 158 | operation. |
141 | 159 | ||
160 | If this driver is compiled as a module, it will be named ums-karma. | ||
161 | |||
142 | config USB_STORAGE_CYPRESS_ATACB | 162 | config USB_STORAGE_CYPRESS_ATACB |
143 | bool "SAT emulation on Cypress USB/ATA Bridge with ATACB" | 163 | tristate "SAT emulation on Cypress USB/ATA Bridge with ATACB" |
144 | depends on USB_STORAGE | 164 | depends on USB_STORAGE |
145 | ---help--- | 165 | ---help--- |
146 | Say Y here if you want to use SAT (ata pass through) on devices based | 166 | Say Y here if you want to use SAT (ata pass through) on devices based |
@@ -150,6 +170,8 @@ config USB_STORAGE_CYPRESS_ATACB | |||
150 | If you say no here your device will still work with the standard usb | 170 | If you say no here your device will still work with the standard usb |
151 | mass storage class. | 171 | mass storage class. |
152 | 172 | ||
173 | If this driver is compiled as a module, it will be named ums-cypress. | ||
174 | |||
153 | config USB_LIBUSUAL | 175 | config USB_LIBUSUAL |
154 | bool "The shared table of common (or usual) storage devices" | 176 | bool "The shared table of common (or usual) storage devices" |
155 | depends on USB | 177 | depends on USB |
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index b32069313390..5be54c019662 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
@@ -10,21 +10,36 @@ EXTRA_CFLAGS := -Idrivers/scsi | |||
10 | obj-$(CONFIG_USB_STORAGE) += usb-storage.o | 10 | obj-$(CONFIG_USB_STORAGE) += usb-storage.o |
11 | 11 | ||
12 | usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o | 12 | usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o |
13 | usb-storage-obj-$(CONFIG_USB_STORAGE_USBAT) += shuttle_usbat.o | ||
14 | usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o | ||
15 | usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55) += sddr55.o | ||
16 | usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o | ||
17 | usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o | ||
18 | usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o | ||
19 | usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o | ||
20 | usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o | ||
21 | usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o | ||
22 | usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o | ||
23 | usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o | ||
24 | 13 | ||
25 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ | 14 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ |
26 | initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y) | 15 | initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y) |
27 | 16 | ||
28 | ifneq ($(CONFIG_USB_LIBUSUAL),) | 17 | ifeq ($(CONFIG_USB_LIBUSUAL),) |
29 | obj-$(CONFIG_USB) += libusual.o | 18 | usb-storage-objs += usual-tables.o |
19 | else | ||
20 | obj-$(CONFIG_USB) += libusual.o usual-tables.o | ||
30 | endif | 21 | endif |
22 | |||
23 | obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o | ||
24 | obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += ums-cypress.o | ||
25 | obj-$(CONFIG_USB_STORAGE_DATAFAB) += ums-datafab.o | ||
26 | obj-$(CONFIG_USB_STORAGE_FREECOM) += ums-freecom.o | ||
27 | obj-$(CONFIG_USB_STORAGE_ISD200) += ums-isd200.o | ||
28 | obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += ums-jumpshot.o | ||
29 | obj-$(CONFIG_USB_STORAGE_KARMA) += ums-karma.o | ||
30 | obj-$(CONFIG_USB_STORAGE_ONETOUCH) += ums-onetouch.o | ||
31 | obj-$(CONFIG_USB_STORAGE_SDDR09) += ums-sddr09.o | ||
32 | obj-$(CONFIG_USB_STORAGE_SDDR55) += ums-sddr55.o | ||
33 | obj-$(CONFIG_USB_STORAGE_USBAT) += ums-usbat.o | ||
34 | |||
35 | ums-alauda-objs := alauda.o | ||
36 | ums-cypress-objs := cypress_atacb.o | ||
37 | ums-datafab-objs := datafab.o | ||
38 | ums-freecom-objs := freecom.o | ||
39 | ums-isd200-objs := isd200.o | ||
40 | ums-jumpshot-objs := jumpshot.o | ||
41 | ums-karma-objs := karma.o | ||
42 | ums-onetouch-objs := onetouch.o | ||
43 | ums-sddr09-objs := sddr09.o | ||
44 | ums-sddr55-objs := sddr55.o | ||
45 | ums-usbat-objs := shuttle_usbat.o | ||
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 8d3711a7ff06..67edc65acb8e 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c | |||
@@ -31,6 +31,8 @@ | |||
31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 31 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/module.h> | ||
35 | |||
34 | #include <scsi/scsi.h> | 36 | #include <scsi/scsi.h> |
35 | #include <scsi/scsi_cmnd.h> | 37 | #include <scsi/scsi_cmnd.h> |
36 | #include <scsi/scsi_device.h> | 38 | #include <scsi/scsi_device.h> |
@@ -39,7 +41,79 @@ | |||
39 | #include "transport.h" | 41 | #include "transport.h" |
40 | #include "protocol.h" | 42 | #include "protocol.h" |
41 | #include "debug.h" | 43 | #include "debug.h" |
42 | #include "alauda.h" | 44 | |
45 | MODULE_DESCRIPTION("Driver for Alauda-based card readers"); | ||
46 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>"); | ||
47 | MODULE_LICENSE("GPL"); | ||
48 | |||
49 | /* | ||
50 | * Status bytes | ||
51 | */ | ||
52 | #define ALAUDA_STATUS_ERROR 0x01 | ||
53 | #define ALAUDA_STATUS_READY 0x40 | ||
54 | |||
55 | /* | ||
56 | * Control opcodes (for request field) | ||
57 | */ | ||
58 | #define ALAUDA_GET_XD_MEDIA_STATUS 0x08 | ||
59 | #define ALAUDA_GET_SM_MEDIA_STATUS 0x98 | ||
60 | #define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a | ||
61 | #define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a | ||
62 | #define ALAUDA_GET_XD_MEDIA_SIG 0x86 | ||
63 | #define ALAUDA_GET_SM_MEDIA_SIG 0x96 | ||
64 | |||
65 | /* | ||
66 | * Bulk command identity (byte 0) | ||
67 | */ | ||
68 | #define ALAUDA_BULK_CMD 0x40 | ||
69 | |||
70 | /* | ||
71 | * Bulk opcodes (byte 1) | ||
72 | */ | ||
73 | #define ALAUDA_BULK_GET_REDU_DATA 0x85 | ||
74 | #define ALAUDA_BULK_READ_BLOCK 0x94 | ||
75 | #define ALAUDA_BULK_ERASE_BLOCK 0xa3 | ||
76 | #define ALAUDA_BULK_WRITE_BLOCK 0xb4 | ||
77 | #define ALAUDA_BULK_GET_STATUS2 0xb7 | ||
78 | #define ALAUDA_BULK_RESET_MEDIA 0xe0 | ||
79 | |||
80 | /* | ||
81 | * Port to operate on (byte 8) | ||
82 | */ | ||
83 | #define ALAUDA_PORT_XD 0x00 | ||
84 | #define ALAUDA_PORT_SM 0x01 | ||
85 | |||
86 | /* | ||
87 | * LBA and PBA are unsigned ints. Special values. | ||
88 | */ | ||
89 | #define UNDEF 0xffff | ||
90 | #define SPARE 0xfffe | ||
91 | #define UNUSABLE 0xfffd | ||
92 | |||
93 | struct alauda_media_info { | ||
94 | unsigned long capacity; /* total media size in bytes */ | ||
95 | unsigned int pagesize; /* page size in bytes */ | ||
96 | unsigned int blocksize; /* number of pages per block */ | ||
97 | unsigned int uzonesize; /* number of usable blocks per zone */ | ||
98 | unsigned int zonesize; /* number of blocks per zone */ | ||
99 | unsigned int blockmask; /* mask to get page from address */ | ||
100 | |||
101 | unsigned char pageshift; | ||
102 | unsigned char blockshift; | ||
103 | unsigned char zoneshift; | ||
104 | |||
105 | u16 **lba_to_pba; /* logical to physical block map */ | ||
106 | u16 **pba_to_lba; /* physical to logical block map */ | ||
107 | }; | ||
108 | |||
109 | struct alauda_info { | ||
110 | struct alauda_media_info port[2]; | ||
111 | int wr_ep; /* endpoint to write data out of */ | ||
112 | |||
113 | unsigned char sense_key; | ||
114 | unsigned long sense_asc; /* additional sense code */ | ||
115 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
116 | }; | ||
43 | 117 | ||
44 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | 118 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) |
45 | #define LSB_of(s) ((s)&0xFF) | 119 | #define LSB_of(s) ((s)&0xFF) |
@@ -52,6 +126,48 @@ | |||
52 | #define PBA_HI(pba) (pba >> 3) | 126 | #define PBA_HI(pba) (pba >> 3) |
53 | #define PBA_ZONE(pba) (pba >> 11) | 127 | #define PBA_ZONE(pba) (pba >> 11) |
54 | 128 | ||
129 | static int init_alauda(struct us_data *us); | ||
130 | |||
131 | |||
132 | /* | ||
133 | * The table of devices | ||
134 | */ | ||
135 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
136 | vendorName, productName, useProtocol, useTransport, \ | ||
137 | initFunction, flags) \ | ||
138 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
139 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
140 | |||
141 | struct usb_device_id alauda_usb_ids[] = { | ||
142 | # include "unusual_alauda.h" | ||
143 | { } /* Terminating entry */ | ||
144 | }; | ||
145 | MODULE_DEVICE_TABLE(usb, alauda_usb_ids); | ||
146 | |||
147 | #undef UNUSUAL_DEV | ||
148 | |||
149 | /* | ||
150 | * The flags table | ||
151 | */ | ||
152 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
153 | vendor_name, product_name, use_protocol, use_transport, \ | ||
154 | init_function, Flags) \ | ||
155 | { \ | ||
156 | .vendorName = vendor_name, \ | ||
157 | .productName = product_name, \ | ||
158 | .useProtocol = use_protocol, \ | ||
159 | .useTransport = use_transport, \ | ||
160 | .initFunction = init_function, \ | ||
161 | } | ||
162 | |||
163 | static struct us_unusual_dev alauda_unusual_dev_list[] = { | ||
164 | # include "unusual_alauda.h" | ||
165 | { } /* Terminating entry */ | ||
166 | }; | ||
167 | |||
168 | #undef UNUSUAL_DEV | ||
169 | |||
170 | |||
55 | /* | 171 | /* |
56 | * Media handling | 172 | * Media handling |
57 | */ | 173 | */ |
@@ -307,7 +423,8 @@ static int alauda_init_media(struct us_data *us) | |||
307 | data[0], data[1], data[2], data[3]); | 423 | data[0], data[1], data[2], data[3]); |
308 | media_info = alauda_card_find_id(data[1]); | 424 | media_info = alauda_card_find_id(data[1]); |
309 | if (media_info == NULL) { | 425 | if (media_info == NULL) { |
310 | printk("alauda_init_media: Unrecognised media signature: " | 426 | printk(KERN_WARNING |
427 | "alauda_init_media: Unrecognised media signature: " | ||
311 | "%02X %02X %02X %02X\n", | 428 | "%02X %02X %02X %02X\n", |
312 | data[0], data[1], data[2], data[3]); | 429 | data[0], data[1], data[2], data[3]); |
313 | return USB_STOR_TRANSPORT_ERROR; | 430 | return USB_STOR_TRANSPORT_ERROR; |
@@ -518,7 +635,8 @@ static int alauda_read_map(struct us_data *us, unsigned int zone) | |||
518 | 635 | ||
519 | /* check even parity */ | 636 | /* check even parity */ |
520 | if (parity[data[6] ^ data[7]]) { | 637 | if (parity[data[6] ^ data[7]]) { |
521 | printk("alauda_read_map: Bad parity in LBA for block %d" | 638 | printk(KERN_WARNING |
639 | "alauda_read_map: Bad parity in LBA for block %d" | ||
522 | " (%02X %02X)\n", i, data[6], data[7]); | 640 | " (%02X %02X)\n", i, data[6], data[7]); |
523 | pba_to_lba[i] = UNUSABLE; | 641 | pba_to_lba[i] = UNUSABLE; |
524 | continue; | 642 | continue; |
@@ -538,13 +656,16 @@ static int alauda_read_map(struct us_data *us, unsigned int zone) | |||
538 | */ | 656 | */ |
539 | 657 | ||
540 | if (lba_offset >= uzonesize) { | 658 | if (lba_offset >= uzonesize) { |
541 | printk("alauda_read_map: Bad low LBA %d for block %d\n", | 659 | printk(KERN_WARNING |
660 | "alauda_read_map: Bad low LBA %d for block %d\n", | ||
542 | lba_real, blocknum); | 661 | lba_real, blocknum); |
543 | continue; | 662 | continue; |
544 | } | 663 | } |
545 | 664 | ||
546 | if (lba_to_pba[lba_offset] != UNDEF) { | 665 | if (lba_to_pba[lba_offset] != UNDEF) { |
547 | printk("alauda_read_map: LBA %d seen for PBA %d and %d\n", | 666 | printk(KERN_WARNING |
667 | "alauda_read_map: " | ||
668 | "LBA %d seen for PBA %d and %d\n", | ||
548 | lba_real, lba_to_pba[lba_offset], blocknum); | 669 | lba_real, lba_to_pba[lba_offset], blocknum); |
549 | continue; | 670 | continue; |
550 | } | 671 | } |
@@ -712,13 +833,15 @@ static int alauda_write_lba(struct us_data *us, u16 lba, | |||
712 | if (pba == 1) { | 833 | if (pba == 1) { |
713 | /* Maybe it is impossible to write to PBA 1. | 834 | /* Maybe it is impossible to write to PBA 1. |
714 | Fake success, but don't do anything. */ | 835 | Fake success, but don't do anything. */ |
715 | printk("alauda_write_lba: avoid writing to pba 1\n"); | 836 | printk(KERN_WARNING |
837 | "alauda_write_lba: avoid writing to pba 1\n"); | ||
716 | return USB_STOR_TRANSPORT_GOOD; | 838 | return USB_STOR_TRANSPORT_GOOD; |
717 | } | 839 | } |
718 | 840 | ||
719 | new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); | 841 | new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); |
720 | if (!new_pba) { | 842 | if (!new_pba) { |
721 | printk("alauda_write_lba: Out of unused blocks\n"); | 843 | printk(KERN_WARNING |
844 | "alauda_write_lba: Out of unused blocks\n"); | ||
722 | return USB_STOR_TRANSPORT_ERROR; | 845 | return USB_STOR_TRANSPORT_ERROR; |
723 | } | 846 | } |
724 | 847 | ||
@@ -818,7 +941,7 @@ static int alauda_read_data(struct us_data *us, unsigned long address, | |||
818 | len = min(sectors, blocksize) * (pagesize + 64); | 941 | len = min(sectors, blocksize) * (pagesize + 64); |
819 | buffer = kmalloc(len, GFP_NOIO); | 942 | buffer = kmalloc(len, GFP_NOIO); |
820 | if (buffer == NULL) { | 943 | if (buffer == NULL) { |
821 | printk("alauda_read_data: Out of memory\n"); | 944 | printk(KERN_WARNING "alauda_read_data: Out of memory\n"); |
822 | return USB_STOR_TRANSPORT_ERROR; | 945 | return USB_STOR_TRANSPORT_ERROR; |
823 | } | 946 | } |
824 | 947 | ||
@@ -911,7 +1034,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address, | |||
911 | len = min(sectors, blocksize) * pagesize; | 1034 | len = min(sectors, blocksize) * pagesize; |
912 | buffer = kmalloc(len, GFP_NOIO); | 1035 | buffer = kmalloc(len, GFP_NOIO); |
913 | if (buffer == NULL) { | 1036 | if (buffer == NULL) { |
914 | printk("alauda_write_data: Out of memory\n"); | 1037 | printk(KERN_WARNING "alauda_write_data: Out of memory\n"); |
915 | return USB_STOR_TRANSPORT_ERROR; | 1038 | return USB_STOR_TRANSPORT_ERROR; |
916 | } | 1039 | } |
917 | 1040 | ||
@@ -921,7 +1044,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address, | |||
921 | */ | 1044 | */ |
922 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); | 1045 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); |
923 | if (blockbuffer == NULL) { | 1046 | if (blockbuffer == NULL) { |
924 | printk("alauda_write_data: Out of memory\n"); | 1047 | printk(KERN_WARNING "alauda_write_data: Out of memory\n"); |
925 | kfree(buffer); | 1048 | kfree(buffer); |
926 | return USB_STOR_TRANSPORT_ERROR; | 1049 | return USB_STOR_TRANSPORT_ERROR; |
927 | } | 1050 | } |
@@ -991,7 +1114,7 @@ static void alauda_info_destructor(void *extra) | |||
991 | /* | 1114 | /* |
992 | * Initialize alauda_info struct and find the data-write endpoint | 1115 | * Initialize alauda_info struct and find the data-write endpoint |
993 | */ | 1116 | */ |
994 | int init_alauda(struct us_data *us) | 1117 | static int init_alauda(struct us_data *us) |
995 | { | 1118 | { |
996 | struct alauda_info *info; | 1119 | struct alauda_info *info; |
997 | struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; | 1120 | struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; |
@@ -1013,7 +1136,7 @@ int init_alauda(struct us_data *us) | |||
1013 | return USB_STOR_TRANSPORT_GOOD; | 1136 | return USB_STOR_TRANSPORT_GOOD; |
1014 | } | 1137 | } |
1015 | 1138 | ||
1016 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) | 1139 | static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) |
1017 | { | 1140 | { |
1018 | int rc; | 1141 | int rc; |
1019 | struct alauda_info *info = (struct alauda_info *) us->extra; | 1142 | struct alauda_info *info = (struct alauda_info *) us->extra; |
@@ -1121,3 +1244,48 @@ int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1121 | return USB_STOR_TRANSPORT_FAILED; | 1244 | return USB_STOR_TRANSPORT_FAILED; |
1122 | } | 1245 | } |
1123 | 1246 | ||
1247 | static int alauda_probe(struct usb_interface *intf, | ||
1248 | const struct usb_device_id *id) | ||
1249 | { | ||
1250 | struct us_data *us; | ||
1251 | int result; | ||
1252 | |||
1253 | result = usb_stor_probe1(&us, intf, id, | ||
1254 | (id - alauda_usb_ids) + alauda_unusual_dev_list); | ||
1255 | if (result) | ||
1256 | return result; | ||
1257 | |||
1258 | us->transport_name = "Alauda Control/Bulk"; | ||
1259 | us->transport = alauda_transport; | ||
1260 | us->transport_reset = usb_stor_Bulk_reset; | ||
1261 | us->max_lun = 1; | ||
1262 | |||
1263 | result = usb_stor_probe2(us); | ||
1264 | return result; | ||
1265 | } | ||
1266 | |||
1267 | static struct usb_driver alauda_driver = { | ||
1268 | .name = "ums-alauda", | ||
1269 | .probe = alauda_probe, | ||
1270 | .disconnect = usb_stor_disconnect, | ||
1271 | .suspend = usb_stor_suspend, | ||
1272 | .resume = usb_stor_resume, | ||
1273 | .reset_resume = usb_stor_reset_resume, | ||
1274 | .pre_reset = usb_stor_pre_reset, | ||
1275 | .post_reset = usb_stor_post_reset, | ||
1276 | .id_table = alauda_usb_ids, | ||
1277 | .soft_unbind = 1, | ||
1278 | }; | ||
1279 | |||
1280 | static int __init alauda_init(void) | ||
1281 | { | ||
1282 | return usb_register(&alauda_driver); | ||
1283 | } | ||
1284 | |||
1285 | static void __exit alauda_exit(void) | ||
1286 | { | ||
1287 | usb_deregister(&alauda_driver); | ||
1288 | } | ||
1289 | |||
1290 | module_init(alauda_init); | ||
1291 | module_exit(alauda_exit); | ||
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h deleted file mode 100644 index a700f87d0803..000000000000 --- a/drivers/usb/storage/alauda.h +++ /dev/null | |||
@@ -1,100 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for Alauda-based card readers | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | ||
6 | * | ||
7 | * See alauda.c for more explanation. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2, or (at your option) any | ||
12 | * later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef _USB_ALAUDA_H | ||
25 | #define _USB_ALAUDA_H | ||
26 | |||
27 | /* | ||
28 | * Status bytes | ||
29 | */ | ||
30 | #define ALAUDA_STATUS_ERROR 0x01 | ||
31 | #define ALAUDA_STATUS_READY 0x40 | ||
32 | |||
33 | /* | ||
34 | * Control opcodes (for request field) | ||
35 | */ | ||
36 | #define ALAUDA_GET_XD_MEDIA_STATUS 0x08 | ||
37 | #define ALAUDA_GET_SM_MEDIA_STATUS 0x98 | ||
38 | #define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a | ||
39 | #define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a | ||
40 | #define ALAUDA_GET_XD_MEDIA_SIG 0x86 | ||
41 | #define ALAUDA_GET_SM_MEDIA_SIG 0x96 | ||
42 | |||
43 | /* | ||
44 | * Bulk command identity (byte 0) | ||
45 | */ | ||
46 | #define ALAUDA_BULK_CMD 0x40 | ||
47 | |||
48 | /* | ||
49 | * Bulk opcodes (byte 1) | ||
50 | */ | ||
51 | #define ALAUDA_BULK_GET_REDU_DATA 0x85 | ||
52 | #define ALAUDA_BULK_READ_BLOCK 0x94 | ||
53 | #define ALAUDA_BULK_ERASE_BLOCK 0xa3 | ||
54 | #define ALAUDA_BULK_WRITE_BLOCK 0xb4 | ||
55 | #define ALAUDA_BULK_GET_STATUS2 0xb7 | ||
56 | #define ALAUDA_BULK_RESET_MEDIA 0xe0 | ||
57 | |||
58 | /* | ||
59 | * Port to operate on (byte 8) | ||
60 | */ | ||
61 | #define ALAUDA_PORT_XD 0x00 | ||
62 | #define ALAUDA_PORT_SM 0x01 | ||
63 | |||
64 | /* | ||
65 | * LBA and PBA are unsigned ints. Special values. | ||
66 | */ | ||
67 | #define UNDEF 0xffff | ||
68 | #define SPARE 0xfffe | ||
69 | #define UNUSABLE 0xfffd | ||
70 | |||
71 | int init_alauda(struct us_data *us); | ||
72 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
73 | |||
74 | struct alauda_media_info { | ||
75 | unsigned long capacity; /* total media size in bytes */ | ||
76 | unsigned int pagesize; /* page size in bytes */ | ||
77 | unsigned int blocksize; /* number of pages per block */ | ||
78 | unsigned int uzonesize; /* number of usable blocks per zone */ | ||
79 | unsigned int zonesize; /* number of blocks per zone */ | ||
80 | unsigned int blockmask; /* mask to get page from address */ | ||
81 | |||
82 | unsigned char pageshift; | ||
83 | unsigned char blockshift; | ||
84 | unsigned char zoneshift; | ||
85 | |||
86 | u16 **lba_to_pba; /* logical to physical block map */ | ||
87 | u16 **pba_to_lba; /* physical to logical block map */ | ||
88 | }; | ||
89 | |||
90 | struct alauda_info { | ||
91 | struct alauda_media_info port[2]; | ||
92 | int wr_ep; /* endpoint to write data out of */ | ||
93 | |||
94 | unsigned char sense_key; | ||
95 | unsigned long sense_asc; /* additional sense code */ | ||
96 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
97 | }; | ||
98 | |||
99 | #endif | ||
100 | |||
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index 898e67d30e56..c84471821183 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/module.h> | ||
22 | #include <scsi/scsi.h> | 23 | #include <scsi/scsi.h> |
23 | #include <scsi/scsi_cmnd.h> | 24 | #include <scsi/scsi_cmnd.h> |
24 | #include <scsi/scsi_eh.h> | 25 | #include <scsi/scsi_eh.h> |
@@ -29,6 +30,49 @@ | |||
29 | #include "scsiglue.h" | 30 | #include "scsiglue.h" |
30 | #include "debug.h" | 31 | #include "debug.h" |
31 | 32 | ||
33 | MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB"); | ||
34 | MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>"); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | |||
37 | /* | ||
38 | * The table of devices | ||
39 | */ | ||
40 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
41 | vendorName, productName, useProtocol, useTransport, \ | ||
42 | initFunction, flags) \ | ||
43 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
44 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
45 | |||
46 | struct usb_device_id cypress_usb_ids[] = { | ||
47 | # include "unusual_cypress.h" | ||
48 | { } /* Terminating entry */ | ||
49 | }; | ||
50 | MODULE_DEVICE_TABLE(usb, cypress_usb_ids); | ||
51 | |||
52 | #undef UNUSUAL_DEV | ||
53 | |||
54 | /* | ||
55 | * The flags table | ||
56 | */ | ||
57 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
58 | vendor_name, product_name, use_protocol, use_transport, \ | ||
59 | init_function, Flags) \ | ||
60 | { \ | ||
61 | .vendorName = vendor_name, \ | ||
62 | .productName = product_name, \ | ||
63 | .useProtocol = use_protocol, \ | ||
64 | .useTransport = use_transport, \ | ||
65 | .initFunction = init_function, \ | ||
66 | } | ||
67 | |||
68 | static struct us_unusual_dev cypress_unusual_dev_list[] = { | ||
69 | # include "unusual_cypress.h" | ||
70 | { } /* Terminating entry */ | ||
71 | }; | ||
72 | |||
73 | #undef UNUSUAL_DEV | ||
74 | |||
75 | |||
32 | /* | 76 | /* |
33 | * ATACB is a protocol used on cypress usb<->ata bridge to | 77 | * ATACB is a protocol used on cypress usb<->ata bridge to |
34 | * send raw ATA command over mass storage | 78 | * send raw ATA command over mass storage |
@@ -36,7 +80,7 @@ | |||
36 | * More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf | 80 | * More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf |
37 | * datasheet from cypress.com. | 81 | * datasheet from cypress.com. |
38 | */ | 82 | */ |
39 | void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) | 83 | static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) |
40 | { | 84 | { |
41 | unsigned char save_cmnd[MAX_COMMAND_SIZE]; | 85 | unsigned char save_cmnd[MAX_COMMAND_SIZE]; |
42 | 86 | ||
@@ -133,19 +177,18 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) | |||
133 | 177 | ||
134 | /* build the command for | 178 | /* build the command for |
135 | * reading the ATA registers */ | 179 | * reading the ATA registers */ |
136 | scsi_eh_prep_cmnd(srb, &ses, NULL, 0, 0); | 180 | scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sizeof(regs)); |
137 | srb->sdb.length = sizeof(regs); | 181 | |
138 | sg_init_one(&ses.sense_sgl, regs, srb->sdb.length); | ||
139 | srb->sdb.table.sgl = &ses.sense_sgl; | ||
140 | srb->sc_data_direction = DMA_FROM_DEVICE; | ||
141 | srb->sdb.table.nents = 1; | ||
142 | /* we use the same command as before, but we set | 182 | /* we use the same command as before, but we set |
143 | * the read taskfile bit, for not executing atacb command, | 183 | * the read taskfile bit, for not executing atacb command, |
144 | * but reading register selected in srb->cmnd[4] | 184 | * but reading register selected in srb->cmnd[4] |
145 | */ | 185 | */ |
186 | srb->cmd_len = 16; | ||
187 | srb->cmnd = ses.cmnd; | ||
146 | srb->cmnd[2] = 1; | 188 | srb->cmnd[2] = 1; |
147 | 189 | ||
148 | usb_stor_transparent_scsi_command(srb, us); | 190 | usb_stor_transparent_scsi_command(srb, us); |
191 | memcpy(regs, srb->sense_buffer, sizeof(regs)); | ||
149 | tmp_result = srb->result; | 192 | tmp_result = srb->result; |
150 | scsi_eh_restore_cmnd(srb, &ses); | 193 | scsi_eh_restore_cmnd(srb, &ses); |
151 | /* we fail to get registers, report invalid command */ | 194 | /* we fail to get registers, report invalid command */ |
@@ -162,8 +205,8 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) | |||
162 | 205 | ||
163 | /* XXX we should generate sk, asc, ascq from status and error | 206 | /* XXX we should generate sk, asc, ascq from status and error |
164 | * regs | 207 | * regs |
165 | * (see 11.1 Error translation ATA device error to SCSI error map) | 208 | * (see 11.1 Error translation ATA device error to SCSI error |
166 | * and ata_to_sense_error from libata. | 209 | * map, and ata_to_sense_error from libata.) |
167 | */ | 210 | */ |
168 | 211 | ||
169 | /* Sense data is current and format is descriptor. */ | 212 | /* Sense data is current and format is descriptor. */ |
@@ -198,3 +241,48 @@ end: | |||
198 | if (srb->cmnd[0] == ATA_12) | 241 | if (srb->cmnd[0] == ATA_12) |
199 | srb->cmd_len = 12; | 242 | srb->cmd_len = 12; |
200 | } | 243 | } |
244 | |||
245 | |||
246 | static int cypress_probe(struct usb_interface *intf, | ||
247 | const struct usb_device_id *id) | ||
248 | { | ||
249 | struct us_data *us; | ||
250 | int result; | ||
251 | |||
252 | result = usb_stor_probe1(&us, intf, id, | ||
253 | (id - cypress_usb_ids) + cypress_unusual_dev_list); | ||
254 | if (result) | ||
255 | return result; | ||
256 | |||
257 | us->protocol_name = "Transparent SCSI with Cypress ATACB"; | ||
258 | us->proto_handler = cypress_atacb_passthrough; | ||
259 | |||
260 | result = usb_stor_probe2(us); | ||
261 | return result; | ||
262 | } | ||
263 | |||
264 | static struct usb_driver cypress_driver = { | ||
265 | .name = "ums-cypress", | ||
266 | .probe = cypress_probe, | ||
267 | .disconnect = usb_stor_disconnect, | ||
268 | .suspend = usb_stor_suspend, | ||
269 | .resume = usb_stor_resume, | ||
270 | .reset_resume = usb_stor_reset_resume, | ||
271 | .pre_reset = usb_stor_pre_reset, | ||
272 | .post_reset = usb_stor_post_reset, | ||
273 | .id_table = cypress_usb_ids, | ||
274 | .soft_unbind = 1, | ||
275 | }; | ||
276 | |||
277 | static int __init cypress_init(void) | ||
278 | { | ||
279 | return usb_register(&cypress_driver); | ||
280 | } | ||
281 | |||
282 | static void __exit cypress_exit(void) | ||
283 | { | ||
284 | usb_deregister(&cypress_driver); | ||
285 | } | ||
286 | |||
287 | module_init(cypress_init); | ||
288 | module_exit(cypress_exit); | ||
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 17f1ae232919..2b6e565262c2 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c | |||
@@ -49,6 +49,7 @@ | |||
49 | */ | 49 | */ |
50 | 50 | ||
51 | #include <linux/errno.h> | 51 | #include <linux/errno.h> |
52 | #include <linux/module.h> | ||
52 | #include <linux/slab.h> | 53 | #include <linux/slab.h> |
53 | 54 | ||
54 | #include <scsi/scsi.h> | 55 | #include <scsi/scsi.h> |
@@ -58,12 +59,65 @@ | |||
58 | #include "transport.h" | 59 | #include "transport.h" |
59 | #include "protocol.h" | 60 | #include "protocol.h" |
60 | #include "debug.h" | 61 | #include "debug.h" |
61 | #include "datafab.h" | 62 | |
63 | MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader"); | ||
64 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>"); | ||
65 | MODULE_LICENSE("GPL"); | ||
66 | |||
67 | struct datafab_info { | ||
68 | unsigned long sectors; /* total sector count */ | ||
69 | unsigned long ssize; /* sector size in bytes */ | ||
70 | signed char lun; /* used for dual-slot readers */ | ||
71 | |||
72 | /* the following aren't used yet */ | ||
73 | unsigned char sense_key; | ||
74 | unsigned long sense_asc; /* additional sense code */ | ||
75 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
76 | }; | ||
62 | 77 | ||
63 | static int datafab_determine_lun(struct us_data *us, | 78 | static int datafab_determine_lun(struct us_data *us, |
64 | struct datafab_info *info); | 79 | struct datafab_info *info); |
65 | 80 | ||
66 | 81 | ||
82 | /* | ||
83 | * The table of devices | ||
84 | */ | ||
85 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
86 | vendorName, productName, useProtocol, useTransport, \ | ||
87 | initFunction, flags) \ | ||
88 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
89 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
90 | |||
91 | struct usb_device_id datafab_usb_ids[] = { | ||
92 | # include "unusual_datafab.h" | ||
93 | { } /* Terminating entry */ | ||
94 | }; | ||
95 | MODULE_DEVICE_TABLE(usb, datafab_usb_ids); | ||
96 | |||
97 | #undef UNUSUAL_DEV | ||
98 | |||
99 | /* | ||
100 | * The flags table | ||
101 | */ | ||
102 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
103 | vendor_name, product_name, use_protocol, use_transport, \ | ||
104 | init_function, Flags) \ | ||
105 | { \ | ||
106 | .vendorName = vendor_name, \ | ||
107 | .productName = product_name, \ | ||
108 | .useProtocol = use_protocol, \ | ||
109 | .useTransport = use_transport, \ | ||
110 | .initFunction = init_function, \ | ||
111 | } | ||
112 | |||
113 | static struct us_unusual_dev datafab_unusual_dev_list[] = { | ||
114 | # include "unusual_datafab.h" | ||
115 | { } /* Terminating entry */ | ||
116 | }; | ||
117 | |||
118 | #undef UNUSUAL_DEV | ||
119 | |||
120 | |||
67 | static inline int | 121 | static inline int |
68 | datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) { | 122 | datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) { |
69 | if (len == 0) | 123 | if (len == 0) |
@@ -500,7 +554,7 @@ static void datafab_info_destructor(void *extra) | |||
500 | 554 | ||
501 | // Transport for the Datafab MDCFE-B | 555 | // Transport for the Datafab MDCFE-B |
502 | // | 556 | // |
503 | int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) | 557 | static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us) |
504 | { | 558 | { |
505 | struct datafab_info *info; | 559 | struct datafab_info *info; |
506 | int rc; | 560 | int rc; |
@@ -665,3 +719,49 @@ int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
665 | info->sense_ascq = 0x00; | 719 | info->sense_ascq = 0x00; |
666 | return USB_STOR_TRANSPORT_FAILED; | 720 | return USB_STOR_TRANSPORT_FAILED; |
667 | } | 721 | } |
722 | |||
723 | static int datafab_probe(struct usb_interface *intf, | ||
724 | const struct usb_device_id *id) | ||
725 | { | ||
726 | struct us_data *us; | ||
727 | int result; | ||
728 | |||
729 | result = usb_stor_probe1(&us, intf, id, | ||
730 | (id - datafab_usb_ids) + datafab_unusual_dev_list); | ||
731 | if (result) | ||
732 | return result; | ||
733 | |||
734 | us->transport_name = "Datafab Bulk-Only"; | ||
735 | us->transport = datafab_transport; | ||
736 | us->transport_reset = usb_stor_Bulk_reset; | ||
737 | us->max_lun = 1; | ||
738 | |||
739 | result = usb_stor_probe2(us); | ||
740 | return result; | ||
741 | } | ||
742 | |||
743 | static struct usb_driver datafab_driver = { | ||
744 | .name = "ums-datafab", | ||
745 | .probe = datafab_probe, | ||
746 | .disconnect = usb_stor_disconnect, | ||
747 | .suspend = usb_stor_suspend, | ||
748 | .resume = usb_stor_resume, | ||
749 | .reset_resume = usb_stor_reset_resume, | ||
750 | .pre_reset = usb_stor_pre_reset, | ||
751 | .post_reset = usb_stor_post_reset, | ||
752 | .id_table = datafab_usb_ids, | ||
753 | .soft_unbind = 1, | ||
754 | }; | ||
755 | |||
756 | static int __init datafab_init(void) | ||
757 | { | ||
758 | return usb_register(&datafab_driver); | ||
759 | } | ||
760 | |||
761 | static void __exit datafab_exit(void) | ||
762 | { | ||
763 | usb_deregister(&datafab_driver); | ||
764 | } | ||
765 | |||
766 | module_init(datafab_init); | ||
767 | module_exit(datafab_exit); | ||
diff --git a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h deleted file mode 100644 index 32e3f271e582..000000000000 --- a/drivers/usb/storage/datafab.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* Driver for Datafab MDCFE-B USB Compact Flash reader | ||
2 | * Header File | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2000 Jimmie Mayfield (mayfield+datafab@sackheads.org) | ||
6 | * | ||
7 | * See datafab.c for more explanation | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2, or (at your option) any | ||
12 | * later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef _USB_DATAFAB_MDCFE_B_H | ||
25 | #define _USB_DATAFAB_MDCFE_B_H | ||
26 | |||
27 | extern int datafab_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
28 | |||
29 | struct datafab_info { | ||
30 | unsigned long sectors; // total sector count | ||
31 | unsigned long ssize; // sector size in bytes | ||
32 | signed char lun; // used for dual-slot readers | ||
33 | |||
34 | // the following aren't used yet | ||
35 | unsigned char sense_key; | ||
36 | unsigned long sense_asc; // additional sense code | ||
37 | unsigned long sense_ascq; // additional sense code qualifier | ||
38 | }; | ||
39 | |||
40 | #endif | ||
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 73ac7262239e..54cc94277acb 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * (http://www.freecom.de/) | 26 | * (http://www.freecom.de/) |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/module.h> | ||
29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
30 | #include <scsi/scsi_cmnd.h> | 31 | #include <scsi/scsi_cmnd.h> |
31 | 32 | ||
@@ -33,7 +34,10 @@ | |||
33 | #include "transport.h" | 34 | #include "transport.h" |
34 | #include "protocol.h" | 35 | #include "protocol.h" |
35 | #include "debug.h" | 36 | #include "debug.h" |
36 | #include "freecom.h" | 37 | |
38 | MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor"); | ||
39 | MODULE_AUTHOR("David Brown <usb-storage@davidb.org>"); | ||
40 | MODULE_LICENSE("GPL"); | ||
37 | 41 | ||
38 | #ifdef CONFIG_USB_STORAGE_DEBUG | 42 | #ifdef CONFIG_USB_STORAGE_DEBUG |
39 | static void pdump (void *, int); | 43 | static void pdump (void *, int); |
@@ -103,6 +107,47 @@ struct freecom_status { | |||
103 | #define FCM_PACKET_LENGTH 64 | 107 | #define FCM_PACKET_LENGTH 64 |
104 | #define FCM_STATUS_PACKET_LENGTH 4 | 108 | #define FCM_STATUS_PACKET_LENGTH 4 |
105 | 109 | ||
110 | static int init_freecom(struct us_data *us); | ||
111 | |||
112 | |||
113 | /* | ||
114 | * The table of devices | ||
115 | */ | ||
116 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
117 | vendorName, productName, useProtocol, useTransport, \ | ||
118 | initFunction, flags) \ | ||
119 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
120 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
121 | |||
122 | struct usb_device_id freecom_usb_ids[] = { | ||
123 | # include "unusual_freecom.h" | ||
124 | { } /* Terminating entry */ | ||
125 | }; | ||
126 | MODULE_DEVICE_TABLE(usb, freecom_usb_ids); | ||
127 | |||
128 | #undef UNUSUAL_DEV | ||
129 | |||
130 | /* | ||
131 | * The flags table | ||
132 | */ | ||
133 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
134 | vendor_name, product_name, use_protocol, use_transport, \ | ||
135 | init_function, Flags) \ | ||
136 | { \ | ||
137 | .vendorName = vendor_name, \ | ||
138 | .productName = product_name, \ | ||
139 | .useProtocol = use_protocol, \ | ||
140 | .useTransport = use_transport, \ | ||
141 | .initFunction = init_function, \ | ||
142 | } | ||
143 | |||
144 | static struct us_unusual_dev freecom_unusual_dev_list[] = { | ||
145 | # include "unusual_freecom.h" | ||
146 | { } /* Terminating entry */ | ||
147 | }; | ||
148 | |||
149 | #undef UNUSUAL_DEV | ||
150 | |||
106 | static int | 151 | static int |
107 | freecom_readdata (struct scsi_cmnd *srb, struct us_data *us, | 152 | freecom_readdata (struct scsi_cmnd *srb, struct us_data *us, |
108 | unsigned int ipipe, unsigned int opipe, int count) | 153 | unsigned int ipipe, unsigned int opipe, int count) |
@@ -173,7 +218,7 @@ freecom_writedata (struct scsi_cmnd *srb, struct us_data *us, | |||
173 | * Transport for the Freecom USB/IDE adaptor. | 218 | * Transport for the Freecom USB/IDE adaptor. |
174 | * | 219 | * |
175 | */ | 220 | */ |
176 | int freecom_transport(struct scsi_cmnd *srb, struct us_data *us) | 221 | static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us) |
177 | { | 222 | { |
178 | struct freecom_cb_wrap *fcb; | 223 | struct freecom_cb_wrap *fcb; |
179 | struct freecom_status *fst; | 224 | struct freecom_status *fst; |
@@ -377,8 +422,7 @@ int freecom_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
377 | return USB_STOR_TRANSPORT_GOOD; | 422 | return USB_STOR_TRANSPORT_GOOD; |
378 | } | 423 | } |
379 | 424 | ||
380 | int | 425 | static int init_freecom(struct us_data *us) |
381 | freecom_init (struct us_data *us) | ||
382 | { | 426 | { |
383 | int result; | 427 | int result; |
384 | char *buffer = us->iobuf; | 428 | char *buffer = us->iobuf; |
@@ -417,7 +461,7 @@ freecom_init (struct us_data *us) | |||
417 | return USB_STOR_TRANSPORT_GOOD; | 461 | return USB_STOR_TRANSPORT_GOOD; |
418 | } | 462 | } |
419 | 463 | ||
420 | int usb_stor_freecom_reset(struct us_data *us) | 464 | static int usb_stor_freecom_reset(struct us_data *us) |
421 | { | 465 | { |
422 | printk (KERN_CRIT "freecom reset called\n"); | 466 | printk (KERN_CRIT "freecom reset called\n"); |
423 | 467 | ||
@@ -479,3 +523,48 @@ static void pdump (void *ibuffer, int length) | |||
479 | } | 523 | } |
480 | #endif | 524 | #endif |
481 | 525 | ||
526 | static int freecom_probe(struct usb_interface *intf, | ||
527 | const struct usb_device_id *id) | ||
528 | { | ||
529 | struct us_data *us; | ||
530 | int result; | ||
531 | |||
532 | result = usb_stor_probe1(&us, intf, id, | ||
533 | (id - freecom_usb_ids) + freecom_unusual_dev_list); | ||
534 | if (result) | ||
535 | return result; | ||
536 | |||
537 | us->transport_name = "Freecom"; | ||
538 | us->transport = freecom_transport; | ||
539 | us->transport_reset = usb_stor_freecom_reset; | ||
540 | us->max_lun = 0; | ||
541 | |||
542 | result = usb_stor_probe2(us); | ||
543 | return result; | ||
544 | } | ||
545 | |||
546 | static struct usb_driver freecom_driver = { | ||
547 | .name = "ums-freecom", | ||
548 | .probe = freecom_probe, | ||
549 | .disconnect = usb_stor_disconnect, | ||
550 | .suspend = usb_stor_suspend, | ||
551 | .resume = usb_stor_resume, | ||
552 | .reset_resume = usb_stor_reset_resume, | ||
553 | .pre_reset = usb_stor_pre_reset, | ||
554 | .post_reset = usb_stor_post_reset, | ||
555 | .id_table = freecom_usb_ids, | ||
556 | .soft_unbind = 1, | ||
557 | }; | ||
558 | |||
559 | static int __init freecom_init(void) | ||
560 | { | ||
561 | return usb_register(&freecom_driver); | ||
562 | } | ||
563 | |||
564 | static void __exit freecom_exit(void) | ||
565 | { | ||
566 | usb_deregister(&freecom_driver); | ||
567 | } | ||
568 | |||
569 | module_init(freecom_init); | ||
570 | module_exit(freecom_exit); | ||
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 383abf2516a5..882c57b399f7 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c | |||
@@ -44,6 +44,7 @@ | |||
44 | 44 | ||
45 | #include <linux/jiffies.h> | 45 | #include <linux/jiffies.h> |
46 | #include <linux/errno.h> | 46 | #include <linux/errno.h> |
47 | #include <linux/module.h> | ||
47 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
48 | #include <linux/hdreg.h> | 49 | #include <linux/hdreg.h> |
49 | #include <linux/scatterlist.h> | 50 | #include <linux/scatterlist.h> |
@@ -57,7 +58,53 @@ | |||
57 | #include "protocol.h" | 58 | #include "protocol.h" |
58 | #include "debug.h" | 59 | #include "debug.h" |
59 | #include "scsiglue.h" | 60 | #include "scsiglue.h" |
60 | #include "isd200.h" | 61 | |
62 | MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); | ||
63 | MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); | ||
64 | MODULE_LICENSE("GPL"); | ||
65 | |||
66 | static int isd200_Initialization(struct us_data *us); | ||
67 | |||
68 | |||
69 | /* | ||
70 | * The table of devices | ||
71 | */ | ||
72 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
73 | vendorName, productName, useProtocol, useTransport, \ | ||
74 | initFunction, flags) \ | ||
75 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
76 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
77 | |||
78 | struct usb_device_id isd200_usb_ids[] = { | ||
79 | # include "unusual_isd200.h" | ||
80 | { } /* Terminating entry */ | ||
81 | }; | ||
82 | MODULE_DEVICE_TABLE(usb, isd200_usb_ids); | ||
83 | |||
84 | #undef UNUSUAL_DEV | ||
85 | #undef USUAL_DEV | ||
86 | |||
87 | /* | ||
88 | * The flags table | ||
89 | */ | ||
90 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
91 | vendor_name, product_name, use_protocol, use_transport, \ | ||
92 | init_function, Flags) \ | ||
93 | { \ | ||
94 | .vendorName = vendor_name, \ | ||
95 | .productName = product_name, \ | ||
96 | .useProtocol = use_protocol, \ | ||
97 | .useTransport = use_transport, \ | ||
98 | .initFunction = init_function, \ | ||
99 | } | ||
100 | |||
101 | static struct us_unusual_dev isd200_unusual_dev_list[] = { | ||
102 | # include "unusual_isd200.h" | ||
103 | { } /* Terminating entry */ | ||
104 | }; | ||
105 | |||
106 | #undef UNUSUAL_DEV | ||
107 | #undef USUAL_DEV | ||
61 | 108 | ||
62 | 109 | ||
63 | /* Timeout defines (in Seconds) */ | 110 | /* Timeout defines (in Seconds) */ |
@@ -1518,7 +1565,7 @@ static int isd200_init_info(struct us_data *us) | |||
1518 | * Initialization for the ISD200 | 1565 | * Initialization for the ISD200 |
1519 | */ | 1566 | */ |
1520 | 1567 | ||
1521 | int isd200_Initialization(struct us_data *us) | 1568 | static int isd200_Initialization(struct us_data *us) |
1522 | { | 1569 | { |
1523 | US_DEBUGP("ISD200 Initialization...\n"); | 1570 | US_DEBUGP("ISD200 Initialization...\n"); |
1524 | 1571 | ||
@@ -1549,7 +1596,7 @@ int isd200_Initialization(struct us_data *us) | |||
1549 | * | 1596 | * |
1550 | */ | 1597 | */ |
1551 | 1598 | ||
1552 | void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) | 1599 | static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) |
1553 | { | 1600 | { |
1554 | int sendToTransport = 1, orig_bufflen; | 1601 | int sendToTransport = 1, orig_bufflen; |
1555 | union ata_cdb ataCdb; | 1602 | union ata_cdb ataCdb; |
@@ -1570,3 +1617,47 @@ void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) | |||
1570 | 1617 | ||
1571 | isd200_srb_set_bufflen(srb, orig_bufflen); | 1618 | isd200_srb_set_bufflen(srb, orig_bufflen); |
1572 | } | 1619 | } |
1620 | |||
1621 | static int isd200_probe(struct usb_interface *intf, | ||
1622 | const struct usb_device_id *id) | ||
1623 | { | ||
1624 | struct us_data *us; | ||
1625 | int result; | ||
1626 | |||
1627 | result = usb_stor_probe1(&us, intf, id, | ||
1628 | (id - isd200_usb_ids) + isd200_unusual_dev_list); | ||
1629 | if (result) | ||
1630 | return result; | ||
1631 | |||
1632 | us->protocol_name = "ISD200 ATA/ATAPI"; | ||
1633 | us->proto_handler = isd200_ata_command; | ||
1634 | |||
1635 | result = usb_stor_probe2(us); | ||
1636 | return result; | ||
1637 | } | ||
1638 | |||
1639 | static struct usb_driver isd200_driver = { | ||
1640 | .name = "ums-isd200", | ||
1641 | .probe = isd200_probe, | ||
1642 | .disconnect = usb_stor_disconnect, | ||
1643 | .suspend = usb_stor_suspend, | ||
1644 | .resume = usb_stor_resume, | ||
1645 | .reset_resume = usb_stor_reset_resume, | ||
1646 | .pre_reset = usb_stor_pre_reset, | ||
1647 | .post_reset = usb_stor_post_reset, | ||
1648 | .id_table = isd200_usb_ids, | ||
1649 | .soft_unbind = 1, | ||
1650 | }; | ||
1651 | |||
1652 | static int __init isd200_init(void) | ||
1653 | { | ||
1654 | return usb_register(&isd200_driver); | ||
1655 | } | ||
1656 | |||
1657 | static void __exit isd200_exit(void) | ||
1658 | { | ||
1659 | usb_deregister(&isd200_driver); | ||
1660 | } | ||
1661 | |||
1662 | module_init(isd200_init); | ||
1663 | module_exit(isd200_exit); | ||
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index df67f13c9e73..1c69420e3acf 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c | |||
@@ -46,6 +46,7 @@ | |||
46 | */ | 46 | */ |
47 | 47 | ||
48 | #include <linux/errno.h> | 48 | #include <linux/errno.h> |
49 | #include <linux/module.h> | ||
49 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
50 | 51 | ||
51 | #include <scsi/scsi.h> | 52 | #include <scsi/scsi.h> |
@@ -55,9 +56,61 @@ | |||
55 | #include "transport.h" | 56 | #include "transport.h" |
56 | #include "protocol.h" | 57 | #include "protocol.h" |
57 | #include "debug.h" | 58 | #include "debug.h" |
58 | #include "jumpshot.h" | ||
59 | 59 | ||
60 | 60 | ||
61 | MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader"); | ||
62 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>"); | ||
63 | MODULE_LICENSE("GPL"); | ||
64 | |||
65 | /* | ||
66 | * The table of devices | ||
67 | */ | ||
68 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
69 | vendorName, productName, useProtocol, useTransport, \ | ||
70 | initFunction, flags) \ | ||
71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
72 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
73 | |||
74 | struct usb_device_id jumpshot_usb_ids[] = { | ||
75 | # include "unusual_jumpshot.h" | ||
76 | { } /* Terminating entry */ | ||
77 | }; | ||
78 | MODULE_DEVICE_TABLE(usb, jumpshot_usb_ids); | ||
79 | |||
80 | #undef UNUSUAL_DEV | ||
81 | |||
82 | /* | ||
83 | * The flags table | ||
84 | */ | ||
85 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
86 | vendor_name, product_name, use_protocol, use_transport, \ | ||
87 | init_function, Flags) \ | ||
88 | { \ | ||
89 | .vendorName = vendor_name, \ | ||
90 | .productName = product_name, \ | ||
91 | .useProtocol = use_protocol, \ | ||
92 | .useTransport = use_transport, \ | ||
93 | .initFunction = init_function, \ | ||
94 | } | ||
95 | |||
96 | static struct us_unusual_dev jumpshot_unusual_dev_list[] = { | ||
97 | # include "unusual_jumpshot.h" | ||
98 | { } /* Terminating entry */ | ||
99 | }; | ||
100 | |||
101 | #undef UNUSUAL_DEV | ||
102 | |||
103 | |||
104 | struct jumpshot_info { | ||
105 | unsigned long sectors; /* total sector count */ | ||
106 | unsigned long ssize; /* sector size in bytes */ | ||
107 | |||
108 | /* the following aren't used yet */ | ||
109 | unsigned char sense_key; | ||
110 | unsigned long sense_asc; /* additional sense code */ | ||
111 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
112 | }; | ||
113 | |||
61 | static inline int jumpshot_bulk_read(struct us_data *us, | 114 | static inline int jumpshot_bulk_read(struct us_data *us, |
62 | unsigned char *data, | 115 | unsigned char *data, |
63 | unsigned int len) | 116 | unsigned int len) |
@@ -429,7 +482,7 @@ static void jumpshot_info_destructor(void *extra) | |||
429 | 482 | ||
430 | // Transport for the Lexar 'Jumpshot' | 483 | // Transport for the Lexar 'Jumpshot' |
431 | // | 484 | // |
432 | int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) | 485 | static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us) |
433 | { | 486 | { |
434 | struct jumpshot_info *info; | 487 | struct jumpshot_info *info; |
435 | int rc; | 488 | int rc; |
@@ -592,3 +645,49 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
592 | info->sense_ascq = 0x00; | 645 | info->sense_ascq = 0x00; |
593 | return USB_STOR_TRANSPORT_FAILED; | 646 | return USB_STOR_TRANSPORT_FAILED; |
594 | } | 647 | } |
648 | |||
649 | static int jumpshot_probe(struct usb_interface *intf, | ||
650 | const struct usb_device_id *id) | ||
651 | { | ||
652 | struct us_data *us; | ||
653 | int result; | ||
654 | |||
655 | result = usb_stor_probe1(&us, intf, id, | ||
656 | (id - jumpshot_usb_ids) + jumpshot_unusual_dev_list); | ||
657 | if (result) | ||
658 | return result; | ||
659 | |||
660 | us->transport_name = "Lexar Jumpshot Control/Bulk"; | ||
661 | us->transport = jumpshot_transport; | ||
662 | us->transport_reset = usb_stor_Bulk_reset; | ||
663 | us->max_lun = 1; | ||
664 | |||
665 | result = usb_stor_probe2(us); | ||
666 | return result; | ||
667 | } | ||
668 | |||
669 | static struct usb_driver jumpshot_driver = { | ||
670 | .name = "ums-jumpshot", | ||
671 | .probe = jumpshot_probe, | ||
672 | .disconnect = usb_stor_disconnect, | ||
673 | .suspend = usb_stor_suspend, | ||
674 | .resume = usb_stor_resume, | ||
675 | .reset_resume = usb_stor_reset_resume, | ||
676 | .pre_reset = usb_stor_pre_reset, | ||
677 | .post_reset = usb_stor_post_reset, | ||
678 | .id_table = jumpshot_usb_ids, | ||
679 | .soft_unbind = 1, | ||
680 | }; | ||
681 | |||
682 | static int __init jumpshot_init(void) | ||
683 | { | ||
684 | return usb_register(&jumpshot_driver); | ||
685 | } | ||
686 | |||
687 | static void __exit jumpshot_exit(void) | ||
688 | { | ||
689 | usb_deregister(&jumpshot_driver); | ||
690 | } | ||
691 | |||
692 | module_init(jumpshot_init); | ||
693 | module_exit(jumpshot_exit); | ||
diff --git a/drivers/usb/storage/jumpshot.h b/drivers/usb/storage/jumpshot.h deleted file mode 100644 index 19bac9d1558f..000000000000 --- a/drivers/usb/storage/jumpshot.h +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | /* Driver for Lexar "Jumpshot" USB Compact Flash reader | ||
2 | * Header File | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2000 Jimmie Mayfield (mayfield+usb@sackheads.org) | ||
6 | * | ||
7 | * See jumpshot.c for more explanation | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2, or (at your option) any | ||
12 | * later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef _USB_JUMPSHOT_H | ||
25 | #define _USB_JUMPSHOT_H | ||
26 | |||
27 | extern int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
28 | |||
29 | struct jumpshot_info { | ||
30 | unsigned long sectors; // total sector count | ||
31 | unsigned long ssize; // sector size in bytes | ||
32 | |||
33 | // the following aren't used yet | ||
34 | unsigned char sense_key; | ||
35 | unsigned long sense_asc; // additional sense code | ||
36 | unsigned long sense_ascq; // additional sense code qualifier | ||
37 | }; | ||
38 | |||
39 | #endif | ||
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index 0d79ae5683f7..7953d93a7739 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c | |||
@@ -18,6 +18,8 @@ | |||
18 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 18 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/module.h> | ||
22 | |||
21 | #include <scsi/scsi.h> | 23 | #include <scsi/scsi.h> |
22 | #include <scsi/scsi_cmnd.h> | 24 | #include <scsi/scsi_cmnd.h> |
23 | #include <scsi/scsi_device.h> | 25 | #include <scsi/scsi_device.h> |
@@ -25,7 +27,10 @@ | |||
25 | #include "usb.h" | 27 | #include "usb.h" |
26 | #include "transport.h" | 28 | #include "transport.h" |
27 | #include "debug.h" | 29 | #include "debug.h" |
28 | #include "karma.h" | 30 | |
31 | MODULE_DESCRIPTION("Driver for Rio Karma"); | ||
32 | MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>"); | ||
33 | MODULE_LICENSE("GPL"); | ||
29 | 34 | ||
30 | #define RIO_PREFIX "RIOP\x00" | 35 | #define RIO_PREFIX "RIOP\x00" |
31 | #define RIO_PREFIX_LEN 5 | 36 | #define RIO_PREFIX_LEN 5 |
@@ -36,13 +41,53 @@ | |||
36 | #define RIO_LEAVE_STORAGE 0x2 | 41 | #define RIO_LEAVE_STORAGE 0x2 |
37 | #define RIO_RESET 0xC | 42 | #define RIO_RESET 0xC |
38 | 43 | ||
39 | extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data *); | ||
40 | |||
41 | struct karma_data { | 44 | struct karma_data { |
42 | int in_storage; | 45 | int in_storage; |
43 | char *recv; | 46 | char *recv; |
44 | }; | 47 | }; |
45 | 48 | ||
49 | static int rio_karma_init(struct us_data *us); | ||
50 | |||
51 | |||
52 | /* | ||
53 | * The table of devices | ||
54 | */ | ||
55 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
56 | vendorName, productName, useProtocol, useTransport, \ | ||
57 | initFunction, flags) \ | ||
58 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
59 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
60 | |||
61 | struct usb_device_id karma_usb_ids[] = { | ||
62 | # include "unusual_karma.h" | ||
63 | { } /* Terminating entry */ | ||
64 | }; | ||
65 | MODULE_DEVICE_TABLE(usb, karma_usb_ids); | ||
66 | |||
67 | #undef UNUSUAL_DEV | ||
68 | |||
69 | /* | ||
70 | * The flags table | ||
71 | */ | ||
72 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
73 | vendor_name, product_name, use_protocol, use_transport, \ | ||
74 | init_function, Flags) \ | ||
75 | { \ | ||
76 | .vendorName = vendor_name, \ | ||
77 | .productName = product_name, \ | ||
78 | .useProtocol = use_protocol, \ | ||
79 | .useTransport = use_transport, \ | ||
80 | .initFunction = init_function, \ | ||
81 | } | ||
82 | |||
83 | static struct us_unusual_dev karma_unusual_dev_list[] = { | ||
84 | # include "unusual_karma.h" | ||
85 | { } /* Terminating entry */ | ||
86 | }; | ||
87 | |||
88 | #undef UNUSUAL_DEV | ||
89 | |||
90 | |||
46 | /* | 91 | /* |
47 | * Send commands to Rio Karma. | 92 | * Send commands to Rio Karma. |
48 | * | 93 | * |
@@ -104,7 +149,7 @@ err: | |||
104 | * Trap START_STOP and READ_10 to leave/re-enter storage mode. | 149 | * Trap START_STOP and READ_10 to leave/re-enter storage mode. |
105 | * Everything else is propagated to the normal bulk layer. | 150 | * Everything else is propagated to the normal bulk layer. |
106 | */ | 151 | */ |
107 | int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us) | 152 | static int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us) |
108 | { | 153 | { |
109 | int ret; | 154 | int ret; |
110 | struct karma_data *data = (struct karma_data *) us->extra; | 155 | struct karma_data *data = (struct karma_data *) us->extra; |
@@ -133,7 +178,7 @@ static void rio_karma_destructor(void *extra) | |||
133 | kfree(data->recv); | 178 | kfree(data->recv); |
134 | } | 179 | } |
135 | 180 | ||
136 | int rio_karma_init(struct us_data *us) | 181 | static int rio_karma_init(struct us_data *us) |
137 | { | 182 | { |
138 | int ret = 0; | 183 | int ret = 0; |
139 | struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO); | 184 | struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO); |
@@ -153,3 +198,48 @@ int rio_karma_init(struct us_data *us) | |||
153 | out: | 198 | out: |
154 | return ret; | 199 | return ret; |
155 | } | 200 | } |
201 | |||
202 | static int karma_probe(struct usb_interface *intf, | ||
203 | const struct usb_device_id *id) | ||
204 | { | ||
205 | struct us_data *us; | ||
206 | int result; | ||
207 | |||
208 | result = usb_stor_probe1(&us, intf, id, | ||
209 | (id - karma_usb_ids) + karma_unusual_dev_list); | ||
210 | if (result) | ||
211 | return result; | ||
212 | |||
213 | us->transport_name = "Rio Karma/Bulk"; | ||
214 | us->transport = rio_karma_transport; | ||
215 | us->transport_reset = usb_stor_Bulk_reset; | ||
216 | |||
217 | result = usb_stor_probe2(us); | ||
218 | return result; | ||
219 | } | ||
220 | |||
221 | static struct usb_driver karma_driver = { | ||
222 | .name = "ums-karma", | ||
223 | .probe = karma_probe, | ||
224 | .disconnect = usb_stor_disconnect, | ||
225 | .suspend = usb_stor_suspend, | ||
226 | .resume = usb_stor_resume, | ||
227 | .reset_resume = usb_stor_reset_resume, | ||
228 | .pre_reset = usb_stor_pre_reset, | ||
229 | .post_reset = usb_stor_post_reset, | ||
230 | .id_table = karma_usb_ids, | ||
231 | .soft_unbind = 1, | ||
232 | }; | ||
233 | |||
234 | static int __init karma_init(void) | ||
235 | { | ||
236 | return usb_register(&karma_driver); | ||
237 | } | ||
238 | |||
239 | static void __exit karma_exit(void) | ||
240 | { | ||
241 | usb_deregister(&karma_driver); | ||
242 | } | ||
243 | |||
244 | module_init(karma_init); | ||
245 | module_exit(karma_exit); | ||
diff --git a/drivers/usb/storage/karma.h b/drivers/usb/storage/karma.h deleted file mode 100644 index 8a60972af8c5..000000000000 --- a/drivers/usb/storage/karma.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _KARMA_USB_H | ||
2 | #define _KARMA_USB_H | ||
3 | |||
4 | extern int rio_karma_init(struct us_data *us); | ||
5 | extern int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
6 | |||
7 | #endif | ||
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c index f970b27ba308..fe3ffe1459b2 100644 --- a/drivers/usb/storage/libusual.c +++ b/drivers/usb/storage/libusual.c | |||
@@ -38,37 +38,6 @@ static atomic_t total_threads = ATOMIC_INIT(0); | |||
38 | static int usu_probe_thread(void *arg); | 38 | static int usu_probe_thread(void *arg); |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * The table. | ||
42 | */ | ||
43 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
44 | vendorName, productName,useProtocol, useTransport, \ | ||
45 | initFunction, flags) \ | ||
46 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
47 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
48 | |||
49 | #define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
50 | vendorName, productName, useProtocol, useTransport, \ | ||
51 | initFunction, flags) \ | ||
52 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
53 | .driver_info = (flags) } | ||
54 | |||
55 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
56 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
57 | .driver_info = ((useType)<<24) } | ||
58 | |||
59 | struct usb_device_id storage_usb_ids [] = { | ||
60 | # include "unusual_devs.h" | ||
61 | { } /* Terminating entry */ | ||
62 | }; | ||
63 | |||
64 | #undef USUAL_DEV | ||
65 | #undef UNUSUAL_DEV | ||
66 | #undef COMPLIANT_DEV | ||
67 | |||
68 | MODULE_DEVICE_TABLE(usb, storage_usb_ids); | ||
69 | EXPORT_SYMBOL_GPL(storage_usb_ids); | ||
70 | |||
71 | /* | ||
72 | * @type: the module type as an integer | 41 | * @type: the module type as an integer |
73 | */ | 42 | */ |
74 | void usb_usual_set_present(int type) | 43 | void usb_usual_set_present(int type) |
@@ -167,7 +136,7 @@ static struct usb_driver usu_driver = { | |||
167 | .name = "libusual", | 136 | .name = "libusual", |
168 | .probe = usu_probe, | 137 | .probe = usu_probe, |
169 | .disconnect = usu_disconnect, | 138 | .disconnect = usu_disconnect, |
170 | .id_table = storage_usb_ids, | 139 | .id_table = usb_storage_usb_ids, |
171 | }; | 140 | }; |
172 | 141 | ||
173 | /* | 142 | /* |
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index c7bf8954b4e4..380233bd6a39 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -35,9 +35,16 @@ | |||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/usb/input.h> | 36 | #include <linux/usb/input.h> |
37 | #include "usb.h" | 37 | #include "usb.h" |
38 | #include "onetouch.h" | ||
39 | #include "debug.h" | 38 | #include "debug.h" |
40 | 39 | ||
40 | MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver"); | ||
41 | MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>"); | ||
42 | MODULE_LICENSE("GPL"); | ||
43 | |||
44 | #define ONETOUCH_PKT_LEN 0x02 | ||
45 | #define ONETOUCH_BUTTON KEY_PROG1 | ||
46 | |||
47 | static int onetouch_connect_input(struct us_data *ss); | ||
41 | static void onetouch_release_input(void *onetouch_); | 48 | static void onetouch_release_input(void *onetouch_); |
42 | 49 | ||
43 | struct usb_onetouch { | 50 | struct usb_onetouch { |
@@ -52,6 +59,46 @@ struct usb_onetouch { | |||
52 | unsigned int is_open:1; | 59 | unsigned int is_open:1; |
53 | }; | 60 | }; |
54 | 61 | ||
62 | |||
63 | /* | ||
64 | * The table of devices | ||
65 | */ | ||
66 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
67 | vendorName, productName, useProtocol, useTransport, \ | ||
68 | initFunction, flags) \ | ||
69 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
70 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
71 | |||
72 | struct usb_device_id onetouch_usb_ids[] = { | ||
73 | # include "unusual_onetouch.h" | ||
74 | { } /* Terminating entry */ | ||
75 | }; | ||
76 | MODULE_DEVICE_TABLE(usb, onetouch_usb_ids); | ||
77 | |||
78 | #undef UNUSUAL_DEV | ||
79 | |||
80 | /* | ||
81 | * The flags table | ||
82 | */ | ||
83 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
84 | vendor_name, product_name, use_protocol, use_transport, \ | ||
85 | init_function, Flags) \ | ||
86 | { \ | ||
87 | .vendorName = vendor_name, \ | ||
88 | .productName = product_name, \ | ||
89 | .useProtocol = use_protocol, \ | ||
90 | .useTransport = use_transport, \ | ||
91 | .initFunction = init_function, \ | ||
92 | } | ||
93 | |||
94 | static struct us_unusual_dev onetouch_unusual_dev_list[] = { | ||
95 | # include "unusual_onetouch.h" | ||
96 | { } /* Terminating entry */ | ||
97 | }; | ||
98 | |||
99 | #undef UNUSUAL_DEV | ||
100 | |||
101 | |||
55 | static void usb_onetouch_irq(struct urb *urb) | 102 | static void usb_onetouch_irq(struct urb *urb) |
56 | { | 103 | { |
57 | struct usb_onetouch *onetouch = urb->context; | 104 | struct usb_onetouch *onetouch = urb->context; |
@@ -127,7 +174,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action) | |||
127 | } | 174 | } |
128 | #endif /* CONFIG_PM */ | 175 | #endif /* CONFIG_PM */ |
129 | 176 | ||
130 | int onetouch_connect_input(struct us_data *ss) | 177 | static int onetouch_connect_input(struct us_data *ss) |
131 | { | 178 | { |
132 | struct usb_device *udev = ss->pusb_dev; | 179 | struct usb_device *udev = ss->pusb_dev; |
133 | struct usb_host_interface *interface; | 180 | struct usb_host_interface *interface; |
@@ -236,3 +283,46 @@ static void onetouch_release_input(void *onetouch_) | |||
236 | onetouch->data, onetouch->data_dma); | 283 | onetouch->data, onetouch->data_dma); |
237 | } | 284 | } |
238 | } | 285 | } |
286 | |||
287 | static int onetouch_probe(struct usb_interface *intf, | ||
288 | const struct usb_device_id *id) | ||
289 | { | ||
290 | struct us_data *us; | ||
291 | int result; | ||
292 | |||
293 | result = usb_stor_probe1(&us, intf, id, | ||
294 | (id - onetouch_usb_ids) + onetouch_unusual_dev_list); | ||
295 | if (result) | ||
296 | return result; | ||
297 | |||
298 | /* Use default transport and protocol */ | ||
299 | |||
300 | result = usb_stor_probe2(us); | ||
301 | return result; | ||
302 | } | ||
303 | |||
304 | static struct usb_driver onetouch_driver = { | ||
305 | .name = "ums-onetouch", | ||
306 | .probe = onetouch_probe, | ||
307 | .disconnect = usb_stor_disconnect, | ||
308 | .suspend = usb_stor_suspend, | ||
309 | .resume = usb_stor_resume, | ||
310 | .reset_resume = usb_stor_reset_resume, | ||
311 | .pre_reset = usb_stor_pre_reset, | ||
312 | .post_reset = usb_stor_post_reset, | ||
313 | .id_table = onetouch_usb_ids, | ||
314 | .soft_unbind = 1, | ||
315 | }; | ||
316 | |||
317 | static int __init onetouch_init(void) | ||
318 | { | ||
319 | return usb_register(&onetouch_driver); | ||
320 | } | ||
321 | |||
322 | static void __exit onetouch_exit(void) | ||
323 | { | ||
324 | usb_deregister(&onetouch_driver); | ||
325 | } | ||
326 | |||
327 | module_init(onetouch_init); | ||
328 | module_exit(onetouch_exit); | ||
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h deleted file mode 100644 index 41c7aa8f0446..000000000000 --- a/drivers/usb/storage/onetouch.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | #ifndef _ONETOUCH_H_ | ||
2 | #define _ONETOUCH_H_ | ||
3 | |||
4 | #define ONETOUCH_PKT_LEN 0x02 | ||
5 | #define ONETOUCH_BUTTON KEY_PROG1 | ||
6 | |||
7 | int onetouch_connect_input(struct us_data *ss); | ||
8 | |||
9 | #endif | ||
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index be441d84bc64..fc310f75eada 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c | |||
@@ -121,6 +121,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, | |||
121 | /* send the command to the transport layer */ | 121 | /* send the command to the transport layer */ |
122 | usb_stor_invoke_transport(srb, us); | 122 | usb_stor_invoke_transport(srb, us); |
123 | } | 123 | } |
124 | EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command); | ||
124 | 125 | ||
125 | /*********************************************************************** | 126 | /*********************************************************************** |
126 | * Scatter-gather transfer buffer access routines | 127 | * Scatter-gather transfer buffer access routines |
@@ -199,6 +200,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, | |||
199 | /* Return the amount actually transferred */ | 200 | /* Return the amount actually transferred */ |
200 | return cnt; | 201 | return cnt; |
201 | } | 202 | } |
203 | EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf); | ||
202 | 204 | ||
203 | /* Store the contents of buffer into srb's transfer buffer and set the | 205 | /* Store the contents of buffer into srb's transfer buffer and set the |
204 | * SCSI residue. | 206 | * SCSI residue. |
@@ -215,3 +217,4 @@ void usb_stor_set_xfer_buf(unsigned char *buffer, | |||
215 | if (buflen < scsi_bufflen(srb)) | 217 | if (buflen < scsi_bufflen(srb)) |
216 | scsi_set_resid(srb, scsi_bufflen(srb) - buflen); | 218 | scsi_set_resid(srb, scsi_bufflen(srb) - buflen); |
217 | } | 219 | } |
220 | EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf); | ||
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 727c506417cc..4ca3b5860643 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -135,6 +135,12 @@ static int slave_configure(struct scsi_device *sdev) | |||
135 | if (sdev->request_queue->max_sectors > max_sectors) | 135 | if (sdev->request_queue->max_sectors > max_sectors) |
136 | blk_queue_max_sectors(sdev->request_queue, | 136 | blk_queue_max_sectors(sdev->request_queue, |
137 | max_sectors); | 137 | max_sectors); |
138 | } else if (sdev->type == TYPE_TAPE) { | ||
139 | /* Tapes need much higher max_sector limits, so just | ||
140 | * raise it to the maximum possible (4 GB / 512) and | ||
141 | * let the queue segment size sort out the real limit. | ||
142 | */ | ||
143 | blk_queue_max_sectors(sdev->request_queue, 0x7FFFFF); | ||
138 | } | 144 | } |
139 | 145 | ||
140 | /* Some USB host controllers can't do DMA; they have to use PIO. | 146 | /* Some USB host controllers can't do DMA; they have to use PIO. |
@@ -563,4 +569,4 @@ unsigned char usb_stor_sense_invalidCDB[18] = { | |||
563 | [7] = 0x0a, /* additional length */ | 569 | [7] = 0x0a, /* additional length */ |
564 | [12] = 0x24 /* Invalid Field in CDB */ | 570 | [12] = 0x24 /* Invalid Field in CDB */ |
565 | }; | 571 | }; |
566 | 572 | EXPORT_SYMBOL_GPL(usb_stor_sense_invalidCDB); | |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 531ae5c5abf3..ab5f9f37575a 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -41,6 +41,7 @@ | |||
41 | */ | 41 | */ |
42 | 42 | ||
43 | #include <linux/errno.h> | 43 | #include <linux/errno.h> |
44 | #include <linux/module.h> | ||
44 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
45 | 46 | ||
46 | #include <scsi/scsi.h> | 47 | #include <scsi/scsi.h> |
@@ -51,7 +52,53 @@ | |||
51 | #include "transport.h" | 52 | #include "transport.h" |
52 | #include "protocol.h" | 53 | #include "protocol.h" |
53 | #include "debug.h" | 54 | #include "debug.h" |
54 | #include "sddr09.h" | 55 | |
56 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader"); | ||
57 | MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>"); | ||
58 | MODULE_LICENSE("GPL"); | ||
59 | |||
60 | static int usb_stor_sddr09_dpcm_init(struct us_data *us); | ||
61 | static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
62 | static int usb_stor_sddr09_init(struct us_data *us); | ||
63 | |||
64 | |||
65 | /* | ||
66 | * The table of devices | ||
67 | */ | ||
68 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
69 | vendorName, productName, useProtocol, useTransport, \ | ||
70 | initFunction, flags) \ | ||
71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
72 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
73 | |||
74 | struct usb_device_id sddr09_usb_ids[] = { | ||
75 | # include "unusual_sddr09.h" | ||
76 | { } /* Terminating entry */ | ||
77 | }; | ||
78 | MODULE_DEVICE_TABLE(usb, sddr09_usb_ids); | ||
79 | |||
80 | #undef UNUSUAL_DEV | ||
81 | |||
82 | /* | ||
83 | * The flags table | ||
84 | */ | ||
85 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
86 | vendor_name, product_name, use_protocol, use_transport, \ | ||
87 | init_function, Flags) \ | ||
88 | { \ | ||
89 | .vendorName = vendor_name, \ | ||
90 | .productName = product_name, \ | ||
91 | .useProtocol = use_protocol, \ | ||
92 | .useTransport = use_transport, \ | ||
93 | .initFunction = init_function, \ | ||
94 | } | ||
95 | |||
96 | static struct us_unusual_dev sddr09_unusual_dev_list[] = { | ||
97 | # include "unusual_sddr09.h" | ||
98 | { } /* Terminating entry */ | ||
99 | }; | ||
100 | |||
101 | #undef UNUSUAL_DEV | ||
55 | 102 | ||
56 | 103 | ||
57 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | 104 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) |
@@ -723,7 +770,7 @@ sddr09_read_data(struct us_data *us, | |||
723 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; | 770 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; |
724 | buffer = kmalloc(len, GFP_NOIO); | 771 | buffer = kmalloc(len, GFP_NOIO); |
725 | if (buffer == NULL) { | 772 | if (buffer == NULL) { |
726 | printk("sddr09_read_data: Out of memory\n"); | 773 | printk(KERN_WARNING "sddr09_read_data: Out of memory\n"); |
727 | return -ENOMEM; | 774 | return -ENOMEM; |
728 | } | 775 | } |
729 | 776 | ||
@@ -838,7 +885,8 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
838 | if (pba == UNDEF) { | 885 | if (pba == UNDEF) { |
839 | pba = sddr09_find_unused_pba(info, lba); | 886 | pba = sddr09_find_unused_pba(info, lba); |
840 | if (!pba) { | 887 | if (!pba) { |
841 | printk("sddr09_write_lba: Out of unused blocks\n"); | 888 | printk(KERN_WARNING |
889 | "sddr09_write_lba: Out of unused blocks\n"); | ||
842 | return -ENOSPC; | 890 | return -ENOSPC; |
843 | } | 891 | } |
844 | info->pba_to_lba[pba] = lba; | 892 | info->pba_to_lba[pba] = lba; |
@@ -849,7 +897,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
849 | if (pba == 1) { | 897 | if (pba == 1) { |
850 | /* Maybe it is impossible to write to PBA 1. | 898 | /* Maybe it is impossible to write to PBA 1. |
851 | Fake success, but don't do anything. */ | 899 | Fake success, but don't do anything. */ |
852 | printk("sddr09: avoid writing to pba 1\n"); | 900 | printk(KERN_WARNING "sddr09: avoid writing to pba 1\n"); |
853 | return 0; | 901 | return 0; |
854 | } | 902 | } |
855 | 903 | ||
@@ -954,7 +1002,7 @@ sddr09_write_data(struct us_data *us, | |||
954 | blocklen = (pagelen << info->blockshift); | 1002 | blocklen = (pagelen << info->blockshift); |
955 | blockbuffer = kmalloc(blocklen, GFP_NOIO); | 1003 | blockbuffer = kmalloc(blocklen, GFP_NOIO); |
956 | if (!blockbuffer) { | 1004 | if (!blockbuffer) { |
957 | printk("sddr09_write_data: Out of memory\n"); | 1005 | printk(KERN_WARNING "sddr09_write_data: Out of memory\n"); |
958 | return -ENOMEM; | 1006 | return -ENOMEM; |
959 | } | 1007 | } |
960 | 1008 | ||
@@ -965,7 +1013,7 @@ sddr09_write_data(struct us_data *us, | |||
965 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; | 1013 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; |
966 | buffer = kmalloc(len, GFP_NOIO); | 1014 | buffer = kmalloc(len, GFP_NOIO); |
967 | if (buffer == NULL) { | 1015 | if (buffer == NULL) { |
968 | printk("sddr09_write_data: Out of memory\n"); | 1016 | printk(KERN_WARNING "sddr09_write_data: Out of memory\n"); |
969 | kfree(blockbuffer); | 1017 | kfree(blockbuffer); |
970 | return -ENOMEM; | 1018 | return -ENOMEM; |
971 | } | 1019 | } |
@@ -1112,7 +1160,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
1112 | 1160 | ||
1113 | if (result) { | 1161 | if (result) { |
1114 | US_DEBUGP("Result of read_deviceID is %d\n", result); | 1162 | US_DEBUGP("Result of read_deviceID is %d\n", result); |
1115 | printk("sddr09: could not read card info\n"); | 1163 | printk(KERN_WARNING "sddr09: could not read card info\n"); |
1116 | return NULL; | 1164 | return NULL; |
1117 | } | 1165 | } |
1118 | 1166 | ||
@@ -1153,7 +1201,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
1153 | sprintf(blurbtxt + strlen(blurbtxt), | 1201 | sprintf(blurbtxt + strlen(blurbtxt), |
1154 | ", WP"); | 1202 | ", WP"); |
1155 | 1203 | ||
1156 | printk("%s\n", blurbtxt); | 1204 | printk(KERN_WARNING "%s\n", blurbtxt); |
1157 | 1205 | ||
1158 | return cardinfo; | 1206 | return cardinfo; |
1159 | } | 1207 | } |
@@ -1184,7 +1232,7 @@ sddr09_read_map(struct us_data *us) { | |||
1184 | alloc_len = (alloc_blocks << CONTROL_SHIFT); | 1232 | alloc_len = (alloc_blocks << CONTROL_SHIFT); |
1185 | buffer = kmalloc(alloc_len, GFP_NOIO); | 1233 | buffer = kmalloc(alloc_len, GFP_NOIO); |
1186 | if (buffer == NULL) { | 1234 | if (buffer == NULL) { |
1187 | printk("sddr09_read_map: out of memory\n"); | 1235 | printk(KERN_WARNING "sddr09_read_map: out of memory\n"); |
1188 | result = -1; | 1236 | result = -1; |
1189 | goto done; | 1237 | goto done; |
1190 | } | 1238 | } |
@@ -1198,7 +1246,7 @@ sddr09_read_map(struct us_data *us) { | |||
1198 | info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO); | 1246 | info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO); |
1199 | 1247 | ||
1200 | if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { | 1248 | if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { |
1201 | printk("sddr09_read_map: out of memory\n"); | 1249 | printk(KERN_WARNING "sddr09_read_map: out of memory\n"); |
1202 | result = -1; | 1250 | result = -1; |
1203 | goto done; | 1251 | goto done; |
1204 | } | 1252 | } |
@@ -1238,7 +1286,8 @@ sddr09_read_map(struct us_data *us) { | |||
1238 | if (ptr[j] != 0) | 1286 | if (ptr[j] != 0) |
1239 | goto nonz; | 1287 | goto nonz; |
1240 | info->pba_to_lba[i] = UNUSABLE; | 1288 | info->pba_to_lba[i] = UNUSABLE; |
1241 | printk("sddr09: PBA %d has no logical mapping\n", i); | 1289 | printk(KERN_WARNING "sddr09: PBA %d has no logical mapping\n", |
1290 | i); | ||
1242 | continue; | 1291 | continue; |
1243 | 1292 | ||
1244 | nonz: | 1293 | nonz: |
@@ -1251,7 +1300,8 @@ sddr09_read_map(struct us_data *us) { | |||
1251 | nonff: | 1300 | nonff: |
1252 | /* normal PBAs start with six FFs */ | 1301 | /* normal PBAs start with six FFs */ |
1253 | if (j < 6) { | 1302 | if (j < 6) { |
1254 | printk("sddr09: PBA %d has no logical mapping: " | 1303 | printk(KERN_WARNING |
1304 | "sddr09: PBA %d has no logical mapping: " | ||
1255 | "reserved area = %02X%02X%02X%02X " | 1305 | "reserved area = %02X%02X%02X%02X " |
1256 | "data status %02X block status %02X\n", | 1306 | "data status %02X block status %02X\n", |
1257 | i, ptr[0], ptr[1], ptr[2], ptr[3], | 1307 | i, ptr[0], ptr[1], ptr[2], ptr[3], |
@@ -1261,7 +1311,8 @@ sddr09_read_map(struct us_data *us) { | |||
1261 | } | 1311 | } |
1262 | 1312 | ||
1263 | if ((ptr[6] >> 4) != 0x01) { | 1313 | if ((ptr[6] >> 4) != 0x01) { |
1264 | printk("sddr09: PBA %d has invalid address field " | 1314 | printk(KERN_WARNING |
1315 | "sddr09: PBA %d has invalid address field " | ||
1265 | "%02X%02X/%02X%02X\n", | 1316 | "%02X%02X/%02X%02X\n", |
1266 | i, ptr[6], ptr[7], ptr[11], ptr[12]); | 1317 | i, ptr[6], ptr[7], ptr[11], ptr[12]); |
1267 | info->pba_to_lba[i] = UNUSABLE; | 1318 | info->pba_to_lba[i] = UNUSABLE; |
@@ -1270,7 +1321,8 @@ sddr09_read_map(struct us_data *us) { | |||
1270 | 1321 | ||
1271 | /* check even parity */ | 1322 | /* check even parity */ |
1272 | if (parity[ptr[6] ^ ptr[7]]) { | 1323 | if (parity[ptr[6] ^ ptr[7]]) { |
1273 | printk("sddr09: Bad parity in LBA for block %d" | 1324 | printk(KERN_WARNING |
1325 | "sddr09: Bad parity in LBA for block %d" | ||
1274 | " (%02X %02X)\n", i, ptr[6], ptr[7]); | 1326 | " (%02X %02X)\n", i, ptr[6], ptr[7]); |
1275 | info->pba_to_lba[i] = UNUSABLE; | 1327 | info->pba_to_lba[i] = UNUSABLE; |
1276 | continue; | 1328 | continue; |
@@ -1289,7 +1341,8 @@ sddr09_read_map(struct us_data *us) { | |||
1289 | */ | 1341 | */ |
1290 | 1342 | ||
1291 | if (lba >= 1000) { | 1343 | if (lba >= 1000) { |
1292 | printk("sddr09: Bad low LBA %d for block %d\n", | 1344 | printk(KERN_WARNING |
1345 | "sddr09: Bad low LBA %d for block %d\n", | ||
1293 | lba, i); | 1346 | lba, i); |
1294 | goto possibly_erase; | 1347 | goto possibly_erase; |
1295 | } | 1348 | } |
@@ -1297,7 +1350,8 @@ sddr09_read_map(struct us_data *us) { | |||
1297 | lba += 1000*(i/0x400); | 1350 | lba += 1000*(i/0x400); |
1298 | 1351 | ||
1299 | if (info->lba_to_pba[lba] != UNDEF) { | 1352 | if (info->lba_to_pba[lba] != UNDEF) { |
1300 | printk("sddr09: LBA %d seen for PBA %d and %d\n", | 1353 | printk(KERN_WARNING |
1354 | "sddr09: LBA %d seen for PBA %d and %d\n", | ||
1301 | lba, info->lba_to_pba[lba], i); | 1355 | lba, info->lba_to_pba[lba], i); |
1302 | goto possibly_erase; | 1356 | goto possibly_erase; |
1303 | } | 1357 | } |
@@ -1399,7 +1453,7 @@ sddr09_common_init(struct us_data *us) { | |||
1399 | * unusual devices list but called from here then LUN 0 of the combo reader | 1453 | * unusual devices list but called from here then LUN 0 of the combo reader |
1400 | * is not recognized. But I do not know what precisely these calls do. | 1454 | * is not recognized. But I do not know what precisely these calls do. |
1401 | */ | 1455 | */ |
1402 | int | 1456 | static int |
1403 | usb_stor_sddr09_dpcm_init(struct us_data *us) { | 1457 | usb_stor_sddr09_dpcm_init(struct us_data *us) { |
1404 | int result; | 1458 | int result; |
1405 | unsigned char *data = us->iobuf; | 1459 | unsigned char *data = us->iobuf; |
@@ -1449,7 +1503,7 @@ usb_stor_sddr09_dpcm_init(struct us_data *us) { | |||
1449 | /* | 1503 | /* |
1450 | * Transport for the Microtech DPCM-USB | 1504 | * Transport for the Microtech DPCM-USB |
1451 | */ | 1505 | */ |
1452 | int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | 1506 | static int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) |
1453 | { | 1507 | { |
1454 | int ret; | 1508 | int ret; |
1455 | 1509 | ||
@@ -1491,7 +1545,7 @@ int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1491 | /* | 1545 | /* |
1492 | * Transport for the Sandisk SDDR-09 | 1546 | * Transport for the Sandisk SDDR-09 |
1493 | */ | 1547 | */ |
1494 | int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | 1548 | static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) |
1495 | { | 1549 | { |
1496 | static unsigned char sensekey = 0, sensecode = 0; | 1550 | static unsigned char sensekey = 0, sensecode = 0; |
1497 | static unsigned char havefakesense = 0; | 1551 | static unsigned char havefakesense = 0; |
@@ -1690,7 +1744,60 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1690 | /* | 1744 | /* |
1691 | * Initialization routine for the sddr09 subdriver | 1745 | * Initialization routine for the sddr09 subdriver |
1692 | */ | 1746 | */ |
1693 | int | 1747 | static int |
1694 | usb_stor_sddr09_init(struct us_data *us) { | 1748 | usb_stor_sddr09_init(struct us_data *us) { |
1695 | return sddr09_common_init(us); | 1749 | return sddr09_common_init(us); |
1696 | } | 1750 | } |
1751 | |||
1752 | static int sddr09_probe(struct usb_interface *intf, | ||
1753 | const struct usb_device_id *id) | ||
1754 | { | ||
1755 | struct us_data *us; | ||
1756 | int result; | ||
1757 | |||
1758 | result = usb_stor_probe1(&us, intf, id, | ||
1759 | (id - sddr09_usb_ids) + sddr09_unusual_dev_list); | ||
1760 | if (result) | ||
1761 | return result; | ||
1762 | |||
1763 | if (us->protocol == US_PR_DPCM_USB) { | ||
1764 | us->transport_name = "Control/Bulk-EUSB/SDDR09"; | ||
1765 | us->transport = dpcm_transport; | ||
1766 | us->transport_reset = usb_stor_CB_reset; | ||
1767 | us->max_lun = 1; | ||
1768 | } else { | ||
1769 | us->transport_name = "EUSB/SDDR09"; | ||
1770 | us->transport = sddr09_transport; | ||
1771 | us->transport_reset = usb_stor_CB_reset; | ||
1772 | us->max_lun = 0; | ||
1773 | } | ||
1774 | |||
1775 | result = usb_stor_probe2(us); | ||
1776 | return result; | ||
1777 | } | ||
1778 | |||
1779 | static struct usb_driver sddr09_driver = { | ||
1780 | .name = "ums-sddr09", | ||
1781 | .probe = sddr09_probe, | ||
1782 | .disconnect = usb_stor_disconnect, | ||
1783 | .suspend = usb_stor_suspend, | ||
1784 | .resume = usb_stor_resume, | ||
1785 | .reset_resume = usb_stor_reset_resume, | ||
1786 | .pre_reset = usb_stor_pre_reset, | ||
1787 | .post_reset = usb_stor_post_reset, | ||
1788 | .id_table = sddr09_usb_ids, | ||
1789 | .soft_unbind = 1, | ||
1790 | }; | ||
1791 | |||
1792 | static int __init sddr09_init(void) | ||
1793 | { | ||
1794 | return usb_register(&sddr09_driver); | ||
1795 | } | ||
1796 | |||
1797 | static void __exit sddr09_exit(void) | ||
1798 | { | ||
1799 | usb_deregister(&sddr09_driver); | ||
1800 | } | ||
1801 | |||
1802 | module_init(sddr09_init); | ||
1803 | module_exit(sddr09_exit); | ||
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h deleted file mode 100644 index b701172e12e3..000000000000 --- a/drivers/usb/storage/sddr09.h +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* Driver for SanDisk SDDR-09 SmartMedia reader | ||
2 | * Header File | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2000 Robert Baruch (autophile@dol.net) | ||
6 | * (c) 2002 Andries Brouwer (aeb@cwi.nl) | ||
7 | * | ||
8 | * See sddr09.c for more explanation | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2, or (at your option) any | ||
13 | * later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but | ||
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #ifndef _USB_SHUTTLE_EUSB_SDDR09_H | ||
26 | #define _USB_SHUTTLE_EUSB_SDDR09_H | ||
27 | |||
28 | /* Sandisk SDDR-09 stuff */ | ||
29 | |||
30 | extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
31 | extern int usb_stor_sddr09_init(struct us_data *us); | ||
32 | |||
33 | /* Microtech DPCM-USB stuff */ | ||
34 | |||
35 | extern int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
36 | extern int usb_stor_sddr09_dpcm_init(struct us_data *us); | ||
37 | |||
38 | #endif | ||
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 0d8df7577899..44dfed7754ed 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/jiffies.h> | 25 | #include <linux/jiffies.h> |
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/module.h> | ||
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | 29 | ||
29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
@@ -33,7 +34,48 @@ | |||
33 | #include "transport.h" | 34 | #include "transport.h" |
34 | #include "protocol.h" | 35 | #include "protocol.h" |
35 | #include "debug.h" | 36 | #include "debug.h" |
36 | #include "sddr55.h" | 37 | |
38 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader"); | ||
39 | MODULE_AUTHOR("Simon Munton"); | ||
40 | MODULE_LICENSE("GPL"); | ||
41 | |||
42 | /* | ||
43 | * The table of devices | ||
44 | */ | ||
45 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
46 | vendorName, productName, useProtocol, useTransport, \ | ||
47 | initFunction, flags) \ | ||
48 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
49 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
50 | |||
51 | struct usb_device_id sddr55_usb_ids[] = { | ||
52 | # include "unusual_sddr55.h" | ||
53 | { } /* Terminating entry */ | ||
54 | }; | ||
55 | MODULE_DEVICE_TABLE(usb, sddr55_usb_ids); | ||
56 | |||
57 | #undef UNUSUAL_DEV | ||
58 | |||
59 | /* | ||
60 | * The flags table | ||
61 | */ | ||
62 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
63 | vendor_name, product_name, use_protocol, use_transport, \ | ||
64 | init_function, Flags) \ | ||
65 | { \ | ||
66 | .vendorName = vendor_name, \ | ||
67 | .productName = product_name, \ | ||
68 | .useProtocol = use_protocol, \ | ||
69 | .useTransport = use_transport, \ | ||
70 | .initFunction = init_function, \ | ||
71 | } | ||
72 | |||
73 | static struct us_unusual_dev sddr55_unusual_dev_list[] = { | ||
74 | # include "unusual_sddr55.h" | ||
75 | { } /* Terminating entry */ | ||
76 | }; | ||
77 | |||
78 | #undef UNUSUAL_DEV | ||
37 | 79 | ||
38 | 80 | ||
39 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | 81 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) |
@@ -513,7 +555,8 @@ static int sddr55_read_deviceID(struct us_data *us, | |||
513 | } | 555 | } |
514 | 556 | ||
515 | 557 | ||
516 | int sddr55_reset(struct us_data *us) { | 558 | static int sddr55_reset(struct us_data *us) |
559 | { | ||
517 | return 0; | 560 | return 0; |
518 | } | 561 | } |
519 | 562 | ||
@@ -703,7 +746,9 @@ static int sddr55_read_map(struct us_data *us) { | |||
703 | 746 | ||
704 | if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED && | 747 | if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED && |
705 | !info->force_read_only) { | 748 | !info->force_read_only) { |
706 | printk("sddr55: map inconsistency at LBA %04X\n", lba + zone * 1000); | 749 | printk(KERN_WARNING |
750 | "sddr55: map inconsistency at LBA %04X\n", | ||
751 | lba + zone * 1000); | ||
707 | info->force_read_only = 1; | 752 | info->force_read_only = 1; |
708 | } | 753 | } |
709 | 754 | ||
@@ -732,7 +777,7 @@ static void sddr55_card_info_destructor(void *extra) { | |||
732 | /* | 777 | /* |
733 | * Transport for the Sandisk SDDR-55 | 778 | * Transport for the Sandisk SDDR-55 |
734 | */ | 779 | */ |
735 | int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) | 780 | static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) |
736 | { | 781 | { |
737 | int result; | 782 | int result; |
738 | static unsigned char inquiry_response[8] = { | 783 | static unsigned char inquiry_response[8] = { |
@@ -929,3 +974,49 @@ int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
929 | return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer? | 974 | return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer? |
930 | } | 975 | } |
931 | 976 | ||
977 | |||
978 | static int sddr55_probe(struct usb_interface *intf, | ||
979 | const struct usb_device_id *id) | ||
980 | { | ||
981 | struct us_data *us; | ||
982 | int result; | ||
983 | |||
984 | result = usb_stor_probe1(&us, intf, id, | ||
985 | (id - sddr55_usb_ids) + sddr55_unusual_dev_list); | ||
986 | if (result) | ||
987 | return result; | ||
988 | |||
989 | us->transport_name = "SDDR55"; | ||
990 | us->transport = sddr55_transport; | ||
991 | us->transport_reset = sddr55_reset; | ||
992 | us->max_lun = 0; | ||
993 | |||
994 | result = usb_stor_probe2(us); | ||
995 | return result; | ||
996 | } | ||
997 | |||
998 | static struct usb_driver sddr55_driver = { | ||
999 | .name = "ums-sddr55", | ||
1000 | .probe = sddr55_probe, | ||
1001 | .disconnect = usb_stor_disconnect, | ||
1002 | .suspend = usb_stor_suspend, | ||
1003 | .resume = usb_stor_resume, | ||
1004 | .reset_resume = usb_stor_reset_resume, | ||
1005 | .pre_reset = usb_stor_pre_reset, | ||
1006 | .post_reset = usb_stor_post_reset, | ||
1007 | .id_table = sddr55_usb_ids, | ||
1008 | .soft_unbind = 1, | ||
1009 | }; | ||
1010 | |||
1011 | static int __init sddr55_init(void) | ||
1012 | { | ||
1013 | return usb_register(&sddr55_driver); | ||
1014 | } | ||
1015 | |||
1016 | static void __exit sddr55_exit(void) | ||
1017 | { | ||
1018 | usb_deregister(&sddr55_driver); | ||
1019 | } | ||
1020 | |||
1021 | module_init(sddr55_init); | ||
1022 | module_exit(sddr55_exit); | ||
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index ae6d64810d2a..b62a28814ebe 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -42,6 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
45 | #include <linux/module.h> | ||
45 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
46 | #include <linux/cdrom.h> | 47 | #include <linux/cdrom.h> |
47 | 48 | ||
@@ -52,7 +53,100 @@ | |||
52 | #include "transport.h" | 53 | #include "transport.h" |
53 | #include "protocol.h" | 54 | #include "protocol.h" |
54 | #include "debug.h" | 55 | #include "debug.h" |
55 | #include "shuttle_usbat.h" | 56 | |
57 | MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); | ||
58 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>"); | ||
59 | MODULE_LICENSE("GPL"); | ||
60 | |||
61 | /* Supported device types */ | ||
62 | #define USBAT_DEV_HP8200 0x01 | ||
63 | #define USBAT_DEV_FLASH 0x02 | ||
64 | |||
65 | #define USBAT_EPP_PORT 0x10 | ||
66 | #define USBAT_EPP_REGISTER 0x30 | ||
67 | #define USBAT_ATA 0x40 | ||
68 | #define USBAT_ISA 0x50 | ||
69 | |||
70 | /* Commands (need to be logically OR'd with an access type */ | ||
71 | #define USBAT_CMD_READ_REG 0x00 | ||
72 | #define USBAT_CMD_WRITE_REG 0x01 | ||
73 | #define USBAT_CMD_READ_BLOCK 0x02 | ||
74 | #define USBAT_CMD_WRITE_BLOCK 0x03 | ||
75 | #define USBAT_CMD_COND_READ_BLOCK 0x04 | ||
76 | #define USBAT_CMD_COND_WRITE_BLOCK 0x05 | ||
77 | #define USBAT_CMD_WRITE_REGS 0x07 | ||
78 | |||
79 | /* Commands (these don't need an access type) */ | ||
80 | #define USBAT_CMD_EXEC_CMD 0x80 | ||
81 | #define USBAT_CMD_SET_FEAT 0x81 | ||
82 | #define USBAT_CMD_UIO 0x82 | ||
83 | |||
84 | /* Methods of accessing UIO register */ | ||
85 | #define USBAT_UIO_READ 1 | ||
86 | #define USBAT_UIO_WRITE 0 | ||
87 | |||
88 | /* Qualifier bits */ | ||
89 | #define USBAT_QUAL_FCQ 0x20 /* full compare */ | ||
90 | #define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ | ||
91 | |||
92 | /* USBAT Flash Media status types */ | ||
93 | #define USBAT_FLASH_MEDIA_NONE 0 | ||
94 | #define USBAT_FLASH_MEDIA_CF 1 | ||
95 | |||
96 | /* USBAT Flash Media change types */ | ||
97 | #define USBAT_FLASH_MEDIA_SAME 0 | ||
98 | #define USBAT_FLASH_MEDIA_CHANGED 1 | ||
99 | |||
100 | /* USBAT ATA registers */ | ||
101 | #define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ | ||
102 | #define USBAT_ATA_FEATURES 0x11 /* set features (W) */ | ||
103 | #define USBAT_ATA_ERROR 0x11 /* error (R) */ | ||
104 | #define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ | ||
105 | #define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ | ||
106 | #define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ | ||
107 | #define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ | ||
108 | #define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ | ||
109 | #define USBAT_ATA_STATUS 0x17 /* device status (R) */ | ||
110 | #define USBAT_ATA_CMD 0x17 /* device command (W) */ | ||
111 | #define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ | ||
112 | |||
113 | /* USBAT User I/O Data registers */ | ||
114 | #define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ | ||
115 | #define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ | ||
116 | /* CDT = ACKD & !UI1 & !UI0 */ | ||
117 | #define USBAT_UIO_1 0x20 /* I/O 1 */ | ||
118 | #define USBAT_UIO_0 0x10 /* I/O 0 */ | ||
119 | #define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ | ||
120 | #define USBAT_UIO_UI1 0x04 /* Input 1 */ | ||
121 | #define USBAT_UIO_UI0 0x02 /* Input 0 */ | ||
122 | #define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ | ||
123 | |||
124 | /* USBAT User I/O Enable registers */ | ||
125 | #define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ | ||
126 | #define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ | ||
127 | #define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ | ||
128 | /* If ACKD=1, set OE1 to 1 also. */ | ||
129 | #define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ | ||
130 | #define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ | ||
131 | |||
132 | /* USBAT Features */ | ||
133 | #define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ | ||
134 | #define USBAT_FEAT_U1 0x08 | ||
135 | #define USBAT_FEAT_U0 0x04 | ||
136 | #define USBAT_FEAT_ET1 0x02 | ||
137 | #define USBAT_FEAT_ET2 0x01 | ||
138 | |||
139 | struct usbat_info { | ||
140 | int devicetype; | ||
141 | |||
142 | /* Used for Flash readers only */ | ||
143 | unsigned long sectors; /* total sector count */ | ||
144 | unsigned long ssize; /* sector size in bytes */ | ||
145 | |||
146 | unsigned char sense_key; | ||
147 | unsigned long sense_asc; /* additional sense code */ | ||
148 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
149 | }; | ||
56 | 150 | ||
57 | #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) ) | 151 | #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) ) |
58 | #define LSB_of(s) ((s)&0xFF) | 152 | #define LSB_of(s) ((s)&0xFF) |
@@ -63,6 +157,48 @@ static int transferred = 0; | |||
63 | static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); | 157 | static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); |
64 | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); | 158 | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); |
65 | 159 | ||
160 | static int init_usbat_cd(struct us_data *us); | ||
161 | static int init_usbat_flash(struct us_data *us); | ||
162 | |||
163 | |||
164 | /* | ||
165 | * The table of devices | ||
166 | */ | ||
167 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
168 | vendorName, productName, useProtocol, useTransport, \ | ||
169 | initFunction, flags) \ | ||
170 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
171 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
172 | |||
173 | struct usb_device_id usbat_usb_ids[] = { | ||
174 | # include "unusual_usbat.h" | ||
175 | { } /* Terminating entry */ | ||
176 | }; | ||
177 | MODULE_DEVICE_TABLE(usb, usbat_usb_ids); | ||
178 | |||
179 | #undef UNUSUAL_DEV | ||
180 | |||
181 | /* | ||
182 | * The flags table | ||
183 | */ | ||
184 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
185 | vendor_name, product_name, use_protocol, use_transport, \ | ||
186 | init_function, Flags) \ | ||
187 | { \ | ||
188 | .vendorName = vendor_name, \ | ||
189 | .productName = product_name, \ | ||
190 | .useProtocol = use_protocol, \ | ||
191 | .useTransport = use_transport, \ | ||
192 | .initFunction = init_function, \ | ||
193 | } | ||
194 | |||
195 | static struct us_unusual_dev usbat_unusual_dev_list[] = { | ||
196 | # include "unusual_usbat.h" | ||
197 | { } /* Terminating entry */ | ||
198 | }; | ||
199 | |||
200 | #undef UNUSUAL_DEV | ||
201 | |||
66 | /* | 202 | /* |
67 | * Convenience function to produce an ATA read/write sectors command | 203 | * Convenience function to produce an ATA read/write sectors command |
68 | * Use cmd=0x20 for read, cmd=0x30 for write | 204 | * Use cmd=0x20 for read, cmd=0x30 for write |
@@ -1684,37 +1820,61 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
1684 | return USB_STOR_TRANSPORT_FAILED; | 1820 | return USB_STOR_TRANSPORT_FAILED; |
1685 | } | 1821 | } |
1686 | 1822 | ||
1687 | int init_usbat_cd(struct us_data *us) | 1823 | static int init_usbat_cd(struct us_data *us) |
1688 | { | 1824 | { |
1689 | return init_usbat(us, USBAT_DEV_HP8200); | 1825 | return init_usbat(us, USBAT_DEV_HP8200); |
1690 | } | 1826 | } |
1691 | 1827 | ||
1692 | 1828 | static int init_usbat_flash(struct us_data *us) | |
1693 | int init_usbat_flash(struct us_data *us) | ||
1694 | { | 1829 | { |
1695 | return init_usbat(us, USBAT_DEV_FLASH); | 1830 | return init_usbat(us, USBAT_DEV_FLASH); |
1696 | } | 1831 | } |
1697 | 1832 | ||
1698 | int init_usbat_probe(struct us_data *us) | 1833 | static int usbat_probe(struct usb_interface *intf, |
1834 | const struct usb_device_id *id) | ||
1699 | { | 1835 | { |
1700 | return init_usbat(us, 0); | 1836 | struct us_data *us; |
1837 | int result; | ||
1838 | |||
1839 | result = usb_stor_probe1(&us, intf, id, | ||
1840 | (id - usbat_usb_ids) + usbat_unusual_dev_list); | ||
1841 | if (result) | ||
1842 | return result; | ||
1843 | |||
1844 | /* The actual transport will be determined later by the | ||
1845 | * initialization routine; this is just a placeholder. | ||
1846 | */ | ||
1847 | us->transport_name = "Shuttle USBAT"; | ||
1848 | us->transport = usbat_flash_transport; | ||
1849 | us->transport_reset = usb_stor_CB_reset; | ||
1850 | us->max_lun = 1; | ||
1851 | |||
1852 | result = usb_stor_probe2(us); | ||
1853 | return result; | ||
1701 | } | 1854 | } |
1702 | 1855 | ||
1703 | /* | 1856 | static struct usb_driver usbat_driver = { |
1704 | * Default transport function. Attempts to detect which transport function | 1857 | .name = "ums-usbat", |
1705 | * should be called, makes it the new default, and calls it. | 1858 | .probe = usbat_probe, |
1706 | * | 1859 | .disconnect = usb_stor_disconnect, |
1707 | * This function should never be called. Our usbat_init() function detects the | 1860 | .suspend = usb_stor_suspend, |
1708 | * device type and changes the us->transport ptr to the transport function | 1861 | .resume = usb_stor_resume, |
1709 | * relevant to the device. | 1862 | .reset_resume = usb_stor_reset_resume, |
1710 | * However, we'll support this impossible(?) case anyway. | 1863 | .pre_reset = usb_stor_pre_reset, |
1711 | */ | 1864 | .post_reset = usb_stor_post_reset, |
1712 | int usbat_transport(struct scsi_cmnd *srb, struct us_data *us) | 1865 | .id_table = usbat_usb_ids, |
1866 | .soft_unbind = 1, | ||
1867 | }; | ||
1868 | |||
1869 | static int __init usbat_init(void) | ||
1713 | { | 1870 | { |
1714 | struct usbat_info *info = (struct usbat_info*) (us->extra); | 1871 | return usb_register(&usbat_driver); |
1715 | 1872 | } | |
1716 | if (usbat_set_transport(us, info, 0)) | ||
1717 | return USB_STOR_TRANSPORT_ERROR; | ||
1718 | 1873 | ||
1719 | return us->transport(srb, us); | 1874 | static void __exit usbat_exit(void) |
1875 | { | ||
1876 | usb_deregister(&usbat_driver); | ||
1720 | } | 1877 | } |
1878 | |||
1879 | module_init(usbat_init); | ||
1880 | module_exit(usbat_exit); | ||
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h deleted file mode 100644 index d8bfc43e9044..000000000000 --- a/drivers/usb/storage/shuttle_usbat.h +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* Driver for SCM Microsystems USB-ATAPI cable | ||
2 | * Header File | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2000 Robert Baruch (autophile@dol.net) | ||
6 | * (c) 2004, 2005 Daniel Drake <dsd@gentoo.org> | ||
7 | * | ||
8 | * See shuttle_usbat.c for more explanation | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2, or (at your option) any | ||
13 | * later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but | ||
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #ifndef _USB_SHUTTLE_USBAT_H | ||
26 | #define _USB_SHUTTLE_USBAT_H | ||
27 | |||
28 | /* Supported device types */ | ||
29 | #define USBAT_DEV_HP8200 0x01 | ||
30 | #define USBAT_DEV_FLASH 0x02 | ||
31 | |||
32 | #define USBAT_EPP_PORT 0x10 | ||
33 | #define USBAT_EPP_REGISTER 0x30 | ||
34 | #define USBAT_ATA 0x40 | ||
35 | #define USBAT_ISA 0x50 | ||
36 | |||
37 | /* Commands (need to be logically OR'd with an access type */ | ||
38 | #define USBAT_CMD_READ_REG 0x00 | ||
39 | #define USBAT_CMD_WRITE_REG 0x01 | ||
40 | #define USBAT_CMD_READ_BLOCK 0x02 | ||
41 | #define USBAT_CMD_WRITE_BLOCK 0x03 | ||
42 | #define USBAT_CMD_COND_READ_BLOCK 0x04 | ||
43 | #define USBAT_CMD_COND_WRITE_BLOCK 0x05 | ||
44 | #define USBAT_CMD_WRITE_REGS 0x07 | ||
45 | |||
46 | /* Commands (these don't need an access type) */ | ||
47 | #define USBAT_CMD_EXEC_CMD 0x80 | ||
48 | #define USBAT_CMD_SET_FEAT 0x81 | ||
49 | #define USBAT_CMD_UIO 0x82 | ||
50 | |||
51 | /* Methods of accessing UIO register */ | ||
52 | #define USBAT_UIO_READ 1 | ||
53 | #define USBAT_UIO_WRITE 0 | ||
54 | |||
55 | /* Qualifier bits */ | ||
56 | #define USBAT_QUAL_FCQ 0x20 /* full compare */ | ||
57 | #define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ | ||
58 | |||
59 | /* USBAT Flash Media status types */ | ||
60 | #define USBAT_FLASH_MEDIA_NONE 0 | ||
61 | #define USBAT_FLASH_MEDIA_CF 1 | ||
62 | |||
63 | /* USBAT Flash Media change types */ | ||
64 | #define USBAT_FLASH_MEDIA_SAME 0 | ||
65 | #define USBAT_FLASH_MEDIA_CHANGED 1 | ||
66 | |||
67 | /* USBAT ATA registers */ | ||
68 | #define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ | ||
69 | #define USBAT_ATA_FEATURES 0x11 /* set features (W) */ | ||
70 | #define USBAT_ATA_ERROR 0x11 /* error (R) */ | ||
71 | #define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ | ||
72 | #define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ | ||
73 | #define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ | ||
74 | #define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ | ||
75 | #define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ | ||
76 | #define USBAT_ATA_STATUS 0x17 /* device status (R) */ | ||
77 | #define USBAT_ATA_CMD 0x17 /* device command (W) */ | ||
78 | #define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ | ||
79 | |||
80 | /* USBAT User I/O Data registers */ | ||
81 | #define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ | ||
82 | #define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ | ||
83 | /* CDT = ACKD & !UI1 & !UI0 */ | ||
84 | #define USBAT_UIO_1 0x20 /* I/O 1 */ | ||
85 | #define USBAT_UIO_0 0x10 /* I/O 0 */ | ||
86 | #define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ | ||
87 | #define USBAT_UIO_UI1 0x04 /* Input 1 */ | ||
88 | #define USBAT_UIO_UI0 0x02 /* Input 0 */ | ||
89 | #define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ | ||
90 | |||
91 | /* USBAT User I/O Enable registers */ | ||
92 | #define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ | ||
93 | #define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ | ||
94 | #define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ | ||
95 | /* If ACKD=1, set OE1 to 1 also. */ | ||
96 | #define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ | ||
97 | #define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ | ||
98 | |||
99 | /* USBAT Features */ | ||
100 | #define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ | ||
101 | #define USBAT_FEAT_U1 0x08 | ||
102 | #define USBAT_FEAT_U0 0x04 | ||
103 | #define USBAT_FEAT_ET1 0x02 | ||
104 | #define USBAT_FEAT_ET2 0x01 | ||
105 | |||
106 | extern int usbat_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
107 | extern int init_usbat_cd(struct us_data *us); | ||
108 | extern int init_usbat_flash(struct us_data *us); | ||
109 | extern int init_usbat_probe(struct us_data *us); | ||
110 | |||
111 | struct usbat_info { | ||
112 | int devicetype; | ||
113 | |||
114 | /* Used for Flash readers only */ | ||
115 | unsigned long sectors; /* total sector count */ | ||
116 | unsigned long ssize; /* sector size in bytes */ | ||
117 | |||
118 | unsigned char sense_key; | ||
119 | unsigned long sense_asc; /* additional sense code */ | ||
120 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
121 | }; | ||
122 | |||
123 | #endif | ||
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index fb65d221cedf..d48c8553539d 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -220,6 +220,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, | |||
220 | status = us->current_urb->actual_length; | 220 | status = us->current_urb->actual_length; |
221 | return status; | 221 | return status; |
222 | } | 222 | } |
223 | EXPORT_SYMBOL_GPL(usb_stor_control_msg); | ||
223 | 224 | ||
224 | /* This is a version of usb_clear_halt() that allows early termination and | 225 | /* This is a version of usb_clear_halt() that allows early termination and |
225 | * doesn't read the status from the device -- this is because some devices | 226 | * doesn't read the status from the device -- this is because some devices |
@@ -254,6 +255,7 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) | |||
254 | US_DEBUGP("%s: result = %d\n", __func__, result); | 255 | US_DEBUGP("%s: result = %d\n", __func__, result); |
255 | return result; | 256 | return result; |
256 | } | 257 | } |
258 | EXPORT_SYMBOL_GPL(usb_stor_clear_halt); | ||
257 | 259 | ||
258 | 260 | ||
259 | /* | 261 | /* |
@@ -352,6 +354,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, | |||
352 | return interpret_urb_result(us, pipe, size, result, | 354 | return interpret_urb_result(us, pipe, size, result, |
353 | us->current_urb->actual_length); | 355 | us->current_urb->actual_length); |
354 | } | 356 | } |
357 | EXPORT_SYMBOL_GPL(usb_stor_ctrl_transfer); | ||
355 | 358 | ||
356 | /* | 359 | /* |
357 | * Receive one interrupt buffer, without timeouts, but allowing early | 360 | * Receive one interrupt buffer, without timeouts, but allowing early |
@@ -407,6 +410,7 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, | |||
407 | return interpret_urb_result(us, pipe, length, result, | 410 | return interpret_urb_result(us, pipe, length, result, |
408 | us->current_urb->actual_length); | 411 | us->current_urb->actual_length); |
409 | } | 412 | } |
413 | EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_buf); | ||
410 | 414 | ||
411 | /* | 415 | /* |
412 | * Transfer a scatter-gather list via bulk transfer | 416 | * Transfer a scatter-gather list via bulk transfer |
@@ -474,6 +478,7 @@ int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe, | |||
474 | scsi_set_resid(srb, scsi_bufflen(srb) - partial); | 478 | scsi_set_resid(srb, scsi_bufflen(srb) - partial); |
475 | return result; | 479 | return result; |
476 | } | 480 | } |
481 | EXPORT_SYMBOL_GPL(usb_stor_bulk_srb); | ||
477 | 482 | ||
478 | /* | 483 | /* |
479 | * Transfer an entire SCSI command's worth of data payload over the bulk | 484 | * Transfer an entire SCSI command's worth of data payload over the bulk |
@@ -509,6 +514,7 @@ int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe, | |||
509 | *residual = length_left; | 514 | *residual = length_left; |
510 | return result; | 515 | return result; |
511 | } | 516 | } |
517 | EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_sg); | ||
512 | 518 | ||
513 | /*********************************************************************** | 519 | /*********************************************************************** |
514 | * Transport routines | 520 | * Transport routines |
@@ -940,6 +946,7 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
940 | usb_stor_clear_halt(us, pipe); | 946 | usb_stor_clear_halt(us, pipe); |
941 | return USB_STOR_TRANSPORT_FAILED; | 947 | return USB_STOR_TRANSPORT_FAILED; |
942 | } | 948 | } |
949 | EXPORT_SYMBOL_GPL(usb_stor_CB_transport); | ||
943 | 950 | ||
944 | /* | 951 | /* |
945 | * Bulk only transport | 952 | * Bulk only transport |
@@ -1156,6 +1163,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1156 | /* we should never get here, but if we do, we're in trouble */ | 1163 | /* we should never get here, but if we do, we're in trouble */ |
1157 | return USB_STOR_TRANSPORT_ERROR; | 1164 | return USB_STOR_TRANSPORT_ERROR; |
1158 | } | 1165 | } |
1166 | EXPORT_SYMBOL_GPL(usb_stor_Bulk_transport); | ||
1159 | 1167 | ||
1160 | /*********************************************************************** | 1168 | /*********************************************************************** |
1161 | * Reset routines | 1169 | * Reset routines |
@@ -1230,6 +1238,7 @@ int usb_stor_CB_reset(struct us_data *us) | |||
1230 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 1238 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
1231 | 0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE); | 1239 | 0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE); |
1232 | } | 1240 | } |
1241 | EXPORT_SYMBOL_GPL(usb_stor_CB_reset); | ||
1233 | 1242 | ||
1234 | /* This issues a Bulk-only Reset to the device in question, including | 1243 | /* This issues a Bulk-only Reset to the device in question, including |
1235 | * clearing the subsequent endpoint halts that may occur. | 1244 | * clearing the subsequent endpoint halts that may occur. |
@@ -1242,6 +1251,7 @@ int usb_stor_Bulk_reset(struct us_data *us) | |||
1242 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 1251 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
1243 | 0, us->ifnum, NULL, 0); | 1252 | 0, us->ifnum, NULL, 0); |
1244 | } | 1253 | } |
1254 | EXPORT_SYMBOL_GPL(usb_stor_Bulk_reset); | ||
1245 | 1255 | ||
1246 | /* Issue a USB port reset to the device. The caller must not hold | 1256 | /* Issue a USB port reset to the device. The caller must not hold |
1247 | * us->dev_mutex. | 1257 | * us->dev_mutex. |
diff --git a/drivers/usb/storage/freecom.h b/drivers/usb/storage/unusual_alauda.h index 20d0fe6ba0c8..8c412f885dd2 100644 --- a/drivers/usb/storage/freecom.h +++ b/drivers/usb/storage/unusual_alauda.h | |||
@@ -1,13 +1,4 @@ | |||
1 | /* Driver for Freecom USB/IDE adaptor | 1 | /* Unusual Devices File for the Alauda-based card readers |
2 | * | ||
3 | * Freecom v0.1: | ||
4 | * | ||
5 | * First release | ||
6 | * | ||
7 | * Current development and maintenance by: | ||
8 | * (c) 2000 David Brown <usb-storage@davidb.org> | ||
9 | * | ||
10 | * See freecom.c for more explanation | ||
11 | * | 2 | * |
12 | * This program is free software; you can redistribute it and/or modify it | 3 | * This program is free software; you can redistribute it and/or modify it |
13 | * under the terms of the GNU General Public License as published by the | 4 | * under the terms of the GNU General Public License as published by the |
@@ -24,11 +15,17 @@ | |||
24 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
25 | */ | 16 | */ |
26 | 17 | ||
27 | #ifndef _FREECOM_USB_H | 18 | #if defined(CONFIG_USB_STORAGE_ALAUDA) || \ |
28 | #define _FREECOM_USB_H | 19 | defined(CONFIG_USB_STORAGE_ALAUDA_MODULE) |
20 | |||
21 | UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102, | ||
22 | "Fujifilm", | ||
23 | "DPC-R1 (Alauda)", | ||
24 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0), | ||
29 | 25 | ||
30 | extern int freecom_transport(struct scsi_cmnd *srb, struct us_data *us); | 26 | UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102, |
31 | extern int usb_stor_freecom_reset(struct us_data *us); | 27 | "Olympus", |
32 | extern int freecom_init (struct us_data *us); | 28 | "MAUSB-10 (Alauda)", |
29 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0), | ||
33 | 30 | ||
34 | #endif | 31 | #endif /* defined(CONFIG_USB_STORAGE_ALAUDA) || ... */ |
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h new file mode 100644 index 000000000000..44be6d75dab6 --- /dev/null +++ b/drivers/usb/storage/unusual_cypress.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* Unusual Devices File for devices based on the Cypress USB/ATA bridge | ||
2 | * with support for ATACB | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2, or (at your option) any | ||
7 | * later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | #if defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || \ | ||
20 | defined(CONFIG_USB_STORAGE_CYPRESS_ATACB_MODULE) | ||
21 | |||
22 | /* CY7C68300 : support atacb */ | ||
23 | UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, | ||
24 | "Cypress", | ||
25 | "Cypress AT2LP", | ||
26 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0), | ||
27 | |||
28 | /* CY7C68310 : support atacb and atacb2 */ | ||
29 | UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, | ||
30 | "Cypress", | ||
31 | "Cypress ISD-300LP", | ||
32 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0), | ||
33 | |||
34 | #endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_datafab.h b/drivers/usb/storage/unusual_datafab.h new file mode 100644 index 000000000000..c9298ce9f223 --- /dev/null +++ b/drivers/usb/storage/unusual_datafab.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /* Unusual Devices File for the Datafab USB Compact Flash reader | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify it | ||
4 | * under the terms of the GNU General Public License as published by the | ||
5 | * Free Software Foundation; either version 2, or (at your option) any | ||
6 | * later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
16 | */ | ||
17 | |||
18 | #if defined(CONFIG_USB_STORAGE_DATAFAB) || \ | ||
19 | defined(CONFIG_USB_STORAGE_DATAFAB_MODULE) | ||
20 | |||
21 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, | ||
22 | "Datafab", | ||
23 | "MDCFE-B USB CF Reader", | ||
24 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
25 | 0), | ||
26 | |||
27 | /* | ||
28 | * The following Datafab-based devices may or may not work | ||
29 | * using the current driver...the 0xffff is arbitrary since I | ||
30 | * don't know what device versions exist for these guys. | ||
31 | * | ||
32 | * The 0xa003 and 0xa004 devices in particular I'm curious about. | ||
33 | * I'm told they exist but so far nobody has come forward to say that | ||
34 | * they work with this driver. Given the success we've had getting | ||
35 | * other Datafab-based cards operational with this driver, I've decided | ||
36 | * to leave these two devices in the list. | ||
37 | */ | ||
38 | UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff, | ||
39 | "SIIG/Datafab", | ||
40 | "SIIG/Datafab Memory Stick+CF Reader/Writer", | ||
41 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
42 | 0), | ||
43 | |||
44 | /* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */ | ||
45 | UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff, | ||
46 | "Datafab/Unknown", | ||
47 | "MD2/MD3 Disk enclosure", | ||
48 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
49 | US_FL_SINGLE_LUN), | ||
50 | |||
51 | UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff, | ||
52 | "Datafab/Unknown", | ||
53 | "Datafab-based Reader", | ||
54 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
55 | 0), | ||
56 | |||
57 | UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff, | ||
58 | "Datafab/Unknown", | ||
59 | "Datafab-based Reader", | ||
60 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
61 | 0), | ||
62 | |||
63 | UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff, | ||
64 | "PNY/Datafab", | ||
65 | "PNY/Datafab CF+SM Reader", | ||
66 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
67 | 0), | ||
68 | |||
69 | UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff, | ||
70 | "Simple Tech/Datafab", | ||
71 | "Simple Tech/Datafab CF+SM Reader", | ||
72 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
73 | 0), | ||
74 | |||
75 | /* Submitted by Olaf Hering <olh@suse.de> */ | ||
76 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
77 | "Datafab Systems, Inc.", | ||
78 | "USB to CF + SM Combo (LC1)", | ||
79 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
80 | 0), | ||
81 | |||
82 | /* Reported by Felix Moeller <felix@derklecks.de> | ||
83 | * in Germany this is sold by Hama with the productnumber 46952 | ||
84 | * as "DualSlot CompactFlash(TM) & MStick Drive USB" | ||
85 | */ | ||
86 | UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff, | ||
87 | "DataFab Systems Inc.", | ||
88 | "USB CF+MS", | ||
89 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
90 | 0), | ||
91 | |||
92 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
93 | "Acomdata", | ||
94 | "CF", | ||
95 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
96 | US_FL_SINGLE_LUN), | ||
97 | |||
98 | #endif /* defined(CONFIG_USB_STORAGE_DATAFAB) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index cfde74a6faa3..1c1f643e8a78 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -53,6 +53,11 @@ | |||
53 | * as opposed to devices that do something strangely or wrongly. | 53 | * as opposed to devices that do something strangely or wrongly. |
54 | */ | 54 | */ |
55 | 55 | ||
56 | #if !defined(CONFIG_USB_STORAGE_SDDR09) && \ | ||
57 | !defined(CONFIG_USB_STORAGE_SDDR09_MODULE) | ||
58 | #define NO_SDDR09 | ||
59 | #endif | ||
60 | |||
56 | /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr> | 61 | /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr> |
57 | */ | 62 | */ |
58 | UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100, | 63 | UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100, |
@@ -80,18 +85,6 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, | |||
80 | "CD-Writer+", | 85 | "CD-Writer+", |
81 | US_SC_8070, US_PR_CB, NULL, 0), | 86 | US_SC_8070, US_PR_CB, NULL, 0), |
82 | 87 | ||
83 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
84 | UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, | ||
85 | "HP", | ||
86 | "CD-Writer+ 8200e", | ||
87 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | ||
88 | |||
89 | UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | ||
90 | "HP", | ||
91 | "CD-Writer+ CD-4e", | ||
92 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | ||
93 | #endif | ||
94 | |||
95 | /* Reported by Ben Efros <ben@pc-doctor.com> */ | 88 | /* Reported by Ben Efros <ben@pc-doctor.com> */ |
96 | UNUSUAL_DEV( 0x03f0, 0x070c, 0x0000, 0x0000, | 89 | UNUSUAL_DEV( 0x03f0, 0x070c, 0x0000, 0x0000, |
97 | "HP", | 90 | "HP", |
@@ -246,12 +239,7 @@ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, | |||
246 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 239 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
247 | US_FL_SINGLE_LUN ), | 240 | US_FL_SINGLE_LUN ), |
248 | 241 | ||
249 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 242 | #ifdef NO_SDDR09 |
250 | UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, | ||
251 | "Microtech", | ||
252 | "CameraMate (DPCM_USB)", | ||
253 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | ||
254 | #else | ||
255 | UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, | 243 | UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, |
256 | "Microtech", | 244 | "Microtech", |
257 | "CameraMate", | 245 | "CameraMate", |
@@ -288,13 +276,6 @@ UNUSUAL_DEV( 0x0457, 0x0151, 0x0100, 0x0100, | |||
288 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 276 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
289 | US_FL_NOT_LOCKABLE ), | 277 | US_FL_NOT_LOCKABLE ), |
290 | 278 | ||
291 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
292 | UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, | ||
293 | "Rio", | ||
294 | "Rio Karma", | ||
295 | US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), | ||
296 | #endif | ||
297 | |||
298 | /* Reported by Tamas Kerecsen <kerecsen@bigfoot.com> | 279 | /* Reported by Tamas Kerecsen <kerecsen@bigfoot.com> |
299 | * Obviously the PROM has not been customized by the VAR; | 280 | * Obviously the PROM has not been customized by the VAR; |
300 | * the Vendor and Product string descriptors are: | 281 | * the Vendor and Product string descriptors are: |
@@ -375,22 +356,6 @@ UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110, | |||
375 | US_SC_DEVICE, US_PR_CB, NULL, | 356 | US_SC_DEVICE, US_PR_CB, NULL, |
376 | US_FL_MAX_SECTORS_MIN), | 357 | US_FL_MAX_SECTORS_MIN), |
377 | 358 | ||
378 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
379 | /* CY7C68300 : support atacb */ | ||
380 | UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, | ||
381 | "Cypress", | ||
382 | "Cypress AT2LP", | ||
383 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, | ||
384 | 0), | ||
385 | |||
386 | /* CY7C68310 : support atacb and atacb2 */ | ||
387 | UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, | ||
388 | "Cypress", | ||
389 | "Cypress ISD-300LP", | ||
390 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, | ||
391 | 0), | ||
392 | #endif | ||
393 | |||
394 | /* Reported by Simon Levitt <simon@whattf.com> | 359 | /* Reported by Simon Levitt <simon@whattf.com> |
395 | * This entry needs Sub and Proto fields */ | 360 | * This entry needs Sub and Proto fields */ |
396 | UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100, | 361 | UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100, |
@@ -467,20 +432,7 @@ UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100, | |||
467 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, | 432 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, |
468 | US_FL_SCM_MULT_TARG ), | 433 | US_FL_SCM_MULT_TARG ), |
469 | 434 | ||
470 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 435 | #ifdef NO_SDDR09 |
471 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, | ||
472 | "Sandisk", | ||
473 | "ImageMate SDDR09", | ||
474 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
475 | 0), | ||
476 | |||
477 | /* This entry is from Andries.Brouwer@cwi.nl */ | ||
478 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | ||
479 | "SCM Microsystems", | ||
480 | "eUSB SmartMedia / CompactFlash Adapter", | ||
481 | US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init, | ||
482 | 0), | ||
483 | #else | ||
484 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | 436 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, |
485 | "SCM Microsystems", | 437 | "SCM Microsystems", |
486 | "eUSB CompactFlash Adapter", | 438 | "eUSB CompactFlash Adapter", |
@@ -535,14 +487,6 @@ UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, | |||
535 | "CD-RW Device", | 487 | "CD-RW Device", |
536 | US_SC_8020, US_PR_CB, NULL, 0), | 488 | US_SC_8020, US_PR_CB, NULL, 0), |
537 | 489 | ||
538 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
539 | UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, | ||
540 | "Shuttle/SCM", | ||
541 | "USBAT-02", | ||
542 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
543 | US_FL_SINGLE_LUN), | ||
544 | #endif | ||
545 | |||
546 | /* Reported by Dmitry Khlystov <adminimus@gmail.com> */ | 490 | /* Reported by Dmitry Khlystov <adminimus@gmail.com> */ |
547 | UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, | 491 | UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, |
548 | "Samsung", | 492 | "Samsung", |
@@ -645,14 +589,6 @@ UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100, | |||
645 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 589 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
646 | US_FL_SINGLE_LUN ), | 590 | US_FL_SINGLE_LUN ), |
647 | 591 | ||
648 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
649 | UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110, | ||
650 | "Sony", | ||
651 | "Portable USB Harddrive V2", | ||
652 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
653 | 0 ), | ||
654 | #endif | ||
655 | |||
656 | /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */ | 592 | /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */ |
657 | UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000, | 593 | UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000, |
658 | "Sony", | 594 | "Sony", |
@@ -749,13 +685,6 @@ UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999, | |||
749 | "Silicon Media R/W", | 685 | "Silicon Media R/W", |
750 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), | 686 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), |
751 | 687 | ||
752 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
753 | UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102, | ||
754 | "Fujifilm", | ||
755 | "DPC-R1 (Alauda)", | ||
756 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
757 | #endif | ||
758 | |||
759 | /* Reported by RTE <raszilki@yandex.ru> */ | 688 | /* Reported by RTE <raszilki@yandex.ru> */ |
760 | UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141, | 689 | UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141, |
761 | "JetFlash", | 690 | "JetFlash", |
@@ -798,32 +727,6 @@ UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110, | |||
798 | US_SC_SCSI, US_PR_BULK, NULL, | 727 | US_SC_SCSI, US_PR_BULK, NULL, |
799 | US_FL_NEED_OVERRIDE ), | 728 | US_FL_NEED_OVERRIDE ), |
800 | 729 | ||
801 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
802 | UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110, | ||
803 | "In-System", | ||
804 | "USB/IDE Bridge (ATA/ATAPI)", | ||
805 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
806 | 0 ), | ||
807 | |||
808 | UNUSUAL_DEV( 0x05ab, 0x0301, 0x0100, 0x0110, | ||
809 | "In-System", | ||
810 | "Portable USB Harddrive V2", | ||
811 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
812 | 0 ), | ||
813 | |||
814 | UNUSUAL_DEV( 0x05ab, 0x0351, 0x0100, 0x0110, | ||
815 | "In-System", | ||
816 | "Portable USB Harddrive V2", | ||
817 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
818 | 0 ), | ||
819 | |||
820 | UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110, | ||
821 | "In-System", | ||
822 | "USB Storage Adapter V2", | ||
823 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
824 | 0 ), | ||
825 | #endif | ||
826 | |||
827 | /* Submitted by Sven Anderson <sven-linux@anderson.de> | 730 | /* Submitted by Sven Anderson <sven-linux@anderson.de> |
828 | * There are at least four ProductIDs used for iPods, so I added 0x1202 and | 731 | * There are at least four ProductIDs used for iPods, so I added 0x1202 and |
829 | * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears | 732 | * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears |
@@ -877,14 +780,6 @@ UNUSUAL_DEV( 0x05c6, 0x1000, 0x0000, 0x9999, | |||
877 | US_SC_DEVICE, US_PR_DEVICE, option_ms_init, | 780 | US_SC_DEVICE, US_PR_DEVICE, option_ms_init, |
878 | 0), | 781 | 0), |
879 | 782 | ||
880 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
881 | UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, | ||
882 | "Lexar", | ||
883 | "Jumpshot USB CF Reader", | ||
884 | US_SC_SCSI, US_PR_JUMPSHOT, NULL, | ||
885 | US_FL_NEED_OVERRIDE ), | ||
886 | #endif | ||
887 | |||
888 | /* Reported by Blake Matheny <bmatheny@purdue.edu> */ | 783 | /* Reported by Blake Matheny <bmatheny@purdue.edu> */ |
889 | UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113, | 784 | UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113, |
890 | "Lexar", | 785 | "Lexar", |
@@ -935,14 +830,6 @@ UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100, | |||
935 | "Floppy Drive", | 830 | "Floppy Drive", |
936 | US_SC_UFI, US_PR_CB, NULL, 0 ), | 831 | US_SC_UFI, US_PR_CB, NULL, 0 ), |
937 | 832 | ||
938 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
939 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, | ||
940 | "Olympus", | ||
941 | "Camedia MAUSB-2", | ||
942 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
943 | 0), | ||
944 | #endif | ||
945 | |||
946 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ | 833 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ |
947 | UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, | 834 | UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, |
948 | "SigmaTel", | 835 | "SigmaTel", |
@@ -1043,35 +930,12 @@ UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009, | |||
1043 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 930 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1044 | US_FL_FIX_CAPACITY ), | 931 | US_FL_FIX_CAPACITY ), |
1045 | 932 | ||
1046 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
1047 | UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, | ||
1048 | "Sandisk", | ||
1049 | "ImageMate SDDR-05b", | ||
1050 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
1051 | US_FL_SINGLE_LUN ), | ||
1052 | #endif | ||
1053 | |||
1054 | UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, | 933 | UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, |
1055 | "Sandisk", | 934 | "Sandisk", |
1056 | "ImageMate SDDR-12", | 935 | "ImageMate SDDR-12", |
1057 | US_SC_SCSI, US_PR_CB, NULL, | 936 | US_SC_SCSI, US_PR_CB, NULL, |
1058 | US_FL_SINGLE_LUN ), | 937 | US_FL_SINGLE_LUN ), |
1059 | 938 | ||
1060 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
1061 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, | ||
1062 | "Sandisk", | ||
1063 | "ImageMate SDDR-09", | ||
1064 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
1065 | 0), | ||
1066 | #endif | ||
1067 | |||
1068 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
1069 | UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999, | ||
1070 | "Freecom", | ||
1071 | "USB-IDE", | ||
1072 | US_SC_QIC, US_PR_FREECOM, freecom_init, 0), | ||
1073 | #endif | ||
1074 | |||
1075 | /* Reported by Eero Volotinen <eero@ping-viini.org> */ | 939 | /* Reported by Eero Volotinen <eero@ping-viini.org> */ |
1076 | UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, | 940 | UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, |
1077 | "Freecom Technologies", | 941 | "Freecom Technologies", |
@@ -1091,12 +955,7 @@ UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, | |||
1091 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, | 955 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, |
1092 | US_FL_SCM_MULT_TARG ), | 956 | US_FL_SCM_MULT_TARG ), |
1093 | 957 | ||
1094 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 958 | #ifdef NO_SDDR09 |
1095 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | ||
1096 | "Microtech", | ||
1097 | "CameraMate (DPCM_USB)", | ||
1098 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | ||
1099 | #else | ||
1100 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | 959 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, |
1101 | "Microtech", | 960 | "Microtech", |
1102 | "CameraMate", | 961 | "CameraMate", |
@@ -1104,108 +963,6 @@ UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | |||
1104 | US_FL_SINGLE_LUN ), | 963 | US_FL_SINGLE_LUN ), |
1105 | #endif | 964 | #endif |
1106 | 965 | ||
1107 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
1108 | UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102, | ||
1109 | "Olympus", | ||
1110 | "MAUSB-10 (Alauda)", | ||
1111 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
1112 | #endif | ||
1113 | |||
1114 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
1115 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, | ||
1116 | "Datafab", | ||
1117 | "MDCFE-B USB CF Reader", | ||
1118 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1119 | 0 ), | ||
1120 | |||
1121 | /* | ||
1122 | * The following Datafab-based devices may or may not work | ||
1123 | * using the current driver...the 0xffff is arbitrary since I | ||
1124 | * don't know what device versions exist for these guys. | ||
1125 | * | ||
1126 | * The 0xa003 and 0xa004 devices in particular I'm curious about. | ||
1127 | * I'm told they exist but so far nobody has come forward to say that | ||
1128 | * they work with this driver. Given the success we've had getting | ||
1129 | * other Datafab-based cards operational with this driver, I've decided | ||
1130 | * to leave these two devices in the list. | ||
1131 | */ | ||
1132 | UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff, | ||
1133 | "SIIG/Datafab", | ||
1134 | "SIIG/Datafab Memory Stick+CF Reader/Writer", | ||
1135 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1136 | 0 ), | ||
1137 | |||
1138 | /* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */ | ||
1139 | UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff, | ||
1140 | "Datafab/Unknown", | ||
1141 | "MD2/MD3 Disk enclosure", | ||
1142 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1143 | US_FL_SINGLE_LUN ), | ||
1144 | |||
1145 | UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff, | ||
1146 | "Datafab/Unknown", | ||
1147 | "Datafab-based Reader", | ||
1148 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1149 | 0 ), | ||
1150 | |||
1151 | UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff, | ||
1152 | "Datafab/Unknown", | ||
1153 | "Datafab-based Reader", | ||
1154 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1155 | 0 ), | ||
1156 | |||
1157 | UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff, | ||
1158 | "PNY/Datafab", | ||
1159 | "PNY/Datafab CF+SM Reader", | ||
1160 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1161 | 0 ), | ||
1162 | |||
1163 | UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff, | ||
1164 | "Simple Tech/Datafab", | ||
1165 | "Simple Tech/Datafab CF+SM Reader", | ||
1166 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1167 | 0 ), | ||
1168 | #endif | ||
1169 | |||
1170 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
1171 | /* Contributed by Peter Waechtler */ | ||
1172 | UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999, | ||
1173 | "Datafab", | ||
1174 | "MDSM-B reader", | ||
1175 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
1176 | US_FL_FIX_INQUIRY ), | ||
1177 | #endif | ||
1178 | |||
1179 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
1180 | /* Submitted by Olaf Hering <olh@suse.de> */ | ||
1181 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
1182 | "Datafab Systems, Inc.", | ||
1183 | "USB to CF + SM Combo (LC1)", | ||
1184 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1185 | 0 ), | ||
1186 | #endif | ||
1187 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
1188 | /* SM part - aeb <Andries.Brouwer@cwi.nl> */ | ||
1189 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
1190 | "Datafab Systems, Inc.", | ||
1191 | "USB to CF + SM Combo (LC1)", | ||
1192 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
1193 | US_FL_SINGLE_LUN ), | ||
1194 | #endif | ||
1195 | |||
1196 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
1197 | /* Reported by Felix Moeller <felix@derklecks.de> | ||
1198 | * in Germany this is sold by Hama with the productnumber 46952 | ||
1199 | * as "DualSlot CompactFlash(TM) & MStick Drive USB" | ||
1200 | */ | ||
1201 | UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff, | ||
1202 | "DataFab Systems Inc.", | ||
1203 | "USB CF+MS", | ||
1204 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1205 | 0 ), | ||
1206 | |||
1207 | #endif | ||
1208 | |||
1209 | /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 | 966 | /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 |
1210 | * Only revision 1.13 tested (same for all of the above devices, | 967 | * Only revision 1.13 tested (same for all of the above devices, |
1211 | * based on the Datafab DF-UG-07 chip). Needed for US_FL_FIX_INQUIRY. | 968 | * based on the Datafab DF-UG-07 chip). Needed for US_FL_FIX_INQUIRY. |
@@ -1409,29 +1166,6 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, | |||
1409 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1166 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1410 | US_FL_SANE_SENSE ), | 1167 | US_FL_SANE_SENSE ), |
1411 | 1168 | ||
1412 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
1413 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, | ||
1414 | "ATI", | ||
1415 | "USB Cable 205", | ||
1416 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
1417 | 0 ), | ||
1418 | #endif | ||
1419 | |||
1420 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
1421 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
1422 | "Acomdata", | ||
1423 | "CF", | ||
1424 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1425 | US_FL_SINGLE_LUN ), | ||
1426 | #endif | ||
1427 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
1428 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
1429 | "Acomdata", | ||
1430 | "SM", | ||
1431 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
1432 | US_FL_SINGLE_LUN ), | ||
1433 | #endif | ||
1434 | |||
1435 | UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, | 1169 | UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, |
1436 | "Maxtor", | 1170 | "Maxtor", |
1437 | "USB to SATA", | 1171 | "USB to SATA", |
@@ -1448,23 +1182,6 @@ UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100, | |||
1448 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1182 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1449 | US_FL_SINGLE_LUN ), | 1183 | US_FL_SINGLE_LUN ), |
1450 | 1184 | ||
1451 | /* Submitted by: Nick Sillik <n.sillik@temple.edu> | ||
1452 | * Needed for OneTouch extension to usb-storage | ||
1453 | * | ||
1454 | */ | ||
1455 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | ||
1456 | UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999, | ||
1457 | "Maxtor", | ||
1458 | "OneTouch External Harddrive", | ||
1459 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
1460 | 0), | ||
1461 | UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999, | ||
1462 | "Maxtor", | ||
1463 | "OneTouch External Harddrive", | ||
1464 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
1465 | 0), | ||
1466 | #endif | ||
1467 | |||
1468 | /* Submitted by Joris Struyve <joris@struyve.be> */ | 1185 | /* Submitted by Joris Struyve <joris@struyve.be> */ |
1469 | UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, | 1186 | UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, |
1470 | "Medion", | 1187 | "Medion", |
@@ -2117,14 +1834,6 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100, | |||
2117 | "Micro Mini 1GB", | 1834 | "Micro Mini 1GB", |
2118 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), | 1835 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), |
2119 | 1836 | ||
2120 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
2121 | UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | ||
2122 | "Sandisk", | ||
2123 | "ImageMate SDDR55", | ||
2124 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
2125 | US_FL_SINGLE_LUN), | ||
2126 | #endif | ||
2127 | |||
2128 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ | 1837 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ |
2129 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, | 1838 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, |
2130 | "DataStor", | 1839 | "DataStor", |
diff --git a/drivers/usb/storage/cypress_atacb.h b/drivers/usb/storage/unusual_freecom.h index fbada898d56b..375867942391 100644 --- a/drivers/usb/storage/cypress_atacb.h +++ b/drivers/usb/storage/unusual_freecom.h | |||
@@ -1,8 +1,4 @@ | |||
1 | /* | 1 | /* Unusual Devices File for the Freecom USB/IDE adaptor |
2 | * Support for emulating SAT (ata pass through) on devices based | ||
3 | * on the Cypress USB/ATA bridge supporting ATACB. | ||
4 | * | ||
5 | * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr) | ||
6 | * | 2 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 3 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 4 | * under the terms of the GNU General Public License as published by the |
@@ -19,7 +15,12 @@ | |||
19 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 16 | */ |
21 | 17 | ||
22 | #ifndef _CYPRESS_ATACB_H_ | 18 | #if defined(CONFIG_USB_STORAGE_FREECOM) || \ |
23 | #define _CYPRESS_ATACB_H_ | 19 | defined(CONFIG_USB_STORAGE_FREECOM_MODULE) |
24 | extern void cypress_atacb_passthrough(struct scsi_cmnd*, struct us_data*); | 20 | |
25 | #endif | 21 | UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999, |
22 | "Freecom", | ||
23 | "USB-IDE", | ||
24 | US_SC_QIC, US_PR_FREECOM, init_freecom, 0), | ||
25 | |||
26 | #endif /* defined(CONFIG_USB_STORAGE_FREECOM) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_isd200.h b/drivers/usb/storage/unusual_isd200.h new file mode 100644 index 000000000000..0d99dde3382a --- /dev/null +++ b/drivers/usb/storage/unusual_isd200.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* Unusual Devices File for In-System Design, Inc. ISD200 ASIC | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify it | ||
4 | * under the terms of the GNU General Public License as published by the | ||
5 | * Free Software Foundation; either version 2, or (at your option) any | ||
6 | * later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
16 | */ | ||
17 | |||
18 | #if defined(CONFIG_USB_STORAGE_ISD200) || \ | ||
19 | defined(CONFIG_USB_STORAGE_ISD200_MODULE) | ||
20 | |||
21 | UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110, | ||
22 | "Sony", | ||
23 | "Portable USB Harddrive V2", | ||
24 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
25 | 0), | ||
26 | |||
27 | UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110, | ||
28 | "In-System", | ||
29 | "USB/IDE Bridge (ATA/ATAPI)", | ||
30 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
31 | 0), | ||
32 | |||
33 | UNUSUAL_DEV( 0x05ab, 0x0301, 0x0100, 0x0110, | ||
34 | "In-System", | ||
35 | "Portable USB Harddrive V2", | ||
36 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
37 | 0), | ||
38 | |||
39 | UNUSUAL_DEV( 0x05ab, 0x0351, 0x0100, 0x0110, | ||
40 | "In-System", | ||
41 | "Portable USB Harddrive V2", | ||
42 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
43 | 0), | ||
44 | |||
45 | UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110, | ||
46 | "In-System", | ||
47 | "USB Storage Adapter V2", | ||
48 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
49 | 0), | ||
50 | |||
51 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, | ||
52 | "ATI", | ||
53 | "USB Cable 205", | ||
54 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
55 | 0), | ||
56 | |||
57 | #endif /* defined(CONFIG_USB_STORAGE_ISD200) || ... */ | ||
diff --git a/drivers/usb/storage/sddr55.h b/drivers/usb/storage/unusual_jumpshot.h index a815a0470c84..2e549b1c2c62 100644 --- a/drivers/usb/storage/sddr55.h +++ b/drivers/usb/storage/unusual_jumpshot.h | |||
@@ -1,10 +1,4 @@ | |||
1 | /* Driver for SanDisk SDDR-55 SmartMedia reader | 1 | /* Unusual Devices File for the Lexar "Jumpshot" Compact Flash reader |
2 | * Header File | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2002 Simon Munton | ||
6 | * | ||
7 | * See sddr55.c for more explanation | ||
8 | * | 2 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 3 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the | 4 | * under the terms of the GNU General Public License as published by the |
@@ -21,12 +15,13 @@ | |||
21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 16 | */ |
23 | 17 | ||
24 | #ifndef _USB_SHUTTLE_EUSB_SDDR55_H | 18 | #if defined(CONFIG_USB_STORAGE_JUMPSHOT) || \ |
25 | #define _USB_SHUTTLE_EUSB_SDDR55_H | 19 | defined(CONFIG_USB_STORAGE_JUMPSHOT_MODULE) |
26 | |||
27 | /* Sandisk SDDR-55 stuff */ | ||
28 | 20 | ||
29 | extern int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us); | 21 | UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, |
30 | extern int sddr55_reset(struct us_data *us); | 22 | "Lexar", |
23 | "Jumpshot USB CF Reader", | ||
24 | US_SC_SCSI, US_PR_JUMPSHOT, NULL, | ||
25 | US_FL_NEED_OVERRIDE), | ||
31 | 26 | ||
32 | #endif | 27 | #endif /* defined(CONFIG_USB_STORAGE_JUMPSHOT) || ... */ |
diff --git a/drivers/usb/storage/isd200.h b/drivers/usb/storage/unusual_karma.h index 0a35f4fa78f8..12ae3a03e802 100644 --- a/drivers/usb/storage/isd200.h +++ b/drivers/usb/storage/unusual_karma.h | |||
@@ -1,11 +1,4 @@ | |||
1 | /* Header File for In-System Design, Inc. ISD200 ASIC | 1 | /* Unusual Devices File for the Rio Karma |
2 | * | ||
3 | * First release | ||
4 | * | ||
5 | * Current development and maintenance by: | ||
6 | * (c) 2000 In-System Design, Inc. (support@in-system.com) | ||
7 | * | ||
8 | * See isd200.c for more information. | ||
9 | * | 2 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 3 | * This program is free software; you can redistribute it and/or modify it |
11 | * under the terms of the GNU General Public License as published by the | 4 | * under the terms of the GNU General Public License as published by the |
@@ -22,10 +15,12 @@ | |||
22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | */ | 16 | */ |
24 | 17 | ||
25 | #ifndef _USB_ISD200_H | 18 | #if defined(CONFIG_USB_STORAGE_KARMA) || \ |
26 | #define _USB_ISD200_H | 19 | defined(CONFIG_USB_STORAGE_KARMA_MODULE) |
27 | 20 | ||
28 | extern void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us); | 21 | UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, |
29 | extern int isd200_Initialization(struct us_data *us); | 22 | "Rio", |
23 | "Rio Karma", | ||
24 | US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), | ||
30 | 25 | ||
31 | #endif | 26 | #endif /* defined(CONFIG_USB_STORAGE_KARMA) || ... */ |
diff --git a/drivers/usb/storage/unusual_onetouch.h b/drivers/usb/storage/unusual_onetouch.h new file mode 100644 index 000000000000..bd9306b637df --- /dev/null +++ b/drivers/usb/storage/unusual_onetouch.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* Unusual Devices File for the Maxtor OneTouch USB hard drive's button | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify it | ||
4 | * under the terms of the GNU General Public License as published by the | ||
5 | * Free Software Foundation; either version 2, or (at your option) any | ||
6 | * later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
16 | */ | ||
17 | |||
18 | #if defined(CONFIG_USB_STORAGE_ONETOUCH) || \ | ||
19 | defined(CONFIG_USB_STORAGE_ONETOUCH_MODULE) | ||
20 | |||
21 | /* Submitted by: Nick Sillik <n.sillik@temple.edu> | ||
22 | * Needed for OneTouch extension to usb-storage | ||
23 | */ | ||
24 | UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999, | ||
25 | "Maxtor", | ||
26 | "OneTouch External Harddrive", | ||
27 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
28 | 0), | ||
29 | |||
30 | UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999, | ||
31 | "Maxtor", | ||
32 | "OneTouch External Harddrive", | ||
33 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
34 | 0), | ||
35 | |||
36 | #endif /* defined(CONFIG_USB_STORAGE_ONETOUCH) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_sddr09.h b/drivers/usb/storage/unusual_sddr09.h new file mode 100644 index 000000000000..50cab511a4d7 --- /dev/null +++ b/drivers/usb/storage/unusual_sddr09.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* Unusual Devices File for SanDisk SDDR-09 SmartMedia reader | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify it | ||
4 | * under the terms of the GNU General Public License as published by the | ||
5 | * Free Software Foundation; either version 2, or (at your option) any | ||
6 | * later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
16 | */ | ||
17 | |||
18 | #if defined(CONFIG_USB_STORAGE_SDDR09) || \ | ||
19 | defined(CONFIG_USB_STORAGE_SDDR09_MODULE) | ||
20 | |||
21 | UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, | ||
22 | "Microtech", | ||
23 | "CameraMate (DPCM_USB)", | ||
24 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0), | ||
25 | |||
26 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, | ||
27 | "Sandisk", | ||
28 | "ImageMate SDDR09", | ||
29 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
30 | 0), | ||
31 | |||
32 | /* This entry is from Andries.Brouwer@cwi.nl */ | ||
33 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | ||
34 | "SCM Microsystems", | ||
35 | "eUSB SmartMedia / CompactFlash Adapter", | ||
36 | US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init, | ||
37 | 0), | ||
38 | |||
39 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, | ||
40 | "Olympus", | ||
41 | "Camedia MAUSB-2", | ||
42 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
43 | 0), | ||
44 | |||
45 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, | ||
46 | "Sandisk", | ||
47 | "ImageMate SDDR-09", | ||
48 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
49 | 0), | ||
50 | |||
51 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | ||
52 | "Microtech", | ||
53 | "CameraMate (DPCM_USB)", | ||
54 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0), | ||
55 | |||
56 | #endif /* defined(CONFIG_USB_STORAGE_SDDR09) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_sddr55.h b/drivers/usb/storage/unusual_sddr55.h new file mode 100644 index 000000000000..ae81ef7a1cfd --- /dev/null +++ b/drivers/usb/storage/unusual_sddr55.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* Unusual Devices File for SanDisk SDDR-55 SmartMedia reader | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify it | ||
4 | * under the terms of the GNU General Public License as published by the | ||
5 | * Free Software Foundation; either version 2, or (at your option) any | ||
6 | * later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
16 | */ | ||
17 | |||
18 | #if defined(CONFIG_USB_STORAGE_SDDR55) || \ | ||
19 | defined(CONFIG_USB_STORAGE_SDDR55_MODULE) | ||
20 | |||
21 | /* Contributed by Peter Waechtler */ | ||
22 | UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999, | ||
23 | "Datafab", | ||
24 | "MDSM-B reader", | ||
25 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
26 | US_FL_FIX_INQUIRY), | ||
27 | |||
28 | /* SM part - aeb <Andries.Brouwer@cwi.nl> */ | ||
29 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
30 | "Datafab Systems, Inc.", | ||
31 | "USB to CF + SM Combo (LC1)", | ||
32 | US_SC_SCSI, US_PR_SDDR55, NULL, 0), | ||
33 | |||
34 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
35 | "Acomdata", | ||
36 | "SM", | ||
37 | US_SC_SCSI, US_PR_SDDR55, NULL, 0), | ||
38 | |||
39 | UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | ||
40 | "Sandisk", | ||
41 | "ImageMate SDDR55", | ||
42 | US_SC_SCSI, US_PR_SDDR55, NULL, 0), | ||
43 | |||
44 | #endif /* defined(CONFIG_USB_STORAGE_SDDR55) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_usbat.h b/drivers/usb/storage/unusual_usbat.h new file mode 100644 index 000000000000..80e869f10180 --- /dev/null +++ b/drivers/usb/storage/unusual_usbat.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* Unusual Devices File for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify it | ||
4 | * under the terms of the GNU General Public License as published by the | ||
5 | * Free Software Foundation; either version 2, or (at your option) any | ||
6 | * later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
16 | */ | ||
17 | |||
18 | #if defined(CONFIG_USB_STORAGE_USBAT) || \ | ||
19 | defined(CONFIG_USB_STORAGE_USBAT_MODULE) | ||
20 | |||
21 | UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, | ||
22 | "HP", | ||
23 | "CD-Writer+ 8200e", | ||
24 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | ||
25 | |||
26 | UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | ||
27 | "HP", | ||
28 | "CD-Writer+ CD-4e", | ||
29 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | ||
30 | |||
31 | UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, | ||
32 | "Shuttle/SCM", | ||
33 | "USBAT-02", | ||
34 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
35 | US_FL_SINGLE_LUN), | ||
36 | |||
37 | UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, | ||
38 | "Sandisk", | ||
39 | "ImageMate SDDR-05b", | ||
40 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
41 | US_FL_SINGLE_LUN), | ||
42 | |||
43 | #endif /* defined(CONFIG_USB_STORAGE_USBAT) || ... */ | ||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 4becf495ca2d..8060b85fe1a3 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Developed with the assistance of: | 6 | * Developed with the assistance of: |
7 | * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) | 7 | * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) |
8 | * (c) 2003 Alan Stern (stern@rowland.harvard.edu) | 8 | * (c) 2003-2009 Alan Stern (stern@rowland.harvard.edu) |
9 | * | 9 | * |
10 | * Initial work by: | 10 | * Initial work by: |
11 | * (c) 1999 Michael Gee (michael@linuxspecific.com) | 11 | * (c) 1999 Michael Gee (michael@linuxspecific.com) |
@@ -66,39 +66,6 @@ | |||
66 | #include "debug.h" | 66 | #include "debug.h" |
67 | #include "initializers.h" | 67 | #include "initializers.h" |
68 | 68 | ||
69 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
70 | #include "shuttle_usbat.h" | ||
71 | #endif | ||
72 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
73 | #include "sddr09.h" | ||
74 | #endif | ||
75 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
76 | #include "sddr55.h" | ||
77 | #endif | ||
78 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
79 | #include "freecom.h" | ||
80 | #endif | ||
81 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
82 | #include "isd200.h" | ||
83 | #endif | ||
84 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
85 | #include "datafab.h" | ||
86 | #endif | ||
87 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
88 | #include "jumpshot.h" | ||
89 | #endif | ||
90 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | ||
91 | #include "onetouch.h" | ||
92 | #endif | ||
93 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
94 | #include "alauda.h" | ||
95 | #endif | ||
96 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
97 | #include "karma.h" | ||
98 | #endif | ||
99 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
100 | #include "cypress_atacb.h" | ||
101 | #endif | ||
102 | #include "sierra_ms.h" | 69 | #include "sierra_ms.h" |
103 | #include "option_ms.h" | 70 | #include "option_ms.h" |
104 | 71 | ||
@@ -118,36 +85,8 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); | |||
118 | 85 | ||
119 | /* | 86 | /* |
120 | * The entries in this table correspond, line for line, | 87 | * The entries in this table correspond, line for line, |
121 | * with the entries of us_unusual_dev_list[]. | 88 | * with the entries in usb_storage_usb_ids[], defined in usual-tables.c. |
122 | */ | 89 | */ |
123 | #ifndef CONFIG_USB_LIBUSUAL | ||
124 | |||
125 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
126 | vendorName, productName,useProtocol, useTransport, \ | ||
127 | initFunction, flags) \ | ||
128 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
129 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
130 | |||
131 | #define COMPLIANT_DEV UNUSUAL_DEV | ||
132 | |||
133 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
135 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
136 | |||
137 | static struct usb_device_id storage_usb_ids [] = { | ||
138 | |||
139 | # include "unusual_devs.h" | ||
140 | #undef UNUSUAL_DEV | ||
141 | #undef COMPLIANT_DEV | ||
142 | #undef USUAL_DEV | ||
143 | /* Terminating entry */ | ||
144 | { } | ||
145 | }; | ||
146 | |||
147 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | ||
148 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
149 | |||
150 | /* This is the list of devices we recognize, along with their flag data */ | ||
151 | 90 | ||
152 | /* The vendor name should be kept at eight characters or less, and | 91 | /* The vendor name should be kept at eight characters or less, and |
153 | * the product name should be kept at 16 characters or less. If a device | 92 | * the product name should be kept at 16 characters or less. If a device |
@@ -179,18 +118,17 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
179 | 118 | ||
180 | static struct us_unusual_dev us_unusual_dev_list[] = { | 119 | static struct us_unusual_dev us_unusual_dev_list[] = { |
181 | # include "unusual_devs.h" | 120 | # include "unusual_devs.h" |
182 | # undef UNUSUAL_DEV | 121 | { } /* Terminating entry */ |
183 | # undef COMPLIANT_DEV | ||
184 | # undef USUAL_DEV | ||
185 | |||
186 | /* Terminating entry */ | ||
187 | { NULL } | ||
188 | }; | 122 | }; |
189 | 123 | ||
124 | #undef UNUSUAL_DEV | ||
125 | #undef COMPLIANT_DEV | ||
126 | #undef USUAL_DEV | ||
127 | |||
190 | 128 | ||
191 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ | 129 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ |
192 | 130 | ||
193 | static int storage_suspend(struct usb_interface *iface, pm_message_t message) | 131 | int usb_stor_suspend(struct usb_interface *iface, pm_message_t message) |
194 | { | 132 | { |
195 | struct us_data *us = usb_get_intfdata(iface); | 133 | struct us_data *us = usb_get_intfdata(iface); |
196 | 134 | ||
@@ -207,8 +145,9 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
207 | mutex_unlock(&us->dev_mutex); | 145 | mutex_unlock(&us->dev_mutex); |
208 | return 0; | 146 | return 0; |
209 | } | 147 | } |
148 | EXPORT_SYMBOL_GPL(usb_stor_suspend); | ||
210 | 149 | ||
211 | static int storage_resume(struct usb_interface *iface) | 150 | int usb_stor_resume(struct usb_interface *iface) |
212 | { | 151 | { |
213 | struct us_data *us = usb_get_intfdata(iface); | 152 | struct us_data *us = usb_get_intfdata(iface); |
214 | 153 | ||
@@ -221,8 +160,9 @@ static int storage_resume(struct usb_interface *iface) | |||
221 | mutex_unlock(&us->dev_mutex); | 160 | mutex_unlock(&us->dev_mutex); |
222 | return 0; | 161 | return 0; |
223 | } | 162 | } |
163 | EXPORT_SYMBOL_GPL(usb_stor_resume); | ||
224 | 164 | ||
225 | static int storage_reset_resume(struct usb_interface *iface) | 165 | int usb_stor_reset_resume(struct usb_interface *iface) |
226 | { | 166 | { |
227 | struct us_data *us = usb_get_intfdata(iface); | 167 | struct us_data *us = usb_get_intfdata(iface); |
228 | 168 | ||
@@ -235,6 +175,7 @@ static int storage_reset_resume(struct usb_interface *iface) | |||
235 | * the device */ | 175 | * the device */ |
236 | return 0; | 176 | return 0; |
237 | } | 177 | } |
178 | EXPORT_SYMBOL_GPL(usb_stor_reset_resume); | ||
238 | 179 | ||
239 | #endif /* CONFIG_PM */ | 180 | #endif /* CONFIG_PM */ |
240 | 181 | ||
@@ -243,7 +184,7 @@ static int storage_reset_resume(struct usb_interface *iface) | |||
243 | * a USB port reset, whether from this driver or a different one. | 184 | * a USB port reset, whether from this driver or a different one. |
244 | */ | 185 | */ |
245 | 186 | ||
246 | static int storage_pre_reset(struct usb_interface *iface) | 187 | int usb_stor_pre_reset(struct usb_interface *iface) |
247 | { | 188 | { |
248 | struct us_data *us = usb_get_intfdata(iface); | 189 | struct us_data *us = usb_get_intfdata(iface); |
249 | 190 | ||
@@ -253,8 +194,9 @@ static int storage_pre_reset(struct usb_interface *iface) | |||
253 | mutex_lock(&us->dev_mutex); | 194 | mutex_lock(&us->dev_mutex); |
254 | return 0; | 195 | return 0; |
255 | } | 196 | } |
197 | EXPORT_SYMBOL_GPL(usb_stor_pre_reset); | ||
256 | 198 | ||
257 | static int storage_post_reset(struct usb_interface *iface) | 199 | int usb_stor_post_reset(struct usb_interface *iface) |
258 | { | 200 | { |
259 | struct us_data *us = usb_get_intfdata(iface); | 201 | struct us_data *us = usb_get_intfdata(iface); |
260 | 202 | ||
@@ -269,6 +211,7 @@ static int storage_post_reset(struct usb_interface *iface) | |||
269 | mutex_unlock(&us->dev_mutex); | 211 | mutex_unlock(&us->dev_mutex); |
270 | return 0; | 212 | return 0; |
271 | } | 213 | } |
214 | EXPORT_SYMBOL_GPL(usb_stor_post_reset); | ||
272 | 215 | ||
273 | /* | 216 | /* |
274 | * fill_inquiry_response takes an unsigned char array (which must | 217 | * fill_inquiry_response takes an unsigned char array (which must |
@@ -311,6 +254,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, | |||
311 | 254 | ||
312 | usb_stor_set_xfer_buf(data, data_len, us->srb); | 255 | usb_stor_set_xfer_buf(data, data_len, us->srb); |
313 | } | 256 | } |
257 | EXPORT_SYMBOL_GPL(fill_inquiry_response); | ||
314 | 258 | ||
315 | static int usb_stor_control_thread(void * __us) | 259 | static int usb_stor_control_thread(void * __us) |
316 | { | 260 | { |
@@ -551,20 +495,13 @@ static void adjust_quirks(struct us_data *us) | |||
551 | vid, pid, f); | 495 | vid, pid, f); |
552 | } | 496 | } |
553 | 497 | ||
554 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
555 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
556 | { | ||
557 | const int id_index = id - storage_usb_ids; | ||
558 | return &us_unusual_dev_list[id_index]; | ||
559 | } | ||
560 | |||
561 | /* Get the unusual_devs entries and the string descriptors */ | 498 | /* Get the unusual_devs entries and the string descriptors */ |
562 | static int get_device_info(struct us_data *us, const struct usb_device_id *id) | 499 | static int get_device_info(struct us_data *us, const struct usb_device_id *id, |
500 | struct us_unusual_dev *unusual_dev) | ||
563 | { | 501 | { |
564 | struct usb_device *dev = us->pusb_dev; | 502 | struct usb_device *dev = us->pusb_dev; |
565 | struct usb_interface_descriptor *idesc = | 503 | struct usb_interface_descriptor *idesc = |
566 | &us->pusb_intf->cur_altsetting->desc; | 504 | &us->pusb_intf->cur_altsetting->desc; |
567 | struct us_unusual_dev *unusual_dev = find_unusual(id); | ||
568 | 505 | ||
569 | /* Store the entries */ | 506 | /* Store the entries */ |
570 | us->unusual_dev = unusual_dev; | 507 | us->unusual_dev = unusual_dev; |
@@ -629,7 +566,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
629 | } | 566 | } |
630 | 567 | ||
631 | /* Get the transport settings */ | 568 | /* Get the transport settings */ |
632 | static int get_transport(struct us_data *us) | 569 | static void get_transport(struct us_data *us) |
633 | { | 570 | { |
634 | switch (us->protocol) { | 571 | switch (us->protocol) { |
635 | case US_PR_CB: | 572 | case US_PR_CB: |
@@ -651,100 +588,11 @@ static int get_transport(struct us_data *us) | |||
651 | us->transport = usb_stor_Bulk_transport; | 588 | us->transport = usb_stor_Bulk_transport; |
652 | us->transport_reset = usb_stor_Bulk_reset; | 589 | us->transport_reset = usb_stor_Bulk_reset; |
653 | break; | 590 | break; |
654 | |||
655 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
656 | case US_PR_USBAT: | ||
657 | us->transport_name = "Shuttle USBAT"; | ||
658 | us->transport = usbat_transport; | ||
659 | us->transport_reset = usb_stor_CB_reset; | ||
660 | us->max_lun = 1; | ||
661 | break; | ||
662 | #endif | ||
663 | |||
664 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
665 | case US_PR_EUSB_SDDR09: | ||
666 | us->transport_name = "EUSB/SDDR09"; | ||
667 | us->transport = sddr09_transport; | ||
668 | us->transport_reset = usb_stor_CB_reset; | ||
669 | us->max_lun = 0; | ||
670 | break; | ||
671 | #endif | ||
672 | |||
673 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
674 | case US_PR_SDDR55: | ||
675 | us->transport_name = "SDDR55"; | ||
676 | us->transport = sddr55_transport; | ||
677 | us->transport_reset = sddr55_reset; | ||
678 | us->max_lun = 0; | ||
679 | break; | ||
680 | #endif | ||
681 | |||
682 | #ifdef CONFIG_USB_STORAGE_DPCM | ||
683 | case US_PR_DPCM_USB: | ||
684 | us->transport_name = "Control/Bulk-EUSB/SDDR09"; | ||
685 | us->transport = dpcm_transport; | ||
686 | us->transport_reset = usb_stor_CB_reset; | ||
687 | us->max_lun = 1; | ||
688 | break; | ||
689 | #endif | ||
690 | |||
691 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
692 | case US_PR_FREECOM: | ||
693 | us->transport_name = "Freecom"; | ||
694 | us->transport = freecom_transport; | ||
695 | us->transport_reset = usb_stor_freecom_reset; | ||
696 | us->max_lun = 0; | ||
697 | break; | ||
698 | #endif | ||
699 | |||
700 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
701 | case US_PR_DATAFAB: | ||
702 | us->transport_name = "Datafab Bulk-Only"; | ||
703 | us->transport = datafab_transport; | ||
704 | us->transport_reset = usb_stor_Bulk_reset; | ||
705 | us->max_lun = 1; | ||
706 | break; | ||
707 | #endif | ||
708 | |||
709 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
710 | case US_PR_JUMPSHOT: | ||
711 | us->transport_name = "Lexar Jumpshot Control/Bulk"; | ||
712 | us->transport = jumpshot_transport; | ||
713 | us->transport_reset = usb_stor_Bulk_reset; | ||
714 | us->max_lun = 1; | ||
715 | break; | ||
716 | #endif | ||
717 | |||
718 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
719 | case US_PR_ALAUDA: | ||
720 | us->transport_name = "Alauda Control/Bulk"; | ||
721 | us->transport = alauda_transport; | ||
722 | us->transport_reset = usb_stor_Bulk_reset; | ||
723 | us->max_lun = 1; | ||
724 | break; | ||
725 | #endif | ||
726 | |||
727 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
728 | case US_PR_KARMA: | ||
729 | us->transport_name = "Rio Karma/Bulk"; | ||
730 | us->transport = rio_karma_transport; | ||
731 | us->transport_reset = usb_stor_Bulk_reset; | ||
732 | break; | ||
733 | #endif | ||
734 | |||
735 | default: | ||
736 | return -EIO; | ||
737 | } | 591 | } |
738 | US_DEBUGP("Transport: %s\n", us->transport_name); | ||
739 | |||
740 | /* fix for single-lun devices */ | ||
741 | if (us->fflags & US_FL_SINGLE_LUN) | ||
742 | us->max_lun = 0; | ||
743 | return 0; | ||
744 | } | 592 | } |
745 | 593 | ||
746 | /* Get the protocol settings */ | 594 | /* Get the protocol settings */ |
747 | static int get_protocol(struct us_data *us) | 595 | static void get_protocol(struct us_data *us) |
748 | { | 596 | { |
749 | switch (us->subclass) { | 597 | switch (us->subclass) { |
750 | case US_SC_RBC: | 598 | case US_SC_RBC: |
@@ -779,26 +627,7 @@ static int get_protocol(struct us_data *us) | |||
779 | us->protocol_name = "Uniform Floppy Interface (UFI)"; | 627 | us->protocol_name = "Uniform Floppy Interface (UFI)"; |
780 | us->proto_handler = usb_stor_ufi_command; | 628 | us->proto_handler = usb_stor_ufi_command; |
781 | break; | 629 | break; |
782 | |||
783 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
784 | case US_SC_ISD200: | ||
785 | us->protocol_name = "ISD200 ATA/ATAPI"; | ||
786 | us->proto_handler = isd200_ata_command; | ||
787 | break; | ||
788 | #endif | ||
789 | |||
790 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
791 | case US_SC_CYP_ATACB: | ||
792 | us->protocol_name = "Transparent SCSI with Cypress ATACB"; | ||
793 | us->proto_handler = cypress_atacb_passthrough; | ||
794 | break; | ||
795 | #endif | ||
796 | |||
797 | default: | ||
798 | return -EIO; | ||
799 | } | 630 | } |
800 | US_DEBUGP("Protocol: %s\n", us->protocol_name); | ||
801 | return 0; | ||
802 | } | 631 | } |
803 | 632 | ||
804 | /* Get the pipe settings */ | 633 | /* Get the pipe settings */ |
@@ -846,12 +675,12 @@ static int get_pipes(struct us_data *us) | |||
846 | us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0); | 675 | us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0); |
847 | us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0); | 676 | us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0); |
848 | us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, | 677 | us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, |
849 | ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 678 | usb_endpoint_num(ep_out)); |
850 | us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, | 679 | us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, |
851 | ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 680 | usb_endpoint_num(ep_in)); |
852 | if (ep_int) { | 681 | if (ep_int) { |
853 | us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, | 682 | us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, |
854 | ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 683 | usb_endpoint_num(ep_int)); |
855 | us->ep_bInterval = ep_int->bInterval; | 684 | us->ep_bInterval = ep_int->bInterval; |
856 | } | 685 | } |
857 | return 0; | 686 | return 0; |
@@ -1012,17 +841,15 @@ static int usb_stor_scan_thread(void * __us) | |||
1012 | } | 841 | } |
1013 | 842 | ||
1014 | 843 | ||
1015 | /* Probe to see if we can drive a newly-connected USB device */ | 844 | /* First part of general USB mass-storage probing */ |
1016 | static int storage_probe(struct usb_interface *intf, | 845 | int usb_stor_probe1(struct us_data **pus, |
1017 | const struct usb_device_id *id) | 846 | struct usb_interface *intf, |
847 | const struct usb_device_id *id, | ||
848 | struct us_unusual_dev *unusual_dev) | ||
1018 | { | 849 | { |
1019 | struct Scsi_Host *host; | 850 | struct Scsi_Host *host; |
1020 | struct us_data *us; | 851 | struct us_data *us; |
1021 | int result; | 852 | int result; |
1022 | struct task_struct *th; | ||
1023 | |||
1024 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
1025 | return -ENXIO; | ||
1026 | 853 | ||
1027 | US_DEBUGP("USB Mass Storage device detected\n"); | 854 | US_DEBUGP("USB Mass Storage device detected\n"); |
1028 | 855 | ||
@@ -1041,7 +868,7 @@ static int storage_probe(struct usb_interface *intf, | |||
1041 | * Allow 16-byte CDBs and thus > 2TB | 868 | * Allow 16-byte CDBs and thus > 2TB |
1042 | */ | 869 | */ |
1043 | host->max_cmd_len = 16; | 870 | host->max_cmd_len = 16; |
1044 | us = host_to_us(host); | 871 | *pus = us = host_to_us(host); |
1045 | memset(us, 0, sizeof(struct us_data)); | 872 | memset(us, 0, sizeof(struct us_data)); |
1046 | mutex_init(&(us->dev_mutex)); | 873 | mutex_init(&(us->dev_mutex)); |
1047 | init_completion(&us->cmnd_ready); | 874 | init_completion(&us->cmnd_ready); |
@@ -1054,24 +881,46 @@ static int storage_probe(struct usb_interface *intf, | |||
1054 | if (result) | 881 | if (result) |
1055 | goto BadDevice; | 882 | goto BadDevice; |
1056 | 883 | ||
1057 | /* | 884 | /* Get the unusual_devs entries and the descriptors */ |
1058 | * Get the unusual_devs entries and the descriptors | 885 | result = get_device_info(us, id, unusual_dev); |
1059 | * | ||
1060 | * id_index is calculated in the declaration to be the index number | ||
1061 | * of the match from the usb_device_id table, so we can find the | ||
1062 | * corresponding entry in the private table. | ||
1063 | */ | ||
1064 | result = get_device_info(us, id); | ||
1065 | if (result) | 886 | if (result) |
1066 | goto BadDevice; | 887 | goto BadDevice; |
1067 | 888 | ||
1068 | /* Get the transport, protocol, and pipe settings */ | 889 | /* Get standard transport and protocol settings */ |
1069 | result = get_transport(us); | 890 | get_transport(us); |
1070 | if (result) | 891 | get_protocol(us); |
1071 | goto BadDevice; | 892 | |
1072 | result = get_protocol(us); | 893 | /* Give the caller a chance to fill in specialized transport |
1073 | if (result) | 894 | * or protocol settings. |
895 | */ | ||
896 | return 0; | ||
897 | |||
898 | BadDevice: | ||
899 | US_DEBUGP("storage_probe() failed\n"); | ||
900 | release_everything(us); | ||
901 | return result; | ||
902 | } | ||
903 | EXPORT_SYMBOL_GPL(usb_stor_probe1); | ||
904 | |||
905 | /* Second part of general USB mass-storage probing */ | ||
906 | int usb_stor_probe2(struct us_data *us) | ||
907 | { | ||
908 | struct task_struct *th; | ||
909 | int result; | ||
910 | |||
911 | /* Make sure the transport and protocol have both been set */ | ||
912 | if (!us->transport || !us->proto_handler) { | ||
913 | result = -ENXIO; | ||
1074 | goto BadDevice; | 914 | goto BadDevice; |
915 | } | ||
916 | US_DEBUGP("Transport: %s\n", us->transport_name); | ||
917 | US_DEBUGP("Protocol: %s\n", us->protocol_name); | ||
918 | |||
919 | /* fix for single-lun devices */ | ||
920 | if (us->fflags & US_FL_SINGLE_LUN) | ||
921 | us->max_lun = 0; | ||
922 | |||
923 | /* Find the endpoints and calculate pipe values */ | ||
1075 | result = get_pipes(us); | 924 | result = get_pipes(us); |
1076 | if (result) | 925 | if (result) |
1077 | goto BadDevice; | 926 | goto BadDevice; |
@@ -1080,7 +929,7 @@ static int storage_probe(struct usb_interface *intf, | |||
1080 | result = usb_stor_acquire_resources(us); | 929 | result = usb_stor_acquire_resources(us); |
1081 | if (result) | 930 | if (result) |
1082 | goto BadDevice; | 931 | goto BadDevice; |
1083 | result = scsi_add_host(host, &intf->dev); | 932 | result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev); |
1084 | if (result) { | 933 | if (result) { |
1085 | printk(KERN_WARNING USB_STORAGE | 934 | printk(KERN_WARNING USB_STORAGE |
1086 | "Unable to add the scsi host\n"); | 935 | "Unable to add the scsi host\n"); |
@@ -1108,9 +957,10 @@ BadDevice: | |||
1108 | release_everything(us); | 957 | release_everything(us); |
1109 | return result; | 958 | return result; |
1110 | } | 959 | } |
960 | EXPORT_SYMBOL_GPL(usb_stor_probe2); | ||
1111 | 961 | ||
1112 | /* Handle a disconnect event from the USB core */ | 962 | /* Handle a USB mass-storage disconnect */ |
1113 | static void storage_disconnect(struct usb_interface *intf) | 963 | void usb_stor_disconnect(struct usb_interface *intf) |
1114 | { | 964 | { |
1115 | struct us_data *us = usb_get_intfdata(intf); | 965 | struct us_data *us = usb_get_intfdata(intf); |
1116 | 966 | ||
@@ -1118,6 +968,42 @@ static void storage_disconnect(struct usb_interface *intf) | |||
1118 | quiesce_and_remove_host(us); | 968 | quiesce_and_remove_host(us); |
1119 | release_everything(us); | 969 | release_everything(us); |
1120 | } | 970 | } |
971 | EXPORT_SYMBOL_GPL(usb_stor_disconnect); | ||
972 | |||
973 | /* The main probe routine for standard devices */ | ||
974 | static int storage_probe(struct usb_interface *intf, | ||
975 | const struct usb_device_id *id) | ||
976 | { | ||
977 | struct us_data *us; | ||
978 | int result; | ||
979 | |||
980 | /* | ||
981 | * If libusual is configured, let it decide whether a standard | ||
982 | * device should be handled by usb-storage or by ub. | ||
983 | * If the device isn't standard (is handled by a subdriver | ||
984 | * module) then don't accept it. | ||
985 | */ | ||
986 | if (usb_usual_check_type(id, USB_US_TYPE_STOR) || | ||
987 | usb_usual_ignore_device(intf)) | ||
988 | return -ENXIO; | ||
989 | |||
990 | /* | ||
991 | * Call the general probe procedures. | ||
992 | * | ||
993 | * The unusual_dev_list array is parallel to the usb_storage_usb_ids | ||
994 | * table, so we use the index of the id entry to find the | ||
995 | * corresponding unusual_devs entry. | ||
996 | */ | ||
997 | result = usb_stor_probe1(&us, intf, id, | ||
998 | (id - usb_storage_usb_ids) + us_unusual_dev_list); | ||
999 | if (result) | ||
1000 | return result; | ||
1001 | |||
1002 | /* No special transport or protocol settings in the main module */ | ||
1003 | |||
1004 | result = usb_stor_probe2(us); | ||
1005 | return result; | ||
1006 | } | ||
1121 | 1007 | ||
1122 | /*********************************************************************** | 1008 | /*********************************************************************** |
1123 | * Initialization and registration | 1009 | * Initialization and registration |
@@ -1126,15 +1012,13 @@ static void storage_disconnect(struct usb_interface *intf) | |||
1126 | static struct usb_driver usb_storage_driver = { | 1012 | static struct usb_driver usb_storage_driver = { |
1127 | .name = "usb-storage", | 1013 | .name = "usb-storage", |
1128 | .probe = storage_probe, | 1014 | .probe = storage_probe, |
1129 | .disconnect = storage_disconnect, | 1015 | .disconnect = usb_stor_disconnect, |
1130 | #ifdef CONFIG_PM | 1016 | .suspend = usb_stor_suspend, |
1131 | .suspend = storage_suspend, | 1017 | .resume = usb_stor_resume, |
1132 | .resume = storage_resume, | 1018 | .reset_resume = usb_stor_reset_resume, |
1133 | .reset_resume = storage_reset_resume, | 1019 | .pre_reset = usb_stor_pre_reset, |
1134 | #endif | 1020 | .post_reset = usb_stor_post_reset, |
1135 | .pre_reset = storage_pre_reset, | 1021 | .id_table = usb_storage_usb_ids, |
1136 | .post_reset = storage_post_reset, | ||
1137 | .id_table = storage_usb_ids, | ||
1138 | .soft_unbind = 1, | 1022 | .soft_unbind = 1, |
1139 | }; | 1023 | }; |
1140 | 1024 | ||
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 65e674e4be99..2609efb2bd7e 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -177,4 +177,25 @@ extern void fill_inquiry_response(struct us_data *us, | |||
177 | #define scsi_unlock(host) spin_unlock_irq(host->host_lock) | 177 | #define scsi_unlock(host) spin_unlock_irq(host->host_lock) |
178 | #define scsi_lock(host) spin_lock_irq(host->host_lock) | 178 | #define scsi_lock(host) spin_lock_irq(host->host_lock) |
179 | 179 | ||
180 | /* General routines provided by the usb-storage standard core */ | ||
181 | #ifdef CONFIG_PM | ||
182 | extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message); | ||
183 | extern int usb_stor_resume(struct usb_interface *iface); | ||
184 | extern int usb_stor_reset_resume(struct usb_interface *iface); | ||
185 | #else | ||
186 | #define usb_stor_suspend NULL | ||
187 | #define usb_stor_resume NULL | ||
188 | #define usb_stor_reset_resume NULL | ||
189 | #endif | ||
190 | |||
191 | extern int usb_stor_pre_reset(struct usb_interface *iface); | ||
192 | extern int usb_stor_post_reset(struct usb_interface *iface); | ||
193 | |||
194 | extern int usb_stor_probe1(struct us_data **pus, | ||
195 | struct usb_interface *intf, | ||
196 | const struct usb_device_id *id, | ||
197 | struct us_unusual_dev *unusual_dev); | ||
198 | extern int usb_stor_probe2(struct us_data *us); | ||
199 | extern void usb_stor_disconnect(struct usb_interface *intf); | ||
200 | |||
180 | #endif | 201 | #endif |
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c new file mode 100644 index 000000000000..468bde7d1971 --- /dev/null +++ b/drivers/usb/storage/usual-tables.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* Driver for USB Mass Storage devices | ||
2 | * Usual Tables File for usb-storage and libusual | ||
3 | * | ||
4 | * Copyright (C) 2009 Alan Stern (stern@rowland.harvard.edu) | ||
5 | * | ||
6 | * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more | ||
7 | * information about this driver. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2, or (at your option) any | ||
12 | * later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/usb.h> | ||
27 | #include <linux/usb_usual.h> | ||
28 | |||
29 | |||
30 | /* | ||
31 | * The table of devices | ||
32 | */ | ||
33 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
34 | vendorName, productName, useProtocol, useTransport, \ | ||
35 | initFunction, flags) \ | ||
36 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
37 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
38 | |||
39 | #define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
40 | vendorName, productName, useProtocol, useTransport, \ | ||
41 | initFunction, flags) \ | ||
42 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
43 | .driver_info = (flags) } | ||
44 | |||
45 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
46 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
47 | .driver_info = ((useType)<<24) } | ||
48 | |||
49 | struct usb_device_id usb_storage_usb_ids[] = { | ||
50 | # include "unusual_devs.h" | ||
51 | { } /* Terminating entry */ | ||
52 | }; | ||
53 | EXPORT_SYMBOL_GPL(usb_storage_usb_ids); | ||
54 | |||
55 | MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); | ||
56 | |||
57 | #undef UNUSUAL_DEV | ||
58 | #undef COMPLIANT_DEV | ||
59 | #undef USUAL_DEV | ||
60 | |||
61 | |||
62 | /* | ||
63 | * The table of devices to ignore | ||
64 | */ | ||
65 | struct ignore_entry { | ||
66 | u16 vid, pid, bcdmin, bcdmax; | ||
67 | }; | ||
68 | |||
69 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
70 | vendorName, productName, useProtocol, useTransport, \ | ||
71 | initFunction, flags) \ | ||
72 | { \ | ||
73 | .vid = id_vendor, \ | ||
74 | .pid = id_product, \ | ||
75 | .bcdmin = bcdDeviceMin, \ | ||
76 | .bcdmax = bcdDeviceMax, \ | ||
77 | } | ||
78 | |||
79 | static struct ignore_entry ignore_ids[] = { | ||
80 | # include "unusual_alauda.h" | ||
81 | # include "unusual_cypress.h" | ||
82 | # include "unusual_datafab.h" | ||
83 | # include "unusual_freecom.h" | ||
84 | # include "unusual_isd200.h" | ||
85 | # include "unusual_jumpshot.h" | ||
86 | # include "unusual_karma.h" | ||
87 | # include "unusual_onetouch.h" | ||
88 | # include "unusual_sddr09.h" | ||
89 | # include "unusual_sddr55.h" | ||
90 | # include "unusual_usbat.h" | ||
91 | { } /* Terminating entry */ | ||
92 | }; | ||
93 | |||
94 | #undef UNUSUAL_DEV | ||
95 | |||
96 | |||
97 | /* Return an error if a device is in the ignore_ids list */ | ||
98 | int usb_usual_ignore_device(struct usb_interface *intf) | ||
99 | { | ||
100 | struct usb_device *udev; | ||
101 | unsigned vid, pid, bcd; | ||
102 | struct ignore_entry *p; | ||
103 | |||
104 | udev = interface_to_usbdev(intf); | ||
105 | vid = le16_to_cpu(udev->descriptor.idVendor); | ||
106 | pid = le16_to_cpu(udev->descriptor.idProduct); | ||
107 | bcd = le16_to_cpu(udev->descriptor.bcdDevice); | ||
108 | |||
109 | for (p = ignore_ids; p->vid; ++p) { | ||
110 | if (p->vid == vid && p->pid == pid && | ||
111 | p->bcdmin <= bcd && p->bcdmax >= bcd) | ||
112 | return -ENXIO; | ||
113 | } | ||
114 | return 0; | ||
115 | } | ||
116 | EXPORT_SYMBOL_GPL(usb_usual_ignore_device); | ||
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index be76084c8d7e..60ba631e99c2 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -410,7 +410,9 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i | |||
410 | } | 410 | } |
411 | 411 | ||
412 | /* let the user know what node this device is now attached to */ | 412 | /* let the user know what node this device is now attached to */ |
413 | info("USB Skeleton device now attached to USBSkel-%d", interface->minor); | 413 | dev_info(&interface->dev, |
414 | "USB Skeleton device now attached to USBSkel-%d", | ||
415 | interface->minor); | ||
414 | return 0; | 416 | return 0; |
415 | 417 | ||
416 | error: | 418 | error: |
@@ -441,7 +443,7 @@ static void skel_disconnect(struct usb_interface *interface) | |||
441 | /* decrement our usage count */ | 443 | /* decrement our usage count */ |
442 | kref_put(&dev->kref, skel_delete); | 444 | kref_put(&dev->kref, skel_delete); |
443 | 445 | ||
444 | info("USB Skeleton #%d now disconnected", minor); | 446 | dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor); |
445 | } | 447 | } |
446 | 448 | ||
447 | static void skel_draw_down(struct usb_skel *dev) | 449 | static void skel_draw_down(struct usb_skel *dev) |
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index 1335cbe1191d..25eae405f622 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c | |||
@@ -638,8 +638,7 @@ static void cbaf_disconnect(struct usb_interface *iface) | |||
638 | usb_put_intf(iface); | 638 | usb_put_intf(iface); |
639 | kfree(cbaf->buffer); | 639 | kfree(cbaf->buffer); |
640 | /* paranoia: clean up crypto keys */ | 640 | /* paranoia: clean up crypto keys */ |
641 | memset(cbaf, 0, sizeof(*cbaf)); | 641 | kzfree(cbaf); |
642 | kfree(cbaf); | ||
643 | } | 642 | } |
644 | 643 | ||
645 | static struct usb_device_id cbaf_id_table[] = { | 644 | static struct usb_device_id cbaf_id_table[] = { |
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 8e18141bb2e0..f0aac0cf315a 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
@@ -889,6 +889,8 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev) | |||
889 | if (usb_dev->wusb == 0 || usb_dev->devnum == 1) | 889 | if (usb_dev->wusb == 0 || usb_dev->devnum == 1) |
890 | return; /* skip non wusb and wusb RHs */ | 890 | return; /* skip non wusb and wusb RHs */ |
891 | 891 | ||
892 | usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED); | ||
893 | |||
892 | wusbhc = wusbhc_get_by_usb_dev(usb_dev); | 894 | wusbhc = wusbhc_get_by_usb_dev(usb_dev); |
893 | if (wusbhc == NULL) | 895 | if (wusbhc == NULL) |
894 | goto error_nodev; | 896 | goto error_nodev; |
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index f4aa28eca70d..8118db7f1d8d 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c | |||
@@ -312,6 +312,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | |||
312 | result = wusb_set_dev_addr(wusbhc, wusb_dev, 0); | 312 | result = wusb_set_dev_addr(wusbhc, wusb_dev, 0); |
313 | if (result < 0) | 313 | if (result < 0) |
314 | goto error_addr0; | 314 | goto error_addr0; |
315 | usb_set_device_state(usb_dev, USB_STATE_DEFAULT); | ||
315 | usb_ep0_reinit(usb_dev); | 316 | usb_ep0_reinit(usb_dev); |
316 | 317 | ||
317 | /* Set new (authenticated) address. */ | 318 | /* Set new (authenticated) address. */ |
@@ -327,6 +328,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | |||
327 | result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address); | 328 | result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address); |
328 | if (result < 0) | 329 | if (result < 0) |
329 | goto error_addr; | 330 | goto error_addr; |
331 | usb_set_device_state(usb_dev, USB_STATE_ADDRESS); | ||
330 | usb_ep0_reinit(usb_dev); | 332 | usb_ep0_reinit(usb_dev); |
331 | usb_dev->authenticated = 1; | 333 | usb_dev->authenticated = 1; |
332 | error_addr: | 334 | error_addr: |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 62bd4441b5e0..378f27745a1d 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops = | |||
457 | 457 | ||
458 | /* AU1100 LCD controller device driver */ | 458 | /* AU1100 LCD controller device driver */ |
459 | 459 | ||
460 | static int __init au1100fb_drv_probe(struct device *dev) | 460 | static int __init au1100fb_drv_probe(struct platform_device *dev) |
461 | { | 461 | { |
462 | struct au1100fb_device *fbdev = NULL; | 462 | struct au1100fb_device *fbdev = NULL; |
463 | struct resource *regs_res; | 463 | struct resource *regs_res; |
@@ -475,7 +475,7 @@ static int __init au1100fb_drv_probe(struct device *dev) | |||
475 | 475 | ||
476 | fbdev->panel = &known_lcd_panels[drv_info.panel_idx]; | 476 | fbdev->panel = &known_lcd_panels[drv_info.panel_idx]; |
477 | 477 | ||
478 | dev_set_drvdata(dev, (void*)fbdev); | 478 | platform_set_drvdata(dev, (void *)fbdev); |
479 | 479 | ||
480 | /* Allocate region for our registers and map them */ | 480 | /* Allocate region for our registers and map them */ |
481 | if (!(regs_res = platform_get_resource(to_platform_device(dev), | 481 | if (!(regs_res = platform_get_resource(to_platform_device(dev), |
@@ -583,19 +583,19 @@ failed: | |||
583 | fb_dealloc_cmap(&fbdev->info.cmap); | 583 | fb_dealloc_cmap(&fbdev->info.cmap); |
584 | } | 584 | } |
585 | kfree(fbdev); | 585 | kfree(fbdev); |
586 | dev_set_drvdata(dev, NULL); | 586 | platform_set_drvdata(dev, NULL); |
587 | 587 | ||
588 | return 0; | 588 | return 0; |
589 | } | 589 | } |
590 | 590 | ||
591 | int au1100fb_drv_remove(struct device *dev) | 591 | int au1100fb_drv_remove(struct platform_device *dev) |
592 | { | 592 | { |
593 | struct au1100fb_device *fbdev = NULL; | 593 | struct au1100fb_device *fbdev = NULL; |
594 | 594 | ||
595 | if (!dev) | 595 | if (!dev) |
596 | return -ENODEV; | 596 | return -ENODEV; |
597 | 597 | ||
598 | fbdev = (struct au1100fb_device*) dev_get_drvdata(dev); | 598 | fbdev = (struct au1100fb_device *) platform_get_drvdata(dev); |
599 | 599 | ||
600 | #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) | 600 | #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) |
601 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); | 601 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); |
@@ -620,9 +620,9 @@ int au1100fb_drv_remove(struct device *dev) | |||
620 | static u32 sys_clksrc; | 620 | static u32 sys_clksrc; |
621 | static struct au1100fb_regs fbregs; | 621 | static struct au1100fb_regs fbregs; |
622 | 622 | ||
623 | int au1100fb_drv_suspend(struct device *dev, pm_message_t state) | 623 | int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) |
624 | { | 624 | { |
625 | struct au1100fb_device *fbdev = dev_get_drvdata(dev); | 625 | struct au1100fb_device *fbdev = platform_get_drvdata(dev); |
626 | 626 | ||
627 | if (!fbdev) | 627 | if (!fbdev) |
628 | return 0; | 628 | return 0; |
@@ -641,9 +641,9 @@ int au1100fb_drv_suspend(struct device *dev, pm_message_t state) | |||
641 | return 0; | 641 | return 0; |
642 | } | 642 | } |
643 | 643 | ||
644 | int au1100fb_drv_resume(struct device *dev) | 644 | int au1100fb_drv_resume(struct platform_device *dev) |
645 | { | 645 | { |
646 | struct au1100fb_device *fbdev = dev_get_drvdata(dev); | 646 | struct au1100fb_device *fbdev = platform_get_drvdata(dev); |
647 | 647 | ||
648 | if (!fbdev) | 648 | if (!fbdev) |
649 | return 0; | 649 | return 0; |
@@ -663,10 +663,11 @@ int au1100fb_drv_resume(struct device *dev) | |||
663 | #define au1100fb_drv_resume NULL | 663 | #define au1100fb_drv_resume NULL |
664 | #endif | 664 | #endif |
665 | 665 | ||
666 | static struct device_driver au1100fb_driver = { | 666 | static struct platform_driver au1100fb_driver = { |
667 | .name = "au1100-lcd", | 667 | .driver = { |
668 | .bus = &platform_bus_type, | 668 | .name = "au1100-lcd", |
669 | 669 | .owner = THIS_MODULE, | |
670 | }, | ||
670 | .probe = au1100fb_drv_probe, | 671 | .probe = au1100fb_drv_probe, |
671 | .remove = au1100fb_drv_remove, | 672 | .remove = au1100fb_drv_remove, |
672 | .suspend = au1100fb_drv_suspend, | 673 | .suspend = au1100fb_drv_suspend, |
@@ -753,12 +754,12 @@ int __init au1100fb_init(void) | |||
753 | return ret; | 754 | return ret; |
754 | } | 755 | } |
755 | 756 | ||
756 | return driver_register(&au1100fb_driver); | 757 | return platform_driver_register(&au1100fb_driver); |
757 | } | 758 | } |
758 | 759 | ||
759 | void __exit au1100fb_cleanup(void) | 760 | void __exit au1100fb_cleanup(void) |
760 | { | 761 | { |
761 | driver_unregister(&au1100fb_driver); | 762 | platform_driver_unregister(&au1100fb_driver); |
762 | 763 | ||
763 | kfree(drv_info.opt_mode); | 764 | kfree(drv_info.opt_mode); |
764 | } | 765 | } |
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 03e57ef88378..0d96f1d2d4c5 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c | |||
@@ -1622,7 +1622,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) | |||
1622 | 1622 | ||
1623 | /* AU1200 LCD controller device driver */ | 1623 | /* AU1200 LCD controller device driver */ |
1624 | 1624 | ||
1625 | static int au1200fb_drv_probe(struct device *dev) | 1625 | static int au1200fb_drv_probe(struct platform_device *dev) |
1626 | { | 1626 | { |
1627 | struct au1200fb_device *fbdev; | 1627 | struct au1200fb_device *fbdev; |
1628 | unsigned long page; | 1628 | unsigned long page; |
@@ -1645,7 +1645,7 @@ static int au1200fb_drv_probe(struct device *dev) | |||
1645 | /* Allocate the framebuffer to the maximum screen size */ | 1645 | /* Allocate the framebuffer to the maximum screen size */ |
1646 | fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; | 1646 | fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; |
1647 | 1647 | ||
1648 | fbdev->fb_mem = dma_alloc_noncoherent(dev, | 1648 | fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev, |
1649 | PAGE_ALIGN(fbdev->fb_len), | 1649 | PAGE_ALIGN(fbdev->fb_len), |
1650 | &fbdev->fb_phys, GFP_KERNEL); | 1650 | &fbdev->fb_phys, GFP_KERNEL); |
1651 | if (!fbdev->fb_mem) { | 1651 | if (!fbdev->fb_mem) { |
@@ -1715,7 +1715,7 @@ failed: | |||
1715 | return ret; | 1715 | return ret; |
1716 | } | 1716 | } |
1717 | 1717 | ||
1718 | static int au1200fb_drv_remove(struct device *dev) | 1718 | static int au1200fb_drv_remove(struct platform_device *dev) |
1719 | { | 1719 | { |
1720 | struct au1200fb_device *fbdev; | 1720 | struct au1200fb_device *fbdev; |
1721 | int plane; | 1721 | int plane; |
@@ -1733,7 +1733,8 @@ static int au1200fb_drv_remove(struct device *dev) | |||
1733 | /* Clean up all probe data */ | 1733 | /* Clean up all probe data */ |
1734 | unregister_framebuffer(&fbdev->fb_info); | 1734 | unregister_framebuffer(&fbdev->fb_info); |
1735 | if (fbdev->fb_mem) | 1735 | if (fbdev->fb_mem) |
1736 | dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), | 1736 | dma_free_noncoherent(&dev->dev, |
1737 | PAGE_ALIGN(fbdev->fb_len), | ||
1737 | fbdev->fb_mem, fbdev->fb_phys); | 1738 | fbdev->fb_mem, fbdev->fb_phys); |
1738 | if (fbdev->fb_info.cmap.len != 0) | 1739 | if (fbdev->fb_info.cmap.len != 0) |
1739 | fb_dealloc_cmap(&fbdev->fb_info.cmap); | 1740 | fb_dealloc_cmap(&fbdev->fb_info.cmap); |
@@ -1747,22 +1748,24 @@ static int au1200fb_drv_remove(struct device *dev) | |||
1747 | } | 1748 | } |
1748 | 1749 | ||
1749 | #ifdef CONFIG_PM | 1750 | #ifdef CONFIG_PM |
1750 | static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level) | 1751 | static int au1200fb_drv_suspend(struct platform_device *dev, u32 state) |
1751 | { | 1752 | { |
1752 | /* TODO */ | 1753 | /* TODO */ |
1753 | return 0; | 1754 | return 0; |
1754 | } | 1755 | } |
1755 | 1756 | ||
1756 | static int au1200fb_drv_resume(struct device *dev, u32 level) | 1757 | static int au1200fb_drv_resume(struct platform_device *dev) |
1757 | { | 1758 | { |
1758 | /* TODO */ | 1759 | /* TODO */ |
1759 | return 0; | 1760 | return 0; |
1760 | } | 1761 | } |
1761 | #endif /* CONFIG_PM */ | 1762 | #endif /* CONFIG_PM */ |
1762 | 1763 | ||
1763 | static struct device_driver au1200fb_driver = { | 1764 | static struct platform_driver au1200fb_driver = { |
1764 | .name = "au1200-lcd", | 1765 | .driver = { |
1765 | .bus = &platform_bus_type, | 1766 | .name = "au1200-lcd", |
1767 | .owner = THIS_MODULE, | ||
1768 | }, | ||
1766 | .probe = au1200fb_drv_probe, | 1769 | .probe = au1200fb_drv_probe, |
1767 | .remove = au1200fb_drv_remove, | 1770 | .remove = au1200fb_drv_remove, |
1768 | #ifdef CONFIG_PM | 1771 | #ifdef CONFIG_PM |
@@ -1906,12 +1909,12 @@ static int __init au1200fb_init(void) | |||
1906 | printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n"); | 1909 | printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n"); |
1907 | #endif | 1910 | #endif |
1908 | 1911 | ||
1909 | return driver_register(&au1200fb_driver); | 1912 | return platform_driver_register(&au1200fb_driver); |
1910 | } | 1913 | } |
1911 | 1914 | ||
1912 | static void __exit au1200fb_cleanup(void) | 1915 | static void __exit au1200fb_cleanup(void) |
1913 | { | 1916 | { |
1914 | driver_unregister(&au1200fb_driver); | 1917 | platform_driver_unregister(&au1200fb_driver); |
1915 | } | 1918 | } |
1916 | 1919 | ||
1917 | module_init(au1200fb_init); | 1920 | module_init(au1200fb_init); |
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index 3a3f80f65219..0573ec685a57 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c | |||
@@ -151,7 +151,7 @@ static int __init pmagbafb_probe(struct device *dev) | |||
151 | 151 | ||
152 | info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev); | 152 | info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev); |
153 | if (!info) { | 153 | if (!info) { |
154 | printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id); | 154 | printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev)); |
155 | return -ENOMEM; | 155 | return -ENOMEM; |
156 | } | 156 | } |
157 | 157 | ||
@@ -160,7 +160,7 @@ static int __init pmagbafb_probe(struct device *dev) | |||
160 | 160 | ||
161 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { | 161 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { |
162 | printk(KERN_ERR "%s: Cannot allocate color map\n", | 162 | printk(KERN_ERR "%s: Cannot allocate color map\n", |
163 | dev->bus_id); | 163 | dev_name(dev)); |
164 | err = -ENOMEM; | 164 | err = -ENOMEM; |
165 | goto err_alloc; | 165 | goto err_alloc; |
166 | } | 166 | } |
@@ -173,8 +173,9 @@ static int __init pmagbafb_probe(struct device *dev) | |||
173 | /* Request the I/O MEM resource. */ | 173 | /* Request the I/O MEM resource. */ |
174 | start = tdev->resource.start; | 174 | start = tdev->resource.start; |
175 | len = tdev->resource.end - start + 1; | 175 | len = tdev->resource.end - start + 1; |
176 | if (!request_mem_region(start, len, dev->bus_id)) { | 176 | if (!request_mem_region(start, len, dev_name(dev))) { |
177 | printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id); | 177 | printk(KERN_ERR "%s: Cannot reserve FB region\n", |
178 | dev_name(dev)); | ||
178 | err = -EBUSY; | 179 | err = -EBUSY; |
179 | goto err_cmap; | 180 | goto err_cmap; |
180 | } | 181 | } |
@@ -183,7 +184,7 @@ static int __init pmagbafb_probe(struct device *dev) | |||
183 | info->fix.mmio_start = start; | 184 | info->fix.mmio_start = start; |
184 | par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); | 185 | par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); |
185 | if (!par->mmio) { | 186 | if (!par->mmio) { |
186 | printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id); | 187 | printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev)); |
187 | err = -ENOMEM; | 188 | err = -ENOMEM; |
188 | goto err_resource; | 189 | goto err_resource; |
189 | } | 190 | } |
@@ -194,7 +195,7 @@ static int __init pmagbafb_probe(struct device *dev) | |||
194 | info->screen_base = ioremap_nocache(info->fix.smem_start, | 195 | info->screen_base = ioremap_nocache(info->fix.smem_start, |
195 | info->fix.smem_len); | 196 | info->fix.smem_len); |
196 | if (!info->screen_base) { | 197 | if (!info->screen_base) { |
197 | printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id); | 198 | printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev)); |
198 | err = -ENOMEM; | 199 | err = -ENOMEM; |
199 | goto err_mmio_map; | 200 | goto err_mmio_map; |
200 | } | 201 | } |
@@ -205,14 +206,14 @@ static int __init pmagbafb_probe(struct device *dev) | |||
205 | err = register_framebuffer(info); | 206 | err = register_framebuffer(info); |
206 | if (err < 0) { | 207 | if (err < 0) { |
207 | printk(KERN_ERR "%s: Cannot register framebuffer\n", | 208 | printk(KERN_ERR "%s: Cannot register framebuffer\n", |
208 | dev->bus_id); | 209 | dev_name(dev)); |
209 | goto err_smem_map; | 210 | goto err_smem_map; |
210 | } | 211 | } |
211 | 212 | ||
212 | get_device(dev); | 213 | get_device(dev); |
213 | 214 | ||
214 | pr_info("fb%d: %s frame buffer device at %s\n", | 215 | pr_info("fb%d: %s frame buffer device at %s\n", |
215 | info->node, info->fix.id, dev->bus_id); | 216 | info->node, info->fix.id, dev_name(dev)); |
216 | 217 | ||
217 | return 0; | 218 | return 0; |
218 | 219 | ||
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 9b80597241b0..98748723af9f 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c | |||
@@ -258,7 +258,7 @@ static int __init pmagbbfb_probe(struct device *dev) | |||
258 | 258 | ||
259 | info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev); | 259 | info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev); |
260 | if (!info) { | 260 | if (!info) { |
261 | printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id); | 261 | printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev)); |
262 | return -ENOMEM; | 262 | return -ENOMEM; |
263 | } | 263 | } |
264 | 264 | ||
@@ -267,7 +267,7 @@ static int __init pmagbbfb_probe(struct device *dev) | |||
267 | 267 | ||
268 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { | 268 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { |
269 | printk(KERN_ERR "%s: Cannot allocate color map\n", | 269 | printk(KERN_ERR "%s: Cannot allocate color map\n", |
270 | dev->bus_id); | 270 | dev_name(dev)); |
271 | err = -ENOMEM; | 271 | err = -ENOMEM; |
272 | goto err_alloc; | 272 | goto err_alloc; |
273 | } | 273 | } |
@@ -280,8 +280,9 @@ static int __init pmagbbfb_probe(struct device *dev) | |||
280 | /* Request the I/O MEM resource. */ | 280 | /* Request the I/O MEM resource. */ |
281 | start = tdev->resource.start; | 281 | start = tdev->resource.start; |
282 | len = tdev->resource.end - start + 1; | 282 | len = tdev->resource.end - start + 1; |
283 | if (!request_mem_region(start, len, dev->bus_id)) { | 283 | if (!request_mem_region(start, len, dev_name(dev))) { |
284 | printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id); | 284 | printk(KERN_ERR "%s: Cannot reserve FB region\n", |
285 | dev_name(dev)); | ||
285 | err = -EBUSY; | 286 | err = -EBUSY; |
286 | goto err_cmap; | 287 | goto err_cmap; |
287 | } | 288 | } |
@@ -290,7 +291,7 @@ static int __init pmagbbfb_probe(struct device *dev) | |||
290 | info->fix.mmio_start = start; | 291 | info->fix.mmio_start = start; |
291 | par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); | 292 | par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); |
292 | if (!par->mmio) { | 293 | if (!par->mmio) { |
293 | printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id); | 294 | printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev)); |
294 | err = -ENOMEM; | 295 | err = -ENOMEM; |
295 | goto err_resource; | 296 | goto err_resource; |
296 | } | 297 | } |
@@ -301,7 +302,7 @@ static int __init pmagbbfb_probe(struct device *dev) | |||
301 | info->fix.smem_start = start + PMAGB_B_FBMEM; | 302 | info->fix.smem_start = start + PMAGB_B_FBMEM; |
302 | par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len); | 303 | par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len); |
303 | if (!par->smem) { | 304 | if (!par->smem) { |
304 | printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id); | 305 | printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev)); |
305 | err = -ENOMEM; | 306 | err = -ENOMEM; |
306 | goto err_mmio_map; | 307 | goto err_mmio_map; |
307 | } | 308 | } |
@@ -316,7 +317,7 @@ static int __init pmagbbfb_probe(struct device *dev) | |||
316 | err = register_framebuffer(info); | 317 | err = register_framebuffer(info); |
317 | if (err < 0) { | 318 | if (err < 0) { |
318 | printk(KERN_ERR "%s: Cannot register framebuffer\n", | 319 | printk(KERN_ERR "%s: Cannot register framebuffer\n", |
319 | dev->bus_id); | 320 | dev_name(dev)); |
320 | goto err_smem_map; | 321 | goto err_smem_map; |
321 | } | 322 | } |
322 | 323 | ||
@@ -328,7 +329,7 @@ static int __init pmagbbfb_probe(struct device *dev) | |||
328 | par->osc1 / 1000, par->osc1 % 1000); | 329 | par->osc1 / 1000, par->osc1 % 1000); |
329 | 330 | ||
330 | pr_info("fb%d: %s frame buffer device at %s\n", | 331 | pr_info("fb%d: %s frame buffer device at %s\n", |
331 | info->node, info->fix.id, dev->bus_id); | 332 | info->node, info->fix.id, dev_name(dev)); |
332 | pr_info("fb%d: Osc0: %s, Osc1: %s, Osc%u selected\n", | 333 | pr_info("fb%d: Osc0: %s, Osc1: %s, Osc%u selected\n", |
333 | info->node, freq0, par->osc1 ? freq1 : "disabled", | 334 | info->node, freq0, par->osc1 ? freq1 : "disabled", |
334 | par->osc1 != 0); | 335 | par->osc1 != 0); |
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 87f826e4c958..e00c1dff55de 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c | |||
@@ -1213,7 +1213,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
1213 | dev->core.driver_data = info; | 1213 | dev->core.driver_data = info; |
1214 | 1214 | ||
1215 | dev_info(info->device, "%s %s, using %u KiB of video memory\n", | 1215 | dev_info(info->device, "%s %s, using %u KiB of video memory\n", |
1216 | dev_driver_string(info->dev), info->dev->bus_id, | 1216 | dev_driver_string(info->dev), dev_name(info->dev), |
1217 | info->fix.smem_len >> 10); | 1217 | info->fix.smem_len >> 10); |
1218 | 1218 | ||
1219 | task = kthread_run(ps3fbd, info, DEVICE_NAME); | 1219 | task = kthread_run(ps3fbd, info, DEVICE_NAME); |
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index 0a0fd48a8566..53f8f1100e81 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c | |||
@@ -61,7 +61,7 @@ | |||
61 | #include <mach-dreamcast/mach/sysasic.h> | 61 | #include <mach-dreamcast/mach/sysasic.h> |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | #ifdef CONFIG_SH_DMA | 64 | #ifdef CONFIG_PVR2_DMA |
65 | #include <linux/pagemap.h> | 65 | #include <linux/pagemap.h> |
66 | #include <mach/dma.h> | 66 | #include <mach/dma.h> |
67 | #include <asm/dma.h> | 67 | #include <asm/dma.h> |
@@ -188,7 +188,7 @@ static unsigned int is_blanked = 0; /* Is the screen blanked? */ | |||
188 | static unsigned long pvr2fb_map; | 188 | static unsigned long pvr2fb_map; |
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | #ifdef CONFIG_SH_DMA | 191 | #ifdef CONFIG_PVR2_DMA |
192 | static unsigned int shdma = PVR2_CASCADE_CHAN; | 192 | static unsigned int shdma = PVR2_CASCADE_CHAN; |
193 | static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS; | 193 | static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS; |
194 | #endif | 194 | #endif |
@@ -207,7 +207,7 @@ static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id); | |||
207 | static int pvr2_init_cable(void); | 207 | static int pvr2_init_cable(void); |
208 | static int pvr2_get_param(const struct pvr2_params *p, const char *s, | 208 | static int pvr2_get_param(const struct pvr2_params *p, const char *s, |
209 | int val, int size); | 209 | int val, int size); |
210 | #ifdef CONFIG_SH_DMA | 210 | #ifdef CONFIG_PVR2_DMA |
211 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, | 211 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, |
212 | size_t count, loff_t *ppos); | 212 | size_t count, loff_t *ppos); |
213 | #endif | 213 | #endif |
@@ -218,7 +218,7 @@ static struct fb_ops pvr2fb_ops = { | |||
218 | .fb_blank = pvr2fb_blank, | 218 | .fb_blank = pvr2fb_blank, |
219 | .fb_check_var = pvr2fb_check_var, | 219 | .fb_check_var = pvr2fb_check_var, |
220 | .fb_set_par = pvr2fb_set_par, | 220 | .fb_set_par = pvr2fb_set_par, |
221 | #ifdef CONFIG_SH_DMA | 221 | #ifdef CONFIG_PVR2_DMA |
222 | .fb_write = pvr2fb_write, | 222 | .fb_write = pvr2fb_write, |
223 | #endif | 223 | #endif |
224 | .fb_fillrect = cfb_fillrect, | 224 | .fb_fillrect = cfb_fillrect, |
@@ -671,7 +671,7 @@ static int pvr2_init_cable(void) | |||
671 | return cable_type; | 671 | return cable_type; |
672 | } | 672 | } |
673 | 673 | ||
674 | #ifdef CONFIG_SH_DMA | 674 | #ifdef CONFIG_PVR2_DMA |
675 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, | 675 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, |
676 | size_t count, loff_t *ppos) | 676 | size_t count, loff_t *ppos) |
677 | { | 677 | { |
@@ -743,7 +743,7 @@ out_unmap: | |||
743 | 743 | ||
744 | return ret; | 744 | return ret; |
745 | } | 745 | } |
746 | #endif /* CONFIG_SH_DMA */ | 746 | #endif /* CONFIG_PVR2_DMA */ |
747 | 747 | ||
748 | /** | 748 | /** |
749 | * pvr2fb_common_init | 749 | * pvr2fb_common_init |
@@ -893,7 +893,7 @@ static int __init pvr2fb_dc_init(void) | |||
893 | return -EBUSY; | 893 | return -EBUSY; |
894 | } | 894 | } |
895 | 895 | ||
896 | #ifdef CONFIG_SH_DMA | 896 | #ifdef CONFIG_PVR2_DMA |
897 | if (request_dma(pvr2dma, "pvr2") != 0) { | 897 | if (request_dma(pvr2dma, "pvr2") != 0) { |
898 | free_irq(HW_EVENT_VSYNC, 0); | 898 | free_irq(HW_EVENT_VSYNC, 0); |
899 | return -EBUSY; | 899 | return -EBUSY; |
@@ -915,7 +915,7 @@ static void __exit pvr2fb_dc_exit(void) | |||
915 | } | 915 | } |
916 | 916 | ||
917 | free_irq(HW_EVENT_VSYNC, 0); | 917 | free_irq(HW_EVENT_VSYNC, 0); |
918 | #ifdef CONFIG_SH_DMA | 918 | #ifdef CONFIG_PVR2_DMA |
919 | free_dma(pvr2dma); | 919 | free_dma(pvr2dma); |
920 | #endif | 920 | #endif |
921 | } | 921 | } |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 2c5d069e5f06..92ea0ab44ce2 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -33,6 +33,8 @@ struct sh_mobile_lcdc_chan { | |||
33 | struct fb_info info; | 33 | struct fb_info info; |
34 | dma_addr_t dma_handle; | 34 | dma_addr_t dma_handle; |
35 | struct fb_deferred_io defio; | 35 | struct fb_deferred_io defio; |
36 | unsigned long frame_end; | ||
37 | wait_queue_head_t frame_end_wait; | ||
36 | }; | 38 | }; |
37 | 39 | ||
38 | struct sh_mobile_lcdc_priv { | 40 | struct sh_mobile_lcdc_priv { |
@@ -226,7 +228,10 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) | |||
226 | static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) | 228 | static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) |
227 | { | 229 | { |
228 | struct sh_mobile_lcdc_priv *priv = data; | 230 | struct sh_mobile_lcdc_priv *priv = data; |
231 | struct sh_mobile_lcdc_chan *ch; | ||
229 | unsigned long tmp; | 232 | unsigned long tmp; |
233 | int is_sub; | ||
234 | int k; | ||
230 | 235 | ||
231 | /* acknowledge interrupt */ | 236 | /* acknowledge interrupt */ |
232 | tmp = lcdc_read(priv, _LDINTR); | 237 | tmp = lcdc_read(priv, _LDINTR); |
@@ -234,8 +239,24 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) | |||
234 | tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */ | 239 | tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */ |
235 | lcdc_write(priv, _LDINTR, tmp); | 240 | lcdc_write(priv, _LDINTR, tmp); |
236 | 241 | ||
237 | /* disable clocks */ | 242 | /* figure out if this interrupt is for main or sub lcd */ |
238 | sh_mobile_lcdc_clk_off(priv); | 243 | is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0; |
244 | |||
245 | /* wake up channel and disable clocks*/ | ||
246 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | ||
247 | ch = &priv->ch[k]; | ||
248 | |||
249 | if (!ch->enabled) | ||
250 | continue; | ||
251 | |||
252 | if (is_sub == lcdc_chan_is_sublcd(ch)) { | ||
253 | ch->frame_end = 1; | ||
254 | wake_up(&ch->frame_end_wait); | ||
255 | |||
256 | sh_mobile_lcdc_clk_off(priv); | ||
257 | } | ||
258 | } | ||
259 | |||
239 | return IRQ_HANDLED; | 260 | return IRQ_HANDLED; |
240 | } | 261 | } |
241 | 262 | ||
@@ -448,18 +469,27 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
448 | struct sh_mobile_lcdc_board_cfg *board_cfg; | 469 | struct sh_mobile_lcdc_board_cfg *board_cfg; |
449 | int k; | 470 | int k; |
450 | 471 | ||
451 | /* tell the board code to disable the panel */ | 472 | /* clean up deferred io and ask board code to disable panel */ |
452 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | 473 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
453 | ch = &priv->ch[k]; | 474 | ch = &priv->ch[k]; |
454 | board_cfg = &ch->cfg.board_cfg; | ||
455 | if (board_cfg->display_off) | ||
456 | board_cfg->display_off(board_cfg->board_data); | ||
457 | 475 | ||
458 | /* cleanup deferred io if enabled */ | 476 | /* deferred io mode: |
477 | * flush frame, and wait for frame end interrupt | ||
478 | * clean up deferred io and enable clock | ||
479 | */ | ||
459 | if (ch->info.fbdefio) { | 480 | if (ch->info.fbdefio) { |
481 | ch->frame_end = 0; | ||
482 | schedule_delayed_work(&ch->info.deferred_work, 0); | ||
483 | wait_event(ch->frame_end_wait, ch->frame_end); | ||
460 | fb_deferred_io_cleanup(&ch->info); | 484 | fb_deferred_io_cleanup(&ch->info); |
461 | ch->info.fbdefio = NULL; | 485 | ch->info.fbdefio = NULL; |
486 | sh_mobile_lcdc_clk_on(priv); | ||
462 | } | 487 | } |
488 | |||
489 | board_cfg = &ch->cfg.board_cfg; | ||
490 | if (board_cfg->display_off) | ||
491 | board_cfg->display_off(board_cfg->board_data); | ||
492 | |||
463 | } | 493 | } |
464 | 494 | ||
465 | /* stop the lcdc */ | 495 | /* stop the lcdc */ |
@@ -652,6 +682,26 @@ static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) | |||
652 | return 0; | 682 | return 0; |
653 | } | 683 | } |
654 | 684 | ||
685 | static int sh_mobile_lcdc_suspend(struct device *dev) | ||
686 | { | ||
687 | struct platform_device *pdev = to_platform_device(dev); | ||
688 | |||
689 | sh_mobile_lcdc_stop(platform_get_drvdata(pdev)); | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static int sh_mobile_lcdc_resume(struct device *dev) | ||
694 | { | ||
695 | struct platform_device *pdev = to_platform_device(dev); | ||
696 | |||
697 | return sh_mobile_lcdc_start(platform_get_drvdata(pdev)); | ||
698 | } | ||
699 | |||
700 | static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { | ||
701 | .suspend = sh_mobile_lcdc_suspend, | ||
702 | .resume = sh_mobile_lcdc_resume, | ||
703 | }; | ||
704 | |||
655 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); | 705 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); |
656 | 706 | ||
657 | static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | 707 | static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) |
@@ -687,7 +737,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
687 | } | 737 | } |
688 | 738 | ||
689 | error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED, | 739 | error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED, |
690 | pdev->dev.bus_id, priv); | 740 | dev_name(&pdev->dev), priv); |
691 | if (error) { | 741 | if (error) { |
692 | dev_err(&pdev->dev, "unable to request irq\n"); | 742 | dev_err(&pdev->dev, "unable to request irq\n"); |
693 | goto err1; | 743 | goto err1; |
@@ -707,6 +757,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
707 | dev_err(&pdev->dev, "unsupported interface type\n"); | 757 | dev_err(&pdev->dev, "unsupported interface type\n"); |
708 | goto err1; | 758 | goto err1; |
709 | } | 759 | } |
760 | init_waitqueue_head(&priv->ch[i].frame_end_wait); | ||
710 | 761 | ||
711 | switch (pdata->ch[i].chan) { | 762 | switch (pdata->ch[i].chan) { |
712 | case LCDC_CHAN_MAINLCD: | 763 | case LCDC_CHAN_MAINLCD: |
@@ -860,6 +911,7 @@ static struct platform_driver sh_mobile_lcdc_driver = { | |||
860 | .driver = { | 911 | .driver = { |
861 | .name = "sh_mobile_lcdc_fb", | 912 | .name = "sh_mobile_lcdc_fb", |
862 | .owner = THIS_MODULE, | 913 | .owner = THIS_MODULE, |
914 | .pm = &sh_mobile_lcdc_dev_pm_ops, | ||
863 | }, | 915 | }, |
864 | .probe = sh_mobile_lcdc_probe, | 916 | .probe = sh_mobile_lcdc_probe, |
865 | .remove = sh_mobile_lcdc_remove, | 917 | .remove = sh_mobile_lcdc_remove, |
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c index 7baf2dd12d50..a1eb0862255b 100644 --- a/drivers/video/tmiofb.c +++ b/drivers/video/tmiofb.c | |||
@@ -751,7 +751,7 @@ static int __devinit tmiofb_probe(struct platform_device *dev) | |||
751 | } | 751 | } |
752 | 752 | ||
753 | retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED, | 753 | retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED, |
754 | dev->dev.bus_id, info); | 754 | dev_name(&dev->dev), info); |
755 | 755 | ||
756 | if (retval) | 756 | if (retval) |
757 | goto err_request_irq; | 757 | goto err_request_irq; |
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c index f1ae3729a19e..cce1982a1b58 100644 --- a/drivers/watchdog/rm9k_wdt.c +++ b/drivers/watchdog/rm9k_wdt.c | |||
@@ -59,8 +59,8 @@ static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); | |||
59 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); | 59 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); |
60 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, | 60 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, |
61 | const char *, unsigned int); | 61 | const char *, unsigned int); |
62 | static int __init wdt_gpi_probe(struct device *); | 62 | static int __init wdt_gpi_probe(struct platform_device *); |
63 | static int __exit wdt_gpi_remove(struct device *); | 63 | static int __exit wdt_gpi_remove(struct platform_device *); |
64 | 64 | ||
65 | 65 | ||
66 | static const char wdt_gpi_name[] = "wdt_gpi"; | 66 | static const char wdt_gpi_name[] = "wdt_gpi"; |
@@ -346,10 +346,9 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv, | |||
346 | } | 346 | } |
347 | 347 | ||
348 | /* No hotplugging on the platform bus - use __init */ | 348 | /* No hotplugging on the platform bus - use __init */ |
349 | static int __init wdt_gpi_probe(struct device *dev) | 349 | static int __init wdt_gpi_probe(struct platform_device *pdv) |
350 | { | 350 | { |
351 | int res; | 351 | int res; |
352 | struct platform_device * const pdv = to_platform_device(dev); | ||
353 | const struct resource | 352 | const struct resource |
354 | * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS, | 353 | * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS, |
355 | IORESOURCE_MEM), | 354 | IORESOURCE_MEM), |
@@ -374,7 +373,7 @@ static int __init wdt_gpi_probe(struct device *dev) | |||
374 | return res; | 373 | return res; |
375 | } | 374 | } |
376 | 375 | ||
377 | static int __exit wdt_gpi_remove(struct device *dev) | 376 | static int __exit wdt_gpi_remove(struct platform_device *dev) |
378 | { | 377 | { |
379 | int res; | 378 | int res; |
380 | 379 | ||
@@ -387,15 +386,13 @@ static int __exit wdt_gpi_remove(struct device *dev) | |||
387 | 386 | ||
388 | 387 | ||
389 | /* Device driver init & exit */ | 388 | /* Device driver init & exit */ |
390 | static struct device_driver wdt_gpi_driver = { | 389 | static struct platform_driver wgt_gpi_driver = { |
391 | .name = (char *) wdt_gpi_name, | 390 | .driver = { |
392 | .bus = &platform_bus_type, | 391 | .name = wdt_gpi_name, |
393 | .owner = THIS_MODULE, | 392 | .owner = THIS_MODULE, |
393 | }, | ||
394 | .probe = wdt_gpi_probe, | 394 | .probe = wdt_gpi_probe, |
395 | .remove = __exit_p(wdt_gpi_remove), | 395 | .remove = __devexit_p(wdt_gpi_remove), |
396 | .shutdown = NULL, | ||
397 | .suspend = NULL, | ||
398 | .resume = NULL, | ||
399 | }; | 396 | }; |
400 | 397 | ||
401 | static int __init wdt_gpi_init_module(void) | 398 | static int __init wdt_gpi_init_module(void) |
@@ -403,12 +400,12 @@ static int __init wdt_gpi_init_module(void) | |||
403 | atomic_set(&opencnt, 1); | 400 | atomic_set(&opencnt, 1); |
404 | if (timeout > MAX_TIMEOUT_SECONDS) | 401 | if (timeout > MAX_TIMEOUT_SECONDS) |
405 | timeout = MAX_TIMEOUT_SECONDS; | 402 | timeout = MAX_TIMEOUT_SECONDS; |
406 | return driver_register(&wdt_gpi_driver); | 403 | return platform_driver_register(&wdt_gpi_driver); |
407 | } | 404 | } |
408 | 405 | ||
409 | static void __exit wdt_gpi_cleanup_module(void) | 406 | static void __exit wdt_gpi_cleanup_module(void) |
410 | { | 407 | { |
411 | driver_unregister(&wdt_gpi_driver); | 408 | platform_driver_unregister(&wdt_gpi_driver); |
412 | } | 409 | } |
413 | 410 | ||
414 | module_init(wdt_gpi_init_module); | 411 | module_init(wdt_gpi_init_module); |
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index a1585d6f6486..d45fb34e2d23 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c | |||
@@ -140,7 +140,7 @@ static int __init zorro_init(void) | |||
140 | 140 | ||
141 | /* Initialize the Zorro bus */ | 141 | /* Initialize the Zorro bus */ |
142 | INIT_LIST_HEAD(&zorro_bus.devices); | 142 | INIT_LIST_HEAD(&zorro_bus.devices); |
143 | strcpy(zorro_bus.dev.bus_id, "zorro"); | 143 | dev_set_name(&zorro_bus.dev, "zorro"); |
144 | error = device_register(&zorro_bus.dev); | 144 | error = device_register(&zorro_bus.dev); |
145 | if (error) { | 145 | if (error) { |
146 | pr_err("Zorro: Error registering zorro_bus\n"); | 146 | pr_err("Zorro: Error registering zorro_bus\n"); |
@@ -167,7 +167,7 @@ static int __init zorro_init(void) | |||
167 | if (request_resource(zorro_find_parent_resource(z), &z->resource)) | 167 | if (request_resource(zorro_find_parent_resource(z), &z->resource)) |
168 | pr_err("Zorro: Address space collision on device %s %pR\n", | 168 | pr_err("Zorro: Address space collision on device %s %pR\n", |
169 | z->name, &z->resource); | 169 | z->name, &z->resource); |
170 | sprintf(z->dev.bus_id, "%02x", i); | 170 | dev_set_name(&z->dev, "%02x", i); |
171 | z->dev.parent = &zorro_bus.dev; | 171 | z->dev.parent = &zorro_bus.dev; |
172 | z->dev.bus = &zorro_bus_type; | 172 | z->dev.bus = &zorro_bus_type; |
173 | error = device_register(&z->dev); | 173 | error = device_register(&z->dev); |