aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2005-07-06 13:31:47 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-07-14 11:02:23 -0400
commitfca297037127e524e8f61b3fc1c7a1886e5d757b (patch)
tree90ee788ff7839cb3b6db67698ff5e065391636bf /drivers/scsi/qla2xxx/qla_os.c
parent0107109ed69c9e04b6fa35ac41d870c74dcce3fc (diff)
[SCSI] qla2xxx: Add OS initialization codes for ISP24xx recognition.
Add OS initialization codes for ISP24xx recognition. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c417
1 files changed, 331 insertions, 86 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 973871833e32..072906994bf5 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -79,6 +79,11 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
79MODULE_PARM_DESC(ql2xloginretrycount, 79MODULE_PARM_DESC(ql2xloginretrycount,
80 "Specify an alternate value for the NVRAM login retry count."); 80 "Specify an alternate value for the NVRAM login retry count.");
81 81
82int ql2xfwloadbin;
83module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
84MODULE_PARM_DESC(ql2xfwloadbin,
85 "Load ISP2xxx firmware image via hotplug.");
86
82static void qla2x00_free_device(scsi_qla_host_t *); 87static void qla2x00_free_device(scsi_qla_host_t *);
83 88
84static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); 89static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);
@@ -91,6 +96,8 @@ static int qla2xxx_slave_alloc(struct scsi_device *);
91static void qla2xxx_slave_destroy(struct scsi_device *); 96static void qla2xxx_slave_destroy(struct scsi_device *);
92static int qla2x00_queuecommand(struct scsi_cmnd *cmd, 97static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
93 void (*fn)(struct scsi_cmnd *)); 98 void (*fn)(struct scsi_cmnd *));
99static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
100 void (*fn)(struct scsi_cmnd *));
94static int qla2xxx_eh_abort(struct scsi_cmnd *); 101static int qla2xxx_eh_abort(struct scsi_cmnd *);
95static int qla2xxx_eh_device_reset(struct scsi_cmnd *); 102static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
96static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); 103static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
@@ -124,6 +131,28 @@ static struct scsi_host_template qla2x00_driver_template = {
124 .max_sectors = 0xFFFF, 131 .max_sectors = 0xFFFF,
125}; 132};
126 133
134static struct scsi_host_template qla24xx_driver_template = {
135 .module = THIS_MODULE,
136 .name = "qla2xxx",
137 .queuecommand = qla24xx_queuecommand,
138
139 .eh_abort_handler = qla2xxx_eh_abort,
140 .eh_device_reset_handler = qla2xxx_eh_device_reset,
141 .eh_bus_reset_handler = qla2xxx_eh_bus_reset,
142 .eh_host_reset_handler = qla2xxx_eh_host_reset,
143
144 .slave_configure = qla2xxx_slave_configure,
145
146 .slave_alloc = qla2xxx_slave_alloc,
147 .slave_destroy = qla2xxx_slave_destroy,
148 .this_id = -1,
149 .cmd_per_lun = 3,
150 .use_clustering = ENABLE_CLUSTERING,
151 .sg_tablesize = SG_ALL,
152
153 .max_sectors = 0xFFFF,
154};
155
127static struct scsi_transport_template *qla2xxx_transport_template = NULL; 156static struct scsi_transport_template *qla2xxx_transport_template = NULL;
128 157
129/* TODO Convert to inlines 158/* TODO Convert to inlines
@@ -171,7 +200,6 @@ static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *);
171static void qla2x00_mem_free(scsi_qla_host_t *ha); 200static void qla2x00_mem_free(scsi_qla_host_t *ha);
172static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha); 201static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha);
173static void qla2x00_free_sp_pool(scsi_qla_host_t *ha); 202static void qla2x00_free_sp_pool(scsi_qla_host_t *ha);
174static srb_t *qla2x00_get_new_sp(scsi_qla_host_t *);
175static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *); 203static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *);
176void qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *); 204void qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *);
177 205
@@ -200,6 +228,54 @@ qla2x00_pci_info_str(struct scsi_qla_host *ha, char *str)
200 return (str); 228 return (str);
201} 229}
202 230
231static char *
232qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str)
233{
234 static char *pci_bus_modes[] = { "33", "66", "100", "133", };
235 uint32_t pci_bus;
236 int pcie_reg;
237
238 pcie_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
239 if (pcie_reg) {
240 char lwstr[6];
241 uint16_t pcie_lstat, lspeed, lwidth;
242
243 pcie_reg += 0x12;
244 pci_read_config_word(ha->pdev, pcie_reg, &pcie_lstat);
245 lspeed = pcie_lstat & (BIT_0 | BIT_1 | BIT_2 | BIT_3);
246 lwidth = (pcie_lstat &
247 (BIT_4 | BIT_5 | BIT_6 | BIT_7 | BIT_8 | BIT_9)) >> 4;
248
249 strcpy(str, "PCIe (");
250 if (lspeed == 1)
251 strcat(str, "2.5Gb/s ");
252 else
253 strcat(str, "<unknown> ");
254 snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
255 strcat(str, lwstr);
256
257 return str;
258 }
259
260 strcpy(str, "PCI");
261 pci_bus = (ha->pci_attr & CSRX_PCIX_BUS_MODE_MASK) >> 8;
262 if (pci_bus == 0 || pci_bus == 8) {
263 strcat(str, " (");
264 strcat(str, pci_bus_modes[pci_bus >> 3]);
265 } else {
266 strcat(str, "-X ");
267 if (pci_bus & BIT_2)
268 strcat(str, "Mode 2");
269 else
270 strcat(str, "Mode 1");
271 strcat(str, " (");
272 strcat(str, pci_bus_modes[pci_bus & ~BIT_2]);
273 }
274 strcat(str, " MHz)");
275
276 return str;
277}
278
203char * 279char *
204qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) 280qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str)
205{ 281{
@@ -238,25 +314,42 @@ qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str)
238 return (str); 314 return (str);
239} 315}
240 316
241/************************************************************************** 317char *
242* qla2x00_queuecommand 318qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str)
243* 319{
244* Description: 320 if (ha->fw_attributes & BIT_0)
245* Queue a command to the controller. 321 strcat(str, "[Class 2] ");
246* 322 if (ha->fw_attributes & BIT_1)
247* Input: 323 strcat(str, "[IP] ");
248* cmd - pointer to Scsi cmd structure 324 if (ha->fw_attributes & BIT_2)
249* fn - pointer to Scsi done function 325 strcat(str, "[Multi-ID] ");
250* 326 if (ha->fw_attributes & BIT_13)
251* Returns: 327 strcat(str, "[Experimental]");
252* 0 - Always 328 return str;
253* 329
254* Note: 330}
255* The mid-level driver tries to ensures that queuecommand never gets invoked 331
256* concurrently with itself or the interrupt handler (although the 332static inline srb_t *
257* interrupt handler may call this routine as part of request-completion 333qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport,
258* handling). 334 struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
259**************************************************************************/ 335{
336 srb_t *sp;
337
338 sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
339 if (!sp)
340 return sp;
341
342 atomic_set(&sp->ref_count, 1);
343 sp->ha = ha;
344 sp->fcport = fcport;
345 sp->cmd = cmd;
346 sp->flags = 0;
347 CMD_SP(cmd) = (void *)sp;
348 cmd->scsi_done = done;
349
350 return sp;
351}
352
260static int 353static int
261qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) 354qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
262{ 355{
@@ -281,18 +374,9 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
281 374
282 spin_unlock_irq(ha->host->host_lock); 375 spin_unlock_irq(ha->host->host_lock);
283 376
284 /* Allocate a command packet from the "sp" pool. */ 377 sp = qla2x00_get_new_sp(ha, fcport, cmd, done);
285 if ((sp = qla2x00_get_new_sp(ha)) == NULL) { 378 if (!sp)
286 goto qc_host_busy_lock; 379 goto qc_host_busy_lock;
287 }
288
289 sp->ha = ha;
290 sp->fcport = fcport;
291 sp->cmd = cmd;
292 sp->flags = 0;
293
294 CMD_SP(cmd) = (void *)sp;
295 cmd->scsi_done = done;
296 380
297 rval = qla2x00_start_scsi(sp); 381 rval = qla2x00_start_scsi(sp);
298 if (rval != QLA_SUCCESS) 382 if (rval != QLA_SUCCESS)
@@ -314,7 +398,6 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
314 398
315qc_host_busy_free_sp: 399qc_host_busy_free_sp:
316 qla2x00_sp_free_dma(ha, sp); 400 qla2x00_sp_free_dma(ha, sp);
317 CMD_SP(cmd) = NULL;
318 mempool_free(sp, ha->srb_mempool); 401 mempool_free(sp, ha->srb_mempool);
319 402
320qc_host_busy_lock: 403qc_host_busy_lock:
@@ -329,6 +412,60 @@ qc_fail_command:
329 return 0; 412 return 0;
330} 413}
331 414
415
416static int
417qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
418{
419 scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
420 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
421 srb_t *sp;
422 int rval;
423
424 if (!fcport) {
425 cmd->result = DID_NO_CONNECT << 16;
426 goto qc24_fail_command;
427 }
428
429 if (atomic_read(&fcport->state) != FCS_ONLINE) {
430 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
431 atomic_read(&ha->loop_state) == LOOP_DEAD) {
432 cmd->result = DID_NO_CONNECT << 16;
433 goto qc24_fail_command;
434 }
435 goto qc24_host_busy;
436 }
437
438 spin_unlock_irq(ha->host->host_lock);
439
440 sp = qla2x00_get_new_sp(ha, fcport, cmd, done);
441 if (!sp)
442 goto qc24_host_busy_lock;
443
444 rval = qla24xx_start_scsi(sp);
445 if (rval != QLA_SUCCESS)
446 goto qc24_host_busy_free_sp;
447
448 spin_lock_irq(ha->host->host_lock);
449
450 return 0;
451
452qc24_host_busy_free_sp:
453 qla2x00_sp_free_dma(ha, sp);
454 mempool_free(sp, ha->srb_mempool);
455
456qc24_host_busy_lock:
457 spin_lock_irq(ha->host->host_lock);
458
459qc24_host_busy:
460 return SCSI_MLQUEUE_HOST_BUSY;
461
462qc24_fail_command:
463 done(cmd);
464
465 return 0;
466}
467
468
332/* 469/*
333 * qla2x00_eh_wait_on_command 470 * qla2x00_eh_wait_on_command
334 * Waits for the command to be returned by the Firmware for some 471 * Waits for the command to be returned by the Firmware for some
@@ -385,8 +522,8 @@ qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd)
385static int 522static int
386qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) 523qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
387{ 524{
388 int return_status; 525 int return_status;
389 unsigned long wait_online; 526 unsigned long wait_online;
390 527
391 wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ); 528 wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
392 while (((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) || 529 while (((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) ||
@@ -1114,13 +1251,39 @@ qla2x00_disable_intrs(scsi_qla_host_t *ha)
1114 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1251 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1115} 1252}
1116 1253
1254static void
1255qla24xx_enable_intrs(scsi_qla_host_t *ha)
1256{
1257 unsigned long flags = 0;
1258 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1259
1260 spin_lock_irqsave(&ha->hardware_lock, flags);
1261 ha->interrupts_on = 1;
1262 WRT_REG_DWORD(&reg->ictrl, ICRX_EN_RISC_INT);
1263 RD_REG_DWORD(&reg->ictrl);
1264 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1265}
1266
1267static void
1268qla24xx_disable_intrs(scsi_qla_host_t *ha)
1269{
1270 unsigned long flags = 0;
1271 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1272
1273 spin_lock_irqsave(&ha->hardware_lock, flags);
1274 ha->interrupts_on = 0;
1275 WRT_REG_DWORD(&reg->ictrl, 0);
1276 RD_REG_DWORD(&reg->ictrl);
1277 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1278}
1279
1117/* 1280/*
1118 * PCI driver interface 1281 * PCI driver interface
1119 */ 1282 */
1120int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) 1283int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1121{ 1284{
1122 int ret = -ENODEV; 1285 int ret = -ENODEV;
1123 struct device_reg_2xxx __iomem *reg; 1286 device_reg_t __iomem *reg;
1124 struct Scsi_Host *host; 1287 struct Scsi_Host *host;
1125 scsi_qla_host_t *ha; 1288 scsi_qla_host_t *ha;
1126 unsigned long flags = 0; 1289 unsigned long flags = 0;
@@ -1132,8 +1295,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1132 if (pci_enable_device(pdev)) 1295 if (pci_enable_device(pdev))
1133 goto probe_out; 1296 goto probe_out;
1134 1297
1135 host = scsi_host_alloc(&qla2x00_driver_template, 1298 host = scsi_host_alloc(brd_info->sht ? brd_info->sht:
1136 sizeof(scsi_qla_host_t)); 1299 &qla2x00_driver_template, sizeof(scsi_qla_host_t));
1137 if (host == NULL) { 1300 if (host == NULL) {
1138 printk(KERN_WARNING 1301 printk(KERN_WARNING
1139 "qla2xxx: Couldn't allocate host from scsi layer!\n"); 1302 "qla2xxx: Couldn't allocate host from scsi layer!\n");
@@ -1155,17 +1318,15 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1155 if (ret) 1318 if (ret)
1156 goto probe_failed; 1319 goto probe_failed;
1157 1320
1158 /* Sanitize the information from PCI BIOS. */
1159 host->irq = pdev->irq;
1160
1161 qla_printk(KERN_INFO, ha, 1321 qla_printk(KERN_INFO, ha,
1162 "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name, 1322 "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name,
1163 host->irq, ha->iobase); 1323 pdev->irq, ha->iobase);
1164 1324
1165 spin_lock_init(&ha->hardware_lock); 1325 spin_lock_init(&ha->hardware_lock);
1166 1326
1167 ha->prev_topology = 0; 1327 ha->prev_topology = 0;
1168 ha->ports = MAX_BUSES; 1328 ha->ports = MAX_BUSES;
1329 ha->init_cb_size = sizeof(init_cb_t);
1169 1330
1170 /* Assign ISP specific operations. */ 1331 /* Assign ISP specific operations. */
1171 ha->isp_ops.pci_config = qla2100_pci_config; 1332 ha->isp_ops.pci_config = qla2100_pci_config;
@@ -1207,7 +1368,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1207 ha->response_q_length = RESPONSE_ENTRY_CNT_2100; 1368 ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
1208 ha->last_loop_id = SNS_LAST_LOOP_ID_2100; 1369 ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
1209 ha->gid_list_info_size = 4; 1370 ha->gid_list_info_size = 4;
1210 } else /*if (IS_QLA2300(ha))*/ { 1371 } else if (IS_QLA23XX(ha)) {
1211 host->max_id = MAX_TARGETS_2200; 1372 host->max_id = MAX_TARGETS_2200;
1212 ha->mbx_count = MAILBOX_REGISTER_COUNT; 1373 ha->mbx_count = MAILBOX_REGISTER_COUNT;
1213 ha->request_q_length = REQUEST_ENTRY_CNT_2200; 1374 ha->request_q_length = REQUEST_ENTRY_CNT_2200;
@@ -1218,6 +1379,38 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1218 ha->isp_ops.fw_dump = qla2300_fw_dump; 1379 ha->isp_ops.fw_dump = qla2300_fw_dump;
1219 ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump; 1380 ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump;
1220 ha->gid_list_info_size = 6; 1381 ha->gid_list_info_size = 6;
1382 } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
1383 host->max_id = MAX_TARGETS_2200;
1384 ha->mbx_count = MAILBOX_REGISTER_COUNT;
1385 ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
1386 ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
1387 ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
1388 ha->init_cb_size = sizeof(struct init_cb_24xx);
1389 ha->isp_ops.pci_config = qla24xx_pci_config;
1390 ha->isp_ops.reset_chip = qla24xx_reset_chip;
1391 ha->isp_ops.chip_diag = qla24xx_chip_diag;
1392 ha->isp_ops.config_rings = qla24xx_config_rings;
1393 ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
1394 ha->isp_ops.nvram_config = qla24xx_nvram_config;
1395 ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
1396 ha->isp_ops.load_risc = qla24xx_load_risc_flash;
1397 if (ql2xfwloadbin)
1398 ha->isp_ops.load_risc = qla24xx_load_risc_hotplug;
1399 ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
1400 ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
1401 ha->isp_ops.intr_handler = qla24xx_intr_handler;
1402 ha->isp_ops.enable_intrs = qla24xx_enable_intrs;
1403 ha->isp_ops.disable_intrs = qla24xx_disable_intrs;
1404 ha->isp_ops.abort_command = qla24xx_abort_command;
1405 ha->isp_ops.abort_target = qla24xx_abort_target;
1406 ha->isp_ops.fabric_login = qla24xx_login_fabric;
1407 ha->isp_ops.fabric_logout = qla24xx_fabric_logout;
1408 ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb;
1409 ha->isp_ops.read_nvram = qla24xx_read_nvram_data;
1410 ha->isp_ops.write_nvram = qla24xx_write_nvram_data;
1411 ha->isp_ops.fw_dump = qla24xx_fw_dump;
1412 ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump;
1413 ha->gid_list_info_size = 8;
1221 } 1414 }
1222 host->can_queue = ha->request_q_length + 128; 1415 host->can_queue = ha->request_q_length + 128;
1223 1416
@@ -1288,14 +1481,15 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1288 host->max_lun = MAX_LUNS; 1481 host->max_lun = MAX_LUNS;
1289 host->transportt = qla2xxx_transport_template; 1482 host->transportt = qla2xxx_transport_template;
1290 1483
1291 ret = request_irq(host->irq, ha->isp_ops.intr_handler, 1484 ret = request_irq(pdev->irq, ha->isp_ops.intr_handler,
1292 SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); 1485 SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha);
1293 if (ret) { 1486 if (ret) {
1294 qla_printk(KERN_WARNING, ha, 1487 qla_printk(KERN_WARNING, ha,
1295 "Failed to reserve interrupt %d already in use.\n", 1488 "Failed to reserve interrupt %d already in use.\n",
1296 host->irq); 1489 pdev->irq);
1297 goto probe_failed; 1490 goto probe_failed;
1298 } 1491 }
1492 host->irq = pdev->irq;
1299 1493
1300 /* Initialized the timer */ 1494 /* Initialized the timer */
1301 qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL); 1495 qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL);
@@ -1303,24 +1497,29 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1303 DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n", 1497 DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n",
1304 ha->host_no, ha)); 1498 ha->host_no, ha));
1305 1499
1306 reg = &ha->iobase->isp;
1307
1308 ha->isp_ops.disable_intrs(ha); 1500 ha->isp_ops.disable_intrs(ha);
1309 1501
1310 /* Ensure mailbox registers are free. */
1311 spin_lock_irqsave(&ha->hardware_lock, flags); 1502 spin_lock_irqsave(&ha->hardware_lock, flags);
1312 WRT_REG_WORD(&reg->semaphore, 0); 1503 reg = ha->iobase;
1313 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT); 1504 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
1314 WRT_REG_WORD(&reg->hccr, HCCR_CLR_HOST_INT); 1505 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
1315 1506 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
1316 /* Enable proper parity */ 1507 } else {
1317 if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) { 1508 WRT_REG_WORD(&reg->isp.semaphore, 0);
1318 if (IS_QLA2300(ha)) 1509 WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
1319 /* SRAM parity */ 1510 WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
1320 WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x1)); 1511
1321 else 1512 /* Enable proper parity */
1322 /* SRAM, Instruction RAM and GP RAM parity */ 1513 if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) {
1323 WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x7)); 1514 if (IS_QLA2300(ha))
1515 /* SRAM parity */
1516 WRT_REG_WORD(&reg->isp.hccr,
1517 (HCCR_ENABLE_PARITY + 0x1));
1518 else
1519 /* SRAM, Instruction RAM and GP RAM parity */
1520 WRT_REG_WORD(&reg->isp.hccr,
1521 (HCCR_ENABLE_PARITY + 0x7));
1522 }
1324 } 1523 }
1325 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1524 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1326 1525
@@ -1360,7 +1559,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1360 " %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str, 1559 " %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str,
1361 ha->model_number, ha->model_desc ? ha->model_desc: "", 1560 ha->model_number, ha->model_desc ? ha->model_desc: "",
1362 ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info), 1561 ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info),
1363 pci_name(ha->pdev), ha->flags.enable_64bit_addressing ? '+': '-', 1562 pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-',
1364 ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str)); 1563 ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str));
1365 1564
1366 /* Go with fc_rport registration. */ 1565 /* Go with fc_rport registration. */
@@ -1629,7 +1828,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
1629 1828
1630 continue; 1829 continue;
1631 } 1830 }
1632 memset(ha->init_cb, 0, sizeof(init_cb_t)); 1831 memset(ha->init_cb, 0, ha->init_cb_size);
1633 1832
1634 /* Get consistent memory allocated for Get Port Database cmd */ 1833 /* Get consistent memory allocated for Get Port Database cmd */
1635 ha->iodesc_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, 1834 ha->iodesc_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
@@ -1841,10 +2040,13 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
1841 if (ha->fw_dump) 2040 if (ha->fw_dump)
1842 free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order); 2041 free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);
1843 2042
1844 if (ha->fw_dump_buffer) 2043 vfree(ha->fw_dump24);
1845 vfree(ha->fw_dump_buffer); 2044
2045 vfree(ha->fw_dump_buffer);
1846 2046
1847 ha->fw_dump = NULL; 2047 ha->fw_dump = NULL;
2048 ha->fw_dump24 = NULL;
2049 ha->fw_dumped = 0;
1848 ha->fw_dump_reading = 0; 2050 ha->fw_dump_reading = 0;
1849 ha->fw_dump_buffer = NULL; 2051 ha->fw_dump_buffer = NULL;
1850} 2052}
@@ -2131,25 +2333,6 @@ qla2x00_rst_aen(scsi_qla_host_t *ha)
2131 } 2333 }
2132} 2334}
2133 2335
2134
2135/*
2136 * This routine will allocate SP from the free queue
2137 * input:
2138 * scsi_qla_host_t *
2139 * output:
2140 * srb_t * or NULL
2141 */
2142static srb_t *
2143qla2x00_get_new_sp(scsi_qla_host_t *ha)
2144{
2145 srb_t *sp;
2146
2147 sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
2148 if (sp)
2149 atomic_set(&sp->ref_count, 1);
2150 return (sp);
2151}
2152
2153static void 2336static void
2154qla2x00_sp_free_dma(scsi_qla_host_t *ha, srb_t *sp) 2337qla2x00_sp_free_dma(scsi_qla_host_t *ha, srb_t *sp)
2155{ 2338{
@@ -2165,6 +2348,7 @@ qla2x00_sp_free_dma(scsi_qla_host_t *ha, srb_t *sp)
2165 } 2348 }
2166 sp->flags &= ~SRB_DMA_VALID; 2349 sp->flags &= ~SRB_DMA_VALID;
2167 } 2350 }
2351 CMD_SP(cmd) = NULL;
2168} 2352}
2169 2353
2170void 2354void
@@ -2174,7 +2358,6 @@ qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *sp)
2174 2358
2175 qla2x00_sp_free_dma(ha, sp); 2359 qla2x00_sp_free_dma(ha, sp);
2176 2360
2177 CMD_SP(cmd) = NULL;
2178 mempool_free(sp, ha->srb_mempool); 2361 mempool_free(sp, ha->srb_mempool);
2179 2362
2180 cmd->scsi_done(cmd); 2363 cmd->scsi_done(cmd);
@@ -2219,7 +2402,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
2219 atomic_set(&fcport->state, FCS_DEVICE_DEAD); 2402 atomic_set(&fcport->state, FCS_DEVICE_DEAD);
2220 2403
2221 DEBUG(printk("scsi(%ld): fcport-%d - port retry count: " 2404 DEBUG(printk("scsi(%ld): fcport-%d - port retry count: "
2222 "%d remainning\n", 2405 "%d remaining\n",
2223 ha->host_no, 2406 ha->host_no,
2224 t, atomic_read(&fcport->port_down_timer))); 2407 t, atomic_read(&fcport->port_down_timer)));
2225 } 2408 }
@@ -2282,7 +2465,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
2282 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 2465 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
2283 } 2466 }
2284 } 2467 }
2285 DEBUG3(printk("scsi(%ld): Loop Down - seconds remainning %d\n", 2468 DEBUG3(printk("scsi(%ld): Loop Down - seconds remaining %d\n",
2286 ha->host_no, 2469 ha->host_no,
2287 atomic_read(&ha->loop_down_timer))); 2470 atomic_read(&ha->loop_down_timer)));
2288 } 2471 }
@@ -2319,12 +2502,68 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
2319 return -ETIMEDOUT; 2502 return -ETIMEDOUT;
2320} 2503}
2321 2504
2505static struct qla_board_info qla_board_tbl[] = {
2506 {
2507 .drv_name = "qla2400",
2508 .isp_name = "ISP2422",
2509 .fw_fname = "ql2400_fw.bin",
2510 .sht = &qla24xx_driver_template,
2511 },
2512 {
2513 .drv_name = "qla2400",
2514 .isp_name = "ISP2432",
2515 .fw_fname = "ql2400_fw.bin",
2516 .sht = &qla24xx_driver_template,
2517 },
2518};
2519
2520static struct pci_device_id qla2xxx_pci_tbl[] = {
2521 {
2522 .vendor = PCI_VENDOR_ID_QLOGIC,
2523 .device = PCI_DEVICE_ID_QLOGIC_ISP2422,
2524 .subvendor = PCI_ANY_ID,
2525 .subdevice = PCI_ANY_ID,
2526 .driver_data = (unsigned long)&qla_board_tbl[0],
2527 },
2528 {
2529 .vendor = PCI_VENDOR_ID_QLOGIC,
2530 .device = PCI_DEVICE_ID_QLOGIC_ISP2432,
2531 .subvendor = PCI_ANY_ID,
2532 .subdevice = PCI_ANY_ID,
2533 .driver_data = (unsigned long)&qla_board_tbl[1],
2534 },
2535 {0, 0},
2536};
2537MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
2538
2539static int __devinit
2540qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2541{
2542 return qla2x00_probe_one(pdev,
2543 (struct qla_board_info *)id->driver_data);
2544}
2545
2546static void __devexit
2547qla2xxx_remove_one(struct pci_dev *pdev)
2548{
2549 qla2x00_remove_one(pdev);
2550}
2551
2552static struct pci_driver qla2xxx_pci_driver = {
2553 .name = "qla2xxx",
2554 .id_table = qla2xxx_pci_tbl,
2555 .probe = qla2xxx_probe_one,
2556 .remove = __devexit_p(qla2xxx_remove_one),
2557};
2558
2322/** 2559/**
2323 * qla2x00_module_init - Module initialization. 2560 * qla2x00_module_init - Module initialization.
2324 **/ 2561 **/
2325static int __init 2562static int __init
2326qla2x00_module_init(void) 2563qla2x00_module_init(void)
2327{ 2564{
2565 int ret = 0;
2566
2328 /* Allocate cache for SRBs. */ 2567 /* Allocate cache for SRBs. */
2329 srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, 2568 srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
2330 SLAB_HWCACHE_ALIGN, NULL, NULL); 2569 SLAB_HWCACHE_ALIGN, NULL, NULL);
@@ -2345,7 +2584,12 @@ qla2x00_module_init(void)
2345 return -ENODEV; 2584 return -ENODEV;
2346 2585
2347 printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); 2586 printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
2348 return 0; 2587 ret = pci_module_init(&qla2xxx_pci_driver);
2588 if (ret) {
2589 kmem_cache_destroy(srb_cachep);
2590 fc_release_transport(qla2xxx_transport_template);
2591 }
2592 return ret;
2349} 2593}
2350 2594
2351/** 2595/**
@@ -2354,6 +2598,7 @@ qla2x00_module_init(void)
2354static void __exit 2598static void __exit
2355qla2x00_module_exit(void) 2599qla2x00_module_exit(void)
2356{ 2600{
2601 pci_unregister_driver(&qla2xxx_pci_driver);
2357 kmem_cache_destroy(srb_cachep); 2602 kmem_cache_destroy(srb_cachep);
2358 fc_release_transport(qla2xxx_transport_template); 2603 fc_release_transport(qla2xxx_transport_template);
2359} 2604}