aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/3w-9xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/3w-9xxx.c')
-rw-r--r--drivers/scsi/3w-9xxx.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 6b49f6a2524d..efd9d8d3a890 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -4,7 +4,7 @@
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 Modifications By: Tom Couch <linuxraid@amcc.com>
6 6
7 Copyright (C) 2004-2006 Applied Micro Circuits Corporation. 7 Copyright (C) 2004-2007 Applied Micro Circuits Corporation.
8 8
9 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
10 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
@@ -69,6 +69,8 @@
69 2.26.02.008 - Free irq handler in __twa_shutdown(). 69 2.26.02.008 - Free irq handler in __twa_shutdown().
70 Serialize reset code. 70 Serialize reset code.
71 Add support for 9650SE controllers. 71 Add support for 9650SE controllers.
72 2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails.
73 2.26.02.010 - Add support for 9690SA controllers.
72*/ 74*/
73 75
74#include <linux/module.h> 76#include <linux/module.h>
@@ -92,7 +94,7 @@
92#include "3w-9xxx.h" 94#include "3w-9xxx.h"
93 95
94/* Globals */ 96/* Globals */
95#define TW_DRIVER_VERSION "2.26.02.008" 97#define TW_DRIVER_VERSION "2.26.02.010"
96static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; 98static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
97static unsigned int twa_device_extension_count; 99static unsigned int twa_device_extension_count;
98static int twa_major = -1; 100static int twa_major = -1;
@@ -124,11 +126,11 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
124 unsigned short *fw_on_ctlr_branch, 126 unsigned short *fw_on_ctlr_branch,
125 unsigned short *fw_on_ctlr_build, 127 unsigned short *fw_on_ctlr_build,
126 u32 *init_connect_result); 128 u32 *init_connect_result);
127static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length); 129static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
128static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds); 130static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
129static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds); 131static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
130static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal); 132static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
131static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset); 133static int twa_reset_device_extension(TW_Device_Extension *tw_dev);
132static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset); 134static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
133static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg); 135static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg);
134static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id); 136static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
@@ -683,7 +685,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
683 full_command_packet = &tw_ioctl->firmware_command; 685 full_command_packet = &tw_ioctl->firmware_command;
684 686
685 /* Load request id and sglist for both command types */ 687 /* Load request id and sglist for both command types */
686 twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted); 688 twa_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
687 689
688 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full)); 690 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
689 691
@@ -700,10 +702,10 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
700 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { 702 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
701 /* Now we need to reset the board */ 703 /* Now we need to reset the board */
702 printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n", 704 printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
703 tw_dev->host->host_no, TW_DRIVER, 0xc, 705 tw_dev->host->host_no, TW_DRIVER, 0x37,
704 cmd); 706 cmd);
705 retval = TW_IOCTL_ERROR_OS_EIO; 707 retval = TW_IOCTL_ERROR_OS_EIO;
706 twa_reset_device_extension(tw_dev, 1); 708 twa_reset_device_extension(tw_dev);
707 goto out3; 709 goto out3;
708 } 710 }
709 711
@@ -890,7 +892,9 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
890 } 892 }
891 893
892 if (status_reg_value & TW_STATUS_QUEUE_ERROR) { 894 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
893 if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags))) 895 if (((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) &&
896 (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9690SA)) ||
897 (!test_bit(TW_IN_RESET, &tw_dev->flags)))
894 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); 898 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
895 writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); 899 writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
896 } 900 }
@@ -935,8 +939,7 @@ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev)
935 unsigned long before; 939 unsigned long before;
936 int retval = 1; 940 int retval = 1;
937 941
938 if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) || 942 if (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9000) {
939 (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) {
940 before = jiffies; 943 before = jiffies;
941 while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { 944 while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) {
942 response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); 945 response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
@@ -1195,7 +1198,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
1195 u32 status_reg_value; 1198 u32 status_reg_value;
1196 TW_Response_Queue response_que; 1199 TW_Response_Queue response_que;
1197 TW_Command_Full *full_command_packet; 1200 TW_Command_Full *full_command_packet;
1198 TW_Command *command_packet;
1199 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance; 1201 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1200 int handled = 0; 1202 int handled = 0;
1201 1203
@@ -1273,7 +1275,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
1273 request_id = TW_RESID_OUT(response_que.response_id); 1275 request_id = TW_RESID_OUT(response_que.response_id);
1274 full_command_packet = tw_dev->command_packet_virt[request_id]; 1276 full_command_packet = tw_dev->command_packet_virt[request_id];
1275 error = 0; 1277 error = 0;
1276 command_packet = &full_command_packet->command.oldcommand;
1277 /* Check for command packet errors */ 1278 /* Check for command packet errors */
1278 if (full_command_packet->command.newcommand.status != 0) { 1279 if (full_command_packet->command.newcommand.status != 0) {
1279 if (tw_dev->srb[request_id] != 0) { 1280 if (tw_dev->srb[request_id] != 0) {
@@ -1352,11 +1353,15 @@ twa_interrupt_bail:
1352} /* End twa_interrupt() */ 1353} /* End twa_interrupt() */
1353 1354
1354/* This function will load the request id and various sgls for ioctls */ 1355/* This function will load the request id and various sgls for ioctls */
1355static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length) 1356static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
1356{ 1357{
1357 TW_Command *oldcommand; 1358 TW_Command *oldcommand;
1358 TW_Command_Apache *newcommand; 1359 TW_Command_Apache *newcommand;
1359 TW_SG_Entry *sgl; 1360 TW_SG_Entry *sgl;
1361 unsigned int pae = 0;
1362
1363 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
1364 pae = 1;
1360 1365
1361 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { 1366 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
1362 newcommand = &full_command_packet->command.newcommand; 1367 newcommand = &full_command_packet->command.newcommand;
@@ -1372,12 +1377,14 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d
1372 1377
1373 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) { 1378 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
1374 /* Load the sg list */ 1379 /* Load the sg list */
1375 sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset)); 1380 if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)
1381 sgl = (TW_SG_Entry *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry)/4) + pae);
1382 else
1383 sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
1376 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); 1384 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
1377 sgl->length = cpu_to_le32(length); 1385 sgl->length = cpu_to_le32(length);
1378 1386
1379 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4)) 1387 oldcommand->size += pae;
1380 oldcommand->size += 1;
1381 } 1388 }
1382 } 1389 }
1383} /* End twa_load_sgl() */ 1390} /* End twa_load_sgl() */
@@ -1506,7 +1513,8 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id,
1506 command_que_value = tw_dev->command_packet_phys[request_id]; 1513 command_que_value = tw_dev->command_packet_phys[request_id];
1507 1514
1508 /* For 9650SE write low 4 bytes first */ 1515 /* For 9650SE write low 4 bytes first */
1509 if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { 1516 if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
1517 (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) {
1510 command_que_value += TW_COMMAND_OFFSET; 1518 command_que_value += TW_COMMAND_OFFSET;
1511 writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); 1519 writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev));
1512 } 1520 }
@@ -1537,7 +1545,8 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id,
1537 TW_UNMASK_COMMAND_INTERRUPT(tw_dev); 1545 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
1538 goto out; 1546 goto out;
1539 } else { 1547 } else {
1540 if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { 1548 if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
1549 (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) {
1541 /* Now write upper 4 bytes */ 1550 /* Now write upper 4 bytes */
1542 writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); 1551 writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4);
1543 } else { 1552 } else {
@@ -1561,7 +1570,7 @@ out:
1561} /* End twa_post_command_packet() */ 1570} /* End twa_post_command_packet() */
1562 1571
1563/* This function will reset a device extension */ 1572/* This function will reset a device extension */
1564static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset) 1573static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
1565{ 1574{
1566 int i = 0; 1575 int i = 0;
1567 int retval = 1; 1576 int retval = 1;
@@ -1719,7 +1728,7 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1719 mutex_lock(&tw_dev->ioctl_lock); 1728 mutex_lock(&tw_dev->ioctl_lock);
1720 1729
1721 /* Now reset the card and some of the device extension data */ 1730 /* Now reset the card and some of the device extension data */
1722 if (twa_reset_device_extension(tw_dev, 0)) { 1731 if (twa_reset_device_extension(tw_dev)) {
1723 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); 1732 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
1724 goto out; 1733 goto out;
1725 } 1734 }
@@ -2001,11 +2010,14 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
2001 2010
2002 pci_set_master(pdev); 2011 pci_set_master(pdev);
2003 2012
2004 retval = pci_set_dma_mask(pdev, sizeof(dma_addr_t) > 4 ? DMA_64BIT_MASK : DMA_32BIT_MASK); 2013 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
2005 if (retval) { 2014 || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
2006 TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask"); 2015 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
2007 goto out_disable_device; 2016 || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
2008 } 2017 TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
2018 retval = -ENODEV;
2019 goto out_disable_device;
2020 }
2009 2021
2010 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension)); 2022 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
2011 if (!host) { 2023 if (!host) {
@@ -2053,7 +2065,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
2053 goto out_iounmap; 2065 goto out_iounmap;
2054 2066
2055 /* Set host specific parameters */ 2067 /* Set host specific parameters */
2056 if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE) 2068 if ((pdev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
2069 (pdev->device == PCI_DEVICE_ID_3WARE_9690SA))
2057 host->max_id = TW_MAX_UNITS_9650SE; 2070 host->max_id = TW_MAX_UNITS_9650SE;
2058 else 2071 else
2059 host->max_id = TW_MAX_UNITS; 2072 host->max_id = TW_MAX_UNITS;
@@ -2160,6 +2173,8 @@ static struct pci_device_id twa_pci_tbl[] __devinitdata = {
2160 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2173 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2161 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, 2174 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE,
2162 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 2175 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2176 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9690SA,
2177 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2163 { } 2178 { }
2164}; 2179};
2165MODULE_DEVICE_TABLE(pci, twa_pci_tbl); 2180MODULE_DEVICE_TABLE(pci, twa_pci_tbl);