diff options
33 files changed, 745 insertions, 883 deletions
diff --git a/Documentation/ABI/removed/raw1394_legacy_isochronous b/Documentation/ABI/removed/raw1394_legacy_isochronous new file mode 100644 index 000000000000..1b629622d883 --- /dev/null +++ b/Documentation/ABI/removed/raw1394_legacy_isochronous | |||
@@ -0,0 +1,16 @@ | |||
1 | What: legacy isochronous ABI of raw1394 (1st generation iso ABI) | ||
2 | Date: June 2007 (scheduled), removed in kernel v2.6.23 | ||
3 | Contact: linux1394-devel@lists.sourceforge.net | ||
4 | Description: | ||
5 | The two request types RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN have | ||
6 | been deprecated for quite some time. They are very inefficient as they | ||
7 | come with high interrupt load and several layers of callbacks for each | ||
8 | packet. Because of these deficiencies, the video1394 and dv1394 drivers | ||
9 | and the 3rd-generation isochronous ABI in raw1394 (rawiso) were created. | ||
10 | |||
11 | Users: | ||
12 | libraw1394 users via the long deprecated API raw1394_iso_write, | ||
13 | raw1394_start_iso_write, raw1394_start_iso_rcv, raw1394_stop_iso_rcv | ||
14 | |||
15 | libdc1394, which optionally uses these old libraw1394 calls | ||
16 | alternatively to the more efficient video1394 ABI | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 7d3f205b0ba5..51b369e7fc70 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -49,16 +49,6 @@ Who: Adrian Bunk <bunk@stusta.de> | |||
49 | 49 | ||
50 | --------------------------- | 50 | --------------------------- |
51 | 51 | ||
52 | What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN | ||
53 | When: June 2007 | ||
54 | Why: Deprecated in favour of the more efficient and robust rawiso interface. | ||
55 | Affected are applications which use the deprecated part of libraw1394 | ||
56 | (raw1394_iso_write, raw1394_start_iso_write, raw1394_start_iso_rcv, | ||
57 | raw1394_stop_iso_rcv) or bypass libraw1394. | ||
58 | Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de> | ||
59 | |||
60 | --------------------------- | ||
61 | |||
62 | What: old NCR53C9x driver | 52 | What: old NCR53C9x driver |
63 | When: October 2007 | 53 | When: October 2007 |
64 | Why: Replaced by the much better esp_scsi driver. Actual low-level | 54 | Why: Replaced by the much better esp_scsi driver. Actual low-level |
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 9eb1edacd825..0aeab3218bb6 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c | |||
@@ -336,8 +336,11 @@ fw_card_bm_work(struct work_struct *work) | |||
336 | } | 336 | } |
337 | 337 | ||
338 | pick_me: | 338 | pick_me: |
339 | /* Now figure out what gap count to set. */ | 339 | /* |
340 | if (card->topology_type == FW_TOPOLOGY_A && | 340 | * Pick a gap count from 1394a table E-1. The table doesn't cover |
341 | * the typically much larger 1394b beta repeater delays though. | ||
342 | */ | ||
343 | if (!card->beta_repeaters_present && | ||
341 | card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) | 344 | card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) |
342 | gap_count = gap_count_table[card->root_node->max_hops]; | 345 | gap_count = gap_count_table[card->root_node->max_hops]; |
343 | else | 346 | else |
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index dbb76427d529..75388641a7d3 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c | |||
@@ -397,7 +397,7 @@ static int ioctl_send_request(struct client *client, void *buffer) | |||
397 | request->tcode & 0x1f, | 397 | request->tcode & 0x1f, |
398 | device->node->node_id, | 398 | device->node->node_id, |
399 | request->generation, | 399 | request->generation, |
400 | device->node->max_speed, | 400 | device->max_speed, |
401 | request->offset, | 401 | request->offset, |
402 | response->response.data, request->length, | 402 | response->response.data, request->length, |
403 | complete_transaction, response); | 403 | complete_transaction, response); |
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index c1ce465d9710..2b6586341635 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -401,8 +401,7 @@ static int read_rom(struct fw_device *device, int index, u32 * data) | |||
401 | 401 | ||
402 | offset = 0xfffff0000400ULL + index * 4; | 402 | offset = 0xfffff0000400ULL + index * 4; |
403 | fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, | 403 | fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, |
404 | device->node_id, | 404 | device->node_id, device->generation, device->max_speed, |
405 | device->generation, SCODE_100, | ||
406 | offset, NULL, 4, complete_transaction, &callback_data); | 405 | offset, NULL, 4, complete_transaction, &callback_data); |
407 | 406 | ||
408 | wait_for_completion(&callback_data.done); | 407 | wait_for_completion(&callback_data.done); |
@@ -418,6 +417,8 @@ static int read_bus_info_block(struct fw_device *device) | |||
418 | u32 stack[16], sp, key; | 417 | u32 stack[16], sp, key; |
419 | int i, end, length; | 418 | int i, end, length; |
420 | 419 | ||
420 | device->max_speed = SCODE_100; | ||
421 | |||
421 | /* First read the bus info block. */ | 422 | /* First read the bus info block. */ |
422 | for (i = 0; i < 5; i++) { | 423 | for (i = 0; i < 5; i++) { |
423 | if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) | 424 | if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) |
@@ -434,6 +435,33 @@ static int read_bus_info_block(struct fw_device *device) | |||
434 | return -1; | 435 | return -1; |
435 | } | 436 | } |
436 | 437 | ||
438 | device->max_speed = device->node->max_speed; | ||
439 | |||
440 | /* | ||
441 | * Determine the speed of | ||
442 | * - devices with link speed less than PHY speed, | ||
443 | * - devices with 1394b PHY (unless only connected to 1394a PHYs), | ||
444 | * - all devices if there are 1394b repeaters. | ||
445 | * Note, we cannot use the bus info block's link_spd as starting point | ||
446 | * because some buggy firmwares set it lower than necessary and because | ||
447 | * 1394-1995 nodes do not have the field. | ||
448 | */ | ||
449 | if ((rom[2] & 0x7) < device->max_speed || | ||
450 | device->max_speed == SCODE_BETA || | ||
451 | device->card->beta_repeaters_present) { | ||
452 | u32 dummy; | ||
453 | |||
454 | /* for S1600 and S3200 */ | ||
455 | if (device->max_speed == SCODE_BETA) | ||
456 | device->max_speed = device->card->link_speed; | ||
457 | |||
458 | while (device->max_speed > SCODE_100) { | ||
459 | if (read_rom(device, 0, &dummy) == RCODE_COMPLETE) | ||
460 | break; | ||
461 | device->max_speed--; | ||
462 | } | ||
463 | } | ||
464 | |||
437 | /* | 465 | /* |
438 | * Now parse the config rom. The config rom is a recursive | 466 | * Now parse the config rom. The config rom is a recursive |
439 | * directory structure so we parse it using a stack of | 467 | * directory structure so we parse it using a stack of |
@@ -680,8 +708,10 @@ static void fw_device_init(struct work_struct *work) | |||
680 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) | 708 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) |
681 | fw_device_shutdown(&device->work.work); | 709 | fw_device_shutdown(&device->work.work); |
682 | else | 710 | else |
683 | fw_notify("created new fw device %s (%d config rom retries)\n", | 711 | fw_notify("created new fw device %s " |
684 | device->device.bus_id, device->config_rom_retries); | 712 | "(%d config rom retries, S%d00)\n", |
713 | device->device.bus_id, device->config_rom_retries, | ||
714 | 1 << device->max_speed); | ||
685 | 715 | ||
686 | /* | 716 | /* |
687 | * Reschedule the IRM work if we just finished reading the | 717 | * Reschedule the IRM work if we just finished reading the |
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index af1723eae4ba..d13e6a69707f 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h | |||
@@ -40,6 +40,7 @@ struct fw_device { | |||
40 | struct fw_node *node; | 40 | struct fw_node *node; |
41 | int node_id; | 41 | int node_id; |
42 | int generation; | 42 | int generation; |
43 | unsigned max_speed; | ||
43 | struct fw_card *card; | 44 | struct fw_card *card; |
44 | struct device device; | 45 | struct device device; |
45 | struct list_head link; | 46 | struct list_head link; |
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 96c8ac5b86cc..41476abc0693 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -1934,12 +1934,12 @@ static int pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1934 | free_irq(pdev->irq, ohci); | 1934 | free_irq(pdev->irq, ohci); |
1935 | err = pci_save_state(pdev); | 1935 | err = pci_save_state(pdev); |
1936 | if (err) { | 1936 | if (err) { |
1937 | fw_error("pci_save_state failed with %d", err); | 1937 | fw_error("pci_save_state failed\n"); |
1938 | return err; | 1938 | return err; |
1939 | } | 1939 | } |
1940 | err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 1940 | err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
1941 | if (err) { | 1941 | if (err) { |
1942 | fw_error("pci_set_power_state failed with %d", err); | 1942 | fw_error("pci_set_power_state failed\n"); |
1943 | return err; | 1943 | return err; |
1944 | } | 1944 | } |
1945 | 1945 | ||
@@ -1955,7 +1955,7 @@ static int pci_resume(struct pci_dev *pdev) | |||
1955 | pci_restore_state(pdev); | 1955 | pci_restore_state(pdev); |
1956 | err = pci_enable_device(pdev); | 1956 | err = pci_enable_device(pdev); |
1957 | if (err) { | 1957 | if (err) { |
1958 | fw_error("pci_enable_device failed with %d", err); | 1958 | fw_error("pci_enable_device failed\n"); |
1959 | return err; | 1959 | return err; |
1960 | } | 1960 | } |
1961 | 1961 | ||
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index a98d3915e26f..7c53be0387fb 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
@@ -30,10 +30,13 @@ | |||
30 | 30 | ||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/moduleparam.h> | ||
33 | #include <linux/mod_devicetable.h> | 34 | #include <linux/mod_devicetable.h> |
34 | #include <linux/device.h> | 35 | #include <linux/device.h> |
35 | #include <linux/scatterlist.h> | 36 | #include <linux/scatterlist.h> |
36 | #include <linux/dma-mapping.h> | 37 | #include <linux/dma-mapping.h> |
38 | #include <linux/blkdev.h> | ||
39 | #include <linux/string.h> | ||
37 | #include <linux/timer.h> | 40 | #include <linux/timer.h> |
38 | 41 | ||
39 | #include <scsi/scsi.h> | 42 | #include <scsi/scsi.h> |
@@ -46,6 +49,18 @@ | |||
46 | #include "fw-topology.h" | 49 | #include "fw-topology.h" |
47 | #include "fw-device.h" | 50 | #include "fw-device.h" |
48 | 51 | ||
52 | /* | ||
53 | * So far only bridges from Oxford Semiconductor are known to support | ||
54 | * concurrent logins. Depending on firmware, four or two concurrent logins | ||
55 | * are possible on OXFW911 and newer Oxsemi bridges. | ||
56 | * | ||
57 | * Concurrent logins are useful together with cluster filesystems. | ||
58 | */ | ||
59 | static int sbp2_param_exclusive_login = 1; | ||
60 | module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644); | ||
61 | MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " | ||
62 | "(default = Y, use N for concurrent initiators)"); | ||
63 | |||
49 | /* I don't know why the SCSI stack doesn't define something like this... */ | 64 | /* I don't know why the SCSI stack doesn't define something like this... */ |
50 | typedef void (*scsi_done_fn_t)(struct scsi_cmnd *); | 65 | typedef void (*scsi_done_fn_t)(struct scsi_cmnd *); |
51 | 66 | ||
@@ -154,7 +169,7 @@ struct sbp2_orb { | |||
154 | #define MANAGEMENT_ORB_LUN(v) ((v)) | 169 | #define MANAGEMENT_ORB_LUN(v) ((v)) |
155 | #define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16) | 170 | #define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16) |
156 | #define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20) | 171 | #define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20) |
157 | #define MANAGEMENT_ORB_EXCLUSIVE ((1) << 28) | 172 | #define MANAGEMENT_ORB_EXCLUSIVE(v) ((v) ? 1 << 28 : 0) |
158 | #define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29) | 173 | #define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29) |
159 | #define MANAGEMENT_ORB_NOTIFY ((1) << 31) | 174 | #define MANAGEMENT_ORB_NOTIFY ((1) << 31) |
160 | 175 | ||
@@ -205,9 +220,8 @@ struct sbp2_command_orb { | |||
205 | scsi_done_fn_t done; | 220 | scsi_done_fn_t done; |
206 | struct fw_unit *unit; | 221 | struct fw_unit *unit; |
207 | 222 | ||
208 | struct sbp2_pointer page_table[SG_ALL]; | 223 | struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8))); |
209 | dma_addr_t page_table_bus; | 224 | dma_addr_t page_table_bus; |
210 | dma_addr_t request_buffer_bus; | ||
211 | }; | 225 | }; |
212 | 226 | ||
213 | /* | 227 | /* |
@@ -347,8 +361,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit, | |||
347 | spin_unlock_irqrestore(&device->card->lock, flags); | 361 | spin_unlock_irqrestore(&device->card->lock, flags); |
348 | 362 | ||
349 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, | 363 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, |
350 | node_id, generation, | 364 | node_id, generation, device->max_speed, offset, |
351 | device->node->max_speed, offset, | ||
352 | &orb->pointer, sizeof(orb->pointer), | 365 | &orb->pointer, sizeof(orb->pointer), |
353 | complete_transaction, orb); | 366 | complete_transaction, orb); |
354 | } | 367 | } |
@@ -383,7 +396,7 @@ static void | |||
383 | complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) | 396 | complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) |
384 | { | 397 | { |
385 | struct sbp2_management_orb *orb = | 398 | struct sbp2_management_orb *orb = |
386 | (struct sbp2_management_orb *)base_orb; | 399 | container_of(base_orb, struct sbp2_management_orb, base); |
387 | 400 | ||
388 | if (status) | 401 | if (status) |
389 | memcpy(&orb->status, status, sizeof(*status)); | 402 | memcpy(&orb->status, status, sizeof(*status)); |
@@ -403,21 +416,11 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, | |||
403 | if (orb == NULL) | 416 | if (orb == NULL) |
404 | return -ENOMEM; | 417 | return -ENOMEM; |
405 | 418 | ||
406 | /* | ||
407 | * The sbp2 device is going to send a block read request to | ||
408 | * read out the request from host memory, so map it for dma. | ||
409 | */ | ||
410 | orb->base.request_bus = | ||
411 | dma_map_single(device->card->device, &orb->request, | ||
412 | sizeof(orb->request), DMA_TO_DEVICE); | ||
413 | if (dma_mapping_error(orb->base.request_bus)) | ||
414 | goto out; | ||
415 | |||
416 | orb->response_bus = | 419 | orb->response_bus = |
417 | dma_map_single(device->card->device, &orb->response, | 420 | dma_map_single(device->card->device, &orb->response, |
418 | sizeof(orb->response), DMA_FROM_DEVICE); | 421 | sizeof(orb->response), DMA_FROM_DEVICE); |
419 | if (dma_mapping_error(orb->response_bus)) | 422 | if (dma_mapping_error(orb->response_bus)) |
420 | goto out; | 423 | goto fail_mapping_response; |
421 | 424 | ||
422 | orb->request.response.high = 0; | 425 | orb->request.response.high = 0; |
423 | orb->request.response.low = orb->response_bus; | 426 | orb->request.response.low = orb->response_bus; |
@@ -432,14 +435,9 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, | |||
432 | orb->request.status_fifo.high = sd->address_handler.offset >> 32; | 435 | orb->request.status_fifo.high = sd->address_handler.offset >> 32; |
433 | orb->request.status_fifo.low = sd->address_handler.offset; | 436 | orb->request.status_fifo.low = sd->address_handler.offset; |
434 | 437 | ||
435 | /* | ||
436 | * FIXME: Yeah, ok this isn't elegant, we hardwire exclusive | ||
437 | * login and 1 second reconnect time. The reconnect setting | ||
438 | * is probably fine, but the exclusive login should be an option. | ||
439 | */ | ||
440 | if (function == SBP2_LOGIN_REQUEST) { | 438 | if (function == SBP2_LOGIN_REQUEST) { |
441 | orb->request.misc |= | 439 | orb->request.misc |= |
442 | MANAGEMENT_ORB_EXCLUSIVE | | 440 | MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login) | |
443 | MANAGEMENT_ORB_RECONNECT(0); | 441 | MANAGEMENT_ORB_RECONNECT(0); |
444 | } | 442 | } |
445 | 443 | ||
@@ -448,6 +446,12 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, | |||
448 | init_completion(&orb->done); | 446 | init_completion(&orb->done); |
449 | orb->base.callback = complete_management_orb; | 447 | orb->base.callback = complete_management_orb; |
450 | 448 | ||
449 | orb->base.request_bus = | ||
450 | dma_map_single(device->card->device, &orb->request, | ||
451 | sizeof(orb->request), DMA_TO_DEVICE); | ||
452 | if (dma_mapping_error(orb->base.request_bus)) | ||
453 | goto fail_mapping_request; | ||
454 | |||
451 | sbp2_send_orb(&orb->base, unit, | 455 | sbp2_send_orb(&orb->base, unit, |
452 | node_id, generation, sd->management_agent_address); | 456 | node_id, generation, sd->management_agent_address); |
453 | 457 | ||
@@ -479,9 +483,10 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, | |||
479 | out: | 483 | out: |
480 | dma_unmap_single(device->card->device, orb->base.request_bus, | 484 | dma_unmap_single(device->card->device, orb->base.request_bus, |
481 | sizeof(orb->request), DMA_TO_DEVICE); | 485 | sizeof(orb->request), DMA_TO_DEVICE); |
486 | fail_mapping_request: | ||
482 | dma_unmap_single(device->card->device, orb->response_bus, | 487 | dma_unmap_single(device->card->device, orb->response_bus, |
483 | sizeof(orb->response), DMA_FROM_DEVICE); | 488 | sizeof(orb->response), DMA_FROM_DEVICE); |
484 | 489 | fail_mapping_response: | |
485 | if (response) | 490 | if (response) |
486 | fw_memcpy_from_be32(response, | 491 | fw_memcpy_from_be32(response, |
487 | orb->response, sizeof(orb->response)); | 492 | orb->response, sizeof(orb->response)); |
@@ -511,7 +516,7 @@ static int sbp2_agent_reset(struct fw_unit *unit) | |||
511 | return -ENOMEM; | 516 | return -ENOMEM; |
512 | 517 | ||
513 | fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, | 518 | fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, |
514 | sd->node_id, sd->generation, SCODE_400, | 519 | sd->node_id, sd->generation, device->max_speed, |
515 | sd->command_block_agent_address + SBP2_AGENT_RESET, | 520 | sd->command_block_agent_address + SBP2_AGENT_RESET, |
516 | &zero, sizeof(zero), complete_agent_reset_write, t); | 521 | &zero, sizeof(zero), complete_agent_reset_write, t); |
517 | 522 | ||
@@ -521,17 +526,15 @@ static int sbp2_agent_reset(struct fw_unit *unit) | |||
521 | static void sbp2_reconnect(struct work_struct *work); | 526 | static void sbp2_reconnect(struct work_struct *work); |
522 | static struct scsi_host_template scsi_driver_template; | 527 | static struct scsi_host_template scsi_driver_template; |
523 | 528 | ||
524 | static void | 529 | static void release_sbp2_device(struct kref *kref) |
525 | release_sbp2_device(struct kref *kref) | ||
526 | { | 530 | { |
527 | struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref); | 531 | struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref); |
528 | struct Scsi_Host *host = | 532 | struct Scsi_Host *host = |
529 | container_of((void *)sd, struct Scsi_Host, hostdata[0]); | 533 | container_of((void *)sd, struct Scsi_Host, hostdata[0]); |
530 | 534 | ||
535 | scsi_remove_host(host); | ||
531 | sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation, | 536 | sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation, |
532 | SBP2_LOGOUT_REQUEST, sd->login_id, NULL); | 537 | SBP2_LOGOUT_REQUEST, sd->login_id, NULL); |
533 | |||
534 | scsi_remove_host(host); | ||
535 | fw_core_remove_address_handler(&sd->address_handler); | 538 | fw_core_remove_address_handler(&sd->address_handler); |
536 | fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id); | 539 | fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id); |
537 | put_device(&sd->unit->device); | 540 | put_device(&sd->unit->device); |
@@ -833,7 +836,8 @@ sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data) | |||
833 | static void | 836 | static void |
834 | complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) | 837 | complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) |
835 | { | 838 | { |
836 | struct sbp2_command_orb *orb = (struct sbp2_command_orb *)base_orb; | 839 | struct sbp2_command_orb *orb = |
840 | container_of(base_orb, struct sbp2_command_orb, base); | ||
837 | struct fw_unit *unit = orb->unit; | 841 | struct fw_unit *unit = orb->unit; |
838 | struct fw_device *device = fw_device(unit->device.parent); | 842 | struct fw_device *device = fw_device(unit->device.parent); |
839 | struct scatterlist *sg; | 843 | struct scatterlist *sg; |
@@ -880,12 +884,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) | |||
880 | 884 | ||
881 | if (orb->page_table_bus != 0) | 885 | if (orb->page_table_bus != 0) |
882 | dma_unmap_single(device->card->device, orb->page_table_bus, | 886 | dma_unmap_single(device->card->device, orb->page_table_bus, |
883 | sizeof(orb->page_table_bus), DMA_TO_DEVICE); | 887 | sizeof(orb->page_table), DMA_TO_DEVICE); |
884 | |||
885 | if (orb->request_buffer_bus != 0) | ||
886 | dma_unmap_single(device->card->device, orb->request_buffer_bus, | ||
887 | sizeof(orb->request_buffer_bus), | ||
888 | DMA_FROM_DEVICE); | ||
889 | 888 | ||
890 | orb->cmd->result = result; | 889 | orb->cmd->result = result; |
891 | orb->done(orb->cmd); | 890 | orb->done(orb->cmd); |
@@ -900,7 +899,6 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) | |||
900 | struct fw_device *device = fw_device(unit->device.parent); | 899 | struct fw_device *device = fw_device(unit->device.parent); |
901 | struct scatterlist *sg; | 900 | struct scatterlist *sg; |
902 | int sg_len, l, i, j, count; | 901 | int sg_len, l, i, j, count; |
903 | size_t size; | ||
904 | dma_addr_t sg_addr; | 902 | dma_addr_t sg_addr; |
905 | 903 | ||
906 | sg = (struct scatterlist *)orb->cmd->request_buffer; | 904 | sg = (struct scatterlist *)orb->cmd->request_buffer; |
@@ -935,6 +933,11 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) | |||
935 | sg_len = sg_dma_len(sg + i); | 933 | sg_len = sg_dma_len(sg + i); |
936 | sg_addr = sg_dma_address(sg + i); | 934 | sg_addr = sg_dma_address(sg + i); |
937 | while (sg_len) { | 935 | while (sg_len) { |
936 | /* FIXME: This won't get us out of the pinch. */ | ||
937 | if (unlikely(j >= ARRAY_SIZE(orb->page_table))) { | ||
938 | fw_error("page table overflow\n"); | ||
939 | goto fail_page_table; | ||
940 | } | ||
938 | l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH); | 941 | l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH); |
939 | orb->page_table[j].low = sg_addr; | 942 | orb->page_table[j].low = sg_addr; |
940 | orb->page_table[j].high = (l << 16); | 943 | orb->page_table[j].high = (l << 16); |
@@ -944,7 +947,13 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) | |||
944 | } | 947 | } |
945 | } | 948 | } |
946 | 949 | ||
947 | size = sizeof(orb->page_table[0]) * j; | 950 | fw_memcpy_to_be32(orb->page_table, orb->page_table, |
951 | sizeof(orb->page_table[0]) * j); | ||
952 | orb->page_table_bus = | ||
953 | dma_map_single(device->card->device, orb->page_table, | ||
954 | sizeof(orb->page_table), DMA_TO_DEVICE); | ||
955 | if (dma_mapping_error(orb->page_table_bus)) | ||
956 | goto fail_page_table; | ||
948 | 957 | ||
949 | /* | 958 | /* |
950 | * The data_descriptor pointer is the one case where we need | 959 | * The data_descriptor pointer is the one case where we need |
@@ -953,20 +962,12 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) | |||
953 | * initiator (i.e. us), but data_descriptor can refer to data | 962 | * initiator (i.e. us), but data_descriptor can refer to data |
954 | * on other nodes so we need to put our ID in descriptor.high. | 963 | * on other nodes so we need to put our ID in descriptor.high. |
955 | */ | 964 | */ |
956 | |||
957 | orb->page_table_bus = | ||
958 | dma_map_single(device->card->device, orb->page_table, | ||
959 | size, DMA_TO_DEVICE); | ||
960 | if (dma_mapping_error(orb->page_table_bus)) | ||
961 | goto fail_page_table; | ||
962 | orb->request.data_descriptor.high = sd->address_high; | 965 | orb->request.data_descriptor.high = sd->address_high; |
963 | orb->request.data_descriptor.low = orb->page_table_bus; | 966 | orb->request.data_descriptor.low = orb->page_table_bus; |
964 | orb->request.misc |= | 967 | orb->request.misc |= |
965 | COMMAND_ORB_PAGE_TABLE_PRESENT | | 968 | COMMAND_ORB_PAGE_TABLE_PRESENT | |
966 | COMMAND_ORB_DATA_SIZE(j); | 969 | COMMAND_ORB_DATA_SIZE(j); |
967 | 970 | ||
968 | fw_memcpy_to_be32(orb->page_table, orb->page_table, size); | ||
969 | |||
970 | return 0; | 971 | return 0; |
971 | 972 | ||
972 | fail_page_table: | 973 | fail_page_table: |
@@ -991,7 +992,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | |||
991 | * transfer direction not handled. | 992 | * transfer direction not handled. |
992 | */ | 993 | */ |
993 | if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) { | 994 | if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) { |
994 | fw_error("Cannot handle DMA_BIDIRECTIONAL - rejecting command"); | 995 | fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n"); |
995 | cmd->result = DID_ERROR << 16; | 996 | cmd->result = DID_ERROR << 16; |
996 | done(cmd); | 997 | done(cmd); |
997 | return 0; | 998 | return 0; |
@@ -1005,11 +1006,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | |||
1005 | 1006 | ||
1006 | /* Initialize rcode to something not RCODE_COMPLETE. */ | 1007 | /* Initialize rcode to something not RCODE_COMPLETE. */ |
1007 | orb->base.rcode = -1; | 1008 | orb->base.rcode = -1; |
1008 | orb->base.request_bus = | ||
1009 | dma_map_single(device->card->device, &orb->request, | ||
1010 | sizeof(orb->request), DMA_TO_DEVICE); | ||
1011 | if (dma_mapping_error(orb->base.request_bus)) | ||
1012 | goto fail_mapping; | ||
1013 | 1009 | ||
1014 | orb->unit = unit; | 1010 | orb->unit = unit; |
1015 | orb->done = done; | 1011 | orb->done = done; |
@@ -1024,8 +1020,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | |||
1024 | * if we set this to max_speed + 7, we get the right value. | 1020 | * if we set this to max_speed + 7, we get the right value. |
1025 | */ | 1021 | */ |
1026 | orb->request.misc = | 1022 | orb->request.misc = |
1027 | COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) | | 1023 | COMMAND_ORB_MAX_PAYLOAD(device->max_speed + 7) | |
1028 | COMMAND_ORB_SPEED(device->node->max_speed) | | 1024 | COMMAND_ORB_SPEED(device->max_speed) | |
1029 | COMMAND_ORB_NOTIFY; | 1025 | COMMAND_ORB_NOTIFY; |
1030 | 1026 | ||
1031 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) | 1027 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) |
@@ -1036,7 +1032,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | |||
1036 | COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA); | 1032 | COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA); |
1037 | 1033 | ||
1038 | if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0) | 1034 | if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0) |
1039 | goto fail_map_payload; | 1035 | goto fail_mapping; |
1040 | 1036 | ||
1041 | fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); | 1037 | fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); |
1042 | 1038 | ||
@@ -1045,15 +1041,17 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | |||
1045 | memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); | 1041 | memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); |
1046 | 1042 | ||
1047 | orb->base.callback = complete_command_orb; | 1043 | orb->base.callback = complete_command_orb; |
1044 | orb->base.request_bus = | ||
1045 | dma_map_single(device->card->device, &orb->request, | ||
1046 | sizeof(orb->request), DMA_TO_DEVICE); | ||
1047 | if (dma_mapping_error(orb->base.request_bus)) | ||
1048 | goto fail_mapping; | ||
1048 | 1049 | ||
1049 | sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation, | 1050 | sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation, |
1050 | sd->command_block_agent_address + SBP2_ORB_POINTER); | 1051 | sd->command_block_agent_address + SBP2_ORB_POINTER); |
1051 | 1052 | ||
1052 | return 0; | 1053 | return 0; |
1053 | 1054 | ||
1054 | fail_map_payload: | ||
1055 | dma_unmap_single(device->card->device, orb->base.request_bus, | ||
1056 | sizeof(orb->request), DMA_TO_DEVICE); | ||
1057 | fail_mapping: | 1055 | fail_mapping: |
1058 | kfree(orb); | 1056 | kfree(orb); |
1059 | fail_alloc: | 1057 | fail_alloc: |
@@ -1087,7 +1085,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) | |||
1087 | fw_notify("setting fix_capacity for %s\n", unit->device.bus_id); | 1085 | fw_notify("setting fix_capacity for %s\n", unit->device.bus_id); |
1088 | sdev->fix_capacity = 1; | 1086 | sdev->fix_capacity = 1; |
1089 | } | 1087 | } |
1090 | 1088 | if (sd->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) | |
1089 | blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); | ||
1091 | return 0; | 1090 | return 0; |
1092 | } | 1091 | } |
1093 | 1092 | ||
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 7aebb8ae0efa..39e5cd12aa52 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c | |||
@@ -135,17 +135,17 @@ static void update_hop_count(struct fw_node *node) | |||
135 | int i; | 135 | int i; |
136 | 136 | ||
137 | for (i = 0; i < node->port_count; i++) { | 137 | for (i = 0; i < node->port_count; i++) { |
138 | if (node->ports[i].node == NULL) | 138 | if (node->ports[i] == NULL) |
139 | continue; | 139 | continue; |
140 | 140 | ||
141 | if (node->ports[i].node->max_hops > max_child_hops) | 141 | if (node->ports[i]->max_hops > max_child_hops) |
142 | max_child_hops = node->ports[i].node->max_hops; | 142 | max_child_hops = node->ports[i]->max_hops; |
143 | 143 | ||
144 | if (node->ports[i].node->max_depth > depths[0]) { | 144 | if (node->ports[i]->max_depth > depths[0]) { |
145 | depths[1] = depths[0]; | 145 | depths[1] = depths[0]; |
146 | depths[0] = node->ports[i].node->max_depth; | 146 | depths[0] = node->ports[i]->max_depth; |
147 | } else if (node->ports[i].node->max_depth > depths[1]) | 147 | } else if (node->ports[i]->max_depth > depths[1]) |
148 | depths[1] = node->ports[i].node->max_depth; | 148 | depths[1] = node->ports[i]->max_depth; |
149 | } | 149 | } |
150 | 150 | ||
151 | node->max_depth = depths[0] + 1; | 151 | node->max_depth = depths[0] + 1; |
@@ -172,7 +172,8 @@ static struct fw_node *build_tree(struct fw_card *card, | |||
172 | struct list_head stack, *h; | 172 | struct list_head stack, *h; |
173 | u32 *next_sid, *end, q; | 173 | u32 *next_sid, *end, q; |
174 | int i, port_count, child_port_count, phy_id, parent_count, stack_depth; | 174 | int i, port_count, child_port_count, phy_id, parent_count, stack_depth; |
175 | int gap_count, topology_type; | 175 | int gap_count; |
176 | bool beta_repeaters_present; | ||
176 | 177 | ||
177 | local_node = NULL; | 178 | local_node = NULL; |
178 | node = NULL; | 179 | node = NULL; |
@@ -182,7 +183,7 @@ static struct fw_node *build_tree(struct fw_card *card, | |||
182 | phy_id = 0; | 183 | phy_id = 0; |
183 | irm_node = NULL; | 184 | irm_node = NULL; |
184 | gap_count = SELF_ID_GAP_COUNT(*sid); | 185 | gap_count = SELF_ID_GAP_COUNT(*sid); |
185 | topology_type = 0; | 186 | beta_repeaters_present = false; |
186 | 187 | ||
187 | while (sid < end) { | 188 | while (sid < end) { |
188 | next_sid = count_ports(sid, &port_count, &child_port_count); | 189 | next_sid = count_ports(sid, &port_count, &child_port_count); |
@@ -214,7 +215,7 @@ static struct fw_node *build_tree(struct fw_card *card, | |||
214 | 215 | ||
215 | node = fw_node_create(q, port_count, card->color); | 216 | node = fw_node_create(q, port_count, card->color); |
216 | if (node == NULL) { | 217 | if (node == NULL) { |
217 | fw_error("Out of memory while building topology."); | 218 | fw_error("Out of memory while building topology.\n"); |
218 | return NULL; | 219 | return NULL; |
219 | } | 220 | } |
220 | 221 | ||
@@ -224,11 +225,6 @@ static struct fw_node *build_tree(struct fw_card *card, | |||
224 | if (SELF_ID_CONTENDER(q)) | 225 | if (SELF_ID_CONTENDER(q)) |
225 | irm_node = node; | 226 | irm_node = node; |
226 | 227 | ||
227 | if (node->phy_speed == SCODE_BETA) | ||
228 | topology_type |= FW_TOPOLOGY_B; | ||
229 | else | ||
230 | topology_type |= FW_TOPOLOGY_A; | ||
231 | |||
232 | parent_count = 0; | 228 | parent_count = 0; |
233 | 229 | ||
234 | for (i = 0; i < port_count; i++) { | 230 | for (i = 0; i < port_count; i++) { |
@@ -249,12 +245,12 @@ static struct fw_node *build_tree(struct fw_card *card, | |||
249 | break; | 245 | break; |
250 | 246 | ||
251 | case SELFID_PORT_CHILD: | 247 | case SELFID_PORT_CHILD: |
252 | node->ports[i].node = child; | 248 | node->ports[i] = child; |
253 | /* | 249 | /* |
254 | * Fix up parent reference for this | 250 | * Fix up parent reference for this |
255 | * child node. | 251 | * child node. |
256 | */ | 252 | */ |
257 | child->ports[child->color].node = node; | 253 | child->ports[child->color] = node; |
258 | child->color = card->color; | 254 | child->color = card->color; |
259 | child = fw_node(child->link.next); | 255 | child = fw_node(child->link.next); |
260 | break; | 256 | break; |
@@ -278,6 +274,10 @@ static struct fw_node *build_tree(struct fw_card *card, | |||
278 | list_add_tail(&node->link, &stack); | 274 | list_add_tail(&node->link, &stack); |
279 | stack_depth += 1 - child_port_count; | 275 | stack_depth += 1 - child_port_count; |
280 | 276 | ||
277 | if (node->phy_speed == SCODE_BETA && | ||
278 | parent_count + child_port_count > 1) | ||
279 | beta_repeaters_present = true; | ||
280 | |||
281 | /* | 281 | /* |
282 | * If all PHYs does not report the same gap count | 282 | * If all PHYs does not report the same gap count |
283 | * setting, we fall back to 63 which will force a gap | 283 | * setting, we fall back to 63 which will force a gap |
@@ -295,7 +295,7 @@ static struct fw_node *build_tree(struct fw_card *card, | |||
295 | card->root_node = node; | 295 | card->root_node = node; |
296 | card->irm_node = irm_node; | 296 | card->irm_node = irm_node; |
297 | card->gap_count = gap_count; | 297 | card->gap_count = gap_count; |
298 | card->topology_type = topology_type; | 298 | card->beta_repeaters_present = beta_repeaters_present; |
299 | 299 | ||
300 | return local_node; | 300 | return local_node; |
301 | } | 301 | } |
@@ -321,7 +321,7 @@ for_each_fw_node(struct fw_card *card, struct fw_node *root, | |||
321 | node->color = card->color; | 321 | node->color = card->color; |
322 | 322 | ||
323 | for (i = 0; i < node->port_count; i++) { | 323 | for (i = 0; i < node->port_count; i++) { |
324 | child = node->ports[i].node; | 324 | child = node->ports[i]; |
325 | if (!child) | 325 | if (!child) |
326 | continue; | 326 | continue; |
327 | if (child->color == card->color) | 327 | if (child->color == card->color) |
@@ -382,11 +382,11 @@ static void move_tree(struct fw_node *node0, struct fw_node *node1, int port) | |||
382 | struct fw_node *tree; | 382 | struct fw_node *tree; |
383 | int i; | 383 | int i; |
384 | 384 | ||
385 | tree = node1->ports[port].node; | 385 | tree = node1->ports[port]; |
386 | node0->ports[port].node = tree; | 386 | node0->ports[port] = tree; |
387 | for (i = 0; i < tree->port_count; i++) { | 387 | for (i = 0; i < tree->port_count; i++) { |
388 | if (tree->ports[i].node == node1) { | 388 | if (tree->ports[i] == node1) { |
389 | tree->ports[i].node = node0; | 389 | tree->ports[i] = node0; |
390 | break; | 390 | break; |
391 | } | 391 | } |
392 | } | 392 | } |
@@ -437,19 +437,17 @@ update_tree(struct fw_card *card, struct fw_node *root) | |||
437 | card->irm_node = node0; | 437 | card->irm_node = node0; |
438 | 438 | ||
439 | for (i = 0; i < node0->port_count; i++) { | 439 | for (i = 0; i < node0->port_count; i++) { |
440 | if (node0->ports[i].node && node1->ports[i].node) { | 440 | if (node0->ports[i] && node1->ports[i]) { |
441 | /* | 441 | /* |
442 | * This port didn't change, queue the | 442 | * This port didn't change, queue the |
443 | * connected node for further | 443 | * connected node for further |
444 | * investigation. | 444 | * investigation. |
445 | */ | 445 | */ |
446 | if (node0->ports[i].node->color == card->color) | 446 | if (node0->ports[i]->color == card->color) |
447 | continue; | 447 | continue; |
448 | list_add_tail(&node0->ports[i].node->link, | 448 | list_add_tail(&node0->ports[i]->link, &list0); |
449 | &list0); | 449 | list_add_tail(&node1->ports[i]->link, &list1); |
450 | list_add_tail(&node1->ports[i].node->link, | 450 | } else if (node0->ports[i]) { |
451 | &list1); | ||
452 | } else if (node0->ports[i].node) { | ||
453 | /* | 451 | /* |
454 | * The nodes connected here were | 452 | * The nodes connected here were |
455 | * unplugged; unref the lost nodes and | 453 | * unplugged; unref the lost nodes and |
@@ -457,10 +455,10 @@ update_tree(struct fw_card *card, struct fw_node *root) | |||
457 | * them. | 455 | * them. |
458 | */ | 456 | */ |
459 | 457 | ||
460 | for_each_fw_node(card, node0->ports[i].node, | 458 | for_each_fw_node(card, node0->ports[i], |
461 | report_lost_node); | 459 | report_lost_node); |
462 | node0->ports[i].node = NULL; | 460 | node0->ports[i] = NULL; |
463 | } else if (node1->ports[i].node) { | 461 | } else if (node1->ports[i]) { |
464 | /* | 462 | /* |
465 | * One or more node were connected to | 463 | * One or more node were connected to |
466 | * this port. Move the new nodes into | 464 | * this port. Move the new nodes into |
@@ -468,7 +466,7 @@ update_tree(struct fw_card *card, struct fw_node *root) | |||
468 | * callbacks for them. | 466 | * callbacks for them. |
469 | */ | 467 | */ |
470 | move_tree(node0, node1, i); | 468 | move_tree(node0, node1, i); |
471 | for_each_fw_node(card, node0->ports[i].node, | 469 | for_each_fw_node(card, node0->ports[i], |
472 | report_found_node); | 470 | report_found_node); |
473 | } | 471 | } |
474 | } | 472 | } |
diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h index 363b6cbcd0b3..1b56b4ac7fb2 100644 --- a/drivers/firewire/fw-topology.h +++ b/drivers/firewire/fw-topology.h | |||
@@ -20,12 +20,6 @@ | |||
20 | #define __fw_topology_h | 20 | #define __fw_topology_h |
21 | 21 | ||
22 | enum { | 22 | enum { |
23 | FW_TOPOLOGY_A = 0x01, | ||
24 | FW_TOPOLOGY_B = 0x02, | ||
25 | FW_TOPOLOGY_MIXED = 0x03, | ||
26 | }; | ||
27 | |||
28 | enum { | ||
29 | FW_NODE_CREATED = 0x00, | 23 | FW_NODE_CREATED = 0x00, |
30 | FW_NODE_UPDATED = 0x01, | 24 | FW_NODE_UPDATED = 0x01, |
31 | FW_NODE_DESTROYED = 0x02, | 25 | FW_NODE_DESTROYED = 0x02, |
@@ -33,21 +27,16 @@ enum { | |||
33 | FW_NODE_LINK_OFF = 0x04, | 27 | FW_NODE_LINK_OFF = 0x04, |
34 | }; | 28 | }; |
35 | 29 | ||
36 | struct fw_port { | ||
37 | struct fw_node *node; | ||
38 | unsigned speed : 3; /* S100, S200, ... S3200 */ | ||
39 | }; | ||
40 | |||
41 | struct fw_node { | 30 | struct fw_node { |
42 | u16 node_id; | 31 | u16 node_id; |
43 | u8 color; | 32 | u8 color; |
44 | u8 port_count; | 33 | u8 port_count; |
45 | unsigned link_on : 1; | 34 | u8 link_on : 1; |
46 | unsigned initiated_reset : 1; | 35 | u8 initiated_reset : 1; |
47 | unsigned b_path : 1; | 36 | u8 b_path : 1; |
48 | u8 phy_speed : 3; /* As in the self ID packet. */ | 37 | u8 phy_speed : 2; /* As in the self ID packet. */ |
49 | u8 max_speed : 5; /* Minimum of all phy-speeds and port speeds on | 38 | u8 max_speed : 2; /* Minimum of all phy-speeds on the path from the |
50 | * the path from the local node to this node. */ | 39 | * local node to this node. */ |
51 | u8 max_depth : 4; /* Maximum depth to any leaf node */ | 40 | u8 max_depth : 4; /* Maximum depth to any leaf node */ |
52 | u8 max_hops : 4; /* Max hops in this sub tree */ | 41 | u8 max_hops : 4; /* Max hops in this sub tree */ |
53 | atomic_t ref_count; | 42 | atomic_t ref_count; |
@@ -58,7 +47,7 @@ struct fw_node { | |||
58 | /* Upper layer specific data. */ | 47 | /* Upper layer specific data. */ |
59 | void *data; | 48 | void *data; |
60 | 49 | ||
61 | struct fw_port ports[0]; | 50 | struct fw_node *ports[0]; |
62 | }; | 51 | }; |
63 | 52 | ||
64 | static inline struct fw_node * | 53 | static inline struct fw_node * |
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index acdc3be38c61..5abed193f4a6 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h | |||
@@ -81,7 +81,6 @@ | |||
81 | 81 | ||
82 | #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) | 82 | #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) |
83 | #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) | 83 | #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) |
84 | #define fw_debug(s, args...) printk(KERN_DEBUG KBUILD_MODNAME ": " s, ## args) | ||
85 | 84 | ||
86 | static inline void | 85 | static inline void |
87 | fw_memcpy_from_be32(void *_dst, void *_src, size_t size) | 86 | fw_memcpy_from_be32(void *_dst, void *_src, size_t size) |
@@ -246,7 +245,7 @@ struct fw_card { | |||
246 | struct fw_node *irm_node; | 245 | struct fw_node *irm_node; |
247 | int color; | 246 | int color; |
248 | int gap_count; | 247 | int gap_count; |
249 | int topology_type; | 248 | bool beta_repeaters_present; |
250 | 249 | ||
251 | int index; | 250 | int index; |
252 | 251 | ||
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 208141377612..65722117ab6e 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c | |||
@@ -2280,7 +2280,7 @@ static void dv1394_remove_host(struct hpsb_host *host) | |||
2280 | } while (video); | 2280 | } while (video); |
2281 | 2281 | ||
2282 | if (found_ohci_card) | 2282 | if (found_ohci_card) |
2283 | class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, | 2283 | device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, |
2284 | IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2))); | 2284 | IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2))); |
2285 | } | 2285 | } |
2286 | 2286 | ||
@@ -2295,9 +2295,9 @@ static void dv1394_add_host(struct hpsb_host *host) | |||
2295 | 2295 | ||
2296 | ohci = (struct ti_ohci *)host->hostdata; | 2296 | ohci = (struct ti_ohci *)host->hostdata; |
2297 | 2297 | ||
2298 | class_device_create(hpsb_protocol_class, NULL, MKDEV( | 2298 | device_create(hpsb_protocol_class, NULL, MKDEV( |
2299 | IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), | 2299 | IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), |
2300 | NULL, "dv1394-%d", id); | 2300 | "dv1394-%d", id); |
2301 | 2301 | ||
2302 | dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); | 2302 | dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); |
2303 | dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); | 2303 | dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); |
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 7c13fb3c167b..93362eed94ed 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c | |||
@@ -599,9 +599,7 @@ static void ether1394_add_host(struct hpsb_host *host) | |||
599 | } | 599 | } |
600 | 600 | ||
601 | SET_MODULE_OWNER(dev); | 601 | SET_MODULE_OWNER(dev); |
602 | 602 | SET_NETDEV_DEV(dev, &host->device); | |
603 | /* This used to be &host->device in Linux 2.6.20 and before. */ | ||
604 | SET_NETDEV_DEV(dev, host->device.parent); | ||
605 | 603 | ||
606 | priv = netdev_priv(dev); | 604 | priv = netdev_priv(dev); |
607 | INIT_LIST_HEAD(&priv->ip_node_list); | 605 | INIT_LIST_HEAD(&priv->ip_node_list); |
diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c index 83a493312751..b6425469b6ee 100644 --- a/drivers/ieee1394/highlevel.c +++ b/drivers/ieee1394/highlevel.c | |||
@@ -483,37 +483,6 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, | |||
483 | return retval; | 483 | return retval; |
484 | } | 484 | } |
485 | 485 | ||
486 | /** | ||
487 | * hpsb_listen_channel - enable receving a certain isochronous channel | ||
488 | * | ||
489 | * Reception is handled through the @hl's iso_receive op. | ||
490 | */ | ||
491 | int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, | ||
492 | unsigned int channel) | ||
493 | { | ||
494 | if (channel > 63) { | ||
495 | HPSB_ERR("%s called with invalid channel", __FUNCTION__); | ||
496 | return -EINVAL; | ||
497 | } | ||
498 | if (host->iso_listen_count[channel]++ == 0) | ||
499 | return host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel); | ||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | /** | ||
504 | * hpsb_unlisten_channel - disable receving a certain isochronous channel | ||
505 | */ | ||
506 | void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, | ||
507 | unsigned int channel) | ||
508 | { | ||
509 | if (channel > 63) { | ||
510 | HPSB_ERR("%s called with invalid channel", __FUNCTION__); | ||
511 | return; | ||
512 | } | ||
513 | if (--host->iso_listen_count[channel] == 0) | ||
514 | host->driver->devctl(host, ISO_UNLISTEN_CHANNEL, channel); | ||
515 | } | ||
516 | |||
517 | static void init_hpsb_highlevel(struct hpsb_host *host) | 486 | static void init_hpsb_highlevel(struct hpsb_host *host) |
518 | { | 487 | { |
519 | INIT_LIST_HEAD(&dummy_zero_addr.host_list); | 488 | INIT_LIST_HEAD(&dummy_zero_addr.host_list); |
@@ -570,20 +539,6 @@ void highlevel_host_reset(struct hpsb_host *host) | |||
570 | read_unlock_irqrestore(&hl_irqs_lock, flags); | 539 | read_unlock_irqrestore(&hl_irqs_lock, flags); |
571 | } | 540 | } |
572 | 541 | ||
573 | void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length) | ||
574 | { | ||
575 | unsigned long flags; | ||
576 | struct hpsb_highlevel *hl; | ||
577 | int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f; | ||
578 | |||
579 | read_lock_irqsave(&hl_irqs_lock, flags); | ||
580 | list_for_each_entry(hl, &hl_irqs, irq_list) { | ||
581 | if (hl->iso_receive) | ||
582 | hl->iso_receive(host, channel, data, length); | ||
583 | } | ||
584 | read_unlock_irqrestore(&hl_irqs_lock, flags); | ||
585 | } | ||
586 | |||
587 | void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, | 542 | void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, |
588 | void *data, size_t length) | 543 | void *data, size_t length) |
589 | { | 544 | { |
diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h index 63474f7ee69d..eb9fe321e09a 100644 --- a/drivers/ieee1394/highlevel.h +++ b/drivers/ieee1394/highlevel.h | |||
@@ -26,9 +26,7 @@ struct hpsb_address_serve { | |||
26 | struct hpsb_highlevel { | 26 | struct hpsb_highlevel { |
27 | const char *name; | 27 | const char *name; |
28 | 28 | ||
29 | /* Any of the following pointers can legally be NULL, except for | 29 | /* Any of the following pointers can legally be NULL. */ |
30 | * iso_receive which can only be NULL when you don't request | ||
31 | * channels. */ | ||
32 | 30 | ||
33 | /* New host initialized. Will also be called during | 31 | /* New host initialized. Will also be called during |
34 | * hpsb_register_highlevel for all hosts already installed. */ | 32 | * hpsb_register_highlevel for all hosts already installed. */ |
@@ -43,13 +41,6 @@ struct hpsb_highlevel { | |||
43 | * You can not expect to be able to do stock hpsb_reads. */ | 41 | * You can not expect to be able to do stock hpsb_reads. */ |
44 | void (*host_reset)(struct hpsb_host *host); | 42 | void (*host_reset)(struct hpsb_host *host); |
45 | 43 | ||
46 | /* An isochronous packet was received. Channel contains the channel | ||
47 | * number for your convenience, it is also contained in the included | ||
48 | * packet header (first quadlet, CRCs are missing). You may get called | ||
49 | * for channel/host combinations you did not request. */ | ||
50 | void (*iso_receive)(struct hpsb_host *host, int channel, | ||
51 | quadlet_t *data, size_t length); | ||
52 | |||
53 | /* A write request was received on either the FCP_COMMAND (direction = | 44 | /* A write request was received on either the FCP_COMMAND (direction = |
54 | * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg | 45 | * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg |
55 | * contains the cts field (first byte of data). */ | 46 | * contains the cts field (first byte of data). */ |
@@ -109,7 +100,6 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store, | |||
109 | int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, | 100 | int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, |
110 | u64 addr, octlet_t data, octlet_t arg, int ext_tcode, | 101 | u64 addr, octlet_t data, octlet_t arg, int ext_tcode, |
111 | u16 flags); | 102 | u16 flags); |
112 | void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length); | ||
113 | void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, | 103 | void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, |
114 | void *data, size_t length); | 104 | void *data, size_t length); |
115 | 105 | ||
@@ -125,10 +115,6 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, | |||
125 | struct hpsb_address_ops *ops, u64 start, u64 end); | 115 | struct hpsb_address_ops *ops, u64 start, u64 end); |
126 | int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, | 116 | int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, |
127 | u64 start); | 117 | u64 start); |
128 | int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, | ||
129 | unsigned int channel); | ||
130 | void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, | ||
131 | unsigned int channel); | ||
132 | 118 | ||
133 | void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host); | 119 | void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host); |
134 | void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, | 120 | void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, |
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index bd0755c789c5..8dd09d850419 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c | |||
@@ -154,15 +154,16 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, | |||
154 | 154 | ||
155 | memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); | 155 | memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); |
156 | h->device.parent = dev; | 156 | h->device.parent = dev; |
157 | set_dev_node(&h->device, dev_to_node(dev)); | ||
157 | snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); | 158 | snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); |
158 | 159 | ||
159 | h->class_dev.dev = &h->device; | 160 | h->host_dev.parent = &h->device; |
160 | h->class_dev.class = &hpsb_host_class; | 161 | h->host_dev.class = &hpsb_host_class; |
161 | snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id); | 162 | snprintf(h->host_dev.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); |
162 | 163 | ||
163 | if (device_register(&h->device)) | 164 | if (device_register(&h->device)) |
164 | goto fail; | 165 | goto fail; |
165 | if (class_device_register(&h->class_dev)) { | 166 | if (device_register(&h->host_dev)) { |
166 | device_unregister(&h->device); | 167 | device_unregister(&h->device); |
167 | goto fail; | 168 | goto fail; |
168 | } | 169 | } |
@@ -202,7 +203,7 @@ void hpsb_remove_host(struct hpsb_host *host) | |||
202 | host->driver = &dummy_driver; | 203 | host->driver = &dummy_driver; |
203 | highlevel_remove_host(host); | 204 | highlevel_remove_host(host); |
204 | 205 | ||
205 | class_device_unregister(&host->class_dev); | 206 | device_unregister(&host->host_dev); |
206 | device_unregister(&host->device); | 207 | device_unregister(&host->device); |
207 | } | 208 | } |
208 | 209 | ||
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index feb55d032294..e4e8aeb4d778 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h | |||
@@ -28,8 +28,6 @@ struct hpsb_host { | |||
28 | struct timer_list timeout; | 28 | struct timer_list timeout; |
29 | unsigned long timeout_interval; | 29 | unsigned long timeout_interval; |
30 | 30 | ||
31 | unsigned char iso_listen_count[64]; | ||
32 | |||
33 | int node_count; /* number of identified nodes on this bus */ | 31 | int node_count; /* number of identified nodes on this bus */ |
34 | int selfid_count; /* total number of SelfIDs received */ | 32 | int selfid_count; /* total number of SelfIDs received */ |
35 | int nodes_active; /* number of nodes with active link layer */ | 33 | int nodes_active; /* number of nodes with active link layer */ |
@@ -57,7 +55,7 @@ struct hpsb_host { | |||
57 | struct hpsb_host_driver *driver; | 55 | struct hpsb_host_driver *driver; |
58 | struct pci_dev *pdev; | 56 | struct pci_dev *pdev; |
59 | struct device device; | 57 | struct device device; |
60 | struct class_device class_dev; | 58 | struct device host_dev; |
61 | 59 | ||
62 | struct delayed_work delayed_reset; | 60 | struct delayed_work delayed_reset; |
63 | unsigned config_roms:31; | 61 | unsigned config_roms:31; |
@@ -99,12 +97,6 @@ enum devctl_cmd { | |||
99 | /* Cancel all outstanding async requests without resetting the bus. | 97 | /* Cancel all outstanding async requests without resetting the bus. |
100 | * Return void. */ | 98 | * Return void. */ |
101 | CANCEL_REQUESTS, | 99 | CANCEL_REQUESTS, |
102 | |||
103 | /* Start or stop receiving isochronous channel in arg. Return void. | ||
104 | * This acts as an optimization hint, hosts are not required not to | ||
105 | * listen on unrequested channels. */ | ||
106 | ISO_LISTEN_CHANNEL, | ||
107 | ISO_UNLISTEN_CHANNEL | ||
108 | }; | 100 | }; |
109 | 101 | ||
110 | enum isoctl_cmd { | 102 | enum isoctl_cmd { |
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 8f71b6a06aa0..0fc8c6e559e4 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c | |||
@@ -1028,11 +1028,6 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, | |||
1028 | handle_incoming_packet(host, tcode, data, size, write_acked); | 1028 | handle_incoming_packet(host, tcode, data, size, write_acked); |
1029 | break; | 1029 | break; |
1030 | 1030 | ||
1031 | |||
1032 | case TCODE_ISO_DATA: | ||
1033 | highlevel_iso_receive(host, data, size); | ||
1034 | break; | ||
1035 | |||
1036 | case TCODE_CYCLE_START: | 1031 | case TCODE_CYCLE_START: |
1037 | /* simply ignore this packet if it is passed on */ | 1032 | /* simply ignore this packet if it is passed on */ |
1038 | break; | 1033 | break; |
@@ -1316,7 +1311,6 @@ EXPORT_SYMBOL(hpsb_make_streampacket); | |||
1316 | EXPORT_SYMBOL(hpsb_make_lockpacket); | 1311 | EXPORT_SYMBOL(hpsb_make_lockpacket); |
1317 | EXPORT_SYMBOL(hpsb_make_lock64packet); | 1312 | EXPORT_SYMBOL(hpsb_make_lock64packet); |
1318 | EXPORT_SYMBOL(hpsb_make_phypacket); | 1313 | EXPORT_SYMBOL(hpsb_make_phypacket); |
1319 | EXPORT_SYMBOL(hpsb_make_isopacket); | ||
1320 | EXPORT_SYMBOL(hpsb_read); | 1314 | EXPORT_SYMBOL(hpsb_read); |
1321 | EXPORT_SYMBOL(hpsb_write); | 1315 | EXPORT_SYMBOL(hpsb_write); |
1322 | EXPORT_SYMBOL(hpsb_packet_success); | 1316 | EXPORT_SYMBOL(hpsb_packet_success); |
@@ -1327,8 +1321,6 @@ EXPORT_SYMBOL(hpsb_unregister_highlevel); | |||
1327 | EXPORT_SYMBOL(hpsb_register_addrspace); | 1321 | EXPORT_SYMBOL(hpsb_register_addrspace); |
1328 | EXPORT_SYMBOL(hpsb_unregister_addrspace); | 1322 | EXPORT_SYMBOL(hpsb_unregister_addrspace); |
1329 | EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace); | 1323 | EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace); |
1330 | EXPORT_SYMBOL(hpsb_listen_channel); | ||
1331 | EXPORT_SYMBOL(hpsb_unlisten_channel); | ||
1332 | EXPORT_SYMBOL(hpsb_get_hostinfo); | 1324 | EXPORT_SYMBOL(hpsb_get_hostinfo); |
1333 | EXPORT_SYMBOL(hpsb_create_hostinfo); | 1325 | EXPORT_SYMBOL(hpsb_create_hostinfo); |
1334 | EXPORT_SYMBOL(hpsb_destroy_hostinfo); | 1326 | EXPORT_SYMBOL(hpsb_destroy_hostinfo); |
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index ad526523d0ef..21d50f73a210 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h | |||
@@ -24,9 +24,8 @@ struct hpsb_packet { | |||
24 | 24 | ||
25 | nodeid_t node_id; | 25 | nodeid_t node_id; |
26 | 26 | ||
27 | /* Async and Iso types should be clear, raw means send-as-is, do not | 27 | /* hpsb_raw = send as-is, do not CRC (but still byte-swap it) */ |
28 | * CRC! Byte swapping shall still be done in this case. */ | 28 | enum { hpsb_async, hpsb_raw } __attribute__((packed)) type; |
29 | enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type; | ||
30 | 29 | ||
31 | /* Okay, this is core internal and a no care for hosts. | 30 | /* Okay, this is core internal and a no care for hosts. |
32 | * queued = queued for sending | 31 | * queued = queued for sending |
@@ -37,7 +36,7 @@ struct hpsb_packet { | |||
37 | hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete | 36 | hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete |
38 | } __attribute__((packed)) state; | 37 | } __attribute__((packed)) state; |
39 | 38 | ||
40 | /* These are core internal. */ | 39 | /* These are core-internal. */ |
41 | signed char tlabel; | 40 | signed char tlabel; |
42 | signed char ack_code; | 41 | signed char ack_code; |
43 | unsigned char tcode; | 42 | unsigned char tcode; |
@@ -62,11 +61,15 @@ struct hpsb_packet { | |||
62 | /* Store jiffies for implementing bus timeouts. */ | 61 | /* Store jiffies for implementing bus timeouts. */ |
63 | unsigned long sendtime; | 62 | unsigned long sendtime; |
64 | 63 | ||
65 | /* Sizes are in bytes. *data can be DMA-mapped. */ | 64 | /* Core-internal. */ |
66 | size_t allocated_data_size; /* as allocated */ | 65 | size_t allocated_data_size; /* as allocated */ |
66 | |||
67 | /* Sizes are in bytes. To be set by caller of hpsb_alloc_packet. */ | ||
67 | size_t data_size; /* as filled in */ | 68 | size_t data_size; /* as filled in */ |
68 | size_t header_size; /* as filled in, not counting the CRC */ | 69 | size_t header_size; /* as filled in, not counting the CRC */ |
69 | quadlet_t *data; | 70 | |
71 | /* Buffers */ | ||
72 | quadlet_t *data; /* can be DMA-mapped */ | ||
70 | quadlet_t header[5]; | 73 | quadlet_t header[5]; |
71 | quadlet_t embedded_data[0]; /* keep as last member */ | 74 | quadlet_t embedded_data[0]; /* keep as last member */ |
72 | }; | 75 | }; |
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 40078ce930c8..c39c70a8aa9f 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c | |||
@@ -89,18 +89,6 @@ static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode, | |||
89 | packet->expect_response = 1; | 89 | packet->expect_response = 1; |
90 | } | 90 | } |
91 | 91 | ||
92 | static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel, | ||
93 | int tag, int sync) | ||
94 | { | ||
95 | packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) | ||
96 | | (TCODE_ISO_DATA << 4) | sync; | ||
97 | |||
98 | packet->header_size = 4; | ||
99 | packet->data_size = length; | ||
100 | packet->type = hpsb_iso; | ||
101 | packet->tcode = TCODE_ISO_DATA; | ||
102 | } | ||
103 | |||
104 | static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) | 92 | static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) |
105 | { | 93 | { |
106 | packet->header[0] = data; | 94 | packet->header[0] = data; |
@@ -491,24 +479,6 @@ struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data) | |||
491 | return p; | 479 | return p; |
492 | } | 480 | } |
493 | 481 | ||
494 | struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, | ||
495 | int length, int channel, | ||
496 | int tag, int sync) | ||
497 | { | ||
498 | struct hpsb_packet *p; | ||
499 | |||
500 | p = hpsb_alloc_packet(length); | ||
501 | if (!p) | ||
502 | return NULL; | ||
503 | |||
504 | p->host = host; | ||
505 | fill_iso_packet(p, length, channel, tag, sync); | ||
506 | |||
507 | p->generation = get_hpsb_generation(host); | ||
508 | |||
509 | return p; | ||
510 | } | ||
511 | |||
512 | /* | 482 | /* |
513 | * FIXME - these functions should probably read from / write to user space to | 483 | * FIXME - these functions should probably read from / write to user space to |
514 | * avoid in kernel buffers for user space callers | 484 | * avoid in kernel buffers for user space callers |
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h index 86b8ee692ea7..d2d5bc3546d7 100644 --- a/drivers/ieee1394/ieee1394_transactions.h +++ b/drivers/ieee1394/ieee1394_transactions.h | |||
@@ -19,8 +19,6 @@ struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, | |||
19 | nodeid_t node, u64 addr, int extcode, | 19 | nodeid_t node, u64 addr, int extcode, |
20 | octlet_t *data, octlet_t arg); | 20 | octlet_t *data, octlet_t arg); |
21 | struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data); | 21 | struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data); |
22 | struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int length, | ||
23 | int channel, int tag, int sync); | ||
24 | struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, | 22 | struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, |
25 | nodeid_t node, u64 addr, | 23 | nodeid_t node, u64 addr, |
26 | quadlet_t *buffer, size_t length); | 24 | quadlet_t *buffer, size_t length); |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 81b3864d2ba7..c4d3d4131f01 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/freezer.h> | 20 | #include <linux/freezer.h> |
21 | #include <asm/atomic.h> | 21 | #include <asm/atomic.h> |
22 | #include <asm/semaphore.h> | ||
22 | 23 | ||
23 | #include "csr.h" | 24 | #include "csr.h" |
24 | #include "highlevel.h" | 25 | #include "highlevel.h" |
@@ -145,8 +146,6 @@ static struct csr1212_bus_ops nodemgr_csr_ops = { | |||
145 | * but now we are much simpler because of the LDM. | 146 | * but now we are much simpler because of the LDM. |
146 | */ | 147 | */ |
147 | 148 | ||
148 | static DEFINE_MUTEX(nodemgr_serialize); | ||
149 | |||
150 | struct host_info { | 149 | struct host_info { |
151 | struct hpsb_host *host; | 150 | struct hpsb_host *host; |
152 | struct list_head list; | 151 | struct list_head list; |
@@ -154,7 +153,7 @@ struct host_info { | |||
154 | }; | 153 | }; |
155 | 154 | ||
156 | static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); | 155 | static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); |
157 | static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, | 156 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, |
158 | char *buffer, int buffer_size); | 157 | char *buffer, int buffer_size); |
159 | static void nodemgr_resume_ne(struct node_entry *ne); | 158 | static void nodemgr_resume_ne(struct node_entry *ne); |
160 | static void nodemgr_remove_ne(struct node_entry *ne); | 159 | static void nodemgr_remove_ne(struct node_entry *ne); |
@@ -165,37 +164,38 @@ struct bus_type ieee1394_bus_type = { | |||
165 | .match = nodemgr_bus_match, | 164 | .match = nodemgr_bus_match, |
166 | }; | 165 | }; |
167 | 166 | ||
168 | static void host_cls_release(struct class_device *class_dev) | 167 | static void host_cls_release(struct device *dev) |
169 | { | 168 | { |
170 | put_device(&container_of((class_dev), struct hpsb_host, class_dev)->device); | 169 | put_device(&container_of((dev), struct hpsb_host, host_dev)->device); |
171 | } | 170 | } |
172 | 171 | ||
173 | struct class hpsb_host_class = { | 172 | struct class hpsb_host_class = { |
174 | .name = "ieee1394_host", | 173 | .name = "ieee1394_host", |
175 | .release = host_cls_release, | 174 | .dev_release = host_cls_release, |
176 | }; | 175 | }; |
177 | 176 | ||
178 | static void ne_cls_release(struct class_device *class_dev) | 177 | static void ne_cls_release(struct device *dev) |
179 | { | 178 | { |
180 | put_device(&container_of((class_dev), struct node_entry, class_dev)->device); | 179 | put_device(&container_of((dev), struct node_entry, node_dev)->device); |
181 | } | 180 | } |
182 | 181 | ||
183 | static struct class nodemgr_ne_class = { | 182 | static struct class nodemgr_ne_class = { |
184 | .name = "ieee1394_node", | 183 | .name = "ieee1394_node", |
185 | .release = ne_cls_release, | 184 | .dev_release = ne_cls_release, |
186 | }; | 185 | }; |
187 | 186 | ||
188 | static void ud_cls_release(struct class_device *class_dev) | 187 | static void ud_cls_release(struct device *dev) |
189 | { | 188 | { |
190 | put_device(&container_of((class_dev), struct unit_directory, class_dev)->device); | 189 | put_device(&container_of((dev), struct unit_directory, unit_dev)->device); |
191 | } | 190 | } |
192 | 191 | ||
193 | /* The name here is only so that unit directory hotplug works with old | 192 | /* The name here is only so that unit directory hotplug works with old |
194 | * style hotplug, which only ever did unit directories anyway. */ | 193 | * style hotplug, which only ever did unit directories anyway. |
194 | */ | ||
195 | static struct class nodemgr_ud_class = { | 195 | static struct class nodemgr_ud_class = { |
196 | .name = "ieee1394", | 196 | .name = "ieee1394", |
197 | .release = ud_cls_release, | 197 | .dev_release = ud_cls_release, |
198 | .uevent = nodemgr_uevent, | 198 | .dev_uevent = nodemgr_uevent, |
199 | }; | 199 | }; |
200 | 200 | ||
201 | static struct hpsb_highlevel nodemgr_highlevel; | 201 | static struct hpsb_highlevel nodemgr_highlevel; |
@@ -730,11 +730,11 @@ static DEFINE_MUTEX(nodemgr_serialize_remove_uds); | |||
730 | 730 | ||
731 | static void nodemgr_remove_uds(struct node_entry *ne) | 731 | static void nodemgr_remove_uds(struct node_entry *ne) |
732 | { | 732 | { |
733 | struct class_device *cdev; | 733 | struct device *dev; |
734 | struct unit_directory *tmp, *ud; | 734 | struct unit_directory *tmp, *ud; |
735 | 735 | ||
736 | /* Iteration over nodemgr_ud_class.children has to be protected by | 736 | /* Iteration over nodemgr_ud_class.devices has to be protected by |
737 | * nodemgr_ud_class.sem, but class_device_unregister() will eventually | 737 | * nodemgr_ud_class.sem, but device_unregister() will eventually |
738 | * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, | 738 | * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, |
739 | * release the semaphore, and then unregister the ud. Since this code | 739 | * release the semaphore, and then unregister the ud. Since this code |
740 | * may be called from other contexts besides the knodemgrds, protect the | 740 | * may be called from other contexts besides the knodemgrds, protect the |
@@ -744,9 +744,9 @@ static void nodemgr_remove_uds(struct node_entry *ne) | |||
744 | for (;;) { | 744 | for (;;) { |
745 | ud = NULL; | 745 | ud = NULL; |
746 | down(&nodemgr_ud_class.sem); | 746 | down(&nodemgr_ud_class.sem); |
747 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 747 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { |
748 | tmp = container_of(cdev, struct unit_directory, | 748 | tmp = container_of(dev, struct unit_directory, |
749 | class_dev); | 749 | unit_dev); |
750 | if (tmp->ne == ne) { | 750 | if (tmp->ne == ne) { |
751 | ud = tmp; | 751 | ud = tmp; |
752 | break; | 752 | break; |
@@ -755,7 +755,7 @@ static void nodemgr_remove_uds(struct node_entry *ne) | |||
755 | up(&nodemgr_ud_class.sem); | 755 | up(&nodemgr_ud_class.sem); |
756 | if (ud == NULL) | 756 | if (ud == NULL) |
757 | break; | 757 | break; |
758 | class_device_unregister(&ud->class_dev); | 758 | device_unregister(&ud->unit_dev); |
759 | device_unregister(&ud->device); | 759 | device_unregister(&ud->device); |
760 | } | 760 | } |
761 | mutex_unlock(&nodemgr_serialize_remove_uds); | 761 | mutex_unlock(&nodemgr_serialize_remove_uds); |
@@ -772,10 +772,9 @@ static void nodemgr_remove_ne(struct node_entry *ne) | |||
772 | 772 | ||
773 | HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 773 | HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
774 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | 774 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); |
775 | |||
776 | nodemgr_remove_uds(ne); | 775 | nodemgr_remove_uds(ne); |
777 | 776 | ||
778 | class_device_unregister(&ne->class_dev); | 777 | device_unregister(&ne->node_dev); |
779 | device_unregister(dev); | 778 | device_unregister(dev); |
780 | 779 | ||
781 | put_device(dev); | 780 | put_device(dev); |
@@ -783,7 +782,9 @@ static void nodemgr_remove_ne(struct node_entry *ne) | |||
783 | 782 | ||
784 | static int __nodemgr_remove_host_dev(struct device *dev, void *data) | 783 | static int __nodemgr_remove_host_dev(struct device *dev, void *data) |
785 | { | 784 | { |
786 | nodemgr_remove_ne(container_of(dev, struct node_entry, device)); | 785 | if (dev->bus == &ieee1394_bus_type) |
786 | nodemgr_remove_ne(container_of(dev, struct node_entry, | ||
787 | device)); | ||
787 | return 0; | 788 | return 0; |
788 | } | 789 | } |
789 | 790 | ||
@@ -850,14 +851,14 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr | |||
850 | snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", | 851 | snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", |
851 | (unsigned long long)(ne->guid)); | 852 | (unsigned long long)(ne->guid)); |
852 | 853 | ||
853 | ne->class_dev.dev = &ne->device; | 854 | ne->node_dev.parent = &ne->device; |
854 | ne->class_dev.class = &nodemgr_ne_class; | 855 | ne->node_dev.class = &nodemgr_ne_class; |
855 | snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx", | 856 | snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx", |
856 | (unsigned long long)(ne->guid)); | 857 | (unsigned long long)(ne->guid)); |
857 | 858 | ||
858 | if (device_register(&ne->device)) | 859 | if (device_register(&ne->device)) |
859 | goto fail_devreg; | 860 | goto fail_devreg; |
860 | if (class_device_register(&ne->class_dev)) | 861 | if (device_register(&ne->node_dev)) |
861 | goto fail_classdevreg; | 862 | goto fail_classdevreg; |
862 | get_device(&ne->device); | 863 | get_device(&ne->device); |
863 | 864 | ||
@@ -885,12 +886,12 @@ fail_alloc: | |||
885 | 886 | ||
886 | static struct node_entry *find_entry_by_guid(u64 guid) | 887 | static struct node_entry *find_entry_by_guid(u64 guid) |
887 | { | 888 | { |
888 | struct class_device *cdev; | 889 | struct device *dev; |
889 | struct node_entry *ne, *ret_ne = NULL; | 890 | struct node_entry *ne, *ret_ne = NULL; |
890 | 891 | ||
891 | down(&nodemgr_ne_class.sem); | 892 | down(&nodemgr_ne_class.sem); |
892 | list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { | 893 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { |
893 | ne = container_of(cdev, struct node_entry, class_dev); | 894 | ne = container_of(dev, struct node_entry, node_dev); |
894 | 895 | ||
895 | if (ne->guid == guid) { | 896 | if (ne->guid == guid) { |
896 | ret_ne = ne; | 897 | ret_ne = ne; |
@@ -906,12 +907,12 @@ static struct node_entry *find_entry_by_guid(u64 guid) | |||
906 | static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, | 907 | static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, |
907 | nodeid_t nodeid) | 908 | nodeid_t nodeid) |
908 | { | 909 | { |
909 | struct class_device *cdev; | 910 | struct device *dev; |
910 | struct node_entry *ne, *ret_ne = NULL; | 911 | struct node_entry *ne, *ret_ne = NULL; |
911 | 912 | ||
912 | down(&nodemgr_ne_class.sem); | 913 | down(&nodemgr_ne_class.sem); |
913 | list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { | 914 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { |
914 | ne = container_of(cdev, struct node_entry, class_dev); | 915 | ne = container_of(dev, struct node_entry, node_dev); |
915 | 916 | ||
916 | if (ne->host == host && ne->nodeid == nodeid) { | 917 | if (ne->host == host && ne->nodeid == nodeid) { |
917 | ret_ne = ne; | 918 | ret_ne = ne; |
@@ -935,14 +936,14 @@ static void nodemgr_register_device(struct node_entry *ne, | |||
935 | snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", | 936 | snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", |
936 | ne->device.bus_id, ud->id); | 937 | ne->device.bus_id, ud->id); |
937 | 938 | ||
938 | ud->class_dev.dev = &ud->device; | 939 | ud->unit_dev.parent = &ud->device; |
939 | ud->class_dev.class = &nodemgr_ud_class; | 940 | ud->unit_dev.class = &nodemgr_ud_class; |
940 | snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u", | 941 | snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u", |
941 | ne->device.bus_id, ud->id); | 942 | ne->device.bus_id, ud->id); |
942 | 943 | ||
943 | if (device_register(&ud->device)) | 944 | if (device_register(&ud->device)) |
944 | goto fail_devreg; | 945 | goto fail_devreg; |
945 | if (class_device_register(&ud->class_dev)) | 946 | if (device_register(&ud->unit_dev)) |
946 | goto fail_classdevreg; | 947 | goto fail_classdevreg; |
947 | get_device(&ud->device); | 948 | get_device(&ud->device); |
948 | 949 | ||
@@ -1159,7 +1160,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent | |||
1159 | 1160 | ||
1160 | #ifdef CONFIG_HOTPLUG | 1161 | #ifdef CONFIG_HOTPLUG |
1161 | 1162 | ||
1162 | static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, | 1163 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, |
1163 | char *buffer, int buffer_size) | 1164 | char *buffer, int buffer_size) |
1164 | { | 1165 | { |
1165 | struct unit_directory *ud; | 1166 | struct unit_directory *ud; |
@@ -1169,10 +1170,10 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, | |||
1169 | /* ieee1394:venNmoNspNverN */ | 1170 | /* ieee1394:venNmoNspNverN */ |
1170 | char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; | 1171 | char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; |
1171 | 1172 | ||
1172 | if (!cdev) | 1173 | if (!dev) |
1173 | return -ENODEV; | 1174 | return -ENODEV; |
1174 | 1175 | ||
1175 | ud = container_of(cdev, struct unit_directory, class_dev); | 1176 | ud = container_of(dev, struct unit_directory, unit_dev); |
1176 | 1177 | ||
1177 | if (ud->ne->in_limbo || ud->ignore_driver) | 1178 | if (ud->ne->in_limbo || ud->ignore_driver) |
1178 | return -ENODEV; | 1179 | return -ENODEV; |
@@ -1207,7 +1208,7 @@ do { \ | |||
1207 | 1208 | ||
1208 | #else | 1209 | #else |
1209 | 1210 | ||
1210 | static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, | 1211 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, |
1211 | char *buffer, int buffer_size) | 1212 | char *buffer, int buffer_size) |
1212 | { | 1213 | { |
1213 | return -ENODEV; | 1214 | return -ENODEV; |
@@ -1378,8 +1379,10 @@ static void nodemgr_node_scan(struct host_info *hi, int generation) | |||
1378 | 1379 | ||
1379 | static void nodemgr_suspend_ne(struct node_entry *ne) | 1380 | static void nodemgr_suspend_ne(struct node_entry *ne) |
1380 | { | 1381 | { |
1381 | struct class_device *cdev; | 1382 | struct device *dev; |
1382 | struct unit_directory *ud; | 1383 | struct unit_directory *ud; |
1384 | struct device_driver *drv; | ||
1385 | int error; | ||
1383 | 1386 | ||
1384 | HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 1387 | HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
1385 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | 1388 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); |
@@ -1388,15 +1391,24 @@ static void nodemgr_suspend_ne(struct node_entry *ne) | |||
1388 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); | 1391 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); |
1389 | 1392 | ||
1390 | down(&nodemgr_ud_class.sem); | 1393 | down(&nodemgr_ud_class.sem); |
1391 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 1394 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { |
1392 | ud = container_of(cdev, struct unit_directory, class_dev); | 1395 | ud = container_of(dev, struct unit_directory, unit_dev); |
1393 | if (ud->ne != ne) | 1396 | if (ud->ne != ne) |
1394 | continue; | 1397 | continue; |
1395 | 1398 | ||
1396 | if (ud->device.driver && | 1399 | drv = get_driver(ud->device.driver); |
1397 | (!ud->device.driver->suspend || | 1400 | if (!drv) |
1398 | ud->device.driver->suspend(&ud->device, PMSG_SUSPEND))) | 1401 | continue; |
1402 | |||
1403 | error = 1; /* release if suspend is not implemented */ | ||
1404 | if (drv->suspend) { | ||
1405 | down(&ud->device.sem); | ||
1406 | error = drv->suspend(&ud->device, PMSG_SUSPEND); | ||
1407 | up(&ud->device.sem); | ||
1408 | } | ||
1409 | if (error) | ||
1399 | device_release_driver(&ud->device); | 1410 | device_release_driver(&ud->device); |
1411 | put_driver(drv); | ||
1400 | } | 1412 | } |
1401 | up(&nodemgr_ud_class.sem); | 1413 | up(&nodemgr_ud_class.sem); |
1402 | } | 1414 | } |
@@ -1404,20 +1416,29 @@ static void nodemgr_suspend_ne(struct node_entry *ne) | |||
1404 | 1416 | ||
1405 | static void nodemgr_resume_ne(struct node_entry *ne) | 1417 | static void nodemgr_resume_ne(struct node_entry *ne) |
1406 | { | 1418 | { |
1407 | struct class_device *cdev; | 1419 | struct device *dev; |
1408 | struct unit_directory *ud; | 1420 | struct unit_directory *ud; |
1421 | struct device_driver *drv; | ||
1409 | 1422 | ||
1410 | ne->in_limbo = 0; | 1423 | ne->in_limbo = 0; |
1411 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); | 1424 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); |
1412 | 1425 | ||
1413 | down(&nodemgr_ud_class.sem); | 1426 | down(&nodemgr_ud_class.sem); |
1414 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 1427 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { |
1415 | ud = container_of(cdev, struct unit_directory, class_dev); | 1428 | ud = container_of(dev, struct unit_directory, unit_dev); |
1416 | if (ud->ne != ne) | 1429 | if (ud->ne != ne) |
1417 | continue; | 1430 | continue; |
1418 | 1431 | ||
1419 | if (ud->device.driver && ud->device.driver->resume) | 1432 | drv = get_driver(ud->device.driver); |
1420 | ud->device.driver->resume(&ud->device); | 1433 | if (!drv) |
1434 | continue; | ||
1435 | |||
1436 | if (drv->resume) { | ||
1437 | down(&ud->device.sem); | ||
1438 | drv->resume(&ud->device); | ||
1439 | up(&ud->device.sem); | ||
1440 | } | ||
1441 | put_driver(drv); | ||
1421 | } | 1442 | } |
1422 | up(&nodemgr_ud_class.sem); | 1443 | up(&nodemgr_ud_class.sem); |
1423 | 1444 | ||
@@ -1428,23 +1449,32 @@ static void nodemgr_resume_ne(struct node_entry *ne) | |||
1428 | 1449 | ||
1429 | static void nodemgr_update_pdrv(struct node_entry *ne) | 1450 | static void nodemgr_update_pdrv(struct node_entry *ne) |
1430 | { | 1451 | { |
1452 | struct device *dev; | ||
1431 | struct unit_directory *ud; | 1453 | struct unit_directory *ud; |
1454 | struct device_driver *drv; | ||
1432 | struct hpsb_protocol_driver *pdrv; | 1455 | struct hpsb_protocol_driver *pdrv; |
1433 | struct class_device *cdev; | 1456 | int error; |
1434 | 1457 | ||
1435 | down(&nodemgr_ud_class.sem); | 1458 | down(&nodemgr_ud_class.sem); |
1436 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 1459 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { |
1437 | ud = container_of(cdev, struct unit_directory, class_dev); | 1460 | ud = container_of(dev, struct unit_directory, unit_dev); |
1438 | if (ud->ne != ne) | 1461 | if (ud->ne != ne) |
1439 | continue; | 1462 | continue; |
1440 | 1463 | ||
1441 | if (ud->device.driver) { | 1464 | drv = get_driver(ud->device.driver); |
1442 | pdrv = container_of(ud->device.driver, | 1465 | if (!drv) |
1443 | struct hpsb_protocol_driver, | 1466 | continue; |
1444 | driver); | 1467 | |
1445 | if (pdrv->update && pdrv->update(ud)) | 1468 | error = 0; |
1446 | device_release_driver(&ud->device); | 1469 | pdrv = container_of(drv, struct hpsb_protocol_driver, driver); |
1470 | if (pdrv->update) { | ||
1471 | down(&ud->device.sem); | ||
1472 | error = pdrv->update(ud); | ||
1473 | up(&ud->device.sem); | ||
1447 | } | 1474 | } |
1475 | if (error) | ||
1476 | device_release_driver(&ud->device); | ||
1477 | put_driver(drv); | ||
1448 | } | 1478 | } |
1449 | up(&nodemgr_ud_class.sem); | 1479 | up(&nodemgr_ud_class.sem); |
1450 | } | 1480 | } |
@@ -1509,7 +1539,7 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge | |||
1509 | static void nodemgr_node_probe(struct host_info *hi, int generation) | 1539 | static void nodemgr_node_probe(struct host_info *hi, int generation) |
1510 | { | 1540 | { |
1511 | struct hpsb_host *host = hi->host; | 1541 | struct hpsb_host *host = hi->host; |
1512 | struct class_device *cdev; | 1542 | struct device *dev; |
1513 | struct node_entry *ne; | 1543 | struct node_entry *ne; |
1514 | 1544 | ||
1515 | /* Do some processing of the nodes we've probed. This pulls them | 1545 | /* Do some processing of the nodes we've probed. This pulls them |
@@ -1522,13 +1552,13 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1522 | * improvement...) */ | 1552 | * improvement...) */ |
1523 | 1553 | ||
1524 | down(&nodemgr_ne_class.sem); | 1554 | down(&nodemgr_ne_class.sem); |
1525 | list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { | 1555 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { |
1526 | ne = container_of(cdev, struct node_entry, class_dev); | 1556 | ne = container_of(dev, struct node_entry, node_dev); |
1527 | if (!ne->needs_probe) | 1557 | if (!ne->needs_probe) |
1528 | nodemgr_probe_ne(hi, ne, generation); | 1558 | nodemgr_probe_ne(hi, ne, generation); |
1529 | } | 1559 | } |
1530 | list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { | 1560 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { |
1531 | ne = container_of(cdev, struct node_entry, class_dev); | 1561 | ne = container_of(dev, struct node_entry, node_dev); |
1532 | if (ne->needs_probe) | 1562 | if (ne->needs_probe) |
1533 | nodemgr_probe_ne(hi, ne, generation); | 1563 | nodemgr_probe_ne(hi, ne, generation); |
1534 | } | 1564 | } |
@@ -1686,18 +1716,12 @@ static int nodemgr_host_thread(void *__hi) | |||
1686 | if (kthread_should_stop()) | 1716 | if (kthread_should_stop()) |
1687 | goto exit; | 1717 | goto exit; |
1688 | 1718 | ||
1689 | if (mutex_lock_interruptible(&nodemgr_serialize)) { | ||
1690 | if (try_to_freeze()) | ||
1691 | continue; | ||
1692 | goto exit; | ||
1693 | } | ||
1694 | |||
1695 | /* Pause for 1/4 second in 1/16 second intervals, | 1719 | /* Pause for 1/4 second in 1/16 second intervals, |
1696 | * to make sure things settle down. */ | 1720 | * to make sure things settle down. */ |
1697 | g = get_hpsb_generation(host); | 1721 | g = get_hpsb_generation(host); |
1698 | for (i = 0; i < 4 ; i++) { | 1722 | for (i = 0; i < 4 ; i++) { |
1699 | if (msleep_interruptible(63) || kthread_should_stop()) | 1723 | if (msleep_interruptible(63) || kthread_should_stop()) |
1700 | goto unlock_exit; | 1724 | goto exit; |
1701 | 1725 | ||
1702 | /* Now get the generation in which the node ID's we collect | 1726 | /* Now get the generation in which the node ID's we collect |
1703 | * are valid. During the bus scan we will use this generation | 1727 | * are valid. During the bus scan we will use this generation |
@@ -1715,7 +1739,6 @@ static int nodemgr_host_thread(void *__hi) | |||
1715 | if (!nodemgr_check_irm_capability(host, reset_cycles) || | 1739 | if (!nodemgr_check_irm_capability(host, reset_cycles) || |
1716 | !nodemgr_do_irm_duties(host, reset_cycles)) { | 1740 | !nodemgr_do_irm_duties(host, reset_cycles)) { |
1717 | reset_cycles++; | 1741 | reset_cycles++; |
1718 | mutex_unlock(&nodemgr_serialize); | ||
1719 | continue; | 1742 | continue; |
1720 | } | 1743 | } |
1721 | reset_cycles = 0; | 1744 | reset_cycles = 0; |
@@ -1732,11 +1755,7 @@ static int nodemgr_host_thread(void *__hi) | |||
1732 | 1755 | ||
1733 | /* Update some of our sysfs symlinks */ | 1756 | /* Update some of our sysfs symlinks */ |
1734 | nodemgr_update_host_dev_links(host); | 1757 | nodemgr_update_host_dev_links(host); |
1735 | |||
1736 | mutex_unlock(&nodemgr_serialize); | ||
1737 | } | 1758 | } |
1738 | unlock_exit: | ||
1739 | mutex_unlock(&nodemgr_serialize); | ||
1740 | exit: | 1759 | exit: |
1741 | HPSB_VERBOSE("NodeMgr: Exiting thread"); | 1760 | HPSB_VERBOSE("NodeMgr: Exiting thread"); |
1742 | return 0; | 1761 | return 0; |
@@ -1756,13 +1775,13 @@ exit: | |||
1756 | */ | 1775 | */ |
1757 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) | 1776 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) |
1758 | { | 1777 | { |
1759 | struct class_device *cdev; | 1778 | struct device *dev; |
1760 | struct hpsb_host *host; | 1779 | struct hpsb_host *host; |
1761 | int error = 0; | 1780 | int error = 0; |
1762 | 1781 | ||
1763 | down(&hpsb_host_class.sem); | 1782 | down(&hpsb_host_class.sem); |
1764 | list_for_each_entry(cdev, &hpsb_host_class.children, node) { | 1783 | list_for_each_entry(dev, &hpsb_host_class.devices, node) { |
1765 | host = container_of(cdev, struct hpsb_host, class_dev); | 1784 | host = container_of(dev, struct hpsb_host, host_dev); |
1766 | 1785 | ||
1767 | if ((error = cb(host, data))) | 1786 | if ((error = cb(host, data))) |
1768 | break; | 1787 | break; |
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h index 4530b29d941c..919e92e2a955 100644 --- a/drivers/ieee1394/nodemgr.h +++ b/drivers/ieee1394/nodemgr.h | |||
@@ -84,7 +84,7 @@ struct unit_directory { | |||
84 | int length; /* Number of quadlets */ | 84 | int length; /* Number of quadlets */ |
85 | 85 | ||
86 | struct device device; | 86 | struct device device; |
87 | struct class_device class_dev; | 87 | struct device unit_dev; |
88 | 88 | ||
89 | struct csr1212_keyval *ud_kv; | 89 | struct csr1212_keyval *ud_kv; |
90 | u32 lun; /* logical unit number immediate value */ | 90 | u32 lun; /* logical unit number immediate value */ |
@@ -107,7 +107,7 @@ struct node_entry { | |||
107 | u32 capabilities; | 107 | u32 capabilities; |
108 | 108 | ||
109 | struct device device; | 109 | struct device device; |
110 | struct class_device class_dev; | 110 | struct device node_dev; |
111 | 111 | ||
112 | /* Means this node is not attached anymore */ | 112 | /* Means this node is not attached anymore */ |
113 | int in_limbo; | 113 | int in_limbo; |
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 5dadfd296f79..5667c8102efc 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -138,19 +138,6 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host-> | |||
138 | #define DBGMSG(fmt, args...) do {} while (0) | 138 | #define DBGMSG(fmt, args...) do {} while (0) |
139 | #endif | 139 | #endif |
140 | 140 | ||
141 | #ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG | ||
142 | #define OHCI_DMA_ALLOC(fmt, args...) \ | ||
143 | HPSB_ERR("%s(%s)alloc(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \ | ||
144 | ++global_outstanding_dmas, ## args) | ||
145 | #define OHCI_DMA_FREE(fmt, args...) \ | ||
146 | HPSB_ERR("%s(%s)free(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \ | ||
147 | --global_outstanding_dmas, ## args) | ||
148 | static int global_outstanding_dmas = 0; | ||
149 | #else | ||
150 | #define OHCI_DMA_ALLOC(fmt, args...) do {} while (0) | ||
151 | #define OHCI_DMA_FREE(fmt, args...) do {} while (0) | ||
152 | #endif | ||
153 | |||
154 | /* print general (card independent) information */ | 141 | /* print general (card independent) information */ |
155 | #define PRINT_G(level, fmt, args...) \ | 142 | #define PRINT_G(level, fmt, args...) \ |
156 | printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) | 143 | printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) |
@@ -170,7 +157,6 @@ static void dma_trm_reset(struct dma_trm_ctx *d); | |||
170 | static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, | 157 | static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, |
171 | enum context_type type, int ctx, int num_desc, | 158 | enum context_type type, int ctx, int num_desc, |
172 | int buf_size, int split_buf_size, int context_base); | 159 | int buf_size, int split_buf_size, int context_base); |
173 | static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d); | ||
174 | static void free_dma_rcv_ctx(struct dma_rcv_ctx *d); | 160 | static void free_dma_rcv_ctx(struct dma_rcv_ctx *d); |
175 | 161 | ||
176 | static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, | 162 | static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, |
@@ -533,9 +519,6 @@ static void ohci_initialize(struct ti_ohci *ohci) | |||
533 | initialize_dma_trm_ctx(&ohci->at_req_context); | 519 | initialize_dma_trm_ctx(&ohci->at_req_context); |
534 | initialize_dma_trm_ctx(&ohci->at_resp_context); | 520 | initialize_dma_trm_ctx(&ohci->at_resp_context); |
535 | 521 | ||
536 | /* Initialize IR Legacy DMA channel mask */ | ||
537 | ohci->ir_legacy_channels = 0; | ||
538 | |||
539 | /* Accept AR requests from all nodes */ | 522 | /* Accept AR requests from all nodes */ |
540 | reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000); | 523 | reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000); |
541 | 524 | ||
@@ -733,7 +716,6 @@ static void insert_packet(struct ti_ohci *ohci, | |||
733 | pci_map_single(ohci->dev, packet->data, | 716 | pci_map_single(ohci->dev, packet->data, |
734 | packet->data_size, | 717 | packet->data_size, |
735 | PCI_DMA_TODEVICE)); | 718 | PCI_DMA_TODEVICE)); |
736 | OHCI_DMA_ALLOC("single, block transmit packet"); | ||
737 | 719 | ||
738 | d->prg_cpu[idx]->end.branchAddress = 0; | 720 | d->prg_cpu[idx]->end.branchAddress = 0; |
739 | d->prg_cpu[idx]->end.status = 0; | 721 | d->prg_cpu[idx]->end.status = 0; |
@@ -783,7 +765,6 @@ static void insert_packet(struct ti_ohci *ohci, | |||
783 | d->prg_cpu[idx]->end.address = cpu_to_le32( | 765 | d->prg_cpu[idx]->end.address = cpu_to_le32( |
784 | pci_map_single(ohci->dev, packet->data, | 766 | pci_map_single(ohci->dev, packet->data, |
785 | packet->data_size, PCI_DMA_TODEVICE)); | 767 | packet->data_size, PCI_DMA_TODEVICE)); |
786 | OHCI_DMA_ALLOC("single, iso transmit packet"); | ||
787 | 768 | ||
788 | d->prg_cpu[idx]->end.branchAddress = 0; | 769 | d->prg_cpu[idx]->end.branchAddress = 0; |
789 | d->prg_cpu[idx]->end.status = 0; | 770 | d->prg_cpu[idx]->end.status = 0; |
@@ -884,36 +865,9 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet) | |||
884 | return -EOVERFLOW; | 865 | return -EOVERFLOW; |
885 | } | 866 | } |
886 | 867 | ||
887 | /* Decide whether we have an iso, a request, or a response packet */ | ||
888 | if (packet->type == hpsb_raw) | 868 | if (packet->type == hpsb_raw) |
889 | d = &ohci->at_req_context; | 869 | d = &ohci->at_req_context; |
890 | else if ((packet->tcode == TCODE_ISO_DATA) && (packet->type == hpsb_iso)) { | 870 | else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA)) |
891 | /* The legacy IT DMA context is initialized on first | ||
892 | * use. However, the alloc cannot be run from | ||
893 | * interrupt context, so we bail out if that is the | ||
894 | * case. I don't see anyone sending ISO packets from | ||
895 | * interrupt context anyway... */ | ||
896 | |||
897 | if (ohci->it_legacy_context.ohci == NULL) { | ||
898 | if (in_interrupt()) { | ||
899 | PRINT(KERN_ERR, | ||
900 | "legacy IT context cannot be initialized during interrupt"); | ||
901 | return -EINVAL; | ||
902 | } | ||
903 | |||
904 | if (alloc_dma_trm_ctx(ohci, &ohci->it_legacy_context, | ||
905 | DMA_CTX_ISO, 0, IT_NUM_DESC, | ||
906 | OHCI1394_IsoXmitContextBase) < 0) { | ||
907 | PRINT(KERN_ERR, | ||
908 | "error initializing legacy IT context"); | ||
909 | return -ENOMEM; | ||
910 | } | ||
911 | |||
912 | initialize_dma_trm_ctx(&ohci->it_legacy_context); | ||
913 | } | ||
914 | |||
915 | d = &ohci->it_legacy_context; | ||
916 | } else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA)) | ||
917 | d = &ohci->at_resp_context; | 871 | d = &ohci->at_resp_context; |
918 | else | 872 | else |
919 | d = &ohci->at_req_context; | 873 | d = &ohci->at_req_context; |
@@ -932,9 +886,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet) | |||
932 | static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) | 886 | static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) |
933 | { | 887 | { |
934 | struct ti_ohci *ohci = host->hostdata; | 888 | struct ti_ohci *ohci = host->hostdata; |
935 | int retval = 0; | 889 | int retval = 0, phy_reg; |
936 | unsigned long flags; | ||
937 | int phy_reg; | ||
938 | 890 | ||
939 | switch (cmd) { | 891 | switch (cmd) { |
940 | case RESET_BUS: | 892 | case RESET_BUS: |
@@ -1027,117 +979,6 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) | |||
1027 | dma_trm_reset(&ohci->at_resp_context); | 979 | dma_trm_reset(&ohci->at_resp_context); |
1028 | break; | 980 | break; |
1029 | 981 | ||
1030 | case ISO_LISTEN_CHANNEL: | ||
1031 | { | ||
1032 | u64 mask; | ||
1033 | struct dma_rcv_ctx *d = &ohci->ir_legacy_context; | ||
1034 | int ir_legacy_active; | ||
1035 | |||
1036 | if (arg<0 || arg>63) { | ||
1037 | PRINT(KERN_ERR, | ||
1038 | "%s: IS0 listen channel %d is out of range", | ||
1039 | __FUNCTION__, arg); | ||
1040 | return -EFAULT; | ||
1041 | } | ||
1042 | |||
1043 | mask = (u64)0x1<<arg; | ||
1044 | |||
1045 | spin_lock_irqsave(&ohci->IR_channel_lock, flags); | ||
1046 | |||
1047 | if (ohci->ISO_channel_usage & mask) { | ||
1048 | PRINT(KERN_ERR, | ||
1049 | "%s: IS0 listen channel %d is already used", | ||
1050 | __FUNCTION__, arg); | ||
1051 | spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); | ||
1052 | return -EFAULT; | ||
1053 | } | ||
1054 | |||
1055 | ir_legacy_active = ohci->ir_legacy_channels; | ||
1056 | |||
1057 | ohci->ISO_channel_usage |= mask; | ||
1058 | ohci->ir_legacy_channels |= mask; | ||
1059 | |||
1060 | spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); | ||
1061 | |||
1062 | if (!ir_legacy_active) { | ||
1063 | if (ohci1394_register_iso_tasklet(ohci, | ||
1064 | &ohci->ir_legacy_tasklet) < 0) { | ||
1065 | PRINT(KERN_ERR, "No IR DMA context available"); | ||
1066 | return -EBUSY; | ||
1067 | } | ||
1068 | |||
1069 | /* the IR context can be assigned to any DMA context | ||
1070 | * by ohci1394_register_iso_tasklet */ | ||
1071 | d->ctx = ohci->ir_legacy_tasklet.context; | ||
1072 | d->ctrlSet = OHCI1394_IsoRcvContextControlSet + | ||
1073 | 32*d->ctx; | ||
1074 | d->ctrlClear = OHCI1394_IsoRcvContextControlClear + | ||
1075 | 32*d->ctx; | ||
1076 | d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx; | ||
1077 | d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx; | ||
1078 | |||
1079 | initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1); | ||
1080 | |||
1081 | if (printk_ratelimit()) | ||
1082 | DBGMSG("IR legacy activated"); | ||
1083 | } | ||
1084 | |||
1085 | spin_lock_irqsave(&ohci->IR_channel_lock, flags); | ||
1086 | |||
1087 | if (arg>31) | ||
1088 | reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet, | ||
1089 | 1<<(arg-32)); | ||
1090 | else | ||
1091 | reg_write(ohci, OHCI1394_IRMultiChanMaskLoSet, | ||
1092 | 1<<arg); | ||
1093 | |||
1094 | spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); | ||
1095 | DBGMSG("Listening enabled on channel %d", arg); | ||
1096 | break; | ||
1097 | } | ||
1098 | case ISO_UNLISTEN_CHANNEL: | ||
1099 | { | ||
1100 | u64 mask; | ||
1101 | |||
1102 | if (arg<0 || arg>63) { | ||
1103 | PRINT(KERN_ERR, | ||
1104 | "%s: IS0 unlisten channel %d is out of range", | ||
1105 | __FUNCTION__, arg); | ||
1106 | return -EFAULT; | ||
1107 | } | ||
1108 | |||
1109 | mask = (u64)0x1<<arg; | ||
1110 | |||
1111 | spin_lock_irqsave(&ohci->IR_channel_lock, flags); | ||
1112 | |||
1113 | if (!(ohci->ISO_channel_usage & mask)) { | ||
1114 | PRINT(KERN_ERR, | ||
1115 | "%s: IS0 unlisten channel %d is not used", | ||
1116 | __FUNCTION__, arg); | ||
1117 | spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); | ||
1118 | return -EFAULT; | ||
1119 | } | ||
1120 | |||
1121 | ohci->ISO_channel_usage &= ~mask; | ||
1122 | ohci->ir_legacy_channels &= ~mask; | ||
1123 | |||
1124 | if (arg>31) | ||
1125 | reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear, | ||
1126 | 1<<(arg-32)); | ||
1127 | else | ||
1128 | reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear, | ||
1129 | 1<<arg); | ||
1130 | |||
1131 | spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); | ||
1132 | DBGMSG("Listening disabled on channel %d", arg); | ||
1133 | |||
1134 | if (ohci->ir_legacy_channels == 0) { | ||
1135 | stop_dma_rcv_ctx(&ohci->ir_legacy_context); | ||
1136 | DBGMSG("ISO legacy receive context stopped"); | ||
1137 | } | ||
1138 | |||
1139 | break; | ||
1140 | } | ||
1141 | default: | 982 | default: |
1142 | PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet", | 983 | PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet", |
1143 | cmd); | 984 | cmd); |
@@ -2869,12 +2710,10 @@ static void dma_trm_tasklet (unsigned long data) | |||
2869 | list_del_init(&packet->driver_list); | 2710 | list_del_init(&packet->driver_list); |
2870 | hpsb_packet_sent(ohci->host, packet, ack); | 2711 | hpsb_packet_sent(ohci->host, packet, ack); |
2871 | 2712 | ||
2872 | if (datasize) { | 2713 | if (datasize) |
2873 | pci_unmap_single(ohci->dev, | 2714 | pci_unmap_single(ohci->dev, |
2874 | cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address), | 2715 | cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address), |
2875 | datasize, PCI_DMA_TODEVICE); | 2716 | datasize, PCI_DMA_TODEVICE); |
2876 | OHCI_DMA_FREE("single Xmit data packet"); | ||
2877 | } | ||
2878 | 2717 | ||
2879 | d->sent_ind = (d->sent_ind+1)%d->num_desc; | 2718 | d->sent_ind = (d->sent_ind+1)%d->num_desc; |
2880 | d->free_prgs++; | 2719 | d->free_prgs++; |
@@ -2885,22 +2724,6 @@ static void dma_trm_tasklet (unsigned long data) | |||
2885 | spin_unlock_irqrestore(&d->lock, flags); | 2724 | spin_unlock_irqrestore(&d->lock, flags); |
2886 | } | 2725 | } |
2887 | 2726 | ||
2888 | static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d) | ||
2889 | { | ||
2890 | if (d->ctrlClear) { | ||
2891 | ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); | ||
2892 | |||
2893 | if (d->type == DMA_CTX_ISO) { | ||
2894 | /* disable interrupts */ | ||
2895 | reg_write(d->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << d->ctx); | ||
2896 | ohci1394_unregister_iso_tasklet(d->ohci, &d->ohci->ir_legacy_tasklet); | ||
2897 | } else { | ||
2898 | tasklet_kill(&d->task); | ||
2899 | } | ||
2900 | } | ||
2901 | } | ||
2902 | |||
2903 | |||
2904 | static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) | 2727 | static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) |
2905 | { | 2728 | { |
2906 | int i; | 2729 | int i; |
@@ -2913,23 +2736,19 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) | |||
2913 | 2736 | ||
2914 | if (d->buf_cpu) { | 2737 | if (d->buf_cpu) { |
2915 | for (i=0; i<d->num_desc; i++) | 2738 | for (i=0; i<d->num_desc; i++) |
2916 | if (d->buf_cpu[i] && d->buf_bus[i]) { | 2739 | if (d->buf_cpu[i] && d->buf_bus[i]) |
2917 | pci_free_consistent( | 2740 | pci_free_consistent( |
2918 | ohci->dev, d->buf_size, | 2741 | ohci->dev, d->buf_size, |
2919 | d->buf_cpu[i], d->buf_bus[i]); | 2742 | d->buf_cpu[i], d->buf_bus[i]); |
2920 | OHCI_DMA_FREE("consistent dma_rcv buf[%d]", i); | ||
2921 | } | ||
2922 | kfree(d->buf_cpu); | 2743 | kfree(d->buf_cpu); |
2923 | kfree(d->buf_bus); | 2744 | kfree(d->buf_bus); |
2924 | } | 2745 | } |
2925 | if (d->prg_cpu) { | 2746 | if (d->prg_cpu) { |
2926 | for (i=0; i<d->num_desc; i++) | 2747 | for (i=0; i<d->num_desc; i++) |
2927 | if (d->prg_cpu[i] && d->prg_bus[i]) { | 2748 | if (d->prg_cpu[i] && d->prg_bus[i]) |
2928 | pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); | 2749 | pci_pool_free(d->prg_pool, d->prg_cpu[i], |
2929 | OHCI_DMA_FREE("consistent dma_rcv prg[%d]", i); | 2750 | d->prg_bus[i]); |
2930 | } | ||
2931 | pci_pool_destroy(d->prg_pool); | 2751 | pci_pool_destroy(d->prg_pool); |
2932 | OHCI_DMA_FREE("dma_rcv prg pool"); | ||
2933 | kfree(d->prg_cpu); | 2752 | kfree(d->prg_cpu); |
2934 | kfree(d->prg_bus); | 2753 | kfree(d->prg_bus); |
2935 | } | 2754 | } |
@@ -2998,13 +2817,10 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, | |||
2998 | } | 2817 | } |
2999 | num_allocs++; | 2818 | num_allocs++; |
3000 | 2819 | ||
3001 | OHCI_DMA_ALLOC("dma_rcv prg pool"); | ||
3002 | |||
3003 | for (i=0; i<d->num_desc; i++) { | 2820 | for (i=0; i<d->num_desc; i++) { |
3004 | d->buf_cpu[i] = pci_alloc_consistent(ohci->dev, | 2821 | d->buf_cpu[i] = pci_alloc_consistent(ohci->dev, |
3005 | d->buf_size, | 2822 | d->buf_size, |
3006 | d->buf_bus+i); | 2823 | d->buf_bus+i); |
3007 | OHCI_DMA_ALLOC("consistent dma_rcv buf[%d]", i); | ||
3008 | 2824 | ||
3009 | if (d->buf_cpu[i] != NULL) { | 2825 | if (d->buf_cpu[i] != NULL) { |
3010 | memset(d->buf_cpu[i], 0, d->buf_size); | 2826 | memset(d->buf_cpu[i], 0, d->buf_size); |
@@ -3016,7 +2832,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, | |||
3016 | } | 2832 | } |
3017 | 2833 | ||
3018 | d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); | 2834 | d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); |
3019 | OHCI_DMA_ALLOC("pool dma_rcv prg[%d]", i); | ||
3020 | 2835 | ||
3021 | if (d->prg_cpu[i] != NULL) { | 2836 | if (d->prg_cpu[i] != NULL) { |
3022 | memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd)); | 2837 | memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd)); |
@@ -3030,18 +2845,11 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, | |||
3030 | 2845 | ||
3031 | spin_lock_init(&d->lock); | 2846 | spin_lock_init(&d->lock); |
3032 | 2847 | ||
3033 | if (type == DMA_CTX_ISO) { | 2848 | d->ctrlSet = context_base + OHCI1394_ContextControlSet; |
3034 | ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet, | 2849 | d->ctrlClear = context_base + OHCI1394_ContextControlClear; |
3035 | OHCI_ISO_MULTICHANNEL_RECEIVE, | 2850 | d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; |
3036 | dma_rcv_tasklet, (unsigned long) d); | ||
3037 | } else { | ||
3038 | d->ctrlSet = context_base + OHCI1394_ContextControlSet; | ||
3039 | d->ctrlClear = context_base + OHCI1394_ContextControlClear; | ||
3040 | d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; | ||
3041 | |||
3042 | tasklet_init (&d->task, dma_rcv_tasklet, (unsigned long) d); | ||
3043 | } | ||
3044 | 2851 | ||
2852 | tasklet_init(&d->task, dma_rcv_tasklet, (unsigned long) d); | ||
3045 | return 0; | 2853 | return 0; |
3046 | } | 2854 | } |
3047 | 2855 | ||
@@ -3057,12 +2865,10 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d) | |||
3057 | 2865 | ||
3058 | if (d->prg_cpu) { | 2866 | if (d->prg_cpu) { |
3059 | for (i=0; i<d->num_desc; i++) | 2867 | for (i=0; i<d->num_desc; i++) |
3060 | if (d->prg_cpu[i] && d->prg_bus[i]) { | 2868 | if (d->prg_cpu[i] && d->prg_bus[i]) |
3061 | pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); | 2869 | pci_pool_free(d->prg_pool, d->prg_cpu[i], |
3062 | OHCI_DMA_FREE("pool dma_trm prg[%d]", i); | 2870 | d->prg_bus[i]); |
3063 | } | ||
3064 | pci_pool_destroy(d->prg_pool); | 2871 | pci_pool_destroy(d->prg_pool); |
3065 | OHCI_DMA_FREE("dma_trm prg pool"); | ||
3066 | kfree(d->prg_cpu); | 2872 | kfree(d->prg_cpu); |
3067 | kfree(d->prg_bus); | 2873 | kfree(d->prg_bus); |
3068 | } | 2874 | } |
@@ -3108,11 +2914,8 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, | |||
3108 | } | 2914 | } |
3109 | num_allocs++; | 2915 | num_allocs++; |
3110 | 2916 | ||
3111 | OHCI_DMA_ALLOC("dma_rcv prg pool"); | ||
3112 | |||
3113 | for (i = 0; i < d->num_desc; i++) { | 2917 | for (i = 0; i < d->num_desc; i++) { |
3114 | d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); | 2918 | d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); |
3115 | OHCI_DMA_ALLOC("pool dma_trm prg[%d]", i); | ||
3116 | 2919 | ||
3117 | if (d->prg_cpu[i] != NULL) { | 2920 | if (d->prg_cpu[i] != NULL) { |
3118 | memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg)); | 2921 | memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg)); |
@@ -3127,28 +2930,10 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, | |||
3127 | spin_lock_init(&d->lock); | 2930 | spin_lock_init(&d->lock); |
3128 | 2931 | ||
3129 | /* initialize tasklet */ | 2932 | /* initialize tasklet */ |
3130 | if (type == DMA_CTX_ISO) { | 2933 | d->ctrlSet = context_base + OHCI1394_ContextControlSet; |
3131 | ohci1394_init_iso_tasklet(&ohci->it_legacy_tasklet, OHCI_ISO_TRANSMIT, | 2934 | d->ctrlClear = context_base + OHCI1394_ContextControlClear; |
3132 | dma_trm_tasklet, (unsigned long) d); | 2935 | d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; |
3133 | if (ohci1394_register_iso_tasklet(ohci, | 2936 | tasklet_init(&d->task, dma_trm_tasklet, (unsigned long)d); |
3134 | &ohci->it_legacy_tasklet) < 0) { | ||
3135 | PRINT(KERN_ERR, "No IT DMA context available"); | ||
3136 | free_dma_trm_ctx(d); | ||
3137 | return -EBUSY; | ||
3138 | } | ||
3139 | |||
3140 | /* IT can be assigned to any context by register_iso_tasklet */ | ||
3141 | d->ctx = ohci->it_legacy_tasklet.context; | ||
3142 | d->ctrlSet = OHCI1394_IsoXmitContextControlSet + 16 * d->ctx; | ||
3143 | d->ctrlClear = OHCI1394_IsoXmitContextControlClear + 16 * d->ctx; | ||
3144 | d->cmdPtr = OHCI1394_IsoXmitCommandPtr + 16 * d->ctx; | ||
3145 | } else { | ||
3146 | d->ctrlSet = context_base + OHCI1394_ContextControlSet; | ||
3147 | d->ctrlClear = context_base + OHCI1394_ContextControlClear; | ||
3148 | d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; | ||
3149 | tasklet_init (&d->task, dma_trm_tasklet, (unsigned long)d); | ||
3150 | } | ||
3151 | |||
3152 | return 0; | 2937 | return 0; |
3153 | } | 2938 | } |
3154 | 2939 | ||
@@ -3294,7 +3079,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, | |||
3294 | ohci->csr_config_rom_cpu = | 3079 | ohci->csr_config_rom_cpu = |
3295 | pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, | 3080 | pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, |
3296 | &ohci->csr_config_rom_bus); | 3081 | &ohci->csr_config_rom_bus); |
3297 | OHCI_DMA_ALLOC("consistent csr_config_rom"); | ||
3298 | if (ohci->csr_config_rom_cpu == NULL) | 3082 | if (ohci->csr_config_rom_cpu == NULL) |
3299 | FAIL(-ENOMEM, "Failed to allocate buffer config rom"); | 3083 | FAIL(-ENOMEM, "Failed to allocate buffer config rom"); |
3300 | ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER; | 3084 | ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER; |
@@ -3303,8 +3087,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, | |||
3303 | ohci->selfid_buf_cpu = | 3087 | ohci->selfid_buf_cpu = |
3304 | pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, | 3088 | pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, |
3305 | &ohci->selfid_buf_bus); | 3089 | &ohci->selfid_buf_bus); |
3306 | OHCI_DMA_ALLOC("consistent selfid_buf"); | ||
3307 | |||
3308 | if (ohci->selfid_buf_cpu == NULL) | 3090 | if (ohci->selfid_buf_cpu == NULL) |
3309 | FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets"); | 3091 | FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets"); |
3310 | ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER; | 3092 | ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER; |
@@ -3377,20 +3159,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, | |||
3377 | ohci->ISO_channel_usage = 0; | 3159 | ohci->ISO_channel_usage = 0; |
3378 | spin_lock_init(&ohci->IR_channel_lock); | 3160 | spin_lock_init(&ohci->IR_channel_lock); |
3379 | 3161 | ||
3380 | /* Allocate the IR DMA context right here so we don't have | ||
3381 | * to do it in interrupt path - note that this doesn't | ||
3382 | * waste much memory and avoids the jugglery required to | ||
3383 | * allocate it in IRQ path. */ | ||
3384 | if (alloc_dma_rcv_ctx(ohci, &ohci->ir_legacy_context, | ||
3385 | DMA_CTX_ISO, 0, IR_NUM_DESC, | ||
3386 | IR_BUF_SIZE, IR_SPLIT_BUF_SIZE, | ||
3387 | OHCI1394_IsoRcvContextBase) < 0) { | ||
3388 | FAIL(-ENOMEM, "Cannot allocate IR Legacy DMA context"); | ||
3389 | } | ||
3390 | |||
3391 | /* We hopefully don't have to pre-allocate IT DMA like we did | ||
3392 | * for IR DMA above. Allocate it on-demand and mark inactive. */ | ||
3393 | ohci->it_legacy_context.ohci = NULL; | ||
3394 | spin_lock_init(&ohci->event_lock); | 3162 | spin_lock_init(&ohci->event_lock); |
3395 | 3163 | ||
3396 | /* | 3164 | /* |
@@ -3483,20 +3251,16 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) | |||
3483 | free_dma_rcv_ctx(&ohci->ar_resp_context); | 3251 | free_dma_rcv_ctx(&ohci->ar_resp_context); |
3484 | free_dma_trm_ctx(&ohci->at_req_context); | 3252 | free_dma_trm_ctx(&ohci->at_req_context); |
3485 | free_dma_trm_ctx(&ohci->at_resp_context); | 3253 | free_dma_trm_ctx(&ohci->at_resp_context); |
3486 | free_dma_rcv_ctx(&ohci->ir_legacy_context); | ||
3487 | free_dma_trm_ctx(&ohci->it_legacy_context); | ||
3488 | 3254 | ||
3489 | case OHCI_INIT_HAVE_SELFID_BUFFER: | 3255 | case OHCI_INIT_HAVE_SELFID_BUFFER: |
3490 | pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, | 3256 | pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, |
3491 | ohci->selfid_buf_cpu, | 3257 | ohci->selfid_buf_cpu, |
3492 | ohci->selfid_buf_bus); | 3258 | ohci->selfid_buf_bus); |
3493 | OHCI_DMA_FREE("consistent selfid_buf"); | ||
3494 | 3259 | ||
3495 | case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER: | 3260 | case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER: |
3496 | pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, | 3261 | pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, |
3497 | ohci->csr_config_rom_cpu, | 3262 | ohci->csr_config_rom_cpu, |
3498 | ohci->csr_config_rom_bus); | 3263 | ohci->csr_config_rom_bus); |
3499 | OHCI_DMA_FREE("consistent csr_config_rom"); | ||
3500 | 3264 | ||
3501 | case OHCI_INIT_HAVE_IOMAPPING: | 3265 | case OHCI_INIT_HAVE_IOMAPPING: |
3502 | iounmap(ohci->registers); | 3266 | iounmap(ohci->registers); |
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h index f1ad539e7c1b..4320bf010495 100644 --- a/drivers/ieee1394/ohci1394.h +++ b/drivers/ieee1394/ohci1394.h | |||
@@ -190,23 +190,10 @@ struct ti_ohci { | |||
190 | unsigned long ir_multichannel_used; /* ditto */ | 190 | unsigned long ir_multichannel_used; /* ditto */ |
191 | spinlock_t IR_channel_lock; | 191 | spinlock_t IR_channel_lock; |
192 | 192 | ||
193 | /* iso receive (legacy API) */ | ||
194 | u64 ir_legacy_channels; /* note: this differs from ISO_channel_usage; | ||
195 | it only accounts for channels listened to | ||
196 | by the legacy API, so that we can know when | ||
197 | it is safe to free the legacy API context */ | ||
198 | |||
199 | struct dma_rcv_ctx ir_legacy_context; | ||
200 | struct ohci1394_iso_tasklet ir_legacy_tasklet; | ||
201 | |||
202 | /* iso transmit */ | 193 | /* iso transmit */ |
203 | int nb_iso_xmit_ctx; | 194 | int nb_iso_xmit_ctx; |
204 | unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */ | 195 | unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */ |
205 | 196 | ||
206 | /* iso transmit (legacy API) */ | ||
207 | struct dma_trm_ctx it_legacy_context; | ||
208 | struct ohci1394_iso_tasklet it_legacy_tasklet; | ||
209 | |||
210 | u64 ISO_channel_usage; | 197 | u64 ISO_channel_usage; |
211 | 198 | ||
212 | /* IEEE-1394 part follows */ | 199 | /* IEEE-1394 part follows */ |
@@ -221,7 +208,6 @@ struct ti_ohci { | |||
221 | 208 | ||
222 | /* Tasklets for iso receive and transmit, used by video1394 | 209 | /* Tasklets for iso receive and transmit, used by video1394 |
223 | * and dv1394 */ | 210 | * and dv1394 */ |
224 | |||
225 | struct list_head iso_tasklet_list; | 211 | struct list_head iso_tasklet_list; |
226 | spinlock_t iso_tasklet_list_lock; | 212 | spinlock_t iso_tasklet_list_lock; |
227 | 213 | ||
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index 0742befe9227..d1a5bcdb5e0b 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c | |||
@@ -477,7 +477,11 @@ static void send_next(struct ti_lynx *lynx, int what) | |||
477 | struct lynx_send_data *d; | 477 | struct lynx_send_data *d; |
478 | struct hpsb_packet *packet; | 478 | struct hpsb_packet *packet; |
479 | 479 | ||
480 | #if 0 /* has been removed from ieee1394 core */ | ||
480 | d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async); | 481 | d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async); |
482 | #else | ||
483 | d = &lynx->async; | ||
484 | #endif | ||
481 | if (!list_empty(&d->pcl_queue)) { | 485 | if (!list_empty(&d->pcl_queue)) { |
482 | PRINT(KERN_ERR, lynx->id, "trying to queue a new packet in nonempty fifo"); | 486 | PRINT(KERN_ERR, lynx->id, "trying to queue a new packet in nonempty fifo"); |
483 | BUG(); | 487 | BUG(); |
@@ -511,9 +515,11 @@ static void send_next(struct ti_lynx *lynx, int what) | |||
511 | case hpsb_async: | 515 | case hpsb_async: |
512 | pcl.buffer[0].control |= PCL_CMD_XMT; | 516 | pcl.buffer[0].control |= PCL_CMD_XMT; |
513 | break; | 517 | break; |
518 | #if 0 /* has been removed from ieee1394 core */ | ||
514 | case hpsb_iso: | 519 | case hpsb_iso: |
515 | pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE; | 520 | pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE; |
516 | break; | 521 | break; |
522 | #endif | ||
517 | case hpsb_raw: | 523 | case hpsb_raw: |
518 | pcl.buffer[0].control |= PCL_CMD_UNFXMT; | 524 | pcl.buffer[0].control |= PCL_CMD_UNFXMT; |
519 | break; | 525 | break; |
@@ -542,9 +548,11 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet) | |||
542 | case hpsb_raw: | 548 | case hpsb_raw: |
543 | d = &lynx->async; | 549 | d = &lynx->async; |
544 | break; | 550 | break; |
551 | #if 0 /* has been removed from ieee1394 core */ | ||
545 | case hpsb_iso: | 552 | case hpsb_iso: |
546 | d = &lynx->iso_send; | 553 | d = &lynx->iso_send; |
547 | break; | 554 | break; |
555 | #endif | ||
548 | default: | 556 | default: |
549 | PRINT(KERN_ERR, lynx->id, "invalid packet type %d", | 557 | PRINT(KERN_ERR, lynx->id, "invalid packet type %d", |
550 | packet->type); | 558 | packet->type); |
@@ -797,7 +805,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) | |||
797 | } | 805 | } |
798 | 806 | ||
799 | break; | 807 | break; |
800 | 808 | #if 0 /* has been removed from ieee1394 core */ | |
801 | case ISO_LISTEN_CHANNEL: | 809 | case ISO_LISTEN_CHANNEL: |
802 | spin_lock_irqsave(&lynx->iso_rcv.lock, flags); | 810 | spin_lock_irqsave(&lynx->iso_rcv.lock, flags); |
803 | 811 | ||
@@ -819,7 +827,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) | |||
819 | 827 | ||
820 | spin_unlock_irqrestore(&lynx->iso_rcv.lock, flags); | 828 | spin_unlock_irqrestore(&lynx->iso_rcv.lock, flags); |
821 | break; | 829 | break; |
822 | 830 | #endif | |
823 | default: | 831 | default: |
824 | PRINT(KERN_ERR, lynx->id, "unknown devctl command %d", cmd); | 832 | PRINT(KERN_ERR, lynx->id, "unknown devctl command %d", cmd); |
825 | retval = -1; | 833 | retval = -1; |
@@ -1009,11 +1017,11 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id) | |||
1009 | pci_unmap_single(lynx->dev, lynx->iso_send.data_dma, | 1017 | pci_unmap_single(lynx->dev, lynx->iso_send.data_dma, |
1010 | packet->data_size, PCI_DMA_TODEVICE); | 1018 | packet->data_size, PCI_DMA_TODEVICE); |
1011 | } | 1019 | } |
1012 | 1020 | #if 0 /* has been removed from ieee1394 core */ | |
1013 | if (!list_empty(&lynx->iso_send.queue)) { | 1021 | if (!list_empty(&lynx->iso_send.queue)) { |
1014 | send_next(lynx, hpsb_iso); | 1022 | send_next(lynx, hpsb_iso); |
1015 | } | 1023 | } |
1016 | 1024 | #endif | |
1017 | spin_unlock(&lynx->iso_send.queue_lock); | 1025 | spin_unlock(&lynx->iso_send.queue_lock); |
1018 | 1026 | ||
1019 | if (pcl.pcl_status & DMA_CHAN_STAT_PKTCMPL) { | 1027 | if (pcl.pcl_status & DMA_CHAN_STAT_PKTCMPL) { |
diff --git a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h index 50daabf6e5fa..a06aaad5b448 100644 --- a/drivers/ieee1394/raw1394-private.h +++ b/drivers/ieee1394/raw1394-private.h | |||
@@ -36,11 +36,6 @@ struct file_info { | |||
36 | 36 | ||
37 | u8 __user *fcp_buffer; | 37 | u8 __user *fcp_buffer; |
38 | 38 | ||
39 | /* old ISO API */ | ||
40 | u64 listen_channels; | ||
41 | quadlet_t __user *iso_buffer; | ||
42 | size_t iso_buffer_length; | ||
43 | |||
44 | u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */ | 39 | u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */ |
45 | 40 | ||
46 | /* new rawiso API */ | 41 | /* new rawiso API */ |
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index f1d05eeb9f51..336e5ff4cfcf 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c | |||
@@ -98,21 +98,6 @@ static struct hpsb_address_ops arm_ops = { | |||
98 | 98 | ||
99 | static void queue_complete_cb(struct pending_request *req); | 99 | static void queue_complete_cb(struct pending_request *req); |
100 | 100 | ||
101 | #include <asm/current.h> | ||
102 | static void print_old_iso_deprecation(void) | ||
103 | { | ||
104 | static pid_t p; | ||
105 | |||
106 | if (p == current->pid) | ||
107 | return; | ||
108 | p = current->pid; | ||
109 | printk(KERN_WARNING "raw1394: WARNING - Program \"%s\" uses unsupported" | ||
110 | " isochronous request types which will be removed in a next" | ||
111 | " kernel release\n", current->comm); | ||
112 | printk(KERN_WARNING "raw1394: Update your software to use libraw1394's" | ||
113 | " newer interface\n"); | ||
114 | } | ||
115 | |||
116 | static struct pending_request *__alloc_pending_request(gfp_t flags) | 101 | static struct pending_request *__alloc_pending_request(gfp_t flags) |
117 | { | 102 | { |
118 | struct pending_request *req; | 103 | struct pending_request *req; |
@@ -297,67 +282,6 @@ static void host_reset(struct hpsb_host *host) | |||
297 | spin_unlock_irqrestore(&host_info_lock, flags); | 282 | spin_unlock_irqrestore(&host_info_lock, flags); |
298 | } | 283 | } |
299 | 284 | ||
300 | static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data, | ||
301 | size_t length) | ||
302 | { | ||
303 | unsigned long flags; | ||
304 | struct host_info *hi; | ||
305 | struct file_info *fi; | ||
306 | struct pending_request *req, *req_next; | ||
307 | struct iso_block_store *ibs = NULL; | ||
308 | LIST_HEAD(reqs); | ||
309 | |||
310 | if ((atomic_read(&iso_buffer_size) + length) > iso_buffer_max) { | ||
311 | HPSB_INFO("dropped iso packet"); | ||
312 | return; | ||
313 | } | ||
314 | |||
315 | spin_lock_irqsave(&host_info_lock, flags); | ||
316 | hi = find_host_info(host); | ||
317 | |||
318 | if (hi != NULL) { | ||
319 | list_for_each_entry(fi, &hi->file_info_list, list) { | ||
320 | if (!(fi->listen_channels & (1ULL << channel))) | ||
321 | continue; | ||
322 | |||
323 | req = __alloc_pending_request(GFP_ATOMIC); | ||
324 | if (!req) | ||
325 | break; | ||
326 | |||
327 | if (!ibs) { | ||
328 | ibs = kmalloc(sizeof(*ibs) + length, | ||
329 | GFP_ATOMIC); | ||
330 | if (!ibs) { | ||
331 | kfree(req); | ||
332 | break; | ||
333 | } | ||
334 | |||
335 | atomic_add(length, &iso_buffer_size); | ||
336 | atomic_set(&ibs->refcount, 0); | ||
337 | ibs->data_size = length; | ||
338 | memcpy(ibs->data, data, length); | ||
339 | } | ||
340 | |||
341 | atomic_inc(&ibs->refcount); | ||
342 | |||
343 | req->file_info = fi; | ||
344 | req->ibs = ibs; | ||
345 | req->data = ibs->data; | ||
346 | req->req.type = RAW1394_REQ_ISO_RECEIVE; | ||
347 | req->req.generation = get_hpsb_generation(host); | ||
348 | req->req.misc = 0; | ||
349 | req->req.recvb = ptr2int(fi->iso_buffer); | ||
350 | req->req.length = min(length, fi->iso_buffer_length); | ||
351 | |||
352 | list_add_tail(&req->list, &reqs); | ||
353 | } | ||
354 | } | ||
355 | spin_unlock_irqrestore(&host_info_lock, flags); | ||
356 | |||
357 | list_for_each_entry_safe(req, req_next, &reqs, list) | ||
358 | queue_complete_req(req); | ||
359 | } | ||
360 | |||
361 | static void fcp_request(struct hpsb_host *host, int nodeid, int direction, | 285 | static void fcp_request(struct hpsb_host *host, int nodeid, int direction, |
362 | int cts, u8 * data, size_t length) | 286 | int cts, u8 * data, size_t length) |
363 | { | 287 | { |
@@ -434,7 +358,11 @@ struct compat_raw1394_req { | |||
434 | 358 | ||
435 | __u64 sendb; | 359 | __u64 sendb; |
436 | __u64 recvb; | 360 | __u64 recvb; |
437 | } __attribute__((packed)); | 361 | } |
362 | #if defined(CONFIG_X86_64) || defined(CONFIG_IA64) | ||
363 | __attribute__((packed)) | ||
364 | #endif | ||
365 | ; | ||
438 | 366 | ||
439 | static const char __user *raw1394_compat_write(const char __user *buf) | 367 | static const char __user *raw1394_compat_write(const char __user *buf) |
440 | { | 368 | { |
@@ -459,7 +387,7 @@ static const char __user *raw1394_compat_write(const char __user *buf) | |||
459 | static int | 387 | static int |
460 | raw1394_compat_read(const char __user *buf, struct raw1394_request *r) | 388 | raw1394_compat_read(const char __user *buf, struct raw1394_request *r) |
461 | { | 389 | { |
462 | struct compat_raw1394_req __user *cr = (typeof(cr)) r; | 390 | struct compat_raw1394_req __user *cr = (typeof(cr)) buf; |
463 | if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) || | 391 | if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) || |
464 | P(type) || | 392 | P(type) || |
465 | P(error) || | 393 | P(error) || |
@@ -587,7 +515,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req) | |||
587 | 515 | ||
588 | req->req.length = 0; | 516 | req->req.length = 0; |
589 | queue_complete_req(req); | 517 | queue_complete_req(req); |
590 | return sizeof(struct raw1394_request); | 518 | return 0; |
591 | } | 519 | } |
592 | 520 | ||
593 | static int state_initialized(struct file_info *fi, struct pending_request *req) | 521 | static int state_initialized(struct file_info *fi, struct pending_request *req) |
@@ -601,7 +529,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) | |||
601 | req->req.generation = atomic_read(&internal_generation); | 529 | req->req.generation = atomic_read(&internal_generation); |
602 | req->req.length = 0; | 530 | req->req.length = 0; |
603 | queue_complete_req(req); | 531 | queue_complete_req(req); |
604 | return sizeof(struct raw1394_request); | 532 | return 0; |
605 | } | 533 | } |
606 | 534 | ||
607 | switch (req->req.type) { | 535 | switch (req->req.type) { |
@@ -673,44 +601,7 @@ out_set_card: | |||
673 | } | 601 | } |
674 | 602 | ||
675 | queue_complete_req(req); | 603 | queue_complete_req(req); |
676 | return sizeof(struct raw1394_request); | 604 | return 0; |
677 | } | ||
678 | |||
679 | static void handle_iso_listen(struct file_info *fi, struct pending_request *req) | ||
680 | { | ||
681 | int channel = req->req.misc; | ||
682 | |||
683 | if ((channel > 63) || (channel < -64)) { | ||
684 | req->req.error = RAW1394_ERROR_INVALID_ARG; | ||
685 | } else if (channel >= 0) { | ||
686 | /* allocate channel req.misc */ | ||
687 | if (fi->listen_channels & (1ULL << channel)) { | ||
688 | req->req.error = RAW1394_ERROR_ALREADY; | ||
689 | } else { | ||
690 | if (hpsb_listen_channel | ||
691 | (&raw1394_highlevel, fi->host, channel)) { | ||
692 | req->req.error = RAW1394_ERROR_ALREADY; | ||
693 | } else { | ||
694 | fi->listen_channels |= 1ULL << channel; | ||
695 | fi->iso_buffer = int2ptr(req->req.recvb); | ||
696 | fi->iso_buffer_length = req->req.length; | ||
697 | } | ||
698 | } | ||
699 | } else { | ||
700 | /* deallocate channel (one's complement neg) req.misc */ | ||
701 | channel = ~channel; | ||
702 | |||
703 | if (fi->listen_channels & (1ULL << channel)) { | ||
704 | hpsb_unlisten_channel(&raw1394_highlevel, fi->host, | ||
705 | channel); | ||
706 | fi->listen_channels &= ~(1ULL << channel); | ||
707 | } else { | ||
708 | req->req.error = RAW1394_ERROR_INVALID_ARG; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | req->req.length = 0; | ||
713 | queue_complete_req(req); | ||
714 | } | 605 | } |
715 | 606 | ||
716 | static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) | 607 | static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) |
@@ -865,7 +756,7 @@ static int handle_async_request(struct file_info *fi, | |||
865 | if (req->req.error) { | 756 | if (req->req.error) { |
866 | req->req.length = 0; | 757 | req->req.length = 0; |
867 | queue_complete_req(req); | 758 | queue_complete_req(req); |
868 | return sizeof(struct raw1394_request); | 759 | return 0; |
869 | } | 760 | } |
870 | 761 | ||
871 | hpsb_set_packet_complete_task(packet, | 762 | hpsb_set_packet_complete_task(packet, |
@@ -883,51 +774,7 @@ static int handle_async_request(struct file_info *fi, | |||
883 | hpsb_free_tlabel(packet); | 774 | hpsb_free_tlabel(packet); |
884 | queue_complete_req(req); | 775 | queue_complete_req(req); |
885 | } | 776 | } |
886 | return sizeof(struct raw1394_request); | 777 | return 0; |
887 | } | ||
888 | |||
889 | static int handle_iso_send(struct file_info *fi, struct pending_request *req, | ||
890 | int channel) | ||
891 | { | ||
892 | unsigned long flags; | ||
893 | struct hpsb_packet *packet; | ||
894 | |||
895 | packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f, | ||
896 | (req->req.misc >> 16) & 0x3, | ||
897 | req->req.misc & 0xf); | ||
898 | if (!packet) | ||
899 | return -ENOMEM; | ||
900 | |||
901 | packet->speed_code = req->req.address & 0x3; | ||
902 | |||
903 | req->packet = packet; | ||
904 | |||
905 | if (copy_from_user(packet->data, int2ptr(req->req.sendb), | ||
906 | req->req.length)) { | ||
907 | req->req.error = RAW1394_ERROR_MEMFAULT; | ||
908 | req->req.length = 0; | ||
909 | queue_complete_req(req); | ||
910 | return sizeof(struct raw1394_request); | ||
911 | } | ||
912 | |||
913 | req->req.length = 0; | ||
914 | hpsb_set_packet_complete_task(packet, | ||
915 | (void (*)(void *))queue_complete_req, | ||
916 | req); | ||
917 | |||
918 | spin_lock_irqsave(&fi->reqlists_lock, flags); | ||
919 | list_add_tail(&req->list, &fi->req_pending); | ||
920 | spin_unlock_irqrestore(&fi->reqlists_lock, flags); | ||
921 | |||
922 | /* Update the generation of the packet just before sending. */ | ||
923 | packet->generation = req->req.generation; | ||
924 | |||
925 | if (hpsb_send_packet(packet) < 0) { | ||
926 | req->req.error = RAW1394_ERROR_SEND_ERROR; | ||
927 | queue_complete_req(req); | ||
928 | } | ||
929 | |||
930 | return sizeof(struct raw1394_request); | ||
931 | } | 778 | } |
932 | 779 | ||
933 | static int handle_async_send(struct file_info *fi, struct pending_request *req) | 780 | static int handle_async_send(struct file_info *fi, struct pending_request *req) |
@@ -943,7 +790,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) | |||
943 | req->req.error = RAW1394_ERROR_INVALID_ARG; | 790 | req->req.error = RAW1394_ERROR_INVALID_ARG; |
944 | req->req.length = 0; | 791 | req->req.length = 0; |
945 | queue_complete_req(req); | 792 | queue_complete_req(req); |
946 | return sizeof(struct raw1394_request); | 793 | return 0; |
947 | } | 794 | } |
948 | 795 | ||
949 | data_size = req->req.length - header_length; | 796 | data_size = req->req.length - header_length; |
@@ -957,7 +804,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) | |||
957 | req->req.error = RAW1394_ERROR_MEMFAULT; | 804 | req->req.error = RAW1394_ERROR_MEMFAULT; |
958 | req->req.length = 0; | 805 | req->req.length = 0; |
959 | queue_complete_req(req); | 806 | queue_complete_req(req); |
960 | return sizeof(struct raw1394_request); | 807 | return 0; |
961 | } | 808 | } |
962 | 809 | ||
963 | if (copy_from_user | 810 | if (copy_from_user |
@@ -966,7 +813,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) | |||
966 | req->req.error = RAW1394_ERROR_MEMFAULT; | 813 | req->req.error = RAW1394_ERROR_MEMFAULT; |
967 | req->req.length = 0; | 814 | req->req.length = 0; |
968 | queue_complete_req(req); | 815 | queue_complete_req(req); |
969 | return sizeof(struct raw1394_request); | 816 | return 0; |
970 | } | 817 | } |
971 | 818 | ||
972 | packet->type = hpsb_async; | 819 | packet->type = hpsb_async; |
@@ -994,7 +841,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) | |||
994 | queue_complete_req(req); | 841 | queue_complete_req(req); |
995 | } | 842 | } |
996 | 843 | ||
997 | return sizeof(struct raw1394_request); | 844 | return 0; |
998 | } | 845 | } |
999 | 846 | ||
1000 | static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, | 847 | static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, |
@@ -1869,7 +1716,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) | |||
1869 | spin_lock_irqsave(&host_info_lock, flags); | 1716 | spin_lock_irqsave(&host_info_lock, flags); |
1870 | list_add_tail(&addr->addr_list, &fi->addr_list); | 1717 | list_add_tail(&addr->addr_list, &fi->addr_list); |
1871 | spin_unlock_irqrestore(&host_info_lock, flags); | 1718 | spin_unlock_irqrestore(&host_info_lock, flags); |
1872 | return sizeof(struct raw1394_request); | 1719 | return 0; |
1873 | } | 1720 | } |
1874 | retval = | 1721 | retval = |
1875 | hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, | 1722 | hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, |
@@ -1887,7 +1734,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) | |||
1887 | return (-EALREADY); | 1734 | return (-EALREADY); |
1888 | } | 1735 | } |
1889 | free_pending_request(req); /* immediate success or fail */ | 1736 | free_pending_request(req); /* immediate success or fail */ |
1890 | return sizeof(struct raw1394_request); | 1737 | return 0; |
1891 | } | 1738 | } |
1892 | 1739 | ||
1893 | static int arm_unregister(struct file_info *fi, struct pending_request *req) | 1740 | static int arm_unregister(struct file_info *fi, struct pending_request *req) |
@@ -1955,7 +1802,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) | |||
1955 | vfree(addr->addr_space_buffer); | 1802 | vfree(addr->addr_space_buffer); |
1956 | kfree(addr); | 1803 | kfree(addr); |
1957 | free_pending_request(req); /* immediate success or fail */ | 1804 | free_pending_request(req); /* immediate success or fail */ |
1958 | return sizeof(struct raw1394_request); | 1805 | return 0; |
1959 | } | 1806 | } |
1960 | retval = | 1807 | retval = |
1961 | hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, | 1808 | hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, |
@@ -1971,7 +1818,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) | |||
1971 | vfree(addr->addr_space_buffer); | 1818 | vfree(addr->addr_space_buffer); |
1972 | kfree(addr); | 1819 | kfree(addr); |
1973 | free_pending_request(req); /* immediate success or fail */ | 1820 | free_pending_request(req); /* immediate success or fail */ |
1974 | return sizeof(struct raw1394_request); | 1821 | return 0; |
1975 | } | 1822 | } |
1976 | 1823 | ||
1977 | /* Copy data from ARM buffer(s) to user buffer. */ | 1824 | /* Copy data from ARM buffer(s) to user buffer. */ |
@@ -2013,7 +1860,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req) | |||
2013 | * queue no response, and therefore nobody | 1860 | * queue no response, and therefore nobody |
2014 | * will free it. */ | 1861 | * will free it. */ |
2015 | free_pending_request(req); | 1862 | free_pending_request(req); |
2016 | return sizeof(struct raw1394_request); | 1863 | return 0; |
2017 | } else { | 1864 | } else { |
2018 | DBGMSG("arm_get_buf request exceeded mapping"); | 1865 | DBGMSG("arm_get_buf request exceeded mapping"); |
2019 | spin_unlock_irqrestore(&host_info_lock, flags); | 1866 | spin_unlock_irqrestore(&host_info_lock, flags); |
@@ -2065,7 +1912,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req) | |||
2065 | * queue no response, and therefore nobody | 1912 | * queue no response, and therefore nobody |
2066 | * will free it. */ | 1913 | * will free it. */ |
2067 | free_pending_request(req); | 1914 | free_pending_request(req); |
2068 | return sizeof(struct raw1394_request); | 1915 | return 0; |
2069 | } else { | 1916 | } else { |
2070 | DBGMSG("arm_set_buf request exceeded mapping"); | 1917 | DBGMSG("arm_set_buf request exceeded mapping"); |
2071 | spin_unlock_irqrestore(&host_info_lock, flags); | 1918 | spin_unlock_irqrestore(&host_info_lock, flags); |
@@ -2086,7 +1933,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req) | |||
2086 | (req->req.misc == RAW1394_NOTIFY_ON)) { | 1933 | (req->req.misc == RAW1394_NOTIFY_ON)) { |
2087 | fi->notification = (u8) req->req.misc; | 1934 | fi->notification = (u8) req->req.misc; |
2088 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ | 1935 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ |
2089 | return sizeof(struct raw1394_request); | 1936 | return 0; |
2090 | } | 1937 | } |
2091 | /* error EINVAL (22) invalid argument */ | 1938 | /* error EINVAL (22) invalid argument */ |
2092 | return (-EINVAL); | 1939 | return (-EINVAL); |
@@ -2119,12 +1966,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req) | |||
2119 | req->req.length = 0; | 1966 | req->req.length = 0; |
2120 | queue_complete_req(req); | 1967 | queue_complete_req(req); |
2121 | } | 1968 | } |
2122 | return sizeof(struct raw1394_request); | 1969 | return 0; |
2123 | } | 1970 | } |
2124 | 1971 | ||
2125 | static int get_config_rom(struct file_info *fi, struct pending_request *req) | 1972 | static int get_config_rom(struct file_info *fi, struct pending_request *req) |
2126 | { | 1973 | { |
2127 | int ret = sizeof(struct raw1394_request); | 1974 | int ret = 0; |
2128 | quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); | 1975 | quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); |
2129 | int status; | 1976 | int status; |
2130 | 1977 | ||
@@ -2154,7 +2001,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req) | |||
2154 | 2001 | ||
2155 | static int update_config_rom(struct file_info *fi, struct pending_request *req) | 2002 | static int update_config_rom(struct file_info *fi, struct pending_request *req) |
2156 | { | 2003 | { |
2157 | int ret = sizeof(struct raw1394_request); | 2004 | int ret = 0; |
2158 | quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); | 2005 | quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); |
2159 | if (!data) | 2006 | if (!data) |
2160 | return -ENOMEM; | 2007 | return -ENOMEM; |
@@ -2221,7 +2068,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) | |||
2221 | 2068 | ||
2222 | hpsb_update_config_rom_image(fi->host); | 2069 | hpsb_update_config_rom_image(fi->host); |
2223 | free_pending_request(req); | 2070 | free_pending_request(req); |
2224 | return sizeof(struct raw1394_request); | 2071 | return 0; |
2225 | } | 2072 | } |
2226 | } | 2073 | } |
2227 | 2074 | ||
@@ -2286,7 +2133,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) | |||
2286 | /* we have to free the request, because we queue no response, | 2133 | /* we have to free the request, because we queue no response, |
2287 | * and therefore nobody will free it */ | 2134 | * and therefore nobody will free it */ |
2288 | free_pending_request(req); | 2135 | free_pending_request(req); |
2289 | return sizeof(struct raw1394_request); | 2136 | return 0; |
2290 | } else { | 2137 | } else { |
2291 | for (dentry = | 2138 | for (dentry = |
2292 | fi->csr1212_dirs[dr]->value.directory.dentries_head; | 2139 | fi->csr1212_dirs[dr]->value.directory.dentries_head; |
@@ -2311,11 +2158,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) | |||
2311 | 2158 | ||
2312 | case RAW1394_REQ_ECHO: | 2159 | case RAW1394_REQ_ECHO: |
2313 | queue_complete_req(req); | 2160 | queue_complete_req(req); |
2314 | return sizeof(struct raw1394_request); | 2161 | return 0; |
2315 | |||
2316 | case RAW1394_REQ_ISO_SEND: | ||
2317 | print_old_iso_deprecation(); | ||
2318 | return handle_iso_send(fi, req, node); | ||
2319 | 2162 | ||
2320 | case RAW1394_REQ_ARM_REGISTER: | 2163 | case RAW1394_REQ_ARM_REGISTER: |
2321 | return arm_register(fi, req); | 2164 | return arm_register(fi, req); |
@@ -2332,27 +2175,30 @@ static int state_connected(struct file_info *fi, struct pending_request *req) | |||
2332 | case RAW1394_REQ_RESET_NOTIFY: | 2175 | case RAW1394_REQ_RESET_NOTIFY: |
2333 | return reset_notification(fi, req); | 2176 | return reset_notification(fi, req); |
2334 | 2177 | ||
2178 | case RAW1394_REQ_ISO_SEND: | ||
2335 | case RAW1394_REQ_ISO_LISTEN: | 2179 | case RAW1394_REQ_ISO_LISTEN: |
2336 | print_old_iso_deprecation(); | 2180 | printk(KERN_DEBUG "raw1394: old iso ABI has been removed\n"); |
2337 | handle_iso_listen(fi, req); | 2181 | req->req.error = RAW1394_ERROR_COMPAT; |
2338 | return sizeof(struct raw1394_request); | 2182 | req->req.misc = RAW1394_KERNELAPI_VERSION; |
2183 | queue_complete_req(req); | ||
2184 | return 0; | ||
2339 | 2185 | ||
2340 | case RAW1394_REQ_FCP_LISTEN: | 2186 | case RAW1394_REQ_FCP_LISTEN: |
2341 | handle_fcp_listen(fi, req); | 2187 | handle_fcp_listen(fi, req); |
2342 | return sizeof(struct raw1394_request); | 2188 | return 0; |
2343 | 2189 | ||
2344 | case RAW1394_REQ_RESET_BUS: | 2190 | case RAW1394_REQ_RESET_BUS: |
2345 | if (req->req.misc == RAW1394_LONG_RESET) { | 2191 | if (req->req.misc == RAW1394_LONG_RESET) { |
2346 | DBGMSG("busreset called (type: LONG)"); | 2192 | DBGMSG("busreset called (type: LONG)"); |
2347 | hpsb_reset_bus(fi->host, LONG_RESET); | 2193 | hpsb_reset_bus(fi->host, LONG_RESET); |
2348 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ | 2194 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ |
2349 | return sizeof(struct raw1394_request); | 2195 | return 0; |
2350 | } | 2196 | } |
2351 | if (req->req.misc == RAW1394_SHORT_RESET) { | 2197 | if (req->req.misc == RAW1394_SHORT_RESET) { |
2352 | DBGMSG("busreset called (type: SHORT)"); | 2198 | DBGMSG("busreset called (type: SHORT)"); |
2353 | hpsb_reset_bus(fi->host, SHORT_RESET); | 2199 | hpsb_reset_bus(fi->host, SHORT_RESET); |
2354 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ | 2200 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ |
2355 | return sizeof(struct raw1394_request); | 2201 | return 0; |
2356 | } | 2202 | } |
2357 | /* error EINVAL (22) invalid argument */ | 2203 | /* error EINVAL (22) invalid argument */ |
2358 | return (-EINVAL); | 2204 | return (-EINVAL); |
@@ -2371,7 +2217,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) | |||
2371 | req->req.generation = get_hpsb_generation(fi->host); | 2217 | req->req.generation = get_hpsb_generation(fi->host); |
2372 | req->req.length = 0; | 2218 | req->req.length = 0; |
2373 | queue_complete_req(req); | 2219 | queue_complete_req(req); |
2374 | return sizeof(struct raw1394_request); | 2220 | return 0; |
2375 | } | 2221 | } |
2376 | 2222 | ||
2377 | switch (req->req.type) { | 2223 | switch (req->req.type) { |
@@ -2384,7 +2230,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) | |||
2384 | if (req->req.length == 0) { | 2230 | if (req->req.length == 0) { |
2385 | req->req.error = RAW1394_ERROR_INVALID_ARG; | 2231 | req->req.error = RAW1394_ERROR_INVALID_ARG; |
2386 | queue_complete_req(req); | 2232 | queue_complete_req(req); |
2387 | return sizeof(struct raw1394_request); | 2233 | return 0; |
2388 | } | 2234 | } |
2389 | 2235 | ||
2390 | return handle_async_request(fi, req, node); | 2236 | return handle_async_request(fi, req, node); |
@@ -2395,7 +2241,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, | |||
2395 | { | 2241 | { |
2396 | struct file_info *fi = (struct file_info *)file->private_data; | 2242 | struct file_info *fi = (struct file_info *)file->private_data; |
2397 | struct pending_request *req; | 2243 | struct pending_request *req; |
2398 | ssize_t retval = 0; | 2244 | ssize_t retval = -EBADFD; |
2399 | 2245 | ||
2400 | #ifdef CONFIG_COMPAT | 2246 | #ifdef CONFIG_COMPAT |
2401 | if (count == sizeof(struct compat_raw1394_req) && | 2247 | if (count == sizeof(struct compat_raw1394_req) && |
@@ -2437,6 +2283,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, | |||
2437 | 2283 | ||
2438 | if (retval < 0) { | 2284 | if (retval < 0) { |
2439 | free_pending_request(req); | 2285 | free_pending_request(req); |
2286 | } else { | ||
2287 | BUG_ON(retval); | ||
2288 | retval = count; | ||
2440 | } | 2289 | } |
2441 | 2290 | ||
2442 | return retval; | 2291 | return retval; |
@@ -2802,6 +2651,103 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, | |||
2802 | return -EINVAL; | 2651 | return -EINVAL; |
2803 | } | 2652 | } |
2804 | 2653 | ||
2654 | #ifdef CONFIG_COMPAT | ||
2655 | struct raw1394_iso_packets32 { | ||
2656 | __u32 n_packets; | ||
2657 | compat_uptr_t infos; | ||
2658 | } __attribute__((packed)); | ||
2659 | |||
2660 | struct raw1394_cycle_timer32 { | ||
2661 | __u32 cycle_timer; | ||
2662 | __u64 local_time; | ||
2663 | } | ||
2664 | #if defined(CONFIG_X86_64) || defined(CONFIG_IA64) | ||
2665 | __attribute__((packed)) | ||
2666 | #endif | ||
2667 | ; | ||
2668 | |||
2669 | #define RAW1394_IOC_ISO_RECV_PACKETS32 \ | ||
2670 | _IOW ('#', 0x25, struct raw1394_iso_packets32) | ||
2671 | #define RAW1394_IOC_ISO_XMIT_PACKETS32 \ | ||
2672 | _IOW ('#', 0x27, struct raw1394_iso_packets32) | ||
2673 | #define RAW1394_IOC_GET_CYCLE_TIMER32 \ | ||
2674 | _IOR ('#', 0x30, struct raw1394_cycle_timer32) | ||
2675 | |||
2676 | static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd, | ||
2677 | struct raw1394_iso_packets32 __user *arg) | ||
2678 | { | ||
2679 | compat_uptr_t infos32; | ||
2680 | void *infos; | ||
2681 | long err = -EFAULT; | ||
2682 | struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets)); | ||
2683 | |||
2684 | if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) && | ||
2685 | !copy_from_user(&infos32, &arg->infos, sizeof infos32)) { | ||
2686 | infos = compat_ptr(infos32); | ||
2687 | if (!copy_to_user(&dst->infos, &infos, sizeof infos)) | ||
2688 | err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst); | ||
2689 | } | ||
2690 | return err; | ||
2691 | } | ||
2692 | |||
2693 | static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr) | ||
2694 | { | ||
2695 | struct raw1394_cycle_timer32 ct; | ||
2696 | int err; | ||
2697 | |||
2698 | err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time); | ||
2699 | if (!err) | ||
2700 | if (copy_to_user(uaddr, &ct, sizeof(ct))) | ||
2701 | err = -EFAULT; | ||
2702 | return err; | ||
2703 | } | ||
2704 | |||
2705 | static long raw1394_compat_ioctl(struct file *file, | ||
2706 | unsigned int cmd, unsigned long arg) | ||
2707 | { | ||
2708 | struct file_info *fi = file->private_data; | ||
2709 | void __user *argp = (void __user *)arg; | ||
2710 | long err; | ||
2711 | |||
2712 | lock_kernel(); | ||
2713 | switch (cmd) { | ||
2714 | /* These requests have same format as long as 'int' has same size. */ | ||
2715 | case RAW1394_IOC_ISO_RECV_INIT: | ||
2716 | case RAW1394_IOC_ISO_RECV_START: | ||
2717 | case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL: | ||
2718 | case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL: | ||
2719 | case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: | ||
2720 | case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: | ||
2721 | case RAW1394_IOC_ISO_RECV_FLUSH: | ||
2722 | case RAW1394_IOC_ISO_XMIT_RECV_STOP: | ||
2723 | case RAW1394_IOC_ISO_XMIT_INIT: | ||
2724 | case RAW1394_IOC_ISO_XMIT_START: | ||
2725 | case RAW1394_IOC_ISO_XMIT_SYNC: | ||
2726 | case RAW1394_IOC_ISO_GET_STATUS: | ||
2727 | case RAW1394_IOC_ISO_SHUTDOWN: | ||
2728 | case RAW1394_IOC_ISO_QUEUE_ACTIVITY: | ||
2729 | err = raw1394_ioctl(NULL, file, cmd, arg); | ||
2730 | break; | ||
2731 | /* These request have different format. */ | ||
2732 | case RAW1394_IOC_ISO_RECV_PACKETS32: | ||
2733 | err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp); | ||
2734 | break; | ||
2735 | case RAW1394_IOC_ISO_XMIT_PACKETS32: | ||
2736 | err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp); | ||
2737 | break; | ||
2738 | case RAW1394_IOC_GET_CYCLE_TIMER32: | ||
2739 | err = raw1394_read_cycle_timer32(fi, argp); | ||
2740 | break; | ||
2741 | default: | ||
2742 | err = -EINVAL; | ||
2743 | break; | ||
2744 | } | ||
2745 | unlock_kernel(); | ||
2746 | |||
2747 | return err; | ||
2748 | } | ||
2749 | #endif | ||
2750 | |||
2805 | static unsigned int raw1394_poll(struct file *file, poll_table * pt) | 2751 | static unsigned int raw1394_poll(struct file *file, poll_table * pt) |
2806 | { | 2752 | { |
2807 | struct file_info *fi = file->private_data; | 2753 | struct file_info *fi = file->private_data; |
@@ -2861,14 +2807,7 @@ static int raw1394_release(struct inode *inode, struct file *file) | |||
2861 | if (fi->iso_state != RAW1394_ISO_INACTIVE) | 2807 | if (fi->iso_state != RAW1394_ISO_INACTIVE) |
2862 | raw1394_iso_shutdown(fi); | 2808 | raw1394_iso_shutdown(fi); |
2863 | 2809 | ||
2864 | for (i = 0; i < 64; i++) { | ||
2865 | if (fi->listen_channels & (1ULL << i)) { | ||
2866 | hpsb_unlisten_channel(&raw1394_highlevel, fi->host, i); | ||
2867 | } | ||
2868 | } | ||
2869 | |||
2870 | spin_lock_irqsave(&host_info_lock, flags); | 2810 | spin_lock_irqsave(&host_info_lock, flags); |
2871 | fi->listen_channels = 0; | ||
2872 | 2811 | ||
2873 | fail = 0; | 2812 | fail = 0; |
2874 | /* set address-entries invalid */ | 2813 | /* set address-entries invalid */ |
@@ -3030,7 +2969,6 @@ static struct hpsb_highlevel raw1394_highlevel = { | |||
3030 | .add_host = add_host, | 2969 | .add_host = add_host, |
3031 | .remove_host = remove_host, | 2970 | .remove_host = remove_host, |
3032 | .host_reset = host_reset, | 2971 | .host_reset = host_reset, |
3033 | .iso_receive = iso_receive, | ||
3034 | .fcp_request = fcp_request, | 2972 | .fcp_request = fcp_request, |
3035 | }; | 2973 | }; |
3036 | 2974 | ||
@@ -3041,7 +2979,9 @@ static const struct file_operations raw1394_fops = { | |||
3041 | .write = raw1394_write, | 2979 | .write = raw1394_write, |
3042 | .mmap = raw1394_mmap, | 2980 | .mmap = raw1394_mmap, |
3043 | .ioctl = raw1394_ioctl, | 2981 | .ioctl = raw1394_ioctl, |
3044 | // .compat_ioctl = ... someone needs to do this | 2982 | #ifdef CONFIG_COMPAT |
2983 | .compat_ioctl = raw1394_compat_ioctl, | ||
2984 | #endif | ||
3045 | .poll = raw1394_poll, | 2985 | .poll = raw1394_poll, |
3046 | .open = raw1394_open, | 2986 | .open = raw1394_open, |
3047 | .release = raw1394_release, | 2987 | .release = raw1394_release, |
@@ -3054,9 +2994,9 @@ static int __init init_raw1394(void) | |||
3054 | hpsb_register_highlevel(&raw1394_highlevel); | 2994 | hpsb_register_highlevel(&raw1394_highlevel); |
3055 | 2995 | ||
3056 | if (IS_ERR | 2996 | if (IS_ERR |
3057 | (class_device_create | 2997 | (device_create( |
3058 | (hpsb_protocol_class, NULL, | 2998 | hpsb_protocol_class, NULL, |
3059 | MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL, | 2999 | MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), |
3060 | RAW1394_DEVICE_NAME))) { | 3000 | RAW1394_DEVICE_NAME))) { |
3061 | ret = -EFAULT; | 3001 | ret = -EFAULT; |
3062 | goto out_unreg; | 3002 | goto out_unreg; |
@@ -3083,9 +3023,9 @@ static int __init init_raw1394(void) | |||
3083 | goto out; | 3023 | goto out; |
3084 | 3024 | ||
3085 | out_dev: | 3025 | out_dev: |
3086 | class_device_destroy(hpsb_protocol_class, | 3026 | device_destroy(hpsb_protocol_class, |
3087 | MKDEV(IEEE1394_MAJOR, | 3027 | MKDEV(IEEE1394_MAJOR, |
3088 | IEEE1394_MINOR_BLOCK_RAW1394 * 16)); | 3028 | IEEE1394_MINOR_BLOCK_RAW1394 * 16)); |
3089 | out_unreg: | 3029 | out_unreg: |
3090 | hpsb_unregister_highlevel(&raw1394_highlevel); | 3030 | hpsb_unregister_highlevel(&raw1394_highlevel); |
3091 | out: | 3031 | out: |
@@ -3094,9 +3034,9 @@ static int __init init_raw1394(void) | |||
3094 | 3034 | ||
3095 | static void __exit cleanup_raw1394(void) | 3035 | static void __exit cleanup_raw1394(void) |
3096 | { | 3036 | { |
3097 | class_device_destroy(hpsb_protocol_class, | 3037 | device_destroy(hpsb_protocol_class, |
3098 | MKDEV(IEEE1394_MAJOR, | 3038 | MKDEV(IEEE1394_MAJOR, |
3099 | IEEE1394_MINOR_BLOCK_RAW1394 * 16)); | 3039 | IEEE1394_MINOR_BLOCK_RAW1394 * 16)); |
3100 | cdev_del(&raw1394_cdev); | 3040 | cdev_del(&raw1394_cdev); |
3101 | hpsb_unregister_highlevel(&raw1394_highlevel); | 3041 | hpsb_unregister_highlevel(&raw1394_highlevel); |
3102 | hpsb_unregister_protocol(&raw1394_driver); | 3042 | hpsb_unregister_protocol(&raw1394_driver); |
diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h index 7bd22ee1afbb..963ac20373d2 100644 --- a/drivers/ieee1394/raw1394.h +++ b/drivers/ieee1394/raw1394.h | |||
@@ -17,11 +17,11 @@ | |||
17 | #define RAW1394_REQ_ASYNC_WRITE 101 | 17 | #define RAW1394_REQ_ASYNC_WRITE 101 |
18 | #define RAW1394_REQ_LOCK 102 | 18 | #define RAW1394_REQ_LOCK 102 |
19 | #define RAW1394_REQ_LOCK64 103 | 19 | #define RAW1394_REQ_LOCK64 103 |
20 | #define RAW1394_REQ_ISO_SEND 104 | 20 | #define RAW1394_REQ_ISO_SEND 104 /* removed ABI, now a no-op */ |
21 | #define RAW1394_REQ_ASYNC_SEND 105 | 21 | #define RAW1394_REQ_ASYNC_SEND 105 |
22 | #define RAW1394_REQ_ASYNC_STREAM 106 | 22 | #define RAW1394_REQ_ASYNC_STREAM 106 |
23 | 23 | ||
24 | #define RAW1394_REQ_ISO_LISTEN 200 | 24 | #define RAW1394_REQ_ISO_LISTEN 200 /* removed ABI, now a no-op */ |
25 | #define RAW1394_REQ_FCP_LISTEN 201 | 25 | #define RAW1394_REQ_FCP_LISTEN 201 |
26 | #define RAW1394_REQ_RESET_BUS 202 | 26 | #define RAW1394_REQ_RESET_BUS 202 |
27 | #define RAW1394_REQ_GET_ROM 203 | 27 | #define RAW1394_REQ_GET_ROM 203 |
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 3f873cc7e247..e0c385a3b450 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -118,14 +118,13 @@ MODULE_PARM_DESC(max_speed, "Force max speed " | |||
118 | "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)"); | 118 | "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)"); |
119 | 119 | ||
120 | /* | 120 | /* |
121 | * Set serialize_io to 1 if you'd like only one scsi command sent | 121 | * Set serialize_io to 0 or N to use dynamically appended lists of command ORBs. |
122 | * down to us at a time (debugging). This might be necessary for very | 122 | * This is and always has been buggy in multiple subtle ways. See above TODOs. |
123 | * badly behaved sbp2 devices. | ||
124 | */ | 123 | */ |
125 | static int sbp2_serialize_io = 1; | 124 | static int sbp2_serialize_io = 1; |
126 | module_param_named(serialize_io, sbp2_serialize_io, int, 0444); | 125 | module_param_named(serialize_io, sbp2_serialize_io, bool, 0444); |
127 | MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers " | 126 | MODULE_PARM_DESC(serialize_io, "Serialize requests coming from SCSI drivers " |
128 | "(default = 1, faster = 0)"); | 127 | "(default = Y, faster but buggy = N)"); |
129 | 128 | ||
130 | /* | 129 | /* |
131 | * Bump up max_sectors if you'd like to support very large sized | 130 | * Bump up max_sectors if you'd like to support very large sized |
@@ -154,9 +153,9 @@ MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported " | |||
154 | * are possible on OXFW911 and newer Oxsemi bridges. | 153 | * are possible on OXFW911 and newer Oxsemi bridges. |
155 | */ | 154 | */ |
156 | static int sbp2_exclusive_login = 1; | 155 | static int sbp2_exclusive_login = 1; |
157 | module_param_named(exclusive_login, sbp2_exclusive_login, int, 0644); | 156 | module_param_named(exclusive_login, sbp2_exclusive_login, bool, 0644); |
158 | MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " | 157 | MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " |
159 | "(default = 1)"); | 158 | "(default = Y, use N for concurrent initiators)"); |
160 | 159 | ||
161 | /* | 160 | /* |
162 | * If any of the following workarounds is required for your device to work, | 161 | * If any of the following workarounds is required for your device to work, |
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index 44402b9d82a8..333a4bb76743 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
@@ -67,7 +67,7 @@ struct sbp2_command_orb { | |||
67 | #define ORB_SET_LUN(v) ((v) & 0xffff) | 67 | #define ORB_SET_LUN(v) ((v) & 0xffff) |
68 | #define ORB_SET_FUNCTION(v) (((v) & 0xf) << 16) | 68 | #define ORB_SET_FUNCTION(v) (((v) & 0xf) << 16) |
69 | #define ORB_SET_RECONNECT(v) (((v) & 0xf) << 20) | 69 | #define ORB_SET_RECONNECT(v) (((v) & 0xf) << 20) |
70 | #define ORB_SET_EXCLUSIVE(v) (((v) & 0x1) << 28) | 70 | #define ORB_SET_EXCLUSIVE(v) ((v) ? 1 << 28 : 0) |
71 | #define ORB_SET_LOGIN_RESP_LENGTH(v) ((v) & 0xffff) | 71 | #define ORB_SET_LOGIN_RESP_LENGTH(v) ((v) & 0xffff) |
72 | #define ORB_SET_PASSWD_LENGTH(v) (((v) & 0xffff) << 16) | 72 | #define ORB_SET_PASSWD_LENGTH(v) (((v) & 0xffff) << 16) |
73 | 73 | ||
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 87ebd0846c34..bd28adfd7afc 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c | |||
@@ -1340,9 +1340,9 @@ static void video1394_add_host (struct hpsb_host *host) | |||
1340 | hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); | 1340 | hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); |
1341 | 1341 | ||
1342 | minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; | 1342 | minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; |
1343 | class_device_create(hpsb_protocol_class, NULL, MKDEV( | 1343 | device_create(hpsb_protocol_class, NULL, |
1344 | IEEE1394_MAJOR, minor), | 1344 | MKDEV(IEEE1394_MAJOR, minor), |
1345 | NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); | 1345 | "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); |
1346 | } | 1346 | } |
1347 | 1347 | ||
1348 | 1348 | ||
@@ -1351,8 +1351,8 @@ static void video1394_remove_host (struct hpsb_host *host) | |||
1351 | struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); | 1351 | struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); |
1352 | 1352 | ||
1353 | if (ohci) | 1353 | if (ohci) |
1354 | class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, | 1354 | device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, |
1355 | IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); | 1355 | IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); |
1356 | return; | 1356 | return; |
1357 | } | 1357 | } |
1358 | 1358 | ||
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index efbe1fda1a22..1a45d6f41b09 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h | |||
@@ -30,16 +30,38 @@ | |||
30 | #define FW_CDEV_EVENT_REQUEST 0x02 | 30 | #define FW_CDEV_EVENT_REQUEST 0x02 |
31 | #define FW_CDEV_EVENT_ISO_INTERRUPT 0x03 | 31 | #define FW_CDEV_EVENT_ISO_INTERRUPT 0x03 |
32 | 32 | ||
33 | /* The 'closure' fields are for user space to use. Data passed in the | 33 | /** |
34 | * 'closure' field for a request will be returned in the corresponding | 34 | * struct fw_cdev_event_common - Common part of all fw_cdev_event_ types |
35 | * event. It's a 64-bit type so that it's a fixed size type big | 35 | * @closure: For arbitrary use by userspace |
36 | * enough to hold a pointer on all platforms. */ | 36 | * @type: Discriminates the fw_cdev_event_ types |
37 | 37 | * | |
38 | * This struct may be used to access generic members of all fw_cdev_event_ | ||
39 | * types regardless of the specific type. | ||
40 | * | ||
41 | * Data passed in the @closure field for a request will be returned in the | ||
42 | * corresponding event. It is big enough to hold a pointer on all platforms. | ||
43 | * The ioctl used to set @closure depends on the @type of event. | ||
44 | */ | ||
38 | struct fw_cdev_event_common { | 45 | struct fw_cdev_event_common { |
39 | __u64 closure; | 46 | __u64 closure; |
40 | __u32 type; | 47 | __u32 type; |
41 | }; | 48 | }; |
42 | 49 | ||
50 | /** | ||
51 | * struct fw_cdev_event_bus_reset - Sent when a bus reset occurred | ||
52 | * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_GET_INFO ioctl | ||
53 | * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_BUS_RESET | ||
54 | * @node_id: New node ID of this node | ||
55 | * @local_node_id: Node ID of the local node, i.e. of the controller | ||
56 | * @bm_node_id: Node ID of the bus manager | ||
57 | * @irm_node_id: Node ID of the iso resource manager | ||
58 | * @root_node_id: Node ID of the root node | ||
59 | * @generation: New bus generation | ||
60 | * | ||
61 | * This event is sent when the bus the device belongs to goes through a bus | ||
62 | * reset. It provides information about the new bus configuration, such as | ||
63 | * new node ID for this device, new root ID, and others. | ||
64 | */ | ||
43 | struct fw_cdev_event_bus_reset { | 65 | struct fw_cdev_event_bus_reset { |
44 | __u64 closure; | 66 | __u64 closure; |
45 | __u32 type; | 67 | __u32 type; |
@@ -51,6 +73,20 @@ struct fw_cdev_event_bus_reset { | |||
51 | __u32 generation; | 73 | __u32 generation; |
52 | }; | 74 | }; |
53 | 75 | ||
76 | /** | ||
77 | * struct fw_cdev_event_response - Sent when a response packet was received | ||
78 | * @closure: See &fw_cdev_event_common; | ||
79 | * set by %FW_CDEV_IOC_SEND_REQUEST ioctl | ||
80 | * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_RESPONSE | ||
81 | * @rcode: Response code returned by the remote node | ||
82 | * @length: Data length, i.e. the response's payload size in bytes | ||
83 | * @data: Payload data, if any | ||
84 | * | ||
85 | * This event is sent when the stack receives a response to an outgoing request | ||
86 | * sent by %FW_CDEV_IOC_SEND_REQUEST ioctl. The payload data for responses | ||
87 | * carrying data (read and lock responses) follows immediately and can be | ||
88 | * accessed through the @data field. | ||
89 | */ | ||
54 | struct fw_cdev_event_response { | 90 | struct fw_cdev_event_response { |
55 | __u64 closure; | 91 | __u64 closure; |
56 | __u32 type; | 92 | __u32 type; |
@@ -59,6 +95,25 @@ struct fw_cdev_event_response { | |||
59 | __u32 data[0]; | 95 | __u32 data[0]; |
60 | }; | 96 | }; |
61 | 97 | ||
98 | /** | ||
99 | * struct fw_cdev_event_request - Sent on incoming request to an address region | ||
100 | * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_ALLOCATE ioctl | ||
101 | * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_REQUEST | ||
102 | * @tcode: Transaction code of the incoming request | ||
103 | * @offset: The offset into the 48-bit per-node address space | ||
104 | * @handle: Reference to the kernel-side pending request | ||
105 | * @length: Data length, i.e. the request's payload size in bytes | ||
106 | * @data: Incoming data, if any | ||
107 | * | ||
108 | * This event is sent when the stack receives an incoming request to an address | ||
109 | * region registered using the %FW_CDEV_IOC_ALLOCATE ioctl. The request is | ||
110 | * guaranteed to be completely contained in the specified region. Userspace is | ||
111 | * responsible for sending the response by %FW_CDEV_IOC_SEND_RESPONSE ioctl, | ||
112 | * using the same @handle. | ||
113 | * | ||
114 | * The payload data for requests carrying data (write and lock requests) | ||
115 | * follows immediately and can be accessed through the @data field. | ||
116 | */ | ||
62 | struct fw_cdev_event_request { | 117 | struct fw_cdev_event_request { |
63 | __u64 closure; | 118 | __u64 closure; |
64 | __u32 type; | 119 | __u32 type; |
@@ -69,14 +124,39 @@ struct fw_cdev_event_request { | |||
69 | __u32 data[0]; | 124 | __u32 data[0]; |
70 | }; | 125 | }; |
71 | 126 | ||
127 | /** | ||
128 | * struct fw_cdev_event_iso_interrupt - Sent when an iso packet was completed | ||
129 | * @closure: See &fw_cdev_event_common; | ||
130 | * set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl | ||
131 | * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_ISO_INTERRUPT | ||
132 | * @cycle: Cycle counter of the interrupt packet | ||
133 | * @header_length: Total length of following headers, in bytes | ||
134 | * @header: Stripped headers, if any | ||
135 | * | ||
136 | * This event is sent when the controller has completed an &fw_cdev_iso_packet | ||
137 | * with the %FW_CDEV_ISO_INTERRUPT bit set. In the receive case, the headers | ||
138 | * stripped of all packets up until and including the interrupt packet are | ||
139 | * returned in the @header field. | ||
140 | */ | ||
72 | struct fw_cdev_event_iso_interrupt { | 141 | struct fw_cdev_event_iso_interrupt { |
73 | __u64 closure; | 142 | __u64 closure; |
74 | __u32 type; | 143 | __u32 type; |
75 | __u32 cycle; | 144 | __u32 cycle; |
76 | __u32 header_length; /* Length in bytes of following headers. */ | 145 | __u32 header_length; |
77 | __u32 header[0]; | 146 | __u32 header[0]; |
78 | }; | 147 | }; |
79 | 148 | ||
149 | /** | ||
150 | * union fw_cdev_event - Convenience union of fw_cdev_event_ types | ||
151 | * @common: Valid for all types | ||
152 | * @bus_reset: Valid if @common.type == %FW_CDEV_EVENT_BUS_RESET | ||
153 | * @response: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE | ||
154 | * @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST | ||
155 | * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT | ||
156 | * | ||
157 | * Convenience union for userspace use. Events could be read(2) into a char | ||
158 | * buffer and then cast to this union for further processing. | ||
159 | */ | ||
80 | union fw_cdev_event { | 160 | union fw_cdev_event { |
81 | struct fw_cdev_event_common common; | 161 | struct fw_cdev_event_common common; |
82 | struct fw_cdev_event_bus_reset bus_reset; | 162 | struct fw_cdev_event_bus_reset bus_reset; |
@@ -105,35 +185,47 @@ union fw_cdev_event { | |||
105 | */ | 185 | */ |
106 | #define FW_CDEV_VERSION 1 | 186 | #define FW_CDEV_VERSION 1 |
107 | 187 | ||
188 | /** | ||
189 | * struct fw_cdev_get_info - General purpose information ioctl | ||
190 | * @version: The version field is just a running serial number. | ||
191 | * We never break backwards compatibility, but may add more | ||
192 | * structs and ioctls in later revisions. | ||
193 | * @rom_length: If @rom is non-zero, at most rom_length bytes of configuration | ||
194 | * ROM will be copied into that user space address. In either | ||
195 | * case, @rom_length is updated with the actual length of the | ||
196 | * configuration ROM. | ||
197 | * @rom: If non-zero, address of a buffer to be filled by a copy of the | ||
198 | * local node's configuration ROM | ||
199 | * @bus_reset: If non-zero, address of a buffer to be filled by a | ||
200 | * &struct fw_cdev_event_bus_reset with the current state | ||
201 | * of the bus. This does not cause a bus reset to happen. | ||
202 | * @bus_reset_closure: Value of &closure in this and subsequent bus reset events | ||
203 | * @card: The index of the card this device belongs to | ||
204 | */ | ||
108 | struct fw_cdev_get_info { | 205 | struct fw_cdev_get_info { |
109 | /* The version field is just a running serial number. We | ||
110 | * never break backwards compatibility. Userspace passes in | ||
111 | * the version it expects and the kernel passes back the | ||
112 | * highest version it can provide. Even if the structs in | ||
113 | * this interface are extended in a later version, the kernel | ||
114 | * will not copy back more data than what was present in the | ||
115 | * interface version userspace expects. */ | ||
116 | __u32 version; | 206 | __u32 version; |
117 | |||
118 | /* If non-zero, at most rom_length bytes of config rom will be | ||
119 | * copied into that user space address. In either case, | ||
120 | * rom_length is updated with the actual length of the config | ||
121 | * rom. */ | ||
122 | __u32 rom_length; | 207 | __u32 rom_length; |
123 | __u64 rom; | 208 | __u64 rom; |
124 | |||
125 | /* If non-zero, a fw_cdev_event_bus_reset struct will be | ||
126 | * copied here with the current state of the bus. This does | ||
127 | * not cause a bus reset to happen. The value of closure in | ||
128 | * this and sub-sequent bus reset events is set to | ||
129 | * bus_reset_closure. */ | ||
130 | __u64 bus_reset; | 209 | __u64 bus_reset; |
131 | __u64 bus_reset_closure; | 210 | __u64 bus_reset_closure; |
132 | |||
133 | /* The index of the card this devices belongs to. */ | ||
134 | __u32 card; | 211 | __u32 card; |
135 | }; | 212 | }; |
136 | 213 | ||
214 | /** | ||
215 | * struct fw_cdev_send_request - Send an asynchronous request packet | ||
216 | * @tcode: Transaction code of the request | ||
217 | * @length: Length of outgoing payload, in bytes | ||
218 | * @offset: 48-bit offset at destination node | ||
219 | * @closure: Passed back to userspace in the response event | ||
220 | * @data: Userspace pointer to payload | ||
221 | * @generation: The bus generation where packet is valid | ||
222 | * | ||
223 | * Send a request to the device. This ioctl implements all outgoing requests. | ||
224 | * Both quadlet and block request specify the payload as a pointer to the data | ||
225 | * in the @data field. Once the transaction completes, the kernel writes an | ||
226 | * &fw_cdev_event_request event back. The @closure field is passed back to | ||
227 | * user space in the response event. | ||
228 | */ | ||
137 | struct fw_cdev_send_request { | 229 | struct fw_cdev_send_request { |
138 | __u32 tcode; | 230 | __u32 tcode; |
139 | __u32 length; | 231 | __u32 length; |
@@ -143,6 +235,19 @@ struct fw_cdev_send_request { | |||
143 | __u32 generation; | 235 | __u32 generation; |
144 | }; | 236 | }; |
145 | 237 | ||
238 | /** | ||
239 | * struct fw_cdev_send_response - Send an asynchronous response packet | ||
240 | * @rcode: Response code as determined by the userspace handler | ||
241 | * @length: Length of outgoing payload, in bytes | ||
242 | * @data: Userspace pointer to payload | ||
243 | * @handle: The handle from the &fw_cdev_event_request | ||
244 | * | ||
245 | * Send a response to an incoming request. By setting up an address range using | ||
246 | * the %FW_CDEV_IOC_ALLOCATE ioctl, userspace can listen for incoming requests. An | ||
247 | * incoming request will generate an %FW_CDEV_EVENT_REQUEST, and userspace must | ||
248 | * send a reply using this ioctl. The event has a handle to the kernel-side | ||
249 | * pending transaction, which should be used with this ioctl. | ||
250 | */ | ||
146 | struct fw_cdev_send_response { | 251 | struct fw_cdev_send_response { |
147 | __u32 rcode; | 252 | __u32 rcode; |
148 | __u32 length; | 253 | __u32 length; |
@@ -150,6 +255,21 @@ struct fw_cdev_send_response { | |||
150 | __u32 handle; | 255 | __u32 handle; |
151 | }; | 256 | }; |
152 | 257 | ||
258 | /** | ||
259 | * struct fw_cdev_allocate - Allocate a CSR address range | ||
260 | * @offset: Start offset of the address range | ||
261 | * @closure: To be passed back to userspace in request events | ||
262 | * @length: Length of the address range, in bytes | ||
263 | * @handle: Handle to the allocation, written by the kernel | ||
264 | * | ||
265 | * Allocate an address range in the 48-bit address space on the local node | ||
266 | * (the controller). This allows userspace to listen for requests with an | ||
267 | * offset within that address range. When the kernel receives a request | ||
268 | * within the range, an &fw_cdev_event_request event will be written back. | ||
269 | * The @closure field is passed back to userspace in the response event. | ||
270 | * The @handle field is an out parameter, returning a handle to the allocated | ||
271 | * range to be used for later deallocation of the range. | ||
272 | */ | ||
153 | struct fw_cdev_allocate { | 273 | struct fw_cdev_allocate { |
154 | __u64 offset; | 274 | __u64 offset; |
155 | __u64 closure; | 275 | __u64 closure; |
@@ -157,6 +277,11 @@ struct fw_cdev_allocate { | |||
157 | __u32 handle; | 277 | __u32 handle; |
158 | }; | 278 | }; |
159 | 279 | ||
280 | /** | ||
281 | * struct fw_cdev_deallocate - Free an address range allocation | ||
282 | * @handle: Handle to the address range, as returned by the kernel when the | ||
283 | * range was allocated | ||
284 | */ | ||
160 | struct fw_cdev_deallocate { | 285 | struct fw_cdev_deallocate { |
161 | __u32 handle; | 286 | __u32 handle; |
162 | }; | 287 | }; |
@@ -164,10 +289,41 @@ struct fw_cdev_deallocate { | |||
164 | #define FW_CDEV_LONG_RESET 0 | 289 | #define FW_CDEV_LONG_RESET 0 |
165 | #define FW_CDEV_SHORT_RESET 1 | 290 | #define FW_CDEV_SHORT_RESET 1 |
166 | 291 | ||
292 | /** | ||
293 | * struct fw_cdev_initiate_bus_reset - Initiate a bus reset | ||
294 | * @type: %FW_CDEV_SHORT_RESET or %FW_CDEV_LONG_RESET | ||
295 | * | ||
296 | * Initiate a bus reset for the bus this device is on. The bus reset can be | ||
297 | * either the original (long) bus reset or the arbitrated (short) bus reset | ||
298 | * introduced in 1394a-2000. | ||
299 | */ | ||
167 | struct fw_cdev_initiate_bus_reset { | 300 | struct fw_cdev_initiate_bus_reset { |
168 | __u32 type; | 301 | __u32 type; /* FW_CDEV_SHORT_RESET or FW_CDEV_LONG_RESET */ |
169 | }; | 302 | }; |
170 | 303 | ||
304 | /** | ||
305 | * struct fw_cdev_add_descriptor - Add contents to the local node's config ROM | ||
306 | * @immediate: If non-zero, immediate key to insert before pointer | ||
307 | * @key: Upper 8 bits of root directory pointer | ||
308 | * @data: Userspace pointer to contents of descriptor block | ||
309 | * @length: Length of descriptor block data, in bytes | ||
310 | * @handle: Handle to the descriptor, written by the kernel | ||
311 | * | ||
312 | * Add a descriptor block and optionally a preceding immediate key to the local | ||
313 | * node's configuration ROM. | ||
314 | * | ||
315 | * The @key field specifies the upper 8 bits of the descriptor root directory | ||
316 | * pointer and the @data and @length fields specify the contents. The @key | ||
317 | * should be of the form 0xXX000000. The offset part of the root directory entry | ||
318 | * will be filled in by the kernel. | ||
319 | * | ||
320 | * If not 0, the @immediate field specifies an immediate key which will be | ||
321 | * inserted before the root directory pointer. | ||
322 | * | ||
323 | * If successful, the kernel adds the descriptor and writes back a handle to the | ||
324 | * kernel-side object to be used for later removal of the descriptor block and | ||
325 | * immediate key. | ||
326 | */ | ||
171 | struct fw_cdev_add_descriptor { | 327 | struct fw_cdev_add_descriptor { |
172 | __u32 immediate; | 328 | __u32 immediate; |
173 | __u32 key; | 329 | __u32 key; |
@@ -176,6 +332,14 @@ struct fw_cdev_add_descriptor { | |||
176 | __u32 handle; | 332 | __u32 handle; |
177 | }; | 333 | }; |
178 | 334 | ||
335 | /** | ||
336 | * struct fw_cdev_remove_descriptor - Remove contents from the configuration ROM | ||
337 | * @handle: Handle to the descriptor, as returned by the kernel when the | ||
338 | * descriptor was added | ||
339 | * | ||
340 | * Remove a descriptor block and accompanying immediate key from the local | ||
341 | * node's configuration ROM. | ||
342 | */ | ||
179 | struct fw_cdev_remove_descriptor { | 343 | struct fw_cdev_remove_descriptor { |
180 | __u32 handle; | 344 | __u32 handle; |
181 | }; | 345 | }; |
@@ -183,12 +347,24 @@ struct fw_cdev_remove_descriptor { | |||
183 | #define FW_CDEV_ISO_CONTEXT_TRANSMIT 0 | 347 | #define FW_CDEV_ISO_CONTEXT_TRANSMIT 0 |
184 | #define FW_CDEV_ISO_CONTEXT_RECEIVE 1 | 348 | #define FW_CDEV_ISO_CONTEXT_RECEIVE 1 |
185 | 349 | ||
186 | #define FW_CDEV_ISO_CONTEXT_MATCH_TAG0 1 | 350 | /** |
187 | #define FW_CDEV_ISO_CONTEXT_MATCH_TAG1 2 | 351 | * struct fw_cdev_create_iso_context - Create a context for isochronous IO |
188 | #define FW_CDEV_ISO_CONTEXT_MATCH_TAG2 4 | 352 | * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE |
189 | #define FW_CDEV_ISO_CONTEXT_MATCH_TAG3 8 | 353 | * @header_size: Header size to strip for receive contexts |
190 | #define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS 15 | 354 | * @channel: Channel to bind to |
191 | 355 | * @speed: Speed to transmit at | |
356 | * @closure: To be returned in &fw_cdev_event_iso_interrupt | ||
357 | * @handle: Handle to context, written back by kernel | ||
358 | * | ||
359 | * Prior to sending or receiving isochronous I/O, a context must be created. | ||
360 | * The context records information about the transmit or receive configuration | ||
361 | * and typically maps to an underlying hardware resource. A context is set up | ||
362 | * for either sending or receiving. It is bound to a specific isochronous | ||
363 | * channel. | ||
364 | * | ||
365 | * If a context was successfully created, the kernel writes back a handle to the | ||
366 | * context, which must be passed in for subsequent operations on that context. | ||
367 | */ | ||
192 | struct fw_cdev_create_iso_context { | 368 | struct fw_cdev_create_iso_context { |
193 | __u32 type; | 369 | __u32 type; |
194 | __u32 header_size; | 370 | __u32 header_size; |
@@ -201,15 +377,49 @@ struct fw_cdev_create_iso_context { | |||
201 | #define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) | 377 | #define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) |
202 | #define FW_CDEV_ISO_INTERRUPT (1 << 16) | 378 | #define FW_CDEV_ISO_INTERRUPT (1 << 16) |
203 | #define FW_CDEV_ISO_SKIP (1 << 17) | 379 | #define FW_CDEV_ISO_SKIP (1 << 17) |
380 | #define FW_CDEV_ISO_SYNC (1 << 17) | ||
204 | #define FW_CDEV_ISO_TAG(v) ((v) << 18) | 381 | #define FW_CDEV_ISO_TAG(v) ((v) << 18) |
205 | #define FW_CDEV_ISO_SY(v) ((v) << 20) | 382 | #define FW_CDEV_ISO_SY(v) ((v) << 20) |
206 | #define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24) | 383 | #define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24) |
207 | 384 | ||
385 | /** | ||
386 | * struct fw_cdev_iso_packet - Isochronous packet | ||
387 | * @control: Contains the header length (8 uppermost bits), the sy field | ||
388 | * (4 bits), the tag field (2 bits), a sync flag (1 bit), | ||
389 | * a skip flag (1 bit), an interrupt flag (1 bit), and the | ||
390 | * payload length (16 lowermost bits) | ||
391 | * @header: Header and payload | ||
392 | * | ||
393 | * &struct fw_cdev_iso_packet is used to describe isochronous packet queues. | ||
394 | * | ||
395 | * Use the FW_CDEV_ISO_ macros to fill in @control. The sy and tag fields are | ||
396 | * specified by IEEE 1394a and IEC 61883. | ||
397 | * | ||
398 | * FIXME - finish this documentation | ||
399 | */ | ||
208 | struct fw_cdev_iso_packet { | 400 | struct fw_cdev_iso_packet { |
209 | __u32 control; | 401 | __u32 control; |
210 | __u32 header[0]; | 402 | __u32 header[0]; |
211 | }; | 403 | }; |
212 | 404 | ||
405 | /** | ||
406 | * struct fw_cdev_queue_iso - Queue isochronous packets for I/O | ||
407 | * @packets: Userspace pointer to packet data | ||
408 | * @data: Pointer into mmap()'ed payload buffer | ||
409 | * @size: Size of packet data in bytes | ||
410 | * @handle: Isochronous context handle | ||
411 | * | ||
412 | * Queue a number of isochronous packets for reception or transmission. | ||
413 | * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs, | ||
414 | * which describe how to transmit from or receive into a contiguous region | ||
415 | * of a mmap()'ed payload buffer. As part of the packet descriptors, | ||
416 | * a series of headers can be supplied, which will be prepended to the | ||
417 | * payload during DMA. | ||
418 | * | ||
419 | * The kernel may or may not queue all packets, but will write back updated | ||
420 | * values of the @packets, @data and @size fields, so the ioctl can be | ||
421 | * resubmitted easily. | ||
422 | */ | ||
213 | struct fw_cdev_queue_iso { | 423 | struct fw_cdev_queue_iso { |
214 | __u64 packets; | 424 | __u64 packets; |
215 | __u64 data; | 425 | __u64 data; |
@@ -217,6 +427,23 @@ struct fw_cdev_queue_iso { | |||
217 | __u32 handle; | 427 | __u32 handle; |
218 | }; | 428 | }; |
219 | 429 | ||
430 | #define FW_CDEV_ISO_CONTEXT_MATCH_TAG0 1 | ||
431 | #define FW_CDEV_ISO_CONTEXT_MATCH_TAG1 2 | ||
432 | #define FW_CDEV_ISO_CONTEXT_MATCH_TAG2 4 | ||
433 | #define FW_CDEV_ISO_CONTEXT_MATCH_TAG3 8 | ||
434 | #define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS 15 | ||
435 | |||
436 | /** | ||
437 | * struct fw_cdev_start_iso - Start an isochronous transmission or reception | ||
438 | * @cycle: Cycle in which to start I/O. If @cycle is greater than or | ||
439 | * equal to 0, the I/O will start on that cycle. | ||
440 | * @sync: Determines the value to wait for for receive packets that have | ||
441 | * the %FW_CDEV_ISO_SYNC bit set | ||
442 | * @tags: Tag filter bit mask. Only valid for isochronous reception. | ||
443 | * Determines the tag values for which packets will be accepted. | ||
444 | * Use FW_CDEV_ISO_CONTEXT_MATCH_ macros to set @tags. | ||
445 | * @handle: Isochronous context handle within which to transmit or receive | ||
446 | */ | ||
220 | struct fw_cdev_start_iso { | 447 | struct fw_cdev_start_iso { |
221 | __s32 cycle; | 448 | __s32 cycle; |
222 | __u32 sync; | 449 | __u32 sync; |
@@ -224,6 +451,10 @@ struct fw_cdev_start_iso { | |||
224 | __u32 handle; | 451 | __u32 handle; |
225 | }; | 452 | }; |
226 | 453 | ||
454 | /** | ||
455 | * struct fw_cdev_stop_iso - Stop an isochronous transmission or reception | ||
456 | * @handle: Handle of isochronous context to stop | ||
457 | */ | ||
227 | struct fw_cdev_stop_iso { | 458 | struct fw_cdev_stop_iso { |
228 | __u32 handle; | 459 | __u32 handle; |
229 | }; | 460 | }; |