aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-06-10 02:36:37 -0400
committerClemens Ladisch <clemens@ladisch.de>2010-06-10 02:36:37 -0400
commit4ffb7a6a066e4be4577976d1c08e237c7479770a (patch)
treefd4c275e8ef894d60602e1b4d1f81150e54b32f8 /drivers
parent3d1f46eb60b155c705e389ecdf313f11b4b91976 (diff)
firewire: add CSR cmstr support
Implement the cmstr bit, which is required for cycle master capable nodes and tested for by the Base 1394 Test Suite. This bit allows the bus master to disable cycle start packets; there are bus master implementations that actually do this. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firewire/core-transaction.c12
-rw-r--r--drivers/firewire/core.h2
-rw-r--r--drivers/firewire/ohci.c35
-rw-r--r--drivers/firewire/ohci.h1
4 files changed, 48 insertions, 2 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index dd8ef650a7cb..e0c6cce894cf 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -1003,7 +1003,12 @@ static u32 read_state_register(struct fw_card *card)
1003 * reset, but then cleared when the units are ready again, which 1003 * reset, but then cleared when the units are ready again, which
1004 * happens immediately for us. 1004 * happens immediately for us.
1005 */ 1005 */
1006 return 0; 1006 u32 value = 0x0000;
1007
1008 /* Bit 8 (cmstr): */
1009 value |= card->driver->read_csr_reg(card, CSR_STATE_CLEAR);
1010
1011 return value;
1007} 1012}
1008 1013
1009static void update_split_timeout(struct fw_card *card) 1014static void update_split_timeout(struct fw_card *card)
@@ -1034,6 +1039,8 @@ static void handle_registers(struct fw_card *card, struct fw_request *request,
1034 if (tcode == TCODE_READ_QUADLET_REQUEST) { 1039 if (tcode == TCODE_READ_QUADLET_REQUEST) {
1035 *data = cpu_to_be32(read_state_register(card)); 1040 *data = cpu_to_be32(read_state_register(card));
1036 } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { 1041 } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
1042 card->driver->write_csr_reg(card, CSR_STATE_CLEAR,
1043 be32_to_cpu(*data));
1037 } else { 1044 } else {
1038 rcode = RCODE_TYPE_ERROR; 1045 rcode = RCODE_TYPE_ERROR;
1039 } 1046 }
@@ -1043,7 +1050,8 @@ static void handle_registers(struct fw_card *card, struct fw_request *request,
1043 if (tcode == TCODE_READ_QUADLET_REQUEST) { 1050 if (tcode == TCODE_READ_QUADLET_REQUEST) {
1044 *data = cpu_to_be32(read_state_register(card)); 1051 *data = cpu_to_be32(read_state_register(card));
1045 } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { 1052 } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
1046 /* FIXME: implement cmstr */ 1053 card->driver->write_csr_reg(card, CSR_STATE_SET,
1054 be32_to_cpu(*data));
1047 /* FIXME: implement abdicate */ 1055 /* FIXME: implement abdicate */
1048 } else { 1056 } else {
1049 rcode = RCODE_TYPE_ERROR; 1057 rcode = RCODE_TYPE_ERROR;
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index 3b8c0f042f49..aaecdd1c1767 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -40,6 +40,8 @@ struct fw_packet;
40 40
41#define FEATURE_PRIORITY_BUDGET 0x01 41#define FEATURE_PRIORITY_BUDGET 0x01
42 42
43#define CSR_STATE_BIT_CMSTR (1 << 8)
44
43struct fw_card_driver { 45struct fw_card_driver {
44 /* 46 /*
45 * Enable the given card with the given initial config rom. 47 * Enable the given card with the given initial config rom.
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 0e5413531785..1dcc2e427eb1 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -172,6 +172,7 @@ struct fw_ohci {
172 unsigned quirks; 172 unsigned quirks;
173 unsigned int pri_req_max; 173 unsigned int pri_req_max;
174 u32 bus_time; 174 u32 bus_time;
175 bool is_root;
175 176
176 /* 177 /*
177 * Spinlock for accessing fw_ohci data. Never call out of 178 * Spinlock for accessing fw_ohci data. Never call out of
@@ -1400,6 +1401,7 @@ static void bus_reset_tasklet(unsigned long data)
1400 unsigned long flags; 1401 unsigned long flags;
1401 void *free_rom = NULL; 1402 void *free_rom = NULL;
1402 dma_addr_t free_rom_bus = 0; 1403 dma_addr_t free_rom_bus = 0;
1404 bool is_new_root;
1403 1405
1404 reg = reg_read(ohci, OHCI1394_NodeID); 1406 reg = reg_read(ohci, OHCI1394_NodeID);
1405 if (!(reg & OHCI1394_NodeID_idValid)) { 1407 if (!(reg & OHCI1394_NodeID_idValid)) {
@@ -1413,6 +1415,12 @@ static void bus_reset_tasklet(unsigned long data)
1413 ohci->node_id = reg & (OHCI1394_NodeID_busNumber | 1415 ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
1414 OHCI1394_NodeID_nodeNumber); 1416 OHCI1394_NodeID_nodeNumber);
1415 1417
1418 is_new_root = (reg & OHCI1394_NodeID_root) != 0;
1419 if (!(ohci->is_root && is_new_root))
1420 reg_write(ohci, OHCI1394_LinkControlSet,
1421 OHCI1394_LinkControl_cycleMaster);
1422 ohci->is_root = is_new_root;
1423
1416 reg = reg_read(ohci, OHCI1394_SelfIDCount); 1424 reg = reg_read(ohci, OHCI1394_SelfIDCount);
1417 if (reg & OHCI1394_SelfIDCount_selfIDError) { 1425 if (reg & OHCI1394_SelfIDCount_selfIDError) {
1418 fw_notify("inconsistent self IDs\n"); 1426 fw_notify("inconsistent self IDs\n");
@@ -2013,6 +2021,16 @@ static u32 ohci_read_csr_reg(struct fw_card *card, int csr_offset)
2013 u32 value; 2021 u32 value;
2014 2022
2015 switch (csr_offset) { 2023 switch (csr_offset) {
2024 case CSR_STATE_CLEAR:
2025 case CSR_STATE_SET:
2026 /* the controller driver handles only the cmstr bit */
2027 if (ohci->is_root &&
2028 (reg_read(ohci, OHCI1394_LinkControlSet) &
2029 OHCI1394_LinkControl_cycleMaster))
2030 return CSR_STATE_BIT_CMSTR;
2031 else
2032 return 0;
2033
2016 case CSR_NODE_IDS: 2034 case CSR_NODE_IDS:
2017 return reg_read(ohci, OHCI1394_NodeID) << 16; 2035 return reg_read(ohci, OHCI1394_NodeID) << 16;
2018 2036
@@ -2050,6 +2068,23 @@ static void ohci_write_csr_reg(struct fw_card *card, int csr_offset, u32 value)
2050 unsigned long flags; 2068 unsigned long flags;
2051 2069
2052 switch (csr_offset) { 2070 switch (csr_offset) {
2071 case CSR_STATE_CLEAR:
2072 /* the controller driver handles only the cmstr bit */
2073 if ((value & CSR_STATE_BIT_CMSTR) && ohci->is_root) {
2074 reg_write(ohci, OHCI1394_LinkControlClear,
2075 OHCI1394_LinkControl_cycleMaster);
2076 flush_writes(ohci);
2077 }
2078 break;
2079
2080 case CSR_STATE_SET:
2081 if ((value & CSR_STATE_BIT_CMSTR) && ohci->is_root) {
2082 reg_write(ohci, OHCI1394_LinkControlSet,
2083 OHCI1394_LinkControl_cycleMaster);
2084 flush_writes(ohci);
2085 }
2086 break;
2087
2053 case CSR_NODE_IDS: 2088 case CSR_NODE_IDS:
2054 reg_write(ohci, OHCI1394_NodeID, value >> 16); 2089 reg_write(ohci, OHCI1394_NodeID, value >> 16);
2055 flush_writes(ohci); 2090 flush_writes(ohci);
diff --git a/drivers/firewire/ohci.h b/drivers/firewire/ohci.h
index 3bc9a5d744eb..0e6c5a466908 100644
--- a/drivers/firewire/ohci.h
+++ b/drivers/firewire/ohci.h
@@ -60,6 +60,7 @@
60#define OHCI1394_LinkControl_cycleSource (1 << 22) 60#define OHCI1394_LinkControl_cycleSource (1 << 22)
61#define OHCI1394_NodeID 0x0E8 61#define OHCI1394_NodeID 0x0E8
62#define OHCI1394_NodeID_idValid 0x80000000 62#define OHCI1394_NodeID_idValid 0x80000000
63#define OHCI1394_NodeID_root 0x40000000
63#define OHCI1394_NodeID_nodeNumber 0x0000003f 64#define OHCI1394_NodeID_nodeNumber 0x0000003f
64#define OHCI1394_NodeID_busNumber 0x0000ffc0 65#define OHCI1394_NodeID_busNumber 0x0000ffc0
65#define OHCI1394_PhyControl 0x0EC 66#define OHCI1394_PhyControl 0x0EC