aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
author <andrew.vasquez@qlogic.com>2005-04-17 16:04:54 -0400
committerJames Bottomley <jejb@titanic>2005-04-18 14:47:19 -0400
commit8482e118afa0cb4321ab3d30b1100d27d63130c0 (patch)
tree971714d297194e1c20e1b80b1d2e031d4517f5ad /drivers/scsi/qla2xxx/qla_os.c
parentf4f051ebb40e74ad0ba02d2cb3a6c16b0393472b (diff)
[PATCH] qla2xxx: add remote port codes...
Add initial support for FC remote port infrastructure. o Use fc_remote_port...() registration and block/unlock functions. o Consolidate 'attribute' (fc-remote/sysfs) helpers into new qla_attr.c file. 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.c302
1 files changed, 36 insertions, 266 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 0e7e51db470c..d0aa18831544 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -63,7 +63,7 @@ module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
63MODULE_PARM_DESC(ql2xlogintimeout, 63MODULE_PARM_DESC(ql2xlogintimeout,
64 "Login timeout value in seconds."); 64 "Login timeout value in seconds.");
65 65
66int qlport_down_retry; 66int qlport_down_retry = 30;
67module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR); 67module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR);
68MODULE_PARM_DESC(qlport_down_retry, 68MODULE_PARM_DESC(qlport_down_retry,
69 "Maximum number of command retries to a port that returns" 69 "Maximum number of command retries to a port that returns"
@@ -246,184 +246,8 @@ static srb_t *qla2x00_get_new_sp(scsi_qla_host_t *);
246static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *); 246static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *);
247void qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *); 247void qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *);
248 248
249static ssize_t qla2x00_sysfs_read_fw_dump(struct kobject *, char *, loff_t,
250 size_t);
251static ssize_t qla2x00_sysfs_write_fw_dump(struct kobject *, char *, loff_t,
252 size_t);
253static struct bin_attribute sysfs_fw_dump_attr = {
254 .attr = {
255 .name = "fw_dump",
256 .mode = S_IRUSR | S_IWUSR,
257 .owner = THIS_MODULE,
258 },
259 .size = 0,
260 .read = qla2x00_sysfs_read_fw_dump,
261 .write = qla2x00_sysfs_write_fw_dump,
262};
263static ssize_t qla2x00_sysfs_read_nvram(struct kobject *, char *, loff_t,
264 size_t);
265static ssize_t qla2x00_sysfs_write_nvram(struct kobject *, char *, loff_t,
266 size_t);
267static struct bin_attribute sysfs_nvram_attr = {
268 .attr = {
269 .name = "nvram",
270 .mode = S_IRUSR | S_IWUSR,
271 .owner = THIS_MODULE,
272 },
273 .size = sizeof(nvram_t),
274 .read = qla2x00_sysfs_read_nvram,
275 .write = qla2x00_sysfs_write_nvram,
276};
277
278/* -------------------------------------------------------------------------- */ 249/* -------------------------------------------------------------------------- */
279 250
280
281/* SysFS attributes. */
282static ssize_t qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf,
283 loff_t off, size_t count)
284{
285 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
286 struct device, kobj)));
287
288 if (ha->fw_dump_reading == 0)
289 return 0;
290 if (off > ha->fw_dump_buffer_len)
291 return 0;
292 if (off + count > ha->fw_dump_buffer_len)
293 count = ha->fw_dump_buffer_len - off;
294
295 memcpy(buf, &ha->fw_dump_buffer[off], count);
296
297 return (count);
298}
299
300static ssize_t qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf,
301 loff_t off, size_t count)
302{
303 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
304 struct device, kobj)));
305 int reading;
306 uint32_t dump_size;
307
308 if (off != 0)
309 return (0);
310
311 reading = simple_strtol(buf, NULL, 10);
312 switch (reading) {
313 case 0:
314 if (ha->fw_dump_reading == 1) {
315 qla_printk(KERN_INFO, ha,
316 "Firmware dump cleared on (%ld).\n",
317 ha->host_no);
318
319 vfree(ha->fw_dump_buffer);
320 free_pages((unsigned long)ha->fw_dump,
321 ha->fw_dump_order);
322
323 ha->fw_dump_reading = 0;
324 ha->fw_dump_buffer = NULL;
325 ha->fw_dump = NULL;
326 }
327 break;
328 case 1:
329 if (ha->fw_dump != NULL && !ha->fw_dump_reading) {
330 ha->fw_dump_reading = 1;
331
332 dump_size = FW_DUMP_SIZE_1M;
333 if (ha->fw_memory_size < 0x20000)
334 dump_size = FW_DUMP_SIZE_128K;
335 else if (ha->fw_memory_size < 0x80000)
336 dump_size = FW_DUMP_SIZE_512K;
337 ha->fw_dump_buffer = (char *)vmalloc(dump_size);
338 if (ha->fw_dump_buffer == NULL) {
339 qla_printk(KERN_WARNING, ha,
340 "Unable to allocate memory for firmware "
341 "dump buffer (%d).\n", dump_size);
342
343 ha->fw_dump_reading = 0;
344 return (count);
345 }
346 qla_printk(KERN_INFO, ha,
347 "Firmware dump ready for read on (%ld).\n",
348 ha->host_no);
349 memset(ha->fw_dump_buffer, 0, dump_size);
350 if (IS_QLA2100(ha) || IS_QLA2200(ha))
351 qla2100_ascii_fw_dump(ha);
352 else
353 qla2300_ascii_fw_dump(ha);
354 ha->fw_dump_buffer_len = strlen(ha->fw_dump_buffer);
355 }
356 break;
357 }
358 return (count);
359}
360
361static ssize_t qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf,
362 loff_t off, size_t count)
363{
364 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
365 struct device, kobj)));
366 uint16_t *witer;
367 unsigned long flags;
368 uint16_t cnt;
369
370 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != sizeof(nvram_t))
371 return 0;
372
373 /* Read NVRAM. */
374 spin_lock_irqsave(&ha->hardware_lock, flags);
375 qla2x00_lock_nvram_access(ha);
376 witer = (uint16_t *)buf;
377 for (cnt = 0; cnt < count / 2; cnt++) {
378 *witer = cpu_to_le16(qla2x00_get_nvram_word(ha,
379 cnt+ha->nvram_base));
380 witer++;
381 }
382 qla2x00_unlock_nvram_access(ha);
383 spin_unlock_irqrestore(&ha->hardware_lock, flags);
384
385 return (count);
386}
387
388static ssize_t qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf,
389 loff_t off, size_t count)
390{
391 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
392 struct device, kobj)));
393 uint8_t *iter;
394 uint16_t *witer;
395 unsigned long flags;
396 uint16_t cnt;
397 uint8_t chksum;
398
399 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != sizeof(nvram_t))
400 return 0;
401
402 /* Checksum NVRAM. */
403 iter = (uint8_t *)buf;
404 chksum = 0;
405 for (cnt = 0; cnt < count - 1; cnt++)
406 chksum += *iter++;
407 chksum = ~chksum + 1;
408 *iter = chksum;
409
410 /* Write NVRAM. */
411 spin_lock_irqsave(&ha->hardware_lock, flags);
412 qla2x00_lock_nvram_access(ha);
413 qla2x00_release_nvram_protection(ha);
414 witer = (uint16_t *)buf;
415 for (cnt = 0; cnt < count / 2; cnt++) {
416 qla2x00_write_nvram_word(ha, cnt+ha->nvram_base,
417 cpu_to_le16(*witer));
418 witer++;
419 }
420 qla2x00_unlock_nvram_access(ha);
421 spin_unlock_irqrestore(&ha->hardware_lock, flags);
422
423 return (count);
424}
425
426/* -------------------------------------------------------------------------- */
427static char * 251static char *
428qla2x00_get_pci_info_str(struct scsi_qla_host *ha, char *str) 252qla2x00_get_pci_info_str(struct scsi_qla_host *ha, char *str)
429{ 253{
@@ -1233,11 +1057,16 @@ qla2xxx_slave_alloc(struct scsi_device *sdev)
1233static int 1057static int
1234qla2xxx_slave_configure(struct scsi_device *sdev) 1058qla2xxx_slave_configure(struct scsi_device *sdev)
1235{ 1059{
1060 scsi_qla_host_t *ha = to_qla_host(sdev->host);
1061 struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
1062
1236 if (sdev->tagged_supported) 1063 if (sdev->tagged_supported)
1237 scsi_activate_tcq(sdev, 32); 1064 scsi_activate_tcq(sdev, 32);
1238 else 1065 else
1239 scsi_deactivate_tcq(sdev, 32); 1066 scsi_deactivate_tcq(sdev, 32);
1240 1067
1068 rport->dev_loss_tmo = ha->port_down_retry_count + 5;
1069
1241 return 0; 1070 return 0;
1242} 1071}
1243 1072
@@ -1370,6 +1199,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1370 unsigned long wait_switch = 0; 1199 unsigned long wait_switch = 0;
1371 char pci_info[20]; 1200 char pci_info[20];
1372 char fw_str[30]; 1201 char fw_str[30];
1202 fc_port_t *fcport;
1373 1203
1374 if (pci_enable_device(pdev)) 1204 if (pci_enable_device(pdev))
1375 return -1; 1205 return -1;
@@ -1395,7 +1225,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1395 /* Configure PCI I/O space */ 1225 /* Configure PCI I/O space */
1396 ret = qla2x00_iospace_config(ha); 1226 ret = qla2x00_iospace_config(ha);
1397 if (ret != 0) { 1227 if (ret != 0) {
1398 goto probe_failed; 1228 goto probe_alloc_failed;
1399 } 1229 }
1400 1230
1401 /* Sanitize the information from PCI BIOS. */ 1231 /* Sanitize the information from PCI BIOS. */
@@ -1469,9 +1299,23 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1469 qla_printk(KERN_WARNING, ha, 1299 qla_printk(KERN_WARNING, ha,
1470 "[ERROR] Failed to allocate memory for adapter\n"); 1300 "[ERROR] Failed to allocate memory for adapter\n");
1471 1301
1472 goto probe_failed; 1302 goto probe_alloc_failed;
1473 } 1303 }
1474 1304
1305 pci_set_drvdata(pdev, ha);
1306 host->this_id = 255;
1307 host->cmd_per_lun = 3;
1308 host->unique_id = ha->instance;
1309 host->max_cmd_len = MAX_CMDSZ;
1310 host->max_channel = ha->ports - 1;
1311 host->max_id = ha->max_targets;
1312 host->max_lun = ha->max_luns;
1313 host->transportt = qla2xxx_transport_template;
1314 if (scsi_add_host(host, &pdev->dev))
1315 goto probe_alloc_failed;
1316
1317 qla2x00_alloc_sysfs_attr(ha);
1318
1475 if (qla2x00_initialize_adapter(ha) && 1319 if (qla2x00_initialize_adapter(ha) &&
1476 !(ha->device_flags & DFLG_NO_CABLE)) { 1320 !(ha->device_flags & DFLG_NO_CABLE)) {
1477 1321
@@ -1485,6 +1329,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1485 goto probe_failed; 1329 goto probe_failed;
1486 } 1330 }
1487 1331
1332 qla2x00_init_host_attr(ha);
1488 /* 1333 /*
1489 * Startup the kernel thread for this host adapter 1334 * Startup the kernel thread for this host adapter
1490 */ 1335 */
@@ -1498,16 +1343,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1498 } 1343 }
1499 wait_for_completion(&ha->dpc_inited); 1344 wait_for_completion(&ha->dpc_inited);
1500 1345
1501 host->this_id = 255;
1502 host->cmd_per_lun = 3;
1503 host->max_cmd_len = MAX_CMDSZ;
1504 host->max_channel = ha->ports - 1;
1505 host->max_lun = ha->max_luns;
1506 BUG_ON(qla2xxx_transport_template == NULL);
1507 host->transportt = qla2xxx_transport_template;
1508 host->unique_id = ha->instance;
1509 host->max_id = ha->max_targets;
1510
1511 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 1346 if (IS_QLA2100(ha) || IS_QLA2200(ha))
1512 ret = request_irq(host->irq, qla2100_intr_handler, 1347 ret = request_irq(host->irq, qla2100_intr_handler,
1513 SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); 1348 SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha);
@@ -1568,7 +1403,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1568 msleep(10); 1403 msleep(10);
1569 } 1404 }
1570 1405
1571 pci_set_drvdata(pdev, ha);
1572 ha->flags.init_done = 1; 1406 ha->flags.init_done = 1;
1573 num_hosts++; 1407 num_hosts++;
1574 1408
@@ -1577,12 +1411,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1577 qla2x00_display_fc_names(ha); 1411 qla2x00_display_fc_names(ha);
1578 } 1412 }
1579 1413
1580 if (scsi_add_host(host, &pdev->dev))
1581 goto probe_failed;
1582
1583 sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);
1584 sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
1585
1586 qla_printk(KERN_INFO, ha, "\n" 1414 qla_printk(KERN_INFO, ha, "\n"
1587 " QLogic Fibre Channel HBA Driver: %s\n" 1415 " QLogic Fibre Channel HBA Driver: %s\n"
1588 " QLogic %s - %s\n" 1416 " QLogic %s - %s\n"
@@ -1592,12 +1420,16 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
1592 pci_name(ha->pdev), ha->flags.enable_64bit_addressing ? '+': '-', 1420 pci_name(ha->pdev), ha->flags.enable_64bit_addressing ? '+': '-',
1593 ha->host_no, qla2x00_get_fw_version_str(ha, fw_str)); 1421 ha->host_no, qla2x00_get_fw_version_str(ha, fw_str));
1594 1422
1595 if (ql2xdoinitscan) 1423 /* Go with fc_rport registration. */
1596 scsi_scan_host(host); 1424 list_for_each_entry(fcport, &ha->fcports, list)
1425 qla2x00_reg_remote_port(ha, fcport);
1597 1426
1598 return 0; 1427 return 0;
1599 1428
1600probe_failed: 1429probe_failed:
1430 scsi_remove_host(host);
1431
1432probe_alloc_failed:
1601 qla2x00_free_device(ha); 1433 qla2x00_free_device(ha);
1602 1434
1603 scsi_host_put(host); 1435 scsi_host_put(host);
@@ -1615,9 +1447,7 @@ void qla2x00_remove_one(struct pci_dev *pdev)
1615 1447
1616 ha = pci_get_drvdata(pdev); 1448 ha = pci_get_drvdata(pdev);
1617 1449
1618 sysfs_remove_bin_file(&ha->host->shost_gendev.kobj, 1450 qla2x00_free_sysfs_attr(ha);
1619 &sysfs_fw_dump_attr);
1620 sysfs_remove_bin_file(&ha->host->shost_gendev.kobj, &sysfs_nvram_attr);
1621 1451
1622 scsi_remove_host(ha->host); 1452 scsi_remove_host(ha->host);
1623 1453
@@ -2090,6 +1920,8 @@ qla2x00_display_fc_names(scsi_qla_host_t *ha)
2090void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, 1920void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
2091 int do_login) 1921 int do_login)
2092{ 1922{
1923 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
1924 fc_remote_port_block(fcport->rport);
2093 /* 1925 /*
2094 * We may need to retry the login, so don't change the state of the 1926 * We may need to retry the login, so don't change the state of the
2095 * port but do the retries. 1927 * port but do the retries.
@@ -2149,7 +1981,8 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
2149 */ 1981 */
2150 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 1982 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
2151 continue; 1983 continue;
2152 1984 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
1985 fc_remote_port_block(fcport->rport);
2153 atomic_set(&fcport->state, FCS_DEVICE_LOST); 1986 atomic_set(&fcport->state, FCS_DEVICE_LOST);
2154 } 1987 }
2155} 1988}
@@ -2815,7 +2648,6 @@ qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *sp)
2815 2648
2816 cmd->scsi_done(cmd); 2649 cmd->scsi_done(cmd);
2817} 2650}
2818
2819/************************************************************************** 2651/**************************************************************************
2820* qla2x00_timer 2652* qla2x00_timer
2821* 2653*
@@ -2953,67 +2785,6 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
2953 return -ETIMEDOUT; 2785 return -ETIMEDOUT;
2954} 2786}
2955 2787
2956static void
2957qla2xxx_get_port_id(struct scsi_target *starget)
2958{
2959 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2960 scsi_qla_host_t *ha = to_qla_host(shost);
2961 struct fc_port *fc;
2962
2963 list_for_each_entry(fc, &ha->fcports, list) {
2964 if (fc->os_target_id == starget->id) {
2965 fc_starget_port_id(starget) = fc->d_id.b.domain << 16 |
2966 fc->d_id.b.area << 8 |
2967 fc->d_id.b.al_pa;
2968 return;
2969 }
2970 }
2971 fc_starget_port_id(starget) = -1;
2972}
2973
2974static void
2975qla2xxx_get_port_name(struct scsi_target *starget)
2976{
2977 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2978 scsi_qla_host_t *ha = to_qla_host(shost);
2979 struct fc_port *fc;
2980
2981 list_for_each_entry(fc, &ha->fcports, list) {
2982 if (fc->os_target_id == starget->id) {
2983 fc_starget_port_name(starget) =
2984 __be64_to_cpu(*(uint64_t *)fc->port_name);
2985 return;
2986 }
2987 }
2988 fc_starget_port_name(starget) = -1;
2989}
2990
2991static void
2992qla2xxx_get_node_name(struct scsi_target *starget)
2993{
2994 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2995 scsi_qla_host_t *ha = to_qla_host(shost);
2996 struct fc_port *fc;
2997
2998 list_for_each_entry(fc, &ha->fcports, list) {
2999 if (fc->os_target_id == starget->id) {
3000 fc_starget_node_name(starget) =
3001 __be64_to_cpu(*(uint64_t *)fc->node_name);
3002 return;
3003 }
3004 }
3005 fc_starget_node_name(starget) = -1;
3006}
3007
3008static struct fc_function_template qla2xxx_transport_functions = {
3009 .get_starget_port_id = qla2xxx_get_port_id,
3010 .show_starget_port_id = 1,
3011 .get_starget_port_name = qla2xxx_get_port_name,
3012 .show_starget_port_name = 1,
3013 .get_starget_node_name = qla2xxx_get_node_name,
3014 .show_starget_node_name = 1,
3015};
3016
3017/** 2788/**
3018 * qla2x00_module_init - Module initialization. 2789 * qla2x00_module_init - Module initialization.
3019 **/ 2790 **/
@@ -3035,8 +2806,7 @@ qla2x00_module_init(void)
3035#if DEBUG_QLA2100 2806#if DEBUG_QLA2100
3036 strcat(qla2x00_version_str, "-debug"); 2807 strcat(qla2x00_version_str, "-debug");
3037#endif 2808#endif
3038 2809 qla2xxx_transport_template = qla2x00_alloc_transport_tmpl();
3039 qla2xxx_transport_template = fc_attach_transport(&qla2xxx_transport_functions);
3040 if (!qla2xxx_transport_template) 2810 if (!qla2xxx_transport_template)
3041 return -ENODEV; 2811 return -ENODEV;
3042 2812