diff options
| -rw-r--r-- | drivers/scsi/3w-9xxx.c | 138 | ||||
| -rw-r--r-- | drivers/scsi/3w-9xxx.h | 18 |
2 files changed, 73 insertions, 83 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index d9152d02088c..0ab26d01877b 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
| @@ -2,8 +2,9 @@ | |||
| 2 | 3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux. | 2 | 3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux. |
| 3 | 3 | ||
| 4 | Written By: Adam Radford <linuxraid@amcc.com> | 4 | Written By: Adam Radford <linuxraid@amcc.com> |
| 5 | Modifications By: Tom Couch <linuxraid@amcc.com> | ||
| 5 | 6 | ||
| 6 | Copyright (C) 2004-2005 Applied Micro Circuits Corporation. | 7 | Copyright (C) 2004-2006 Applied Micro Circuits Corporation. |
| 7 | 8 | ||
| 8 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
| 9 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
| @@ -62,6 +63,8 @@ | |||
| 62 | 2.26.02.003 - Correctly handle single sgl's with use_sg=1. | 63 | 2.26.02.003 - Correctly handle single sgl's with use_sg=1. |
| 63 | 2.26.02.004 - Add support for 9550SX controllers. | 64 | 2.26.02.004 - Add support for 9550SX controllers. |
| 64 | 2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher. | 65 | 2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher. |
| 66 | 2.26.02.006 - Fix 9550SX pchip reset timeout. | ||
| 67 | Add big endian support. | ||
| 65 | */ | 68 | */ |
| 66 | 69 | ||
| 67 | #include <linux/module.h> | 70 | #include <linux/module.h> |
| @@ -85,7 +88,7 @@ | |||
| 85 | #include "3w-9xxx.h" | 88 | #include "3w-9xxx.h" |
| 86 | 89 | ||
| 87 | /* Globals */ | 90 | /* Globals */ |
| 88 | #define TW_DRIVER_VERSION "2.26.02.005" | 91 | #define TW_DRIVER_VERSION "2.26.02.006" |
| 89 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; | 92 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; |
| 90 | static unsigned int twa_device_extension_count; | 93 | static unsigned int twa_device_extension_count; |
| 91 | static int twa_major = -1; | 94 | static int twa_major = -1; |
| @@ -208,7 +211,7 @@ static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id) | |||
| 208 | 211 | ||
| 209 | header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; | 212 | header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; |
| 210 | tw_dev->posted_request_count--; | 213 | tw_dev->posted_request_count--; |
| 211 | aen = header->status_block.error; | 214 | aen = le16_to_cpu(header->status_block.error); |
| 212 | full_command_packet = tw_dev->command_packet_virt[request_id]; | 215 | full_command_packet = tw_dev->command_packet_virt[request_id]; |
| 213 | command_packet = &full_command_packet->command.oldcommand; | 216 | command_packet = &full_command_packet->command.oldcommand; |
| 214 | 217 | ||
| @@ -305,7 +308,7 @@ static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset) | |||
| 305 | 308 | ||
| 306 | tw_dev->posted_request_count--; | 309 | tw_dev->posted_request_count--; |
| 307 | header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; | 310 | header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id]; |
| 308 | aen = header->status_block.error; | 311 | aen = le16_to_cpu(header->status_block.error); |
| 309 | queue = 0; | 312 | queue = 0; |
| 310 | count++; | 313 | count++; |
| 311 | 314 | ||
| @@ -365,7 +368,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H | |||
| 365 | tw_dev->aen_clobber = 1; | 368 | tw_dev->aen_clobber = 1; |
| 366 | } | 369 | } |
| 367 | 370 | ||
| 368 | aen = header->status_block.error; | 371 | aen = le16_to_cpu(header->status_block.error); |
| 369 | memset(event, 0, sizeof(TW_Event)); | 372 | memset(event, 0, sizeof(TW_Event)); |
| 370 | 373 | ||
| 371 | event->severity = TW_SEV_OUT(header->status_block.severity__reserved); | 374 | event->severity = TW_SEV_OUT(header->status_block.severity__reserved); |
| @@ -382,7 +385,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H | |||
| 382 | 385 | ||
| 383 | header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0'; | 386 | header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0'; |
| 384 | event->parameter_len = strlen(header->err_specific_desc); | 387 | event->parameter_len = strlen(header->err_specific_desc); |
| 385 | memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len); | 388 | memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + (error_str[0] == '\0' ? 0 : (1 + strlen(error_str)))); |
| 386 | if (event->severity != TW_AEN_SEVERITY_DEBUG) | 389 | if (event->severity != TW_AEN_SEVERITY_DEBUG) |
| 387 | printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n", | 390 | printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n", |
| 388 | host, | 391 | host, |
| @@ -462,24 +465,24 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id) | |||
| 462 | command_packet = &full_command_packet->command.oldcommand; | 465 | command_packet = &full_command_packet->command.oldcommand; |
| 463 | command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM); | 466 | command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM); |
| 464 | command_packet->request_id = request_id; | 467 | command_packet->request_id = request_id; |
| 465 | command_packet->byte8_offset.param.sgl[0].address = tw_dev->generic_buffer_phys[request_id]; | 468 | command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); |
| 466 | command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE; | 469 | command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); |
| 467 | command_packet->size = TW_COMMAND_SIZE; | 470 | command_packet->size = TW_COMMAND_SIZE; |
| 468 | command_packet->byte6_offset.parameter_count = 1; | 471 | command_packet->byte6_offset.parameter_count = cpu_to_le16(1); |
| 469 | 472 | ||
| 470 | /* Setup the param */ | 473 | /* Setup the param */ |
| 471 | param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; | 474 | param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; |
| 472 | memset(param, 0, TW_SECTOR_SIZE); | 475 | memset(param, 0, TW_SECTOR_SIZE); |
| 473 | param->table_id = TW_TIMEKEEP_TABLE | 0x8000; /* Controller time keep table */ | 476 | param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */ |
| 474 | param->parameter_id = 0x3; /* SchedulerTime */ | 477 | param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */ |
| 475 | param->parameter_size_bytes = 4; | 478 | param->parameter_size_bytes = cpu_to_le16(4); |
| 476 | 479 | ||
| 477 | /* Convert system time in UTC to local time seconds since last | 480 | /* Convert system time in UTC to local time seconds since last |
| 478 | Sunday 12:00AM */ | 481 | Sunday 12:00AM */ |
| 479 | do_gettimeofday(&utc); | 482 | do_gettimeofday(&utc); |
| 480 | local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60)); | 483 | local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60)); |
| 481 | schedulertime = local_time - (3 * 86400); | 484 | schedulertime = local_time - (3 * 86400); |
| 482 | schedulertime = schedulertime % 604800; | 485 | schedulertime = cpu_to_le32(schedulertime % 604800); |
| 483 | 486 | ||
| 484 | memcpy(param->data, &schedulertime, sizeof(u32)); | 487 | memcpy(param->data, &schedulertime, sizeof(u32)); |
| 485 | 488 | ||
| @@ -931,26 +934,19 @@ out: | |||
| 931 | /* This function will clear the pchip/response queue on 9550SX */ | 934 | /* This function will clear the pchip/response queue on 9550SX */ |
| 932 | static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev) | 935 | static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev) |
| 933 | { | 936 | { |
| 934 | u32 status_reg_value, response_que_value; | 937 | u32 response_que_value = 0; |
| 935 | int count = 0, retval = 1; | 938 | unsigned long before; |
| 939 | int retval = 1; | ||
| 936 | 940 | ||
| 937 | if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) { | 941 | if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) { |
| 938 | status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); | 942 | before = jiffies; |
| 939 | 943 | while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { | |
| 940 | while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) { | ||
| 941 | response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); | 944 | response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); |
| 942 | if ((response_que_value & TW_9550SX_DRAIN_COMPLETED) == TW_9550SX_DRAIN_COMPLETED) { | 945 | if (time_after(jiffies, before + HZ * 30)) |
| 943 | /* P-chip settle time */ | ||
| 944 | msleep(500); | ||
| 945 | retval = 0; | ||
| 946 | goto out; | 946 | goto out; |
| 947 | } | ||
| 948 | status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); | ||
| 949 | count++; | ||
| 950 | } | 947 | } |
| 951 | if (count == TW_MAX_RESPONSE_DRAIN) | 948 | /* P-chip settle time */ |
| 952 | goto out; | 949 | msleep(500); |
| 953 | |||
| 954 | retval = 0; | 950 | retval = 0; |
| 955 | } else | 951 | } else |
| 956 | retval = 0; | 952 | retval = 0; |
| @@ -972,7 +968,7 @@ static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_ | |||
| 972 | error_str = &(full_command_packet->header.err_specific_desc[strlen(full_command_packet->header.err_specific_desc) + 1]); | 968 | error_str = &(full_command_packet->header.err_specific_desc[strlen(full_command_packet->header.err_specific_desc) + 1]); |
| 973 | 969 | ||
| 974 | /* Don't print error for Logical unit not supported during rollcall */ | 970 | /* Don't print error for Logical unit not supported during rollcall */ |
| 975 | error = full_command_packet->header.status_block.error; | 971 | error = le16_to_cpu(full_command_packet->header.status_block.error); |
| 976 | if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) { | 972 | if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) { |
| 977 | if (print_host) | 973 | if (print_host) |
| 978 | printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n", | 974 | printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n", |
| @@ -1047,18 +1043,18 @@ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl | |||
| 1047 | command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM); | 1043 | command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM); |
| 1048 | command_packet->size = TW_COMMAND_SIZE; | 1044 | command_packet->size = TW_COMMAND_SIZE; |
| 1049 | command_packet->request_id = request_id; | 1045 | command_packet->request_id = request_id; |
| 1050 | command_packet->byte6_offset.block_count = 1; | 1046 | command_packet->byte6_offset.block_count = cpu_to_le16(1); |
| 1051 | 1047 | ||
| 1052 | /* Now setup the param */ | 1048 | /* Now setup the param */ |
| 1053 | param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; | 1049 | param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id]; |
| 1054 | memset(param, 0, TW_SECTOR_SIZE); | 1050 | memset(param, 0, TW_SECTOR_SIZE); |
| 1055 | param->table_id = table_id | 0x8000; | 1051 | param->table_id = cpu_to_le16(table_id | 0x8000); |
| 1056 | param->parameter_id = parameter_id; | 1052 | param->parameter_id = cpu_to_le16(parameter_id); |
| 1057 | param->parameter_size_bytes = parameter_size_bytes; | 1053 | param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes); |
| 1058 | param_value = tw_dev->generic_buffer_phys[request_id]; | 1054 | param_value = tw_dev->generic_buffer_phys[request_id]; |
| 1059 | 1055 | ||
| 1060 | command_packet->byte8_offset.param.sgl[0].address = param_value; | 1056 | command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(param_value); |
| 1061 | command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE; | 1057 | command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE); |
| 1062 | 1058 | ||
| 1063 | /* Post the command packet to the board */ | 1059 | /* Post the command packet to the board */ |
| 1064 | twa_post_command_packet(tw_dev, request_id, 1); | 1060 | twa_post_command_packet(tw_dev, request_id, 1); |
| @@ -1107,18 +1103,20 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits, | |||
| 1107 | tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand; | 1103 | tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand; |
| 1108 | tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION); | 1104 | tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION); |
| 1109 | tw_initconnect->request_id = request_id; | 1105 | tw_initconnect->request_id = request_id; |
| 1110 | tw_initconnect->message_credits = message_credits; | 1106 | tw_initconnect->message_credits = cpu_to_le16(message_credits); |
| 1111 | tw_initconnect->features = set_features; | 1107 | tw_initconnect->features = set_features; |
| 1112 | 1108 | ||
| 1113 | /* Turn on 64-bit sgl support if we need to */ | 1109 | /* Turn on 64-bit sgl support if we need to */ |
| 1114 | tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0; | 1110 | tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0; |
| 1115 | 1111 | ||
| 1112 | tw_initconnect->features = cpu_to_le32(tw_initconnect->features); | ||
| 1113 | |||
| 1116 | if (set_features & TW_EXTENDED_INIT_CONNECT) { | 1114 | if (set_features & TW_EXTENDED_INIT_CONNECT) { |
| 1117 | tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED; | 1115 | tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED; |
| 1118 | tw_initconnect->fw_srl = current_fw_srl; | 1116 | tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl); |
| 1119 | tw_initconnect->fw_arch_id = current_fw_arch_id; | 1117 | tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id); |
| 1120 | tw_initconnect->fw_branch = current_fw_branch; | 1118 | tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch); |
| 1121 | tw_initconnect->fw_build = current_fw_build; | 1119 | tw_initconnect->fw_build = cpu_to_le16(current_fw_build); |
| 1122 | } else | 1120 | } else |
| 1123 | tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE; | 1121 | tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE; |
| 1124 | 1122 | ||
| @@ -1130,11 +1128,11 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits, | |||
| 1130 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection"); | 1128 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection"); |
| 1131 | } else { | 1129 | } else { |
| 1132 | if (set_features & TW_EXTENDED_INIT_CONNECT) { | 1130 | if (set_features & TW_EXTENDED_INIT_CONNECT) { |
| 1133 | *fw_on_ctlr_srl = tw_initconnect->fw_srl; | 1131 | *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl); |
| 1134 | *fw_on_ctlr_arch_id = tw_initconnect->fw_arch_id; | 1132 | *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id); |
| 1135 | *fw_on_ctlr_branch = tw_initconnect->fw_branch; | 1133 | *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch); |
| 1136 | *fw_on_ctlr_build = tw_initconnect->fw_build; | 1134 | *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build); |
| 1137 | *init_connect_result = tw_initconnect->result; | 1135 | *init_connect_result = le32_to_cpu(tw_initconnect->result); |
| 1138 | } | 1136 | } |
| 1139 | retval = 0; | 1137 | retval = 0; |
| 1140 | } | 1138 | } |
| @@ -1358,10 +1356,10 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d | |||
| 1358 | newcommand = &full_command_packet->command.newcommand; | 1356 | newcommand = &full_command_packet->command.newcommand; |
| 1359 | newcommand->request_id__lunl = | 1357 | newcommand->request_id__lunl = |
| 1360 | TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id); | 1358 | TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id); |
| 1361 | newcommand->sg_list[0].address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1; | 1359 | newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); |
| 1362 | newcommand->sg_list[0].length = length; | 1360 | newcommand->sg_list[0].length = cpu_to_le32(length); |
| 1363 | newcommand->sgl_entries__lunh = | 1361 | newcommand->sgl_entries__lunh = |
| 1364 | TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1); | 1362 | cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1)); |
| 1365 | } else { | 1363 | } else { |
| 1366 | oldcommand = &full_command_packet->command.oldcommand; | 1364 | oldcommand = &full_command_packet->command.oldcommand; |
| 1367 | oldcommand->request_id = request_id; | 1365 | oldcommand->request_id = request_id; |
| @@ -1369,8 +1367,8 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d | |||
| 1369 | if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { | 1367 | if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { |
| 1370 | /* Load the sg list */ | 1368 | /* Load the sg list */ |
| 1371 | sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); | 1369 | sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); |
| 1372 | sgl->address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1; | 1370 | sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); |
| 1373 | sgl->length = length; | 1371 | sgl->length = cpu_to_le32(length); |
| 1374 | 1372 | ||
| 1375 | if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4)) | 1373 | if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4)) |
| 1376 | oldcommand->size += 1; | 1374 | oldcommand->size += 1; |
| @@ -1828,10 +1826,10 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, | |||
| 1828 | if (srb) { | 1826 | if (srb) { |
| 1829 | command_packet->unit = srb->device->id; | 1827 | command_packet->unit = srb->device->id; |
| 1830 | command_packet->request_id__lunl = | 1828 | command_packet->request_id__lunl = |
| 1831 | TW_REQ_LUN_IN(srb->device->lun, request_id); | 1829 | cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id)); |
| 1832 | } else { | 1830 | } else { |
| 1833 | command_packet->request_id__lunl = | 1831 | command_packet->request_id__lunl = |
| 1834 | TW_REQ_LUN_IN(0, request_id); | 1832 | cpu_to_le16(TW_REQ_LUN_IN(0, request_id)); |
| 1835 | command_packet->unit = 0; | 1833 | command_packet->unit = 0; |
| 1836 | } | 1834 | } |
| 1837 | 1835 | ||
| @@ -1841,8 +1839,8 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, | |||
| 1841 | /* Map sglist from scsi layer to cmd packet */ | 1839 | /* Map sglist from scsi layer to cmd packet */ |
| 1842 | if (tw_dev->srb[request_id]->use_sg == 0) { | 1840 | if (tw_dev->srb[request_id]->use_sg == 0) { |
| 1843 | if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) { | 1841 | if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) { |
| 1844 | command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id]; | 1842 | command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); |
| 1845 | command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH; | 1843 | command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); |
| 1846 | if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL) | 1844 | if (tw_dev->srb[request_id]->sc_data_direction == DMA_TO_DEVICE || tw_dev->srb[request_id]->sc_data_direction == DMA_BIDIRECTIONAL) |
| 1847 | memcpy(tw_dev->generic_buffer_virt[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen); | 1845 | memcpy(tw_dev->generic_buffer_virt[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen); |
| 1848 | } else { | 1846 | } else { |
| @@ -1850,12 +1848,12 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, | |||
| 1850 | if (buffaddr == 0) | 1848 | if (buffaddr == 0) |
| 1851 | goto out; | 1849 | goto out; |
| 1852 | 1850 | ||
| 1853 | command_packet->sg_list[0].address = buffaddr; | 1851 | command_packet->sg_list[0].address = TW_CPU_TO_SGL(buffaddr); |
| 1854 | command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen; | 1852 | command_packet->sg_list[0].length = cpu_to_le32(tw_dev->srb[request_id]->request_bufflen); |
| 1855 | } | 1853 | } |
| 1856 | command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), 1); | 1854 | command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), 1)); |
| 1857 | 1855 | ||
| 1858 | if (command_packet->sg_list[0].address & TW_ALIGNMENT_9000_SGL) { | 1856 | if (command_packet->sg_list[0].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) { |
| 1859 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi"); | 1857 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi"); |
| 1860 | goto out; | 1858 | goto out; |
| 1861 | } | 1859 | } |
| @@ -1869,35 +1867,35 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, | |||
| 1869 | memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length); | 1867 | memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length); |
| 1870 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | 1868 | kunmap_atomic(buf - sg->offset, KM_IRQ0); |
| 1871 | } | 1869 | } |
| 1872 | command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id]; | 1870 | command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); |
| 1873 | command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH; | 1871 | command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); |
| 1874 | } else { | 1872 | } else { |
| 1875 | sg_count = twa_map_scsi_sg_data(tw_dev, request_id); | 1873 | sg_count = twa_map_scsi_sg_data(tw_dev, request_id); |
| 1876 | if (sg_count == 0) | 1874 | if (sg_count == 0) |
| 1877 | goto out; | 1875 | goto out; |
| 1878 | 1876 | ||
| 1879 | for (i = 0; i < sg_count; i++) { | 1877 | for (i = 0; i < sg_count; i++) { |
| 1880 | command_packet->sg_list[i].address = sg_dma_address(&sglist[i]); | 1878 | command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(&sglist[i])); |
| 1881 | command_packet->sg_list[i].length = sg_dma_len(&sglist[i]); | 1879 | command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(&sglist[i])); |
| 1882 | if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) { | 1880 | if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) { |
| 1883 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi"); | 1881 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi"); |
| 1884 | goto out; | 1882 | goto out; |
| 1885 | } | 1883 | } |
| 1886 | } | 1884 | } |
| 1887 | } | 1885 | } |
| 1888 | command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg); | 1886 | command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg)); |
| 1889 | } | 1887 | } |
| 1890 | } else { | 1888 | } else { |
| 1891 | /* Internal cdb post */ | 1889 | /* Internal cdb post */ |
| 1892 | for (i = 0; i < use_sg; i++) { | 1890 | for (i = 0; i < use_sg; i++) { |
| 1893 | command_packet->sg_list[i].address = sglistarg[i].address; | 1891 | command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address); |
| 1894 | command_packet->sg_list[i].length = sglistarg[i].length; | 1892 | command_packet->sg_list[i].length = cpu_to_le32(sglistarg[i].length); |
| 1895 | if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) { | 1893 | if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) { |
| 1896 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post"); | 1894 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post"); |
| 1897 | goto out; | 1895 | goto out; |
| 1898 | } | 1896 | } |
| 1899 | } | 1897 | } |
| 1900 | command_packet->sgl_entries__lunh = TW_REQ_LUN_IN(0, use_sg); | 1898 | command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg)); |
| 1901 | } | 1899 | } |
| 1902 | 1900 | ||
| 1903 | if (srb) { | 1901 | if (srb) { |
| @@ -2115,8 +2113,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
| 2115 | TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH), | 2113 | TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH), |
| 2116 | (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE, | 2114 | (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE, |
| 2117 | TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH), | 2115 | TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH), |
| 2118 | *(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE, | 2116 | le32_to_cpu(*(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE, |
| 2119 | TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH)); | 2117 | TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH))); |
| 2120 | 2118 | ||
| 2121 | /* Now setup the interrupt handler */ | 2119 | /* Now setup the interrupt handler */ |
| 2122 | retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev); | 2120 | retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev); |
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index 1b16d57f0314..e5685be96f45 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h | |||
| @@ -2,8 +2,9 @@ | |||
| 2 | 3w-9xxx.h -- 3ware 9000 Storage Controller device driver for Linux. | 2 | 3w-9xxx.h -- 3ware 9000 Storage Controller device driver for Linux. |
| 3 | 3 | ||
| 4 | Written By: Adam Radford <linuxraid@amcc.com> | 4 | Written By: Adam Radford <linuxraid@amcc.com> |
| 5 | Modifications By: Tom Couch <linuxraid@amcc.com> | ||
| 5 | 6 | ||
| 6 | Copyright (C) 2004-2005 Applied Micro Circuits Corporation. | 7 | Copyright (C) 2004-2006 Applied Micro Circuits Corporation. |
| 7 | 8 | ||
| 8 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
| 9 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
| @@ -287,9 +288,6 @@ static twa_message_type twa_error_table[] = { | |||
| 287 | #define TW_STATUS_UNEXPECTED_BITS 0x00F00000 | 288 | #define TW_STATUS_UNEXPECTED_BITS 0x00F00000 |
| 288 | #define TW_STATUS_VALID_INTERRUPT 0x00DF0000 | 289 | #define TW_STATUS_VALID_INTERRUPT 0x00DF0000 |
| 289 | 290 | ||
| 290 | /* RESPONSE QUEUE BIT DEFINITIONS */ | ||
| 291 | #define TW_RESPONSE_ID_MASK 0x00000FF0 | ||
| 292 | |||
| 293 | /* PCI related defines */ | 291 | /* PCI related defines */ |
| 294 | #define TW_NUMDEVICES 1 | 292 | #define TW_NUMDEVICES 1 |
| 295 | #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 | 293 | #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 |
| @@ -471,6 +469,7 @@ printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \ | |||
| 471 | #define TW_APACHE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 72 : 109) | 469 | #define TW_APACHE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 72 : 109) |
| 472 | #define TW_ESCALADE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 41 : 62) | 470 | #define TW_ESCALADE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 41 : 62) |
| 473 | #define TW_PADDING_LENGTH (sizeof(dma_addr_t) > 4 ? 8 : 0) | 471 | #define TW_PADDING_LENGTH (sizeof(dma_addr_t) > 4 ? 8 : 0) |
| 472 | #define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x)) | ||
| 474 | 473 | ||
| 475 | #pragma pack(1) | 474 | #pragma pack(1) |
| 476 | 475 | ||
| @@ -614,13 +613,6 @@ typedef union TAG_TW_Response_Queue { | |||
| 614 | u32 value; | 613 | u32 value; |
| 615 | } TW_Response_Queue; | 614 | } TW_Response_Queue; |
| 616 | 615 | ||
| 617 | typedef struct TAG_TW_Info { | ||
| 618 | char *buffer; | ||
| 619 | int length; | ||
| 620 | int offset; | ||
| 621 | int position; | ||
| 622 | } TW_Info; | ||
| 623 | |||
| 624 | /* Compatibility information structure */ | 616 | /* Compatibility information structure */ |
| 625 | typedef struct TAG_TW_Compatibility_Info | 617 | typedef struct TAG_TW_Compatibility_Info |
| 626 | { | 618 | { |
| @@ -636,6 +628,8 @@ typedef struct TAG_TW_Compatibility_Info | |||
| 636 | unsigned short driver_build_low; | 628 | unsigned short driver_build_low; |
| 637 | } TW_Compatibility_Info; | 629 | } TW_Compatibility_Info; |
| 638 | 630 | ||
| 631 | #pragma pack() | ||
| 632 | |||
| 639 | typedef struct TAG_TW_Device_Extension { | 633 | typedef struct TAG_TW_Device_Extension { |
| 640 | u32 __iomem *base_addr; | 634 | u32 __iomem *base_addr; |
| 641 | unsigned long *generic_buffer_virt[TW_Q_LENGTH]; | 635 | unsigned long *generic_buffer_virt[TW_Q_LENGTH]; |
| @@ -679,7 +673,5 @@ typedef struct TAG_TW_Device_Extension { | |||
| 679 | unsigned short working_build; | 673 | unsigned short working_build; |
| 680 | } TW_Device_Extension; | 674 | } TW_Device_Extension; |
| 681 | 675 | ||
| 682 | #pragma pack() | ||
| 683 | |||
| 684 | #endif /* _3W_9XXX_H */ | 676 | #endif /* _3W_9XXX_H */ |
| 685 | 677 | ||
