diff options
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r-- | drivers/firewire/ohci.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index ebb897329c1..fd7170a9ad2 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -253,7 +253,6 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
253 | #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 | 253 | #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 |
254 | 254 | ||
255 | #define OHCI1394_REGISTER_SIZE 0x800 | 255 | #define OHCI1394_REGISTER_SIZE 0x800 |
256 | #define OHCI_LOOP_COUNT 500 | ||
257 | #define OHCI1394_PCI_HCI_Control 0x40 | 256 | #define OHCI1394_PCI_HCI_Control 0x40 |
258 | #define SELF_ID_BUF_SIZE 0x800 | 257 | #define SELF_ID_BUF_SIZE 0x800 |
259 | #define OHCI_TCODE_PHY_PACKET 0x0e | 258 | #define OHCI_TCODE_PHY_PACKET 0x0e |
@@ -291,6 +290,9 @@ static const struct { | |||
291 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID, | 290 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID, |
292 | QUIRK_CYCLE_TIMER}, | 291 | QUIRK_CYCLE_TIMER}, |
293 | 292 | ||
293 | {PCI_VENDOR_ID_O2, PCI_ANY_ID, PCI_ANY_ID, | ||
294 | QUIRK_NO_MSI}, | ||
295 | |||
294 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, | 296 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, |
295 | QUIRK_CYCLE_TIMER}, | 297 | QUIRK_CYCLE_TIMER}, |
296 | 298 | ||
@@ -514,6 +516,12 @@ static inline void flush_writes(const struct fw_ohci *ohci) | |||
514 | reg_read(ohci, OHCI1394_Version); | 516 | reg_read(ohci, OHCI1394_Version); |
515 | } | 517 | } |
516 | 518 | ||
519 | /* | ||
520 | * Beware! read_phy_reg(), write_phy_reg(), update_phy_reg(), and | ||
521 | * read_paged_phy_reg() require the caller to hold ohci->phy_reg_mutex. | ||
522 | * In other words, only use ohci_read_phy_reg() and ohci_update_phy_reg() | ||
523 | * directly. Exceptions are intrinsically serialized contexts like pci_probe. | ||
524 | */ | ||
517 | static int read_phy_reg(struct fw_ohci *ohci, int addr) | 525 | static int read_phy_reg(struct fw_ohci *ohci, int addr) |
518 | { | 526 | { |
519 | u32 val; | 527 | u32 val; |
@@ -522,6 +530,9 @@ static int read_phy_reg(struct fw_ohci *ohci, int addr) | |||
522 | reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); | 530 | reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); |
523 | for (i = 0; i < 3 + 100; i++) { | 531 | for (i = 0; i < 3 + 100; i++) { |
524 | val = reg_read(ohci, OHCI1394_PhyControl); | 532 | val = reg_read(ohci, OHCI1394_PhyControl); |
533 | if (!~val) | ||
534 | return -ENODEV; /* Card was ejected. */ | ||
535 | |||
525 | if (val & OHCI1394_PhyControl_ReadDone) | 536 | if (val & OHCI1394_PhyControl_ReadDone) |
526 | return OHCI1394_PhyControl_ReadData(val); | 537 | return OHCI1394_PhyControl_ReadData(val); |
527 | 538 | ||
@@ -545,6 +556,9 @@ static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val) | |||
545 | OHCI1394_PhyControl_Write(addr, val)); | 556 | OHCI1394_PhyControl_Write(addr, val)); |
546 | for (i = 0; i < 3 + 100; i++) { | 557 | for (i = 0; i < 3 + 100; i++) { |
547 | val = reg_read(ohci, OHCI1394_PhyControl); | 558 | val = reg_read(ohci, OHCI1394_PhyControl); |
559 | if (!~val) | ||
560 | return -ENODEV; /* Card was ejected. */ | ||
561 | |||
548 | if (!(val & OHCI1394_PhyControl_WritePending)) | 562 | if (!(val & OHCI1394_PhyControl_WritePending)) |
549 | return 0; | 563 | return 0; |
550 | 564 | ||
@@ -630,7 +644,6 @@ static void ar_context_link_page(struct ar_context *ctx, unsigned int index) | |||
630 | ctx->last_buffer_index = index; | 644 | ctx->last_buffer_index = index; |
631 | 645 | ||
632 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); | 646 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); |
633 | flush_writes(ctx->ohci); | ||
634 | } | 647 | } |
635 | 648 | ||
636 | static void ar_context_release(struct ar_context *ctx) | 649 | static void ar_context_release(struct ar_context *ctx) |
@@ -1002,7 +1015,6 @@ static void ar_context_run(struct ar_context *ctx) | |||
1002 | 1015 | ||
1003 | reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ctx->descriptors_bus | 1); | 1016 | reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ctx->descriptors_bus | 1); |
1004 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); | 1017 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); |
1005 | flush_writes(ctx->ohci); | ||
1006 | } | 1018 | } |
1007 | 1019 | ||
1008 | static struct descriptor *find_branch_descriptor(struct descriptor *d, int z) | 1020 | static struct descriptor *find_branch_descriptor(struct descriptor *d, int z) |
@@ -1202,14 +1214,14 @@ static void context_stop(struct context *ctx) | |||
1202 | 1214 | ||
1203 | reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); | 1215 | reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); |
1204 | ctx->running = false; | 1216 | ctx->running = false; |
1205 | flush_writes(ctx->ohci); | ||
1206 | 1217 | ||
1207 | for (i = 0; i < 10; i++) { | 1218 | for (i = 0; i < 1000; i++) { |
1208 | reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs)); | 1219 | reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs)); |
1209 | if ((reg & CONTEXT_ACTIVE) == 0) | 1220 | if ((reg & CONTEXT_ACTIVE) == 0) |
1210 | return; | 1221 | return; |
1211 | 1222 | ||
1212 | mdelay(1); | 1223 | if (i) |
1224 | udelay(10); | ||
1213 | } | 1225 | } |
1214 | fw_error("Error: DMA context still active (0x%08x)\n", reg); | 1226 | fw_error("Error: DMA context still active (0x%08x)\n", reg); |
1215 | } | 1227 | } |
@@ -1346,12 +1358,10 @@ static int at_context_queue_packet(struct context *ctx, | |||
1346 | 1358 | ||
1347 | context_append(ctx, d, z, 4 - z); | 1359 | context_append(ctx, d, z, 4 - z); |
1348 | 1360 | ||
1349 | if (ctx->running) { | 1361 | if (ctx->running) |
1350 | reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); | 1362 | reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); |
1351 | flush_writes(ohci); | 1363 | else |
1352 | } else { | ||
1353 | context_run(ctx, 0); | 1364 | context_run(ctx, 0); |
1354 | } | ||
1355 | 1365 | ||
1356 | return 0; | 1366 | return 0; |
1357 | } | 1367 | } |
@@ -1960,14 +1970,18 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
1960 | 1970 | ||
1961 | static int software_reset(struct fw_ohci *ohci) | 1971 | static int software_reset(struct fw_ohci *ohci) |
1962 | { | 1972 | { |
1973 | u32 val; | ||
1963 | int i; | 1974 | int i; |
1964 | 1975 | ||
1965 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); | 1976 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); |
1977 | for (i = 0; i < 500; i++) { | ||
1978 | val = reg_read(ohci, OHCI1394_HCControlSet); | ||
1979 | if (!~val) | ||
1980 | return -ENODEV; /* Card was ejected. */ | ||
1966 | 1981 | ||
1967 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | 1982 | if (!(val & OHCI1394_HCControl_softReset)) |
1968 | if ((reg_read(ohci, OHCI1394_HCControlSet) & | ||
1969 | OHCI1394_HCControl_softReset) == 0) | ||
1970 | return 0; | 1983 | return 0; |
1984 | |||
1971 | msleep(1); | 1985 | msleep(1); |
1972 | } | 1986 | } |
1973 | 1987 | ||
@@ -2168,8 +2182,13 @@ static int ohci_enable(struct fw_card *card, | |||
2168 | ohci_driver_name, ohci)) { | 2182 | ohci_driver_name, ohci)) { |
2169 | fw_error("Failed to allocate interrupt %d.\n", dev->irq); | 2183 | fw_error("Failed to allocate interrupt %d.\n", dev->irq); |
2170 | pci_disable_msi(dev); | 2184 | pci_disable_msi(dev); |
2171 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | 2185 | |
2172 | ohci->config_rom, ohci->config_rom_bus); | 2186 | if (config_rom) { |
2187 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | ||
2188 | ohci->next_config_rom, | ||
2189 | ohci->next_config_rom_bus); | ||
2190 | ohci->next_config_rom = NULL; | ||
2191 | } | ||
2173 | return -EIO; | 2192 | return -EIO; |
2174 | } | 2193 | } |
2175 | 2194 | ||
@@ -2197,7 +2216,9 @@ static int ohci_enable(struct fw_card *card, | |||
2197 | OHCI1394_LinkControl_rcvPhyPkt); | 2216 | OHCI1394_LinkControl_rcvPhyPkt); |
2198 | 2217 | ||
2199 | ar_context_run(&ohci->ar_request_ctx); | 2218 | ar_context_run(&ohci->ar_request_ctx); |
2200 | ar_context_run(&ohci->ar_response_ctx); /* also flushes writes */ | 2219 | ar_context_run(&ohci->ar_response_ctx); |
2220 | |||
2221 | flush_writes(ohci); | ||
2201 | 2222 | ||
2202 | /* We are ready to go, reset bus to finish initialization. */ | 2223 | /* We are ready to go, reset bus to finish initialization. */ |
2203 | fw_schedule_bus_reset(&ohci->card, false, true); | 2224 | fw_schedule_bus_reset(&ohci->card, false, true); |
@@ -3129,7 +3150,6 @@ static void ohci_flush_queue_iso(struct fw_iso_context *base) | |||
3129 | &container_of(base, struct iso_context, base)->context; | 3150 | &container_of(base, struct iso_context, base)->context; |
3130 | 3151 | ||
3131 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); | 3152 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); |
3132 | flush_writes(ctx->ohci); | ||
3133 | } | 3153 | } |
3134 | 3154 | ||
3135 | static const struct fw_card_driver ohci_driver = { | 3155 | static const struct fw_card_driver ohci_driver = { |