aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-22 13:47:24 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-22 13:47:24 -0500
commit2152f8536668a957ea3214735b4761e7b22ef7d8 (patch)
tree56723fc51445b1bc930c6400d4c00fd6fc831f88 /drivers/scsi/qla2xxx/qla_os.c
parent7cae7e26f245151b9ccad868bf2edf8c8048d307 (diff)
parent30afc84cf7325e88fb9746340eba3c161080ff49 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (138 commits) [SCSI] libata: implement minimal transport template for ->eh_timed_out [SCSI] eliminate rphy allocation in favour of expander/end device allocation [SCSI] convert mptsas over to end_device/expander allocations [SCSI] allow displaying and setting of cache type via sysfs [SCSI] add scsi_mode_select to scsi_lib.c [SCSI] 3ware 9000 add big endian support [SCSI] qla2xxx: update MAINTAINERS [SCSI] scsi: move target_destroy call [SCSI] fusion - bump version [SCSI] fusion - expander hotplug suport in mptsas module [SCSI] fusion - exposing raid components in mptsas [SCSI] fusion - memory leak, and initializing fields [SCSI] fusion - exclosure misspelled [SCSI] fusion - cleanup mptsas event handling functions [SCSI] fusion - removing target_id/bus_id from the VirtDevice structure [SCSI] fusion - static fix's [SCSI] fusion - move some debug firmware event debug msgs to verbose level [SCSI] fusion - loginfo header update [SCSI] add scsi_reprobe_device [SCSI] megaraid_sas: fix extended timeout handling ...
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c165
1 files changed, 95 insertions, 70 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 9f91f1a20542..029bbf461bb2 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -8,8 +8,8 @@
8 8
9#include <linux/moduleparam.h> 9#include <linux/moduleparam.h>
10#include <linux/vmalloc.h> 10#include <linux/vmalloc.h>
11#include <linux/smp_lock.h>
12#include <linux/delay.h> 11#include <linux/delay.h>
12#include <linux/kthread.h>
13 13
14#include <scsi/scsi_tcq.h> 14#include <scsi/scsi_tcq.h>
15#include <scsi/scsicam.h> 15#include <scsi/scsicam.h>
@@ -1146,6 +1146,57 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha)
1146 pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK); 1146 pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
1147} 1147}
1148 1148
1149static inline void
1150qla2x00_set_isp_flags(scsi_qla_host_t *ha)
1151{
1152 ha->device_type = DT_EXTENDED_IDS;
1153 switch (ha->pdev->device) {
1154 case PCI_DEVICE_ID_QLOGIC_ISP2100:
1155 ha->device_type |= DT_ISP2100;
1156 ha->device_type &= ~DT_EXTENDED_IDS;
1157 break;
1158 case PCI_DEVICE_ID_QLOGIC_ISP2200:
1159 ha->device_type |= DT_ISP2200;
1160 ha->device_type &= ~DT_EXTENDED_IDS;
1161 break;
1162 case PCI_DEVICE_ID_QLOGIC_ISP2300:
1163 ha->device_type |= DT_ISP2300;
1164 ha->device_type |= DT_ZIO_SUPPORTED;
1165 break;
1166 case PCI_DEVICE_ID_QLOGIC_ISP2312:
1167 ha->device_type |= DT_ISP2312;
1168 ha->device_type |= DT_ZIO_SUPPORTED;
1169 break;
1170 case PCI_DEVICE_ID_QLOGIC_ISP2322:
1171 ha->device_type |= DT_ISP2322;
1172 ha->device_type |= DT_ZIO_SUPPORTED;
1173 if (ha->pdev->subsystem_vendor == 0x1028 &&
1174 ha->pdev->subsystem_device == 0x0170)
1175 ha->device_type |= DT_OEM_001;
1176 break;
1177 case PCI_DEVICE_ID_QLOGIC_ISP6312:
1178 ha->device_type |= DT_ISP6312;
1179 break;
1180 case PCI_DEVICE_ID_QLOGIC_ISP6322:
1181 ha->device_type |= DT_ISP6322;
1182 break;
1183 case PCI_DEVICE_ID_QLOGIC_ISP2422:
1184 ha->device_type |= DT_ISP2422;
1185 ha->device_type |= DT_ZIO_SUPPORTED;
1186 break;
1187 case PCI_DEVICE_ID_QLOGIC_ISP2432:
1188 ha->device_type |= DT_ISP2432;
1189 ha->device_type |= DT_ZIO_SUPPORTED;
1190 break;
1191 case PCI_DEVICE_ID_QLOGIC_ISP5422:
1192 ha->device_type |= DT_ISP5422;
1193 break;
1194 case PCI_DEVICE_ID_QLOGIC_ISP5432:
1195 ha->device_type |= DT_ISP5432;
1196 break;
1197 }
1198}
1199
1149static int 1200static int
1150qla2x00_iospace_config(scsi_qla_host_t *ha) 1201qla2x00_iospace_config(scsi_qla_host_t *ha)
1151{ 1202{
@@ -1307,7 +1358,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1307 ha->brd_info = brd_info; 1358 ha->brd_info = brd_info;
1308 sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no); 1359 sprintf(ha->host_str, "%s_%ld", ha->brd_info->drv_name, ha->host_no);
1309 1360
1310 ha->dpc_pid = -1; 1361 /* Set ISP-type information. */
1362 qla2x00_set_isp_flags(ha);
1311 1363
1312 /* Configure PCI I/O space */ 1364 /* Configure PCI I/O space */
1313 ret = qla2x00_iospace_config(ha); 1365 ret = qla2x00_iospace_config(ha);
@@ -1386,7 +1438,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1386 ha->gid_list_info_size = 6; 1438 ha->gid_list_info_size = 6;
1387 if (IS_QLA2322(ha) || IS_QLA6322(ha)) 1439 if (IS_QLA2322(ha) || IS_QLA6322(ha))
1388 ha->optrom_size = OPTROM_SIZE_2322; 1440 ha->optrom_size = OPTROM_SIZE_2322;
1389 } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 1441 } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
1390 host->max_id = MAX_TARGETS_2200; 1442 host->max_id = MAX_TARGETS_2200;
1391 ha->mbx_count = MAILBOX_REGISTER_COUNT; 1443 ha->mbx_count = MAILBOX_REGISTER_COUNT;
1392 ha->request_q_length = REQUEST_ENTRY_CNT_24XX; 1444 ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
@@ -1449,9 +1501,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1449 */ 1501 */
1450 spin_lock_init(&ha->mbx_reg_lock); 1502 spin_lock_init(&ha->mbx_reg_lock);
1451 1503
1452 init_completion(&ha->dpc_inited);
1453 init_completion(&ha->dpc_exited);
1454
1455 qla2x00_config_dma_addressing(ha); 1504 qla2x00_config_dma_addressing(ha);
1456 if (qla2x00_mem_alloc(ha)) { 1505 if (qla2x00_mem_alloc(ha)) {
1457 qla_printk(KERN_WARNING, ha, 1506 qla_printk(KERN_WARNING, ha,
@@ -1478,16 +1527,14 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1478 /* 1527 /*
1479 * Startup the kernel thread for this host adapter 1528 * Startup the kernel thread for this host adapter
1480 */ 1529 */
1481 ha->dpc_should_die = 0; 1530 ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha,
1482 ha->dpc_pid = kernel_thread(qla2x00_do_dpc, ha, 0); 1531 "%s_dpc", ha->host_str);
1483 if (ha->dpc_pid < 0) { 1532 if (IS_ERR(ha->dpc_thread)) {
1484 qla_printk(KERN_WARNING, ha, 1533 qla_printk(KERN_WARNING, ha,
1485 "Unable to start DPC thread!\n"); 1534 "Unable to start DPC thread!\n");
1486 1535 ret = PTR_ERR(ha->dpc_thread);
1487 ret = -ENODEV;
1488 goto probe_failed; 1536 goto probe_failed;
1489 } 1537 }
1490 wait_for_completion(&ha->dpc_inited);
1491 1538
1492 host->this_id = 255; 1539 host->this_id = 255;
1493 host->cmd_per_lun = 3; 1540 host->cmd_per_lun = 3;
@@ -1517,7 +1564,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1517 1564
1518 spin_lock_irqsave(&ha->hardware_lock, flags); 1565 spin_lock_irqsave(&ha->hardware_lock, flags);
1519 reg = ha->iobase; 1566 reg = ha->iobase;
1520 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 1567 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
1521 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT); 1568 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
1522 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT); 1569 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
1523 } else { 1570 } else {
@@ -1621,8 +1668,6 @@ EXPORT_SYMBOL_GPL(qla2x00_remove_one);
1621static void 1668static void
1622qla2x00_free_device(scsi_qla_host_t *ha) 1669qla2x00_free_device(scsi_qla_host_t *ha)
1623{ 1670{
1624 int ret;
1625
1626 /* Abort any outstanding IO descriptors. */ 1671 /* Abort any outstanding IO descriptors. */
1627 if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) 1672 if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
1628 qla2x00_cancel_io_descriptors(ha); 1673 qla2x00_cancel_io_descriptors(ha);
@@ -1632,18 +1677,15 @@ qla2x00_free_device(scsi_qla_host_t *ha)
1632 qla2x00_stop_timer(ha); 1677 qla2x00_stop_timer(ha);
1633 1678
1634 /* Kill the kernel thread for this host */ 1679 /* Kill the kernel thread for this host */
1635 if (ha->dpc_pid >= 0) { 1680 if (ha->dpc_thread) {
1636 ha->dpc_should_die = 1; 1681 struct task_struct *t = ha->dpc_thread;
1637 wmb();
1638 ret = kill_proc(ha->dpc_pid, SIGHUP, 1);
1639 if (ret) {
1640 qla_printk(KERN_ERR, ha,
1641 "Unable to signal DPC thread -- (%d)\n", ret);
1642 1682
1643 /* TODO: SOMETHING MORE??? */ 1683 /*
1644 } else { 1684 * qla2xxx_wake_dpc checks for ->dpc_thread
1645 wait_for_completion(&ha->dpc_exited); 1685 * so we need to zero it out.
1646 } 1686 */
1687 ha->dpc_thread = NULL;
1688 kthread_stop(t);
1647 } 1689 }
1648 1690
1649 /* Stop currently executing firmware. */ 1691 /* Stop currently executing firmware. */
@@ -1775,8 +1817,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
1775 atomic_set(&fcport->state, FCS_DEVICE_LOST); 1817 atomic_set(&fcport->state, FCS_DEVICE_LOST);
1776 } 1818 }
1777 1819
1778 if (defer && ha->dpc_wait && !ha->dpc_active) 1820 if (defer)
1779 up(ha->dpc_wait); 1821 qla2xxx_wake_dpc(ha);
1780} 1822}
1781 1823
1782/* 1824/*
@@ -1993,7 +2035,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
1993{ 2035{
1994 struct list_head *fcpl, *fcptemp; 2036 struct list_head *fcpl, *fcptemp;
1995 fc_port_t *fcport; 2037 fc_port_t *fcport;
1996 unsigned int wtime;/* max wait time if mbx cmd is busy. */
1997 2038
1998 if (ha == NULL) { 2039 if (ha == NULL) {
1999 /* error */ 2040 /* error */
@@ -2001,11 +2042,6 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
2001 return; 2042 return;
2002 } 2043 }
2003 2044
2004 /* Make sure all other threads are stopped. */
2005 wtime = 60 * 1000;
2006 while (ha->dpc_wait && wtime)
2007 wtime = msleep_interruptible(wtime);
2008
2009 /* free ioctl memory */ 2045 /* free ioctl memory */
2010 qla2x00_free_ioctl_mem(ha); 2046 qla2x00_free_ioctl_mem(ha);
2011 2047
@@ -2156,7 +2192,6 @@ qla2x00_free_sp_pool( scsi_qla_host_t *ha)
2156static int 2192static int
2157qla2x00_do_dpc(void *data) 2193qla2x00_do_dpc(void *data)
2158{ 2194{
2159 DECLARE_MUTEX_LOCKED(sem);
2160 scsi_qla_host_t *ha; 2195 scsi_qla_host_t *ha;
2161 fc_port_t *fcport; 2196 fc_port_t *fcport;
2162 uint8_t status; 2197 uint8_t status;
@@ -2164,32 +2199,19 @@ qla2x00_do_dpc(void *data)
2164 2199
2165 ha = (scsi_qla_host_t *)data; 2200 ha = (scsi_qla_host_t *)data;
2166 2201
2167 lock_kernel();
2168
2169 daemonize("%s_dpc", ha->host_str);
2170 allow_signal(SIGHUP);
2171
2172 ha->dpc_wait = &sem;
2173
2174 set_user_nice(current, -20); 2202 set_user_nice(current, -20);
2175 2203
2176 unlock_kernel(); 2204 while (!kthread_should_stop()) {
2177
2178 complete(&ha->dpc_inited);
2179
2180 while (1) {
2181 DEBUG3(printk("qla2x00: DPC handler sleeping\n")); 2205 DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
2182 2206
2183 if (down_interruptible(&sem)) 2207 set_current_state(TASK_INTERRUPTIBLE);
2184 break; 2208 schedule();
2185 2209 __set_current_state(TASK_RUNNING);
2186 if (ha->dpc_should_die)
2187 break;
2188 2210
2189 DEBUG3(printk("qla2x00: DPC handler waking up\n")); 2211 DEBUG3(printk("qla2x00: DPC handler waking up\n"));
2190 2212
2191 /* Initialization not yet finished. Don't do anything yet. */ 2213 /* Initialization not yet finished. Don't do anything yet. */
2192 if (!ha->flags.init_done || ha->dpc_active) 2214 if (!ha->flags.init_done)
2193 continue; 2215 continue;
2194 2216
2195 DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no)); 2217 DEBUG3(printk("scsi(%ld): DPC handler\n", ha->host_no));
@@ -2273,7 +2295,7 @@ qla2x00_do_dpc(void *data)
2273 } else 2295 } else
2274 status = 2296 status =
2275 qla2x00_local_device_login( 2297 qla2x00_local_device_login(
2276 ha, fcport->loop_id); 2298 ha, fcport);
2277 2299
2278 if (status == QLA_SUCCESS) { 2300 if (status == QLA_SUCCESS) {
2279 fcport->old_loop_id = fcport->loop_id; 2301 fcport->old_loop_id = fcport->loop_id;
@@ -2356,10 +2378,16 @@ qla2x00_do_dpc(void *data)
2356 /* 2378 /*
2357 * Make sure that nobody tries to wake us up again. 2379 * Make sure that nobody tries to wake us up again.
2358 */ 2380 */
2359 ha->dpc_wait = NULL;
2360 ha->dpc_active = 0; 2381 ha->dpc_active = 0;
2361 2382
2362 complete_and_exit(&ha->dpc_exited, 0); 2383 return 0;
2384}
2385
2386void
2387qla2xxx_wake_dpc(scsi_qla_host_t *ha)
2388{
2389 if (ha->dpc_thread)
2390 wake_up_process(ha->dpc_thread);
2363} 2391}
2364 2392
2365/* 2393/*
@@ -2540,11 +2568,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
2540 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || 2568 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
2541 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || 2569 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
2542 test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || 2570 test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
2543 test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) && 2571 test_bit(RELOGIN_NEEDED, &ha->dpc_flags)))
2544 ha->dpc_wait && !ha->dpc_active) { 2572 qla2xxx_wake_dpc(ha);
2545
2546 up(ha->dpc_wait);
2547 }
2548 2573
2549 qla2x00_restart_timer(ha, WATCH_INTERVAL); 2574 qla2x00_restart_timer(ha, WATCH_INTERVAL);
2550} 2575}
@@ -2576,13 +2601,12 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
2576 2601
2577/* Firmware interface routines. */ 2602/* Firmware interface routines. */
2578 2603
2579#define FW_BLOBS 6 2604#define FW_BLOBS 5
2580#define FW_ISP21XX 0 2605#define FW_ISP21XX 0
2581#define FW_ISP22XX 1 2606#define FW_ISP22XX 1
2582#define FW_ISP2300 2 2607#define FW_ISP2300 2
2583#define FW_ISP2322 3 2608#define FW_ISP2322 3
2584#define FW_ISP63XX 4 2609#define FW_ISP24XX 4
2585#define FW_ISP24XX 5
2586 2610
2587static DECLARE_MUTEX(qla_fw_lock); 2611static DECLARE_MUTEX(qla_fw_lock);
2588 2612
@@ -2591,7 +2615,6 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
2591 { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, }, 2615 { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
2592 { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, }, 2616 { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
2593 { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, 2617 { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
2594 { .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, },
2595 { .name = "ql2400_fw.bin", }, 2618 { .name = "ql2400_fw.bin", },
2596}; 2619};
2597 2620
@@ -2605,13 +2628,11 @@ qla2x00_request_firmware(scsi_qla_host_t *ha)
2605 blob = &qla_fw_blobs[FW_ISP21XX]; 2628 blob = &qla_fw_blobs[FW_ISP21XX];
2606 } else if (IS_QLA2200(ha)) { 2629 } else if (IS_QLA2200(ha)) {
2607 blob = &qla_fw_blobs[FW_ISP22XX]; 2630 blob = &qla_fw_blobs[FW_ISP22XX];
2608 } else if (IS_QLA2300(ha) || IS_QLA2312(ha)) { 2631 } else if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
2609 blob = &qla_fw_blobs[FW_ISP2300]; 2632 blob = &qla_fw_blobs[FW_ISP2300];
2610 } else if (IS_QLA2322(ha)) { 2633 } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
2611 blob = &qla_fw_blobs[FW_ISP2322]; 2634 blob = &qla_fw_blobs[FW_ISP2322];
2612 } else if (IS_QLA6312(ha) || IS_QLA6322(ha)) { 2635 } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
2613 blob = &qla_fw_blobs[FW_ISP63XX];
2614 } else if (IS_QLA24XX(ha)) {
2615 blob = &qla_fw_blobs[FW_ISP24XX]; 2636 blob = &qla_fw_blobs[FW_ISP24XX];
2616 } 2637 }
2617 2638
@@ -2667,6 +2688,10 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
2667 PCI_ANY_ID, PCI_ANY_ID, }, 2688 PCI_ANY_ID, PCI_ANY_ID, },
2668 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432, 2689 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432,
2669 PCI_ANY_ID, PCI_ANY_ID, }, 2690 PCI_ANY_ID, PCI_ANY_ID, },
2691 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422,
2692 PCI_ANY_ID, PCI_ANY_ID, },
2693 { PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432,
2694 PCI_ANY_ID, PCI_ANY_ID, },
2670 { 0 }, 2695 { 0 },
2671}; 2696};
2672MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); 2697MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);