diff options
Diffstat (limited to 'drivers/ieee1394/sbp2.c')
-rw-r--r-- | drivers/ieee1394/sbp2.c | 85 |
1 files changed, 30 insertions, 55 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 5413dc43b9f1..1d5ceb7ecc83 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -127,10 +127,12 @@ MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported (default = " | |||
127 | * talking to a single sbp2 device at the same time (filesystem coherency, | 127 | * talking to a single sbp2 device at the same time (filesystem coherency, |
128 | * etc.). If you're running an sbp2 device that supports multiple logins, | 128 | * etc.). If you're running an sbp2 device that supports multiple logins, |
129 | * and you're either running read-only filesystems or some sort of special | 129 | * and you're either running read-only filesystems or some sort of special |
130 | * filesystem supporting multiple hosts (one such filesystem is OpenGFS, | 130 | * filesystem supporting multiple hosts, e.g. OpenGFS, Oracle Cluster |
131 | * see opengfs.sourceforge.net for more info), then set exclusive_login | 131 | * File System, or Lustre, then set exclusive_login to zero. |
132 | * to zero. Note: The Oxsemi OXFW911 sbp2 chipset supports up to four | 132 | * |
133 | * concurrent logins. | 133 | * So far only bridges from Oxford Semiconductor are known to support |
134 | * concurrent logins. Depending on firmware, four or two concurrent logins | ||
135 | * are possible on OXFW911 and newer Oxsemi bridges. | ||
134 | */ | 136 | */ |
135 | static int exclusive_login = 1; | 137 | static int exclusive_login = 1; |
136 | module_param(exclusive_login, int, 0644); | 138 | module_param(exclusive_login, int, 0644); |
@@ -306,8 +308,9 @@ static const struct { | |||
306 | u32 model_id; | 308 | u32 model_id; |
307 | unsigned workarounds; | 309 | unsigned workarounds; |
308 | } sbp2_workarounds_table[] = { | 310 | } sbp2_workarounds_table[] = { |
309 | /* TSB42AA9 */ { | 311 | /* DViCO Momobay CX-1 with TSB42AA9 bridge */ { |
310 | .firmware_revision = 0x002800, | 312 | .firmware_revision = 0x002800, |
313 | .model_id = 0x001010, | ||
311 | .workarounds = SBP2_WORKAROUND_INQUIRY_36 | | 314 | .workarounds = SBP2_WORKAROUND_INQUIRY_36 | |
312 | SBP2_WORKAROUND_MODE_SENSE_8, | 315 | SBP2_WORKAROUND_MODE_SENSE_8, |
313 | }, | 316 | }, |
@@ -791,12 +794,12 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud | |||
791 | scsi_id->ud = ud; | 794 | scsi_id->ud = ud; |
792 | scsi_id->speed_code = IEEE1394_SPEED_100; | 795 | scsi_id->speed_code = IEEE1394_SPEED_100; |
793 | scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100]; | 796 | scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100]; |
797 | scsi_id->status_fifo_addr = CSR1212_INVALID_ADDR_SPACE; | ||
794 | atomic_set(&scsi_id->sbp2_login_complete, 0); | 798 | atomic_set(&scsi_id->sbp2_login_complete, 0); |
795 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); | 799 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); |
796 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); | 800 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); |
797 | INIT_LIST_HEAD(&scsi_id->scsi_list); | 801 | INIT_LIST_HEAD(&scsi_id->scsi_list); |
798 | spin_lock_init(&scsi_id->sbp2_command_orb_lock); | 802 | spin_lock_init(&scsi_id->sbp2_command_orb_lock); |
799 | scsi_id->sbp2_lun = 0; | ||
800 | 803 | ||
801 | ud->device.driver_data = scsi_id; | 804 | ud->device.driver_data = scsi_id; |
802 | 805 | ||
@@ -844,8 +847,8 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud | |||
844 | scsi_id->status_fifo_addr = hpsb_allocate_and_register_addrspace( | 847 | scsi_id->status_fifo_addr = hpsb_allocate_and_register_addrspace( |
845 | &sbp2_highlevel, ud->ne->host, &sbp2_ops, | 848 | &sbp2_highlevel, ud->ne->host, &sbp2_ops, |
846 | sizeof(struct sbp2_status_block), sizeof(quadlet_t), | 849 | sizeof(struct sbp2_status_block), sizeof(quadlet_t), |
847 | 0x010000000000ULL, CSR1212_ALL_SPACE_END); | 850 | ud->ne->host->low_addr_space, CSR1212_ALL_SPACE_END); |
848 | if (scsi_id->status_fifo_addr == ~0ULL) { | 851 | if (scsi_id->status_fifo_addr == CSR1212_INVALID_ADDR_SPACE) { |
849 | SBP2_ERR("failed to allocate status FIFO address range"); | 852 | SBP2_ERR("failed to allocate status FIFO address range"); |
850 | goto failed_alloc; | 853 | goto failed_alloc; |
851 | } | 854 | } |
@@ -1087,9 +1090,9 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id) | |||
1087 | SBP2_DMA_FREE("single query logins data"); | 1090 | SBP2_DMA_FREE("single query logins data"); |
1088 | } | 1091 | } |
1089 | 1092 | ||
1090 | if (scsi_id->status_fifo_addr) | 1093 | if (scsi_id->status_fifo_addr != CSR1212_INVALID_ADDR_SPACE) |
1091 | hpsb_unregister_addrspace(&sbp2_highlevel, hi->host, | 1094 | hpsb_unregister_addrspace(&sbp2_highlevel, hi->host, |
1092 | scsi_id->status_fifo_addr); | 1095 | scsi_id->status_fifo_addr); |
1093 | 1096 | ||
1094 | scsi_id->ud->device.driver_data = NULL; | 1097 | scsi_id->ud->device.driver_data = NULL; |
1095 | 1098 | ||
@@ -1213,13 +1216,11 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) | |||
1213 | SBP2_DEBUG("length_max_logins = %x", | 1216 | SBP2_DEBUG("length_max_logins = %x", |
1214 | (unsigned int)scsi_id->query_logins_response->length_max_logins); | 1217 | (unsigned int)scsi_id->query_logins_response->length_max_logins); |
1215 | 1218 | ||
1216 | SBP2_DEBUG("Query logins to SBP-2 device successful"); | ||
1217 | |||
1218 | max_logins = RESPONSE_GET_MAX_LOGINS(scsi_id->query_logins_response->length_max_logins); | 1219 | max_logins = RESPONSE_GET_MAX_LOGINS(scsi_id->query_logins_response->length_max_logins); |
1219 | SBP2_DEBUG("Maximum concurrent logins supported: %d", max_logins); | 1220 | SBP2_INFO("Maximum concurrent logins supported: %d", max_logins); |
1220 | 1221 | ||
1221 | active_logins = RESPONSE_GET_ACTIVE_LOGINS(scsi_id->query_logins_response->length_max_logins); | 1222 | active_logins = RESPONSE_GET_ACTIVE_LOGINS(scsi_id->query_logins_response->length_max_logins); |
1222 | SBP2_DEBUG("Number of active logins: %d", active_logins); | 1223 | SBP2_INFO("Number of active logins: %d", active_logins); |
1223 | 1224 | ||
1224 | if (active_logins >= max_logins) { | 1225 | if (active_logins >= max_logins) { |
1225 | return -EIO; | 1226 | return -EIO; |
@@ -1648,6 +1649,8 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, | |||
1648 | } | 1649 | } |
1649 | } | 1650 | } |
1650 | 1651 | ||
1652 | #define SBP2_PAYLOAD_TO_BYTES(p) (1 << ((p) + 2)) | ||
1653 | |||
1651 | /* | 1654 | /* |
1652 | * This function is called in order to determine the max speed and packet | 1655 | * This function is called in order to determine the max speed and packet |
1653 | * size we can use in our ORBs. Note, that we (the driver and host) only | 1656 | * size we can use in our ORBs. Note, that we (the driver and host) only |
@@ -1660,13 +1663,12 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, | |||
1660 | static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) | 1663 | static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) |
1661 | { | 1664 | { |
1662 | struct sbp2scsi_host_info *hi = scsi_id->hi; | 1665 | struct sbp2scsi_host_info *hi = scsi_id->hi; |
1666 | u8 payload; | ||
1663 | 1667 | ||
1664 | SBP2_DEBUG_ENTER(); | 1668 | SBP2_DEBUG_ENTER(); |
1665 | 1669 | ||
1666 | /* Initial setting comes from the hosts speed map */ | ||
1667 | scsi_id->speed_code = | 1670 | scsi_id->speed_code = |
1668 | hi->host->speed_map[NODEID_TO_NODE(hi->host->node_id) * 64 + | 1671 | hi->host->speed[NODEID_TO_NODE(scsi_id->ne->nodeid)]; |
1669 | NODEID_TO_NODE(scsi_id->ne->nodeid)]; | ||
1670 | 1672 | ||
1671 | /* Bump down our speed if the user requested it */ | 1673 | /* Bump down our speed if the user requested it */ |
1672 | if (scsi_id->speed_code > max_speed) { | 1674 | if (scsi_id->speed_code > max_speed) { |
@@ -1677,15 +1679,22 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) | |||
1677 | 1679 | ||
1678 | /* Payload size is the lesser of what our speed supports and what | 1680 | /* Payload size is the lesser of what our speed supports and what |
1679 | * our host supports. */ | 1681 | * our host supports. */ |
1680 | scsi_id->max_payload_size = | 1682 | payload = min(sbp2_speedto_max_payload[scsi_id->speed_code], |
1681 | min(sbp2_speedto_max_payload[scsi_id->speed_code], | 1683 | (u8) (hi->host->csr.max_rec - 1)); |
1682 | (u8) (hi->host->csr.max_rec - 1)); | 1684 | |
1685 | /* If physical DMA is off, work around limitation in ohci1394: | ||
1686 | * packet size must not exceed PAGE_SIZE */ | ||
1687 | if (scsi_id->ne->host->low_addr_space < (1ULL << 32)) | ||
1688 | while (SBP2_PAYLOAD_TO_BYTES(payload) + 24 > PAGE_SIZE && | ||
1689 | payload) | ||
1690 | payload--; | ||
1683 | 1691 | ||
1684 | HPSB_DEBUG("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]", | 1692 | HPSB_DEBUG("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]", |
1685 | NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid), | 1693 | NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid), |
1686 | hpsb_speedto_str[scsi_id->speed_code], | 1694 | hpsb_speedto_str[scsi_id->speed_code], |
1687 | 1 << ((u32) scsi_id->max_payload_size + 2)); | 1695 | SBP2_PAYLOAD_TO_BYTES(payload)); |
1688 | 1696 | ||
1697 | scsi_id->max_payload_size = payload; | ||
1689 | return 0; | 1698 | return 0; |
1690 | } | 1699 | } |
1691 | 1700 | ||
@@ -2113,33 +2122,6 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense | |||
2113 | } | 2122 | } |
2114 | 2123 | ||
2115 | /* | 2124 | /* |
2116 | * This function is called after a command is completed, in order to do any necessary SBP-2 | ||
2117 | * response data translations for the SCSI stack | ||
2118 | */ | ||
2119 | static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, | ||
2120 | struct scsi_cmnd *SCpnt) | ||
2121 | { | ||
2122 | u8 *scsi_buf = SCpnt->request_buffer; | ||
2123 | |||
2124 | SBP2_DEBUG_ENTER(); | ||
2125 | |||
2126 | if (SCpnt->cmnd[0] == INQUIRY && (SCpnt->cmnd[1] & 3) == 0) { | ||
2127 | /* | ||
2128 | * Make sure data length is ok. Minimum length is 36 bytes | ||
2129 | */ | ||
2130 | if (scsi_buf[4] == 0) { | ||
2131 | scsi_buf[4] = 36 - 5; | ||
2132 | } | ||
2133 | |||
2134 | /* | ||
2135 | * Fix ansi revision and response data format | ||
2136 | */ | ||
2137 | scsi_buf[2] |= 2; | ||
2138 | scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; | ||
2139 | } | ||
2140 | } | ||
2141 | |||
2142 | /* | ||
2143 | * This function deals with status writes from the SBP-2 device | 2125 | * This function deals with status writes from the SBP-2 device |
2144 | */ | 2126 | */ |
2145 | static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, | 2127 | static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, |
@@ -2478,13 +2460,6 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, | |||
2478 | } | 2460 | } |
2479 | 2461 | ||
2480 | /* | 2462 | /* |
2481 | * Take care of any sbp2 response data mucking here (RBC stuff, etc.) | ||
2482 | */ | ||
2483 | if (SCpnt->result == DID_OK << 16) { | ||
2484 | sbp2_check_sbp2_response(scsi_id, SCpnt); | ||
2485 | } | ||
2486 | |||
2487 | /* | ||
2488 | * If a bus reset is in progress and there was an error, complete | 2463 | * If a bus reset is in progress and there was an error, complete |
2489 | * the command as busy so that it will get retried. | 2464 | * the command as busy so that it will get retried. |
2490 | */ | 2465 | */ |