diff options
author | adam radford <aradford@gmail.com> | 2006-03-15 15:43:19 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-03-19 11:18:42 -0500 |
commit | 75913d9bb8328c4eca54cad39a5fb665b48383eb (patch) | |
tree | 62f991852c7424eaac8532064eec815dd9509fa6 /drivers/scsi | |
parent | 95e6a856772413993f54916ca9bf21ccfa6a537e (diff) |
[SCSI] 3ware 9000 add big endian support
The attached patch updates the 3ware 9000 driver:
- Fix 9550SX pchip reset timeout.
- Add big endian support.
Signed-off-by: Adam Radford <linuxraid@amcc.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-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 | ||