aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
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/firewire/ohci.c
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/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c35
1 files changed, 35 insertions, 0 deletions
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);