diff options
-rw-r--r-- | MAINTAINERS | 8 | ||||
-rw-r--r-- | drivers/firewire/fw-card.c | 5 | ||||
-rw-r--r-- | drivers/firewire/fw-cdev.c | 17 | ||||
-rw-r--r-- | drivers/firewire/fw-device.h | 1 | ||||
-rw-r--r-- | drivers/firewire/fw-ohci.c | 187 | ||||
-rw-r--r-- | drivers/firewire/fw-sbp2.c | 53 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 7 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.h | 1 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.c | 31 | ||||
-rw-r--r-- | include/linux/Kbuild | 2 | ||||
-rw-r--r-- | include/linux/firewire-cdev.h | 14 |
11 files changed, 247 insertions, 79 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index aa1017556438..124b9508ae2e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1498,6 +1498,14 @@ P: Alexander Viro | |||
1498 | M: viro@zeniv.linux.org.uk | 1498 | M: viro@zeniv.linux.org.uk |
1499 | S: Maintained | 1499 | S: Maintained |
1500 | 1500 | ||
1501 | FIREWIRE SUBSYSTEM | ||
1502 | P: Kristian Hoegsberg, Stefan Richter | ||
1503 | M: krh@redhat.com, stefanr@s5r6.in-berlin.de | ||
1504 | L: linux1394-devel@lists.sourceforge.net | ||
1505 | W: http://www.linux1394.org/ | ||
1506 | T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git | ||
1507 | S: Maintained | ||
1508 | |||
1501 | FIRMWARE LOADER (request_firmware) | 1509 | FIRMWARE LOADER (request_firmware) |
1502 | L: linux-kernel@vger.kernel.org | 1510 | L: linux-kernel@vger.kernel.org |
1503 | S: Orphan | 1511 | S: Orphan |
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 636151a64add..9eb1edacd825 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c | |||
@@ -407,11 +407,6 @@ fw_card_add(struct fw_card *card, | |||
407 | card->link_speed = link_speed; | 407 | card->link_speed = link_speed; |
408 | card->guid = guid; | 408 | card->guid = guid; |
409 | 409 | ||
410 | /* Activate link_on bit and contender bit in our self ID packets.*/ | ||
411 | if (card->driver->update_phy_reg(card, 4, 0, | ||
412 | PHY_LINK_ACTIVE | PHY_CONTENDER) < 0) | ||
413 | return -EIO; | ||
414 | |||
415 | /* | 410 | /* |
416 | * The subsystem grabs a reference when the card is added and | 411 | * The subsystem grabs a reference when the card is added and |
417 | * drops it when the driver calls fw_core_remove_card. | 412 | * drops it when the driver calls fw_core_remove_card. |
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 3ab3585d3601..5d402d63799f 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c | |||
@@ -677,12 +677,21 @@ static int ioctl_create_iso_context(struct client *client, void *buffer) | |||
677 | return 0; | 677 | return 0; |
678 | } | 678 | } |
679 | 679 | ||
680 | /* Macros for decoding the iso packet control header. */ | ||
681 | #define GET_PAYLOAD_LENGTH(v) ((v) & 0xffff) | ||
682 | #define GET_INTERRUPT(v) (((v) >> 16) & 0x01) | ||
683 | #define GET_SKIP(v) (((v) >> 17) & 0x01) | ||
684 | #define GET_TAG(v) (((v) >> 18) & 0x02) | ||
685 | #define GET_SY(v) (((v) >> 20) & 0x04) | ||
686 | #define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff) | ||
687 | |||
680 | static int ioctl_queue_iso(struct client *client, void *buffer) | 688 | static int ioctl_queue_iso(struct client *client, void *buffer) |
681 | { | 689 | { |
682 | struct fw_cdev_queue_iso *request = buffer; | 690 | struct fw_cdev_queue_iso *request = buffer; |
683 | struct fw_cdev_iso_packet __user *p, *end, *next; | 691 | struct fw_cdev_iso_packet __user *p, *end, *next; |
684 | struct fw_iso_context *ctx = client->iso_context; | 692 | struct fw_iso_context *ctx = client->iso_context; |
685 | unsigned long payload, buffer_end, header_length; | 693 | unsigned long payload, buffer_end, header_length; |
694 | u32 control; | ||
686 | int count; | 695 | int count; |
687 | struct { | 696 | struct { |
688 | struct fw_iso_packet packet; | 697 | struct fw_iso_packet packet; |
@@ -717,8 +726,14 @@ static int ioctl_queue_iso(struct client *client, void *buffer) | |||
717 | end = (void __user *)p + request->size; | 726 | end = (void __user *)p + request->size; |
718 | count = 0; | 727 | count = 0; |
719 | while (p < end) { | 728 | while (p < end) { |
720 | if (__copy_from_user(&u.packet, p, sizeof(*p))) | 729 | if (get_user(control, &p->control)) |
721 | return -EFAULT; | 730 | return -EFAULT; |
731 | u.packet.payload_length = GET_PAYLOAD_LENGTH(control); | ||
732 | u.packet.interrupt = GET_INTERRUPT(control); | ||
733 | u.packet.skip = GET_SKIP(control); | ||
734 | u.packet.tag = GET_TAG(control); | ||
735 | u.packet.sy = GET_SY(control); | ||
736 | u.packet.header_length = GET_HEADER_LENGTH(control); | ||
722 | 737 | ||
723 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { | 738 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { |
724 | header_length = u.packet.header_length; | 739 | header_length = u.packet.header_length; |
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index 0ba9d64ccf4c..af1723eae4ba 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h | |||
@@ -99,6 +99,7 @@ fw_unit(struct device *dev) | |||
99 | #define CSR_DEPENDENT_INFO 0x14 | 99 | #define CSR_DEPENDENT_INFO 0x14 |
100 | #define CSR_MODEL 0x17 | 100 | #define CSR_MODEL 0x17 |
101 | #define CSR_INSTANCE 0x18 | 101 | #define CSR_INSTANCE 0x18 |
102 | #define CSR_DIRECTORY_ID 0x20 | ||
102 | 103 | ||
103 | #define SBP2_COMMAND_SET_SPECIFIER 0x38 | 104 | #define SBP2_COMMAND_SET_SPECIFIER 0x38 |
104 | #define SBP2_COMMAND_SET 0x39 | 105 | #define SBP2_COMMAND_SET 0x39 |
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 2e4cfa57126d..0d08bf9b78c2 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -417,12 +417,21 @@ ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs) | |||
417 | ctx->current_buffer = ab.next; | 417 | ctx->current_buffer = ab.next; |
418 | ctx->pointer = ctx->current_buffer->data; | 418 | ctx->pointer = ctx->current_buffer->data; |
419 | 419 | ||
420 | reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), | 420 | return 0; |
421 | le32_to_cpu(ab.descriptor.branch_address)); | 421 | } |
422 | |||
423 | static void ar_context_run(struct ar_context *ctx) | ||
424 | { | ||
425 | struct ar_buffer *ab = ctx->current_buffer; | ||
426 | dma_addr_t ab_bus; | ||
427 | size_t offset; | ||
428 | |||
429 | offset = offsetof(struct ar_buffer, data); | ||
430 | ab_bus = ab->descriptor.data_address - offset; | ||
431 | |||
432 | reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1); | ||
422 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); | 433 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); |
423 | flush_writes(ctx->ohci); | 434 | flush_writes(ctx->ohci); |
424 | |||
425 | return 0; | ||
426 | } | 435 | } |
427 | 436 | ||
428 | static void context_tasklet(unsigned long data) | 437 | static void context_tasklet(unsigned long data) |
@@ -1039,11 +1048,78 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
1039 | return IRQ_HANDLED; | 1048 | return IRQ_HANDLED; |
1040 | } | 1049 | } |
1041 | 1050 | ||
1051 | static int software_reset(struct fw_ohci *ohci) | ||
1052 | { | ||
1053 | int i; | ||
1054 | |||
1055 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); | ||
1056 | |||
1057 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | ||
1058 | if ((reg_read(ohci, OHCI1394_HCControlSet) & | ||
1059 | OHCI1394_HCControl_softReset) == 0) | ||
1060 | return 0; | ||
1061 | msleep(1); | ||
1062 | } | ||
1063 | |||
1064 | return -EBUSY; | ||
1065 | } | ||
1066 | |||
1042 | static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | 1067 | static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) |
1043 | { | 1068 | { |
1044 | struct fw_ohci *ohci = fw_ohci(card); | 1069 | struct fw_ohci *ohci = fw_ohci(card); |
1045 | struct pci_dev *dev = to_pci_dev(card->device); | 1070 | struct pci_dev *dev = to_pci_dev(card->device); |
1046 | 1071 | ||
1072 | if (software_reset(ohci)) { | ||
1073 | fw_error("Failed to reset ohci card.\n"); | ||
1074 | return -EBUSY; | ||
1075 | } | ||
1076 | |||
1077 | /* | ||
1078 | * Now enable LPS, which we need in order to start accessing | ||
1079 | * most of the registers. In fact, on some cards (ALI M5251), | ||
1080 | * accessing registers in the SClk domain without LPS enabled | ||
1081 | * will lock up the machine. Wait 50msec to make sure we have | ||
1082 | * full link enabled. | ||
1083 | */ | ||
1084 | reg_write(ohci, OHCI1394_HCControlSet, | ||
1085 | OHCI1394_HCControl_LPS | | ||
1086 | OHCI1394_HCControl_postedWriteEnable); | ||
1087 | flush_writes(ohci); | ||
1088 | msleep(50); | ||
1089 | |||
1090 | reg_write(ohci, OHCI1394_HCControlClear, | ||
1091 | OHCI1394_HCControl_noByteSwapData); | ||
1092 | |||
1093 | reg_write(ohci, OHCI1394_LinkControlSet, | ||
1094 | OHCI1394_LinkControl_rcvSelfID | | ||
1095 | OHCI1394_LinkControl_cycleTimerEnable | | ||
1096 | OHCI1394_LinkControl_cycleMaster); | ||
1097 | |||
1098 | reg_write(ohci, OHCI1394_ATRetries, | ||
1099 | OHCI1394_MAX_AT_REQ_RETRIES | | ||
1100 | (OHCI1394_MAX_AT_RESP_RETRIES << 4) | | ||
1101 | (OHCI1394_MAX_PHYS_RESP_RETRIES << 8)); | ||
1102 | |||
1103 | ar_context_run(&ohci->ar_request_ctx); | ||
1104 | ar_context_run(&ohci->ar_response_ctx); | ||
1105 | |||
1106 | reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus); | ||
1107 | reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000); | ||
1108 | reg_write(ohci, OHCI1394_IntEventClear, ~0); | ||
1109 | reg_write(ohci, OHCI1394_IntMaskClear, ~0); | ||
1110 | reg_write(ohci, OHCI1394_IntMaskSet, | ||
1111 | OHCI1394_selfIDComplete | | ||
1112 | OHCI1394_RQPkt | OHCI1394_RSPkt | | ||
1113 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | | ||
1114 | OHCI1394_isochRx | OHCI1394_isochTx | | ||
1115 | OHCI1394_masterIntEnable | | ||
1116 | OHCI1394_cycle64Seconds); | ||
1117 | |||
1118 | /* Activate link_on bit and contender bit in our self ID packets.*/ | ||
1119 | if (ohci_update_phy_reg(card, 4, 0, | ||
1120 | PHY_LINK_ACTIVE | PHY_CONTENDER) < 0) | ||
1121 | return -EIO; | ||
1122 | |||
1047 | /* | 1123 | /* |
1048 | * When the link is not yet enabled, the atomic config rom | 1124 | * When the link is not yet enabled, the atomic config rom |
1049 | * update mechanism described below in ohci_set_config_rom() | 1125 | * update mechanism described below in ohci_set_config_rom() |
@@ -1701,22 +1777,6 @@ static const struct fw_card_driver ohci_driver = { | |||
1701 | .stop_iso = ohci_stop_iso, | 1777 | .stop_iso = ohci_stop_iso, |
1702 | }; | 1778 | }; |
1703 | 1779 | ||
1704 | static int software_reset(struct fw_ohci *ohci) | ||
1705 | { | ||
1706 | int i; | ||
1707 | |||
1708 | reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); | ||
1709 | |||
1710 | for (i = 0; i < OHCI_LOOP_COUNT; i++) { | ||
1711 | if ((reg_read(ohci, OHCI1394_HCControlSet) & | ||
1712 | OHCI1394_HCControl_softReset) == 0) | ||
1713 | return 0; | ||
1714 | msleep(1); | ||
1715 | } | ||
1716 | |||
1717 | return -EBUSY; | ||
1718 | } | ||
1719 | |||
1720 | static int __devinit | 1780 | static int __devinit |
1721 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | 1781 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) |
1722 | { | 1782 | { |
@@ -1762,33 +1822,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1762 | goto fail_iomem; | 1822 | goto fail_iomem; |
1763 | } | 1823 | } |
1764 | 1824 | ||
1765 | if (software_reset(ohci)) { | ||
1766 | fw_error("Failed to reset ohci card.\n"); | ||
1767 | err = -EBUSY; | ||
1768 | goto fail_registers; | ||
1769 | } | ||
1770 | |||
1771 | /* | ||
1772 | * Now enable LPS, which we need in order to start accessing | ||
1773 | * most of the registers. In fact, on some cards (ALI M5251), | ||
1774 | * accessing registers in the SClk domain without LPS enabled | ||
1775 | * will lock up the machine. Wait 50msec to make sure we have | ||
1776 | * full link enabled. | ||
1777 | */ | ||
1778 | reg_write(ohci, OHCI1394_HCControlSet, | ||
1779 | OHCI1394_HCControl_LPS | | ||
1780 | OHCI1394_HCControl_postedWriteEnable); | ||
1781 | flush_writes(ohci); | ||
1782 | msleep(50); | ||
1783 | |||
1784 | reg_write(ohci, OHCI1394_HCControlClear, | ||
1785 | OHCI1394_HCControl_noByteSwapData); | ||
1786 | |||
1787 | reg_write(ohci, OHCI1394_LinkControlSet, | ||
1788 | OHCI1394_LinkControl_rcvSelfID | | ||
1789 | OHCI1394_LinkControl_cycleTimerEnable | | ||
1790 | OHCI1394_LinkControl_cycleMaster); | ||
1791 | |||
1792 | ar_context_init(&ohci->ar_request_ctx, ohci, | 1825 | ar_context_init(&ohci->ar_request_ctx, ohci, |
1793 | OHCI1394_AsReqRcvContextControlSet); | 1826 | OHCI1394_AsReqRcvContextControlSet); |
1794 | 1827 | ||
@@ -1801,11 +1834,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1801 | context_init(&ohci->at_response_ctx, ohci, AT_BUFFER_SIZE, | 1834 | context_init(&ohci->at_response_ctx, ohci, AT_BUFFER_SIZE, |
1802 | OHCI1394_AsRspTrContextControlSet, handle_at_packet); | 1835 | OHCI1394_AsRspTrContextControlSet, handle_at_packet); |
1803 | 1836 | ||
1804 | reg_write(ohci, OHCI1394_ATRetries, | ||
1805 | OHCI1394_MAX_AT_REQ_RETRIES | | ||
1806 | (OHCI1394_MAX_AT_RESP_RETRIES << 4) | | ||
1807 | (OHCI1394_MAX_PHYS_RESP_RETRIES << 8)); | ||
1808 | |||
1809 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); | 1837 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); |
1810 | ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); | 1838 | ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); |
1811 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); | 1839 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); |
@@ -1835,18 +1863,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
1835 | goto fail_registers; | 1863 | goto fail_registers; |
1836 | } | 1864 | } |
1837 | 1865 | ||
1838 | reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus); | ||
1839 | reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000); | ||
1840 | reg_write(ohci, OHCI1394_IntEventClear, ~0); | ||
1841 | reg_write(ohci, OHCI1394_IntMaskClear, ~0); | ||
1842 | reg_write(ohci, OHCI1394_IntMaskSet, | ||
1843 | OHCI1394_selfIDComplete | | ||
1844 | OHCI1394_RQPkt | OHCI1394_RSPkt | | ||
1845 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | | ||
1846 | OHCI1394_isochRx | OHCI1394_isochTx | | ||
1847 | OHCI1394_masterIntEnable | | ||
1848 | OHCI1394_cycle64Seconds); | ||
1849 | |||
1850 | bus_options = reg_read(ohci, OHCI1394_BusOptions); | 1866 | bus_options = reg_read(ohci, OHCI1394_BusOptions); |
1851 | max_receive = (bus_options >> 12) & 0xf; | 1867 | max_receive = (bus_options >> 12) & 0xf; |
1852 | link_speed = bus_options & 0x7; | 1868 | link_speed = bus_options & 0x7; |
@@ -1908,6 +1924,45 @@ static void pci_remove(struct pci_dev *dev) | |||
1908 | fw_notify("Removed fw-ohci device.\n"); | 1924 | fw_notify("Removed fw-ohci device.\n"); |
1909 | } | 1925 | } |
1910 | 1926 | ||
1927 | #ifdef CONFIG_PM | ||
1928 | static int pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1929 | { | ||
1930 | struct fw_ohci *ohci = pci_get_drvdata(pdev); | ||
1931 | int err; | ||
1932 | |||
1933 | software_reset(ohci); | ||
1934 | free_irq(pdev->irq, ohci); | ||
1935 | err = pci_save_state(pdev); | ||
1936 | if (err) { | ||
1937 | fw_error("pci_save_state failed with %d", err); | ||
1938 | return err; | ||
1939 | } | ||
1940 | err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1941 | if (err) { | ||
1942 | fw_error("pci_set_power_state failed with %d", err); | ||
1943 | return err; | ||
1944 | } | ||
1945 | |||
1946 | return 0; | ||
1947 | } | ||
1948 | |||
1949 | static int pci_resume(struct pci_dev *pdev) | ||
1950 | { | ||
1951 | struct fw_ohci *ohci = pci_get_drvdata(pdev); | ||
1952 | int err; | ||
1953 | |||
1954 | pci_set_power_state(pdev, PCI_D0); | ||
1955 | pci_restore_state(pdev); | ||
1956 | err = pci_enable_device(pdev); | ||
1957 | if (err) { | ||
1958 | fw_error("pci_enable_device failed with %d", err); | ||
1959 | return err; | ||
1960 | } | ||
1961 | |||
1962 | return ohci_enable(&ohci->card, ohci->config_rom, CONFIG_ROM_SIZE); | ||
1963 | } | ||
1964 | #endif | ||
1965 | |||
1911 | static struct pci_device_id pci_table[] = { | 1966 | static struct pci_device_id pci_table[] = { |
1912 | { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) }, | 1967 | { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) }, |
1913 | { } | 1968 | { } |
@@ -1920,6 +1975,10 @@ static struct pci_driver fw_ohci_pci_driver = { | |||
1920 | .id_table = pci_table, | 1975 | .id_table = pci_table, |
1921 | .probe = pci_probe, | 1976 | .probe = pci_probe, |
1922 | .remove = pci_remove, | 1977 | .remove = pci_remove, |
1978 | #ifdef CONFIG_PM | ||
1979 | .resume = pci_resume, | ||
1980 | .suspend = pci_suspend, | ||
1981 | #endif | ||
1923 | }; | 1982 | }; |
1924 | 1983 | ||
1925 | MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>"); | 1984 | MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>"); |
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 68300414e5f4..a98d3915e26f 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
@@ -1108,6 +1108,58 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd) | |||
1108 | return SUCCESS; | 1108 | return SUCCESS; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | /* | ||
1112 | * Format of /sys/bus/scsi/devices/.../ieee1394_id: | ||
1113 | * u64 EUI-64 : u24 directory_ID : u16 LUN (all printed in hexadecimal) | ||
1114 | * | ||
1115 | * This is the concatenation of target port identifier and logical unit | ||
1116 | * identifier as per SAM-2...SAM-4 annex A. | ||
1117 | */ | ||
1118 | static ssize_t | ||
1119 | sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr, | ||
1120 | char *buf) | ||
1121 | { | ||
1122 | struct scsi_device *sdev = to_scsi_device(dev); | ||
1123 | struct sbp2_device *sd; | ||
1124 | struct fw_unit *unit; | ||
1125 | struct fw_device *device; | ||
1126 | u32 directory_id; | ||
1127 | struct fw_csr_iterator ci; | ||
1128 | int key, value, lun; | ||
1129 | |||
1130 | if (!sdev) | ||
1131 | return 0; | ||
1132 | sd = (struct sbp2_device *)sdev->host->hostdata; | ||
1133 | unit = sd->unit; | ||
1134 | device = fw_device(unit->device.parent); | ||
1135 | |||
1136 | /* implicit directory ID */ | ||
1137 | directory_id = ((unit->directory - device->config_rom) * 4 | ||
1138 | + CSR_CONFIG_ROM) & 0xffffff; | ||
1139 | |||
1140 | /* explicit directory ID, overrides implicit ID if present */ | ||
1141 | fw_csr_iterator_init(&ci, unit->directory); | ||
1142 | while (fw_csr_iterator_next(&ci, &key, &value)) | ||
1143 | if (key == CSR_DIRECTORY_ID) { | ||
1144 | directory_id = value; | ||
1145 | break; | ||
1146 | } | ||
1147 | |||
1148 | /* FIXME: Make this work for multi-lun devices. */ | ||
1149 | lun = 0; | ||
1150 | |||
1151 | return sprintf(buf, "%08x%08x:%06x:%04x\n", | ||
1152 | device->config_rom[3], device->config_rom[4], | ||
1153 | directory_id, lun); | ||
1154 | } | ||
1155 | |||
1156 | static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL); | ||
1157 | |||
1158 | static struct device_attribute *sbp2_scsi_sysfs_attrs[] = { | ||
1159 | &dev_attr_ieee1394_id, | ||
1160 | NULL | ||
1161 | }; | ||
1162 | |||
1111 | static struct scsi_host_template scsi_driver_template = { | 1163 | static struct scsi_host_template scsi_driver_template = { |
1112 | .module = THIS_MODULE, | 1164 | .module = THIS_MODULE, |
1113 | .name = "SBP-2 IEEE-1394", | 1165 | .name = "SBP-2 IEEE-1394", |
@@ -1121,6 +1173,7 @@ static struct scsi_host_template scsi_driver_template = { | |||
1121 | .use_clustering = ENABLE_CLUSTERING, | 1173 | .use_clustering = ENABLE_CLUSTERING, |
1122 | .cmd_per_lun = 1, | 1174 | .cmd_per_lun = 1, |
1123 | .can_queue = 1, | 1175 | .can_queue = 1, |
1176 | .sdev_attrs = sbp2_scsi_sysfs_attrs, | ||
1124 | }; | 1177 | }; |
1125 | 1178 | ||
1126 | MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>"); | 1179 | MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>"); |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 835937e38529..81b3864d2ba7 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -976,7 +976,8 @@ static struct unit_directory *nodemgr_process_unit_directory | |||
976 | 976 | ||
977 | ud->ne = ne; | 977 | ud->ne = ne; |
978 | ud->ignore_driver = ignore_drivers; | 978 | ud->ignore_driver = ignore_drivers; |
979 | ud->address = ud_kv->offset + CSR1212_CONFIG_ROM_SPACE_BASE; | 979 | ud->address = ud_kv->offset + CSR1212_REGISTER_SPACE_BASE; |
980 | ud->directory_id = ud->address & 0xffffff; | ||
980 | ud->ud_kv = ud_kv; | 981 | ud->ud_kv = ud_kv; |
981 | ud->id = (*id)++; | 982 | ud->id = (*id)++; |
982 | 983 | ||
@@ -1085,6 +1086,10 @@ static struct unit_directory *nodemgr_process_unit_directory | |||
1085 | 1086 | ||
1086 | break; | 1087 | break; |
1087 | 1088 | ||
1089 | case CSR1212_KV_ID_DIRECTORY_ID: | ||
1090 | ud->directory_id = kv->value.immediate; | ||
1091 | break; | ||
1092 | |||
1088 | default: | 1093 | default: |
1089 | break; | 1094 | break; |
1090 | } | 1095 | } |
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h index e7ac683c72c7..4530b29d941c 100644 --- a/drivers/ieee1394/nodemgr.h +++ b/drivers/ieee1394/nodemgr.h | |||
@@ -75,6 +75,7 @@ struct unit_directory { | |||
75 | struct csr1212_keyval *model_name_kv; | 75 | struct csr1212_keyval *model_name_kv; |
76 | quadlet_t specifier_id; | 76 | quadlet_t specifier_id; |
77 | quadlet_t version; | 77 | quadlet_t version; |
78 | quadlet_t directory_id; | ||
78 | 79 | ||
79 | unsigned int id; | 80 | unsigned int id; |
80 | 81 | ||
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 875eadd5e8f5..3f873cc7e247 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -194,6 +194,27 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" | |||
194 | ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) | 194 | ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) |
195 | ", or a combination)"); | 195 | ", or a combination)"); |
196 | 196 | ||
197 | /* | ||
198 | * This influences the format of the sysfs attribute | ||
199 | * /sys/bus/scsi/devices/.../ieee1394_id. | ||
200 | * | ||
201 | * The default format is like in older kernels: %016Lx:%d:%d | ||
202 | * It contains the target's EUI-64, a number given to the logical unit by | ||
203 | * the ieee1394 driver's nodemgr (starting at 0), and the LUN. | ||
204 | * | ||
205 | * The long format is: %016Lx:%06x:%04x | ||
206 | * It contains the target's EUI-64, the unit directory's directory_ID as per | ||
207 | * IEEE 1212 clause 7.7.19, and the LUN. This format comes closest to the | ||
208 | * format of SBP(-3) target port and logical unit identifier as per SAM (SCSI | ||
209 | * Architecture Model) rev.2 to 4 annex A. Therefore and because it is | ||
210 | * independent of the implementation of the ieee1394 nodemgr, the longer format | ||
211 | * is recommended for future use. | ||
212 | */ | ||
213 | static int sbp2_long_sysfs_ieee1394_id; | ||
214 | module_param_named(long_ieee1394_id, sbp2_long_sysfs_ieee1394_id, bool, 0644); | ||
215 | MODULE_PARM_DESC(long_ieee1394_id, "8+3+2 bytes format of ieee1394_id in sysfs " | ||
216 | "(default = backwards-compatible = N, SAM-conforming = Y)"); | ||
217 | |||
197 | 218 | ||
198 | #define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args) | 219 | #define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args) |
199 | #define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args) | 220 | #define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args) |
@@ -2100,8 +2121,14 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, | |||
2100 | if (!(lu = (struct sbp2_lu *)sdev->host->hostdata[0])) | 2121 | if (!(lu = (struct sbp2_lu *)sdev->host->hostdata[0])) |
2101 | return 0; | 2122 | return 0; |
2102 | 2123 | ||
2103 | return sprintf(buf, "%016Lx:%d:%d\n", (unsigned long long)lu->ne->guid, | 2124 | if (sbp2_long_sysfs_ieee1394_id) |
2104 | lu->ud->id, ORB_SET_LUN(lu->lun)); | 2125 | return sprintf(buf, "%016Lx:%06x:%04x\n", |
2126 | (unsigned long long)lu->ne->guid, | ||
2127 | lu->ud->directory_id, ORB_SET_LUN(lu->lun)); | ||
2128 | else | ||
2129 | return sprintf(buf, "%016Lx:%d:%d\n", | ||
2130 | (unsigned long long)lu->ne->guid, | ||
2131 | lu->ud->id, ORB_SET_LUN(lu->lun)); | ||
2105 | } | 2132 | } |
2106 | 2133 | ||
2107 | MODULE_AUTHOR("Ben Collins <bcollins@debian.org>"); | 2134 | MODULE_AUTHOR("Ben Collins <bcollins@debian.org>"); |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index e1013156c25e..f317c270d4bf 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -62,6 +62,8 @@ header-y += fadvise.h | |||
62 | header-y += fd.h | 62 | header-y += fd.h |
63 | header-y += fdreg.h | 63 | header-y += fdreg.h |
64 | header-y += fib_rules.h | 64 | header-y += fib_rules.h |
65 | header-y += firewire-cdev.h | ||
66 | header-y += firewire-constants.h | ||
65 | header-y += fuse.h | 67 | header-y += fuse.h |
66 | header-y += genetlink.h | 68 | header-y += genetlink.h |
67 | header-y += gen_stats.h | 69 | header-y += gen_stats.h |
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index d4455eb2ae35..efbe1fda1a22 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h | |||
@@ -198,13 +198,15 @@ struct fw_cdev_create_iso_context { | |||
198 | __u32 handle; | 198 | __u32 handle; |
199 | }; | 199 | }; |
200 | 200 | ||
201 | #define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) | ||
202 | #define FW_CDEV_ISO_INTERRUPT (1 << 16) | ||
203 | #define FW_CDEV_ISO_SKIP (1 << 17) | ||
204 | #define FW_CDEV_ISO_TAG(v) ((v) << 18) | ||
205 | #define FW_CDEV_ISO_SY(v) ((v) << 20) | ||
206 | #define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24) | ||
207 | |||
201 | struct fw_cdev_iso_packet { | 208 | struct fw_cdev_iso_packet { |
202 | __u16 payload_length; /* Length of indirect payload. */ | 209 | __u32 control; |
203 | __u32 interrupt : 1; /* Generate interrupt on this packet */ | ||
204 | __u32 skip : 1; /* Set to not send packet at all. */ | ||
205 | __u32 tag : 2; | ||
206 | __u32 sy : 4; | ||
207 | __u32 header_length : 8; /* Length of immediate header. */ | ||
208 | __u32 header[0]; | 210 | __u32 header[0]; |
209 | }; | 211 | }; |
210 | 212 | ||