qla_os.c 81.6 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
A
Andrew Vasquez 已提交
2
 * QLogic Fibre Channel HBA Driver
3
 * Copyright (c)  2003-2008 QLogic Corporation
L
Linus Torvalds 已提交
4
 *
A
Andrew Vasquez 已提交
5
 * See LICENSE.qla2xxx for copyright and licensing details.
L
Linus Torvalds 已提交
6 7 8 9 10 11
 */
#include "qla_def.h"

#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
12
#include <linux/kthread.h>
13
#include <linux/mutex.h>
L
Linus Torvalds 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27

#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>

/*
 * Driver version
 */
char qla2x00_version_str[40];

/*
 * SRB allocation cache
 */
28
static struct kmem_cache *srb_cachep;
L
Linus Torvalds 已提交
29 30 31 32 33 34

int ql2xlogintimeout = 20;
module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xlogintimeout,
		"Login timeout value in seconds.");

35
int qlport_down_retry;
L
Linus Torvalds 已提交
36 37
module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(qlport_down_retry,
38
		"Maximum number of command retries to a port that returns "
L
Linus Torvalds 已提交
39 40 41 42 43 44
		"a PORT-DOWN status.");

int ql2xplogiabsentdevice;
module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xplogiabsentdevice,
		"Option to enable PLOGI to devices that are not present after "
45
		"a Fabric scan.  This is needed for several broken switches. "
L
Linus Torvalds 已提交
46 47 48 49 50 51 52
		"Default is 0 - no PLOGI. 1 - perfom PLOGI.");

int ql2xloginretrycount = 0;
module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xloginretrycount,
		"Specify an alternate value for the NVRAM login retry count.");

53 54 55 56 57 58 59
int ql2xallocfwdump = 1;
module_param(ql2xallocfwdump, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xallocfwdump,
		"Option to enable allocation of memory for a firmware dump "
		"during HBA initialization.  Memory allocation requirements "
		"vary by ISP type.  Default is 1 - allocate memory.");

60
int ql2xextended_error_logging;
61
module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR);
62
MODULE_PARM_DESC(ql2xextended_error_logging,
63 64 65
		"Option to enable extended error logging, "
		"Default is 0 - no logging. 1 - log errors.");

L
Linus Torvalds 已提交
66 67 68 69
static void qla2x00_free_device(scsi_qla_host_t *);

static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);

70
int ql2xfdmienable=1;
71 72 73 74 75
module_param(ql2xfdmienable, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xfdmienable,
		"Enables FDMI registratons "
		"Default is 0 - no FDMI. 1 - perfom FDMI.");

76 77 78 79 80 81 82 83 84 85 86 87 88
#define MAX_Q_DEPTH    32
static int ql2xmaxqdepth = MAX_Q_DEPTH;
module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xmaxqdepth,
		"Maximum queue depth to report for target devices.");

int ql2xqfullrampup = 120;
module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xqfullrampup,
		"Number of seconds to wait to begin to ramp-up the queue "
		"depth for a device after a queue-full condition has been "
		"detected.  Default is 120 seconds.");

89 90 91 92 93 94
int ql2xiidmaenable=1;
module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xiidmaenable,
		"Enables iIDMA settings "
		"Default is 1 - perform iIDMA. 0 - no iIDMA.");

95 96 97 98 99 100
int ql2xmaxqueues = 1;
module_param(ql2xmaxqueues, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xmaxqueues,
		"Enables MQ settings "
		"Default is 1 for single queue. Set it to number \
			of queues in MQ mode.");
L
Linus Torvalds 已提交
101
/*
A
Andrew Vasquez 已提交
102
 * SCSI host template entry points
L
Linus Torvalds 已提交
103 104
 */
static int qla2xxx_slave_configure(struct scsi_device * device);
已提交
105
static int qla2xxx_slave_alloc(struct scsi_device *);
106 107
static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
static void qla2xxx_scan_start(struct Scsi_Host *);
已提交
108
static void qla2xxx_slave_destroy(struct scsi_device *);
L
Linus Torvalds 已提交
109 110
static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
		void (*fn)(struct scsi_cmnd *));
111 112
static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
		void (*fn)(struct scsi_cmnd *));
L
Linus Torvalds 已提交
113 114
static int qla2xxx_eh_abort(struct scsi_cmnd *);
static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
115
static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
L
Linus Torvalds 已提交
116 117 118
static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
static int qla2xxx_eh_host_reset(struct scsi_cmnd *);

119 120 121
static int qla2x00_change_queue_depth(struct scsi_device *, int);
static int qla2x00_change_queue_type(struct scsi_device *, int);

A
Adrian Bunk 已提交
122
static struct scsi_host_template qla2x00_driver_template = {
L
Linus Torvalds 已提交
123
	.module			= THIS_MODULE,
124
	.name			= QLA2XXX_DRIVER_NAME,
L
Linus Torvalds 已提交
125 126 127 128
	.queuecommand		= qla2x00_queuecommand,

	.eh_abort_handler	= qla2xxx_eh_abort,
	.eh_device_reset_handler = qla2xxx_eh_device_reset,
129
	.eh_target_reset_handler = qla2xxx_eh_target_reset,
L
Linus Torvalds 已提交
130 131 132 133 134
	.eh_bus_reset_handler	= qla2xxx_eh_bus_reset,
	.eh_host_reset_handler	= qla2xxx_eh_host_reset,

	.slave_configure	= qla2xxx_slave_configure,

已提交
135 136
	.slave_alloc		= qla2xxx_slave_alloc,
	.slave_destroy		= qla2xxx_slave_destroy,
137 138
	.scan_finished		= qla2xxx_scan_finished,
	.scan_start		= qla2xxx_scan_start,
139 140
	.change_queue_depth	= qla2x00_change_queue_depth,
	.change_queue_type	= qla2x00_change_queue_type,
L
Linus Torvalds 已提交
141 142 143 144 145 146 147 148 149 150
	.this_id		= -1,
	.cmd_per_lun		= 3,
	.use_clustering		= ENABLE_CLUSTERING,
	.sg_tablesize		= SG_ALL,

	/*
	 * The RISC allows for each command to transfer (2^32-1) bytes of data,
	 * which equates to 0x800000 sectors.
	 */
	.max_sectors		= 0xFFFF,
151
	.shost_attrs		= qla2x00_host_attrs,
L
Linus Torvalds 已提交
152 153
};

154
struct scsi_host_template qla24xx_driver_template = {
155
	.module			= THIS_MODULE,
156
	.name			= QLA2XXX_DRIVER_NAME,
157 158 159 160
	.queuecommand		= qla24xx_queuecommand,

	.eh_abort_handler	= qla2xxx_eh_abort,
	.eh_device_reset_handler = qla2xxx_eh_device_reset,
161
	.eh_target_reset_handler = qla2xxx_eh_target_reset,
162 163 164 165 166 167 168
	.eh_bus_reset_handler	= qla2xxx_eh_bus_reset,
	.eh_host_reset_handler	= qla2xxx_eh_host_reset,

	.slave_configure	= qla2xxx_slave_configure,

	.slave_alloc		= qla2xxx_slave_alloc,
	.slave_destroy		= qla2xxx_slave_destroy,
169 170
	.scan_finished		= qla2xxx_scan_finished,
	.scan_start		= qla2xxx_scan_start,
171 172
	.change_queue_depth	= qla2x00_change_queue_depth,
	.change_queue_type	= qla2x00_change_queue_type,
173 174 175 176 177 178
	.this_id		= -1,
	.cmd_per_lun		= 3,
	.use_clustering		= ENABLE_CLUSTERING,
	.sg_tablesize		= SG_ALL,

	.max_sectors		= 0xFFFF,
179
	.shost_attrs		= qla2x00_host_attrs,
180 181
};

L
Linus Torvalds 已提交
182
static struct scsi_transport_template *qla2xxx_transport_template = NULL;
183
struct scsi_transport_template *qla2xxx_transport_vport_template = NULL;
L
Linus Torvalds 已提交
184 185 186 187 188 189

/* TODO Convert to inlines
 *
 * Timer routines
 */

190
__inline__ void
191
qla2x00_start_timer(scsi_qla_host_t *vha, void *func, unsigned long interval)
L
Linus Torvalds 已提交
192
{
193 194 195 196 197 198
	init_timer(&vha->timer);
	vha->timer.expires = jiffies + interval * HZ;
	vha->timer.data = (unsigned long)vha;
	vha->timer.function = (void (*)(unsigned long))func;
	add_timer(&vha->timer);
	vha->timer_active = 1;
L
Linus Torvalds 已提交
199 200 201
}

static inline void
202
qla2x00_restart_timer(scsi_qla_host_t *vha, unsigned long interval)
L
Linus Torvalds 已提交
203
{
204
	mod_timer(&vha->timer, jiffies + interval * HZ);
L
Linus Torvalds 已提交
205 206
}

A
Adrian Bunk 已提交
207
static __inline__ void
208
qla2x00_stop_timer(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
209
{
210 211
	del_timer_sync(&vha->timer);
	vha->timer_active = 0;
L
Linus Torvalds 已提交
212 213 214 215 216 217
}

static int qla2x00_do_dpc(void *data);

static void qla2x00_rst_aen(scsi_qla_host_t *);

218 219
static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
	struct req_que **, struct rsp_que **);
220 221
static void qla2x00_mem_free(struct qla_hw_data *);
static void qla2x00_sp_free_dma(srb_t *);
L
Linus Torvalds 已提交
222 223

/* -------------------------------------------------------------------------- */
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
static int qla2x00_alloc_queues(struct qla_hw_data *ha)
{
	ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_queues,
				GFP_KERNEL);
	if (!ha->req_q_map) {
		qla_printk(KERN_WARNING, ha,
			"Unable to allocate memory for request queue ptrs\n");
		goto fail_req_map;
	}

	ha->rsp_q_map = kzalloc(sizeof(struct rsp_que *) * ha->max_queues,
				GFP_KERNEL);
	if (!ha->rsp_q_map) {
		qla_printk(KERN_WARNING, ha,
			"Unable to allocate memory for response queue ptrs\n");
		goto fail_rsp_map;
	}
	set_bit(0, ha->rsp_qid_map);
	set_bit(0, ha->req_qid_map);
	return 1;

fail_rsp_map:
	kfree(ha->req_q_map);
	ha->req_q_map = NULL;
fail_req_map:
	return -ENOMEM;
}

static void qla2x00_free_que(struct qla_hw_data *ha, struct req_que *req,
	struct rsp_que *rsp)
{
	if (rsp && rsp->ring)
		dma_free_coherent(&ha->pdev->dev,
		(rsp->length + 1) * sizeof(response_t),
		rsp->ring, rsp->dma);

	kfree(rsp);
	rsp = NULL;
	if (req && req->ring)
		dma_free_coherent(&ha->pdev->dev,
		(req->length + 1) * sizeof(request_t),
		req->ring, req->dma);

	kfree(req);
	req = NULL;
}

static void qla2x00_free_queues(struct qla_hw_data *ha)
{
	struct req_que *req;
	struct rsp_que *rsp;
	int cnt;

	for (cnt = 0; cnt < ha->max_queues; cnt++) {
		rsp = ha->rsp_q_map[cnt];
		req = ha->req_q_map[cnt];
		qla2x00_free_que(ha, req, rsp);
	}
	kfree(ha->rsp_q_map);
	ha->rsp_q_map = NULL;

	kfree(ha->req_q_map);
	ha->req_q_map = NULL;
}

L
Linus Torvalds 已提交
289
static char *
290
qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str)
L
Linus Torvalds 已提交
291
{
292
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
	static char *pci_bus_modes[] = {
		"33", "66", "100", "133",
	};
	uint16_t pci_bus;

	strcpy(str, "PCI");
	pci_bus = (ha->pci_attr & (BIT_9 | BIT_10)) >> 9;
	if (pci_bus) {
		strcat(str, "-X (");
		strcat(str, pci_bus_modes[pci_bus]);
	} else {
		pci_bus = (ha->pci_attr & BIT_8) >> 8;
		strcat(str, " (");
		strcat(str, pci_bus_modes[pci_bus]);
	}
	strcat(str, " MHz)");

	return (str);
}

313
static char *
314
qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str)
315 316
{
	static char *pci_bus_modes[] = { "33", "66", "100", "133", };
317
	struct qla_hw_data *ha = vha->hw;
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
	uint32_t pci_bus;
	int pcie_reg;

	pcie_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
	if (pcie_reg) {
		char lwstr[6];
		uint16_t pcie_lstat, lspeed, lwidth;

		pcie_reg += 0x12;
		pci_read_config_word(ha->pdev, pcie_reg, &pcie_lstat);
		lspeed = pcie_lstat & (BIT_0 | BIT_1 | BIT_2 | BIT_3);
		lwidth = (pcie_lstat &
		    (BIT_4 | BIT_5 | BIT_6 | BIT_7 | BIT_8 | BIT_9)) >> 4;

		strcpy(str, "PCIe (");
		if (lspeed == 1)
334
			strcat(str, "2.5GT/s ");
335
		else if (lspeed == 2)
336
			strcat(str, "5.0GT/s ");
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
		else
			strcat(str, "<unknown> ");
		snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
		strcat(str, lwstr);

		return str;
	}

	strcpy(str, "PCI");
	pci_bus = (ha->pci_attr & CSRX_PCIX_BUS_MODE_MASK) >> 8;
	if (pci_bus == 0 || pci_bus == 8) {
		strcat(str, " (");
		strcat(str, pci_bus_modes[pci_bus >> 3]);
	} else {
		strcat(str, "-X ");
		if (pci_bus & BIT_2)
			strcat(str, "Mode 2");
		else
			strcat(str, "Mode 1");
		strcat(str, " (");
		strcat(str, pci_bus_modes[pci_bus & ~BIT_2]);
	}
	strcat(str, " MHz)");

	return str;
}

364
static char *
365
qla2x00_fw_version_str(struct scsi_qla_host *vha, char *str)
L
Linus Torvalds 已提交
366 367
{
	char un_str[10];
368
	struct qla_hw_data *ha = vha->hw;
A
Andrew Vasquez 已提交
369

L
Linus Torvalds 已提交
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
	sprintf(str, "%d.%02d.%02d ", ha->fw_major_version,
	    ha->fw_minor_version,
	    ha->fw_subminor_version);

	if (ha->fw_attributes & BIT_9) {
		strcat(str, "FLX");
		return (str);
	}

	switch (ha->fw_attributes & 0xFF) {
	case 0x7:
		strcat(str, "EF");
		break;
	case 0x17:
		strcat(str, "TP");
		break;
	case 0x37:
		strcat(str, "IP");
		break;
	case 0x77:
		strcat(str, "VI");
		break;
	default:
		sprintf(un_str, "(%x)", ha->fw_attributes);
		strcat(str, un_str);
		break;
	}
	if (ha->fw_attributes & 0x100)
		strcat(str, "X");

	return (str);
}

403
static char *
404
qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str)
405
{
406
	struct qla_hw_data *ha = vha->hw;
407 408 409 410
	sprintf(str, "%d.%02d.%02d ", ha->fw_major_version,
	    ha->fw_minor_version,
	    ha->fw_subminor_version);

411 412 413 414 415 416
	if (ha->fw_attributes & BIT_0)
		strcat(str, "[Class 2] ");
	if (ha->fw_attributes & BIT_1)
		strcat(str, "[IP] ");
	if (ha->fw_attributes & BIT_2)
		strcat(str, "[Multi-ID] ");
417 418 419 420 421 422
	if (ha->fw_attributes & BIT_3)
		strcat(str, "[SB-2] ");
	if (ha->fw_attributes & BIT_4)
		strcat(str, "[T10 CRC] ");
	if (ha->fw_attributes & BIT_5)
		strcat(str, "[VI] ");
423 424
	if (ha->fw_attributes & BIT_10)
		strcat(str, "[84XX] ");
425 426 427 428 429 430
	if (ha->fw_attributes & BIT_13)
		strcat(str, "[Experimental]");
	return str;
}

static inline srb_t *
431
qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
432 433 434
    struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
	srb_t *sp;
435
	struct qla_hw_data *ha = vha->hw;
436 437 438 439 440

	sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
	if (!sp)
		return sp;

441
	sp->vha = vha;
442 443
	sp->fcport = fcport;
	sp->cmd = cmd;
444
	sp->que = ha->req_q_map[0];
445 446 447 448 449 450 451
	sp->flags = 0;
	CMD_SP(cmd) = (void *)sp;
	cmd->scsi_done = done;

	return sp;
}

L
Linus Torvalds 已提交
452
static int
已提交
453
qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
L
Linus Torvalds 已提交
454
{
455
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
456
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
457
	struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
458
	struct qla_hw_data *ha = vha->hw;
已提交
459 460
	srb_t *sp;
	int rval;
L
Linus Torvalds 已提交
461

462 463 464 465 466
	if (unlikely(pci_channel_offline(ha->pdev))) {
		cmd->result = DID_REQUEUE << 16;
		goto qc_fail_command;
	}

467 468 469
	rval = fc_remote_port_chkready(rport);
	if (rval) {
		cmd->result = rval;
已提交
470 471
		goto qc_fail_command;
	}
L
Linus Torvalds 已提交
472

473
	/* Close window on fcport/rport state-transitioning. */
474 475
	if (fcport->drport)
		goto qc_target_busy;
476

已提交
477 478
	if (atomic_read(&fcport->state) != FCS_ONLINE) {
		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
479
		    atomic_read(&vha->loop_state) == LOOP_DEAD) {
已提交
480 481 482
			cmd->result = DID_NO_CONNECT << 16;
			goto qc_fail_command;
		}
483
		goto qc_target_busy;
已提交
484
	}
L
Linus Torvalds 已提交
485

486
	spin_unlock_irq(vha->host->host_lock);
L
Linus Torvalds 已提交
487

488
	sp = qla2x00_get_new_sp(vha, fcport, cmd, done);
489
	if (!sp)
已提交
490
		goto qc_host_busy_lock;
L
Linus Torvalds 已提交
491

492
	rval = ha->isp_ops->start_scsi(sp);
已提交
493 494
	if (rval != QLA_SUCCESS)
		goto qc_host_busy_free_sp;
L
Linus Torvalds 已提交
495

496
	spin_lock_irq(vha->host->host_lock);
L
Linus Torvalds 已提交
497

已提交
498
	return 0;
L
Linus Torvalds 已提交
499

已提交
500
qc_host_busy_free_sp:
501
	qla2x00_sp_free_dma(sp);
已提交
502
	mempool_free(sp, ha->srb_mempool);
L
Linus Torvalds 已提交
503

已提交
504
qc_host_busy_lock:
505
	spin_lock_irq(vha->host->host_lock);
已提交
506
	return SCSI_MLQUEUE_HOST_BUSY;
L
Linus Torvalds 已提交
507

508 509 510
qc_target_busy:
	return SCSI_MLQUEUE_TARGET_BUSY;

已提交
511 512
qc_fail_command:
	done(cmd);
L
Linus Torvalds 已提交
513

已提交
514
	return 0;
L
Linus Torvalds 已提交
515 516
}

517 518 519 520

static int
qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
521
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
522
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
523
	struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
524 525
	struct qla_hw_data *ha = vha->hw;
	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
526 527 528
	srb_t *sp;
	int rval;

529
	if (unlikely(pci_channel_offline(ha->pdev))) {
530 531 532 533
		cmd->result = DID_REQUEUE << 16;
		goto qc24_fail_command;
	}

534 535 536
	rval = fc_remote_port_chkready(rport);
	if (rval) {
		cmd->result = rval;
537 538 539
		goto qc24_fail_command;
	}

540
	/* Close window on fcport/rport state-transitioning. */
541 542
	if (fcport->drport)
		goto qc24_target_busy;
543

544 545
	if (atomic_read(&fcport->state) != FCS_ONLINE) {
		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
546
		    atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
547 548 549
			cmd->result = DID_NO_CONNECT << 16;
			goto qc24_fail_command;
		}
550
		goto qc24_target_busy;
551 552
	}

553
	spin_unlock_irq(vha->host->host_lock);
554

555
	sp = qla2x00_get_new_sp(base_vha, fcport, cmd, done);
556 557 558
	if (!sp)
		goto qc24_host_busy_lock;

559
	rval = ha->isp_ops->start_scsi(sp);
560 561 562
	if (rval != QLA_SUCCESS)
		goto qc24_host_busy_free_sp;

563
	spin_lock_irq(vha->host->host_lock);
564 565 566 567

	return 0;

qc24_host_busy_free_sp:
568 569
	qla2x00_sp_free_dma(sp);
	mempool_free(sp, ha->srb_mempool);
570 571

qc24_host_busy_lock:
572
	spin_lock_irq(vha->host->host_lock);
573 574
	return SCSI_MLQUEUE_HOST_BUSY;

575 576 577
qc24_target_busy:
	return SCSI_MLQUEUE_TARGET_BUSY;

578 579 580 581 582 583 584
qc24_fail_command:
	done(cmd);

	return 0;
}


L
Linus Torvalds 已提交
585 586 587 588 589 590 591 592 593 594 595 596 597
/*
 * qla2x00_eh_wait_on_command
 *    Waits for the command to be returned by the Firmware for some
 *    max time.
 *
 * Input:
 *    cmd = Scsi Command to wait on.
 *
 * Return:
 *    Not Found : 0
 *    Found : 1
 */
static int
598
qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
L
Linus Torvalds 已提交
599
{
600 601
#define ABORT_POLLING_PERIOD	1000
#define ABORT_WAIT_ITER		((10 * 1000) / (ABORT_POLLING_PERIOD))
已提交
602 603
	unsigned long wait_iter = ABORT_WAIT_ITER;
	int ret = QLA_SUCCESS;
L
Linus Torvalds 已提交
604

已提交
605
	while (CMD_SP(cmd)) {
606
		msleep(ABORT_POLLING_PERIOD);
L
Linus Torvalds 已提交
607

已提交
608 609 610 611 612
		if (--wait_iter)
			break;
	}
	if (CMD_SP(cmd))
		ret = QLA_FUNCTION_FAILED;
L
Linus Torvalds 已提交
613

已提交
614
	return ret;
L
Linus Torvalds 已提交
615 616 617 618
}

/*
 * qla2x00_wait_for_hba_online
A
Andrew Vasquez 已提交
619
 *    Wait till the HBA is online after going through
L
Linus Torvalds 已提交
620 621 622 623 624
 *    <= MAX_RETRIES_OF_ISP_ABORT  or
 *    finally HBA is disabled ie marked offline
 *
 * Input:
 *     ha - pointer to host adapter structure
A
Andrew Vasquez 已提交
625 626
 *
 * Note:
L
Linus Torvalds 已提交
627 628 629 630 631 632 633
 *    Does context switching-Release SPIN_LOCK
 *    (if any) before calling this routine.
 *
 * Return:
 *    Success (Adapter is online) : 0
 *    Failed  (Adapter is offline/disabled) : 1
 */
634
int
635
qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
636
{
637 638
	int		return_status;
	unsigned long	wait_online;
639 640
	struct qla_hw_data *ha = vha->hw;
	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
L
Linus Torvalds 已提交
641

A
Andrew Vasquez 已提交
642
	wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
643 644 645 646
	while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
	    test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
	    test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
	    ha->dpc_active) && time_before(jiffies, wait_online)) {
L
Linus Torvalds 已提交
647 648 649

		msleep(1000);
	}
650
	if (base_vha->flags.online)
A
Andrew Vasquez 已提交
651
		return_status = QLA_SUCCESS;
L
Linus Torvalds 已提交
652 653 654 655 656 657 658 659 660
	else
		return_status = QLA_FUNCTION_FAILED;

	return (return_status);
}

/*
 * qla2x00_wait_for_loop_ready
 *    Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
A
Andrew Vasquez 已提交
661
 *    to be in LOOP_READY state.
L
Linus Torvalds 已提交
662 663
 * Input:
 *     ha - pointer to host adapter structure
A
Andrew Vasquez 已提交
664 665
 *
 * Note:
L
Linus Torvalds 已提交
666 667
 *    Does context switching-Release SPIN_LOCK
 *    (if any) before calling this routine.
A
Andrew Vasquez 已提交
668
 *
L
Linus Torvalds 已提交
669 670 671 672 673
 *
 * Return:
 *    Success (LOOP_READY) : 0
 *    Failed  (LOOP_NOT_READY) : 1
 */
A
Andrew Vasquez 已提交
674
static inline int
675
qla2x00_wait_for_loop_ready(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
676 677 678
{
	int 	 return_status = QLA_SUCCESS;
	unsigned long loop_timeout ;
679 680
	struct qla_hw_data *ha = vha->hw;
	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
L
Linus Torvalds 已提交
681 682

	/* wait for 5 min at the max for loop to be ready */
A
Andrew Vasquez 已提交
683
	loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ);
L
Linus Torvalds 已提交
684

685 686 687 688
	while ((!atomic_read(&base_vha->loop_down_timer) &&
	    atomic_read(&base_vha->loop_state) == LOOP_DOWN) ||
	    atomic_read(&base_vha->loop_state) != LOOP_READY) {
		if (atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
689 690 691
			return_status = QLA_FUNCTION_FAILED;
			break;
		}
L
Linus Torvalds 已提交
692 693 694 695 696 697
		msleep(1000);
		if (time_after_eq(jiffies, loop_timeout)) {
			return_status = QLA_FUNCTION_FAILED;
			break;
		}
	}
A
Andrew Vasquez 已提交
698
	return (return_status);
L
Linus Torvalds 已提交
699 700
}

701 702 703
void
qla2x00_abort_fcport_cmds(fc_port_t *fcport)
{
704
	int cnt, que, id;
705 706
	unsigned long flags;
	srb_t *sp;
707 708
	scsi_qla_host_t *vha = fcport->vha;
	struct qla_hw_data *ha = vha->hw;
709
	struct req_que *req;
710

711
	spin_lock_irqsave(&ha->hardware_lock, flags);
712 713 714 715
	for (que = 0; que < QLA_MAX_HOST_QUES; que++) {
		id = vha->req_ques[que];
		req = ha->req_q_map[id];
		if (!req)
716
			continue;
717 718 719 720 721 722
		for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
			sp = req->outstanding_cmds[cnt];
			if (!sp)
				continue;
			if (sp->fcport != fcport)
				continue;
723

724 725
			spin_unlock_irqrestore(&ha->hardware_lock, flags);
			if (ha->isp_ops->abort_command(vha, sp, req)) {
726
				DEBUG2(qla_printk(KERN_WARNING, ha,
727 728 729 730 731 732 733 734 735 736
				"Abort failed --  %lx\n",
				sp->cmd->serial_number));
			} else {
				if (qla2x00_eh_wait_on_command(sp->cmd) !=
					QLA_SUCCESS)
					DEBUG2(qla_printk(KERN_WARNING, ha,
					"Abort failed while waiting --  %lx\n",
					sp->cmd->serial_number));
			}
			spin_lock_irqsave(&ha->hardware_lock, flags);
737 738
		}
	}
739
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
740 741
}

742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
static void
qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
{
	struct Scsi_Host *shost = cmnd->device->host;
	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
	unsigned long flags;

	spin_lock_irqsave(shost->host_lock, flags);
	while (rport->port_state == FC_PORTSTATE_BLOCKED) {
		spin_unlock_irqrestore(shost->host_lock, flags);
		msleep(1000);
		spin_lock_irqsave(shost->host_lock, flags);
	}
	spin_unlock_irqrestore(shost->host_lock, flags);
	return;
}

L
Linus Torvalds 已提交
759 760 761 762 763 764 765 766 767 768 769 770 771
/**************************************************************************
* qla2xxx_eh_abort
*
* Description:
*    The abort function will abort the specified command.
*
* Input:
*    cmd = Linux SCSI command packet to be aborted.
*
* Returns:
*    Either SUCCESS or FAILED.
*
* Note:
772
*    Only return FAILED if command not returned by firmware.
L
Linus Torvalds 已提交
773
**************************************************************************/
774
static int
L
Linus Torvalds 已提交
775 776
qla2xxx_eh_abort(struct scsi_cmnd *cmd)
{
777
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
已提交
778
	srb_t *sp;
779
	int ret, i;
已提交
780 781
	unsigned int id, lun;
	unsigned long serial;
782
	unsigned long flags;
783
	int wait = 0;
784
	struct qla_hw_data *ha = vha->hw;
785
	struct req_que *req;
786
	srb_t *spt;
L
Linus Torvalds 已提交
787

788 789
	qla2x00_block_error_handler(cmd);

已提交
790
	if (!CMD_SP(cmd))
791
		return SUCCESS;
L
Linus Torvalds 已提交
792

793
	ret = SUCCESS;
L
Linus Torvalds 已提交
794

已提交
795 796 797
	id = cmd->device->id;
	lun = cmd->device->lun;
	serial = cmd->serial_number;
798 799 800 801
	spt = (srb_t *) CMD_SP(cmd);
	if (!spt)
		return SUCCESS;
	req = spt->que;
L
Linus Torvalds 已提交
802

已提交
803
	/* Check active list for command command. */
804
	spin_lock_irqsave(&ha->hardware_lock, flags);
805 806
	for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
		sp = req->outstanding_cmds[i];
L
Linus Torvalds 已提交
807

808 809
		if (sp == NULL)
			continue;
L
Linus Torvalds 已提交
810

811 812
		if (sp->cmd != cmd)
			continue;
L
Linus Torvalds 已提交
813

814 815 816 817 818 819 820 821 822 823 824
		DEBUG2(printk("%s(%ld): aborting sp %p from RISC."
		" pid=%ld.\n", __func__, vha->host_no, sp, serial));

		spin_unlock_irqrestore(&ha->hardware_lock, flags);
		if (ha->isp_ops->abort_command(vha, sp, req)) {
			DEBUG2(printk("%s(%ld): abort_command "
			"mbx failed.\n", __func__, vha->host_no));
		} else {
			DEBUG3(printk("%s(%ld): abort_command "
			"mbx success.\n", __func__, vha->host_no));
			wait = 1;
825
		}
826 827
		spin_lock_irqsave(&ha->hardware_lock, flags);
		break;
已提交
828
	}
829
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
L
Linus Torvalds 已提交
830

已提交
831
	/* Wait for the command to be returned. */
832
	if (wait) {
833
		if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) {
A
Andrew Vasquez 已提交
834
			qla_printk(KERN_ERR, ha,
已提交
835
			    "scsi(%ld:%d:%d): Abort handler timed out -- %lx "
836
			    "%x.\n", vha->host_no, id, lun, serial, ret);
837
			ret = FAILED;
已提交
838
		}
L
Linus Torvalds 已提交
839 840
	}

A
Andrew Vasquez 已提交
841
	qla_printk(KERN_INFO, ha,
842
	    "scsi(%ld:%d:%d): Abort command issued -- %d %lx %x.\n",
843
	    vha->host_no, id, lun, wait, serial, ret);
L
Linus Torvalds 已提交
844

已提交
845 846
	return ret;
}
L
Linus Torvalds 已提交
847

848 849 850 851 852 853
enum nexus_wait_type {
	WAIT_HOST = 0,
	WAIT_TARGET,
	WAIT_LUN,
};

已提交
854
static int
855
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
856
	unsigned int l, srb_t *sp, enum nexus_wait_type type)
已提交
857
{
858
	int cnt, match, status;
859
	unsigned long flags;
860
	struct qla_hw_data *ha = vha->hw;
861
	struct req_que *req;
L
Linus Torvalds 已提交
862

863
	status = QLA_SUCCESS;
864 865 866
	if (!sp)
		return status;

867
	spin_lock_irqsave(&ha->hardware_lock, flags);
868 869 870 871 872
	req = sp->que;
	for (cnt = 1; status == QLA_SUCCESS &&
		cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
		sp = req->outstanding_cmds[cnt];
		if (!sp)
873
			continue;
874

875 876 877 878 879 880 881 882 883 884 885 886 887 888
		if (vha->vp_idx != sp->fcport->vha->vp_idx)
			continue;
		match = 0;
		switch (type) {
		case WAIT_HOST:
			match = 1;
			break;
		case WAIT_TARGET:
			match = sp->cmd->device->id == t;
			break;
		case WAIT_LUN:
			match = (sp->cmd->device->id == t &&
				sp->cmd->device->lun == l);
			break;
889
		}
890 891 892 893 894 895
		if (!match)
			continue;

		spin_unlock_irqrestore(&ha->hardware_lock, flags);
		status = qla2x00_eh_wait_on_command(sp->cmd);
		spin_lock_irqsave(&ha->hardware_lock, flags);
L
Linus Torvalds 已提交
896
	}
897
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
898 899

	return status;
L
Linus Torvalds 已提交
900 901
}

902 903 904 905 906 907
static char *reset_errors[] = {
	"HBA not online",
	"HBA not ready",
	"Task management failed",
	"Waiting for command completions",
};
L
Linus Torvalds 已提交
908

909
static int
910 911
__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
    struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int))
L
Linus Torvalds 已提交
912
{
913
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
914
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
915
	int err;
L
Linus Torvalds 已提交
916

917 918
	qla2x00_block_error_handler(cmd);

919
	if (!fcport)
920
		return FAILED;
L
Linus Torvalds 已提交
921

922 923
	qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET ISSUED.\n",
	    vha->host_no, cmd->device->id, cmd->device->lun, name);
L
Linus Torvalds 已提交
924

925
	err = 0;
926
	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
927 928
		goto eh_reset_failed;
	err = 1;
929
	if (qla2x00_wait_for_loop_ready(vha) != QLA_SUCCESS)
930 931 932 933 934
		goto eh_reset_failed;
	err = 2;
	if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS)
		goto eh_reset_failed;
	err = 3;
935
	if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
936
	    cmd->device->lun, (srb_t *) CMD_SP(cmd), type) != QLA_SUCCESS)
937 938
		goto eh_reset_failed;

939 940
	qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n",
	    vha->host_no, cmd->device->id, cmd->device->lun, name);
941 942 943 944

	return SUCCESS;

 eh_reset_failed:
945 946
	qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n"
	    , vha->host_no, cmd->device->id, cmd->device->lun, name,
947 948 949
	    reset_errors[err]);
	return FAILED;
}
L
Linus Torvalds 已提交
950

951 952 953
static int
qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
{
954 955
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
956

957 958
	return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
	    ha->isp_ops->lun_reset);
L
Linus Torvalds 已提交
959 960 961
}

static int
962
qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
L
Linus Torvalds 已提交
963
{
964 965
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
966

967 968
	return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
	    ha->isp_ops->target_reset);
L
Linus Torvalds 已提交
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985
}

/**************************************************************************
* qla2xxx_eh_bus_reset
*
* Description:
*    The bus reset function will reset the bus and abort any executing
*    commands.
*
* Input:
*    cmd = Linux SCSI command packet of the command that cause the
*          bus reset.
*
* Returns:
*    SUCCESS/FAILURE (defined as macro in scsi.h).
*
**************************************************************************/
986
static int
L
Linus Torvalds 已提交
987 988
qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
{
989
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
990
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
991
	int ret = FAILED;
已提交
992 993
	unsigned int id, lun;
	unsigned long serial;
994
	srb_t *sp = (srb_t *) CMD_SP(cmd);
已提交
995

996 997
	qla2x00_block_error_handler(cmd);

已提交
998 999 1000
	id = cmd->device->id;
	lun = cmd->device->lun;
	serial = cmd->serial_number;
L
Linus Torvalds 已提交
1001

1002
	if (!fcport)
已提交
1003
		return ret;
L
Linus Torvalds 已提交
1004

1005
	qla_printk(KERN_INFO, vha->hw,
1006
	    "scsi(%ld:%d:%d): BUS RESET ISSUED.\n", vha->host_no, id, lun);
L
Linus Torvalds 已提交
1007

1008
	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
L
Linus Torvalds 已提交
1009
		DEBUG2(printk("%s failed:board disabled\n",__func__));
已提交
1010
		goto eh_bus_reset_done;
L
Linus Torvalds 已提交
1011 1012
	}

1013 1014
	if (qla2x00_wait_for_loop_ready(vha) == QLA_SUCCESS) {
		if (qla2x00_loop_reset(vha) == QLA_SUCCESS)
已提交
1015
			ret = SUCCESS;
L
Linus Torvalds 已提交
1016
	}
已提交
1017 1018
	if (ret == FAILED)
		goto eh_bus_reset_done;
L
Linus Torvalds 已提交
1019

1020
	/* Flush outstanding commands. */
1021
	if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) !=
1022
	    QLA_SUCCESS)
1023
		ret = FAILED;
L
Linus Torvalds 已提交
1024

已提交
1025
eh_bus_reset_done:
1026
	qla_printk(KERN_INFO, vha->hw, "%s: reset %s\n", __func__,
已提交
1027
	    (ret == FAILED) ? "failed" : "succeded");
L
Linus Torvalds 已提交
1028

已提交
1029
	return ret;
L
Linus Torvalds 已提交
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
}

/**************************************************************************
* qla2xxx_eh_host_reset
*
* Description:
*    The reset function will reset the Adapter.
*
* Input:
*      cmd = Linux SCSI command packet of the command that cause the
*            adapter reset.
*
* Returns:
*      Either SUCCESS or FAILED.
*
* Note:
**************************************************************************/
1047
static int
L
Linus Torvalds 已提交
1048 1049
qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
{
1050
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
1051
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
1052
	struct qla_hw_data *ha = vha->hw;
1053
	int ret = FAILED;
已提交
1054 1055
	unsigned int id, lun;
	unsigned long serial;
1056
	srb_t *sp = (srb_t *) CMD_SP(cmd);
1057
	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
L
Linus Torvalds 已提交
1058

1059 1060
	qla2x00_block_error_handler(cmd);

已提交
1061 1062 1063 1064
	id = cmd->device->id;
	lun = cmd->device->lun;
	serial = cmd->serial_number;

1065
	if (!fcport)
已提交
1066
		return ret;
L
Linus Torvalds 已提交
1067 1068

	qla_printk(KERN_INFO, ha,
1069
	    "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", vha->host_no, id, lun);
L
Linus Torvalds 已提交
1070

1071
	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
已提交
1072
		goto eh_host_reset_lock;
L
Linus Torvalds 已提交
1073 1074 1075

	/*
	 * Fixme-may be dpc thread is active and processing
A
Andrew Vasquez 已提交
1076
	 * loop_resync,so wait a while for it to
L
Linus Torvalds 已提交
1077 1078 1079 1080 1081
	 * be completed and then issue big hammer.Otherwise
	 * it may cause I/O failure as big hammer marks the
	 * devices as lost kicking of the port_down_timer
	 * while dpc is stuck for the mailbox to complete.
	 */
1082 1083 1084
	qla2x00_wait_for_loop_ready(vha);
	if (vha != base_vha) {
		if (qla2x00_vp_abort_isp(vha))
已提交
1085
			goto eh_host_reset_lock;
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
	} else {
		set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
		if (qla2x00_abort_isp(base_vha)) {
			clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
			/* failed. schedule dpc to try */
			set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);

			if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
				goto eh_host_reset_lock;
		}
		clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
A
Andrew Vasquez 已提交
1097
	}
L
Linus Torvalds 已提交
1098

1099
	/* Waiting for command to be returned to OS.*/
1100
	if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) ==
1101
		QLA_SUCCESS)
已提交
1102
		ret = SUCCESS;
L
Linus Torvalds 已提交
1103

已提交
1104 1105 1106
eh_host_reset_lock:
	qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
	    (ret == FAILED) ? "failed" : "succeded");
L
Linus Torvalds 已提交
1107

已提交
1108 1109
	return ret;
}
L
Linus Torvalds 已提交
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120

/*
* qla2x00_loop_reset
*      Issue loop reset.
*
* Input:
*      ha = adapter block pointer.
*
* Returns:
*      0 = success
*/
1121
int
1122
qla2x00_loop_reset(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
1123
{
1124
	int ret;
1125
	struct fc_port *fcport;
1126
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
1127

1128
	if (ha->flags.enable_lip_full_login && !vha->vp_idx) {
1129
		ret = qla2x00_full_login_lip(vha);
1130
		if (ret != QLA_SUCCESS) {
1131
			DEBUG2_3(printk("%s(%ld): failed: "
1132
			    "full_login_lip=%d.\n", __func__, vha->host_no,
1133
			    ret));
1134 1135 1136 1137 1138
		}
		atomic_set(&vha->loop_state, LOOP_DOWN);
		atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
		qla2x00_mark_all_devices_lost(vha, 0);
		qla2x00_wait_for_loop_ready(vha);
1139 1140
	}

1141
	if (ha->flags.enable_lip_reset && !vha->vp_idx) {
1142
		ret = qla2x00_lip_reset(vha);
1143
		if (ret != QLA_SUCCESS) {
1144
			DEBUG2_3(printk("%s(%ld): failed: "
1145 1146 1147
			    "lip_reset=%d.\n", __func__, vha->host_no, ret));
		} else
			qla2x00_wait_for_loop_ready(vha);
L
Linus Torvalds 已提交
1148 1149
	}

1150
	if (ha->flags.enable_target_reset) {
1151
		list_for_each_entry(fcport, &vha->vp_fcports, list) {
1152
			if (fcport->port_type != FCT_TARGET)
L
Linus Torvalds 已提交
1153 1154
				continue;

1155
			ret = ha->isp_ops->target_reset(fcport, 0);
1156 1157 1158
			if (ret != QLA_SUCCESS) {
				DEBUG2_3(printk("%s(%ld): bus_reset failed: "
				    "target_reset=%d d_id=%x.\n", __func__,
1159
				    vha->host_no, ret, fcport->d_id.b24));
1160
			}
L
Linus Torvalds 已提交
1161 1162 1163
		}
	}
	/* Issue marker command only when we are going to start the I/O */
1164
	vha->marker_needed = 1;
L
Linus Torvalds 已提交
1165

1166
	return QLA_SUCCESS;
L
Linus Torvalds 已提交
1167 1168
}

1169
void
1170
qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1171
{
1172
	int que, cnt;
1173 1174
	unsigned long flags;
	srb_t *sp;
1175
	struct qla_hw_data *ha = vha->hw;
1176
	struct req_que *req;
1177 1178

	spin_lock_irqsave(&ha->hardware_lock, flags);
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
	for (que = 0; que < QLA_MAX_HOST_QUES; que++) {
		req = ha->req_q_map[vha->req_ques[que]];
		if (!req)
			continue;
		for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
			sp = req->outstanding_cmds[cnt];
			if (sp && sp->vha == vha) {
				req->outstanding_cmds[cnt] = NULL;
				sp->cmd->result = res;
				qla2x00_sp_compl(ha, sp);
			}
1190 1191 1192 1193 1194
		}
	}
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

已提交
1195 1196
static int
qla2xxx_slave_alloc(struct scsi_device *sdev)
L
Linus Torvalds 已提交
1197
{
1198
	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
L
Linus Torvalds 已提交
1199

1200
	if (!rport || fc_remote_port_chkready(rport))
已提交
1201
		return -ENXIO;
1202

1203
	sdev->hostdata = *(fc_port_t **)rport->dd_data;
L
Linus Torvalds 已提交
1204

已提交
1205 1206
	return 0;
}
L
Linus Torvalds 已提交
1207

已提交
1208 1209 1210
static int
qla2xxx_slave_configure(struct scsi_device *sdev)
{
1211 1212
	scsi_qla_host_t *vha = shost_priv(sdev->host);
	struct qla_hw_data *ha = vha->hw;
已提交
1213
	struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
1214
	struct req_que *req = ha->req_q_map[0];
已提交
1215

已提交
1216
	if (sdev->tagged_supported)
1217
		scsi_activate_tcq(sdev, req->max_q_depth);
已提交
1218
	else
1219
		scsi_deactivate_tcq(sdev, req->max_q_depth);
L
Linus Torvalds 已提交
1220

1221
	rport->dev_loss_tmo = ha->port_down_retry_count;
已提交
1222

已提交
1223 1224
	return 0;
}
L
Linus Torvalds 已提交
1225

已提交
1226 1227 1228 1229
static void
qla2xxx_slave_destroy(struct scsi_device *sdev)
{
	sdev->hostdata = NULL;
L
Linus Torvalds 已提交
1230 1231
}

1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
static int
qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
	return sdev->queue_depth;
}

static int
qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type)
{
	if (sdev->tagged_supported) {
		scsi_set_tag_type(sdev, tag_type);
		if (tag_type)
			scsi_activate_tcq(sdev, sdev->queue_depth);
		else
			scsi_deactivate_tcq(sdev, sdev->queue_depth);
	} else
		tag_type = 0;

	return tag_type;
}

L
Linus Torvalds 已提交
1254 1255 1256 1257 1258 1259 1260 1261
/**
 * qla2x00_config_dma_addressing() - Configure OS DMA addressing method.
 * @ha: HA context
 *
 * At exit, the @ha's flags.enable_64bit_addressing set to indicated
 * supported addressing method.
 */
static void
1262
qla2x00_config_dma_addressing(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
1263
{
1264
	struct qla_hw_data *ha = vha->hw;
1265
	/* Assume a 32bit DMA mask. */
L
Linus Torvalds 已提交
1266 1267
	ha->flags.enable_64bit_addressing = 0;

1268 1269 1270 1271 1272
	if (!dma_set_mask(&ha->pdev->dev, DMA_64BIT_MASK)) {
		/* Any upper-dword bits set? */
		if (MSD(dma_get_required_mask(&ha->pdev->dev)) &&
		    !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
			/* Ok, a 64bit DMA mask is applicable. */
L
Linus Torvalds 已提交
1273
			ha->flags.enable_64bit_addressing = 1;
1274 1275
			ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64;
			ha->isp_ops->build_iocbs = qla2x00_build_scsi_iocbs_64;
1276
			return;
L
Linus Torvalds 已提交
1277 1278
		}
	}
1279 1280 1281

	dma_set_mask(&ha->pdev->dev, DMA_32BIT_MASK);
	pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
L
Linus Torvalds 已提交
1282 1283
}

1284
static void
1285
qla2x00_enable_intrs(struct qla_hw_data *ha)
1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
{
	unsigned long flags = 0;
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;

	spin_lock_irqsave(&ha->hardware_lock, flags);
	ha->interrupts_on = 1;
	/* enable risc and host interrupts */
	WRT_REG_WORD(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);
	RD_REG_WORD(&reg->ictrl);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

}

static void
1300
qla2x00_disable_intrs(struct qla_hw_data *ha)
1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313
{
	unsigned long flags = 0;
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;

	spin_lock_irqsave(&ha->hardware_lock, flags);
	ha->interrupts_on = 0;
	/* disable risc and host interrupts */
	WRT_REG_WORD(&reg->ictrl, 0);
	RD_REG_WORD(&reg->ictrl);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

static void
1314
qla24xx_enable_intrs(struct qla_hw_data *ha)
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326
{
	unsigned long flags = 0;
	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;

	spin_lock_irqsave(&ha->hardware_lock, flags);
	ha->interrupts_on = 1;
	WRT_REG_DWORD(&reg->ictrl, ICRX_EN_RISC_INT);
	RD_REG_DWORD(&reg->ictrl);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

static void
1327
qla24xx_disable_intrs(struct qla_hw_data *ha)
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353
{
	unsigned long flags = 0;
	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;

	spin_lock_irqsave(&ha->hardware_lock, flags);
	ha->interrupts_on = 0;
	WRT_REG_DWORD(&reg->ictrl, 0);
	RD_REG_DWORD(&reg->ictrl);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

static struct isp_operations qla2100_isp_ops = {
	.pci_config		= qla2100_pci_config,
	.reset_chip		= qla2x00_reset_chip,
	.chip_diag		= qla2x00_chip_diag,
	.config_rings		= qla2x00_config_rings,
	.reset_adapter		= qla2x00_reset_adapter,
	.nvram_config		= qla2x00_nvram_config,
	.update_fw_options	= qla2x00_update_fw_options,
	.load_risc		= qla2x00_load_risc,
	.pci_info_str		= qla2x00_pci_info_str,
	.fw_version_str		= qla2x00_fw_version_str,
	.intr_handler		= qla2100_intr_handler,
	.enable_intrs		= qla2x00_enable_intrs,
	.disable_intrs		= qla2x00_disable_intrs,
	.abort_command		= qla2x00_abort_command,
1354 1355
	.target_reset		= qla2x00_abort_target,
	.lun_reset		= qla2x00_lun_reset,
1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370
	.fabric_login		= qla2x00_login_fabric,
	.fabric_logout		= qla2x00_fabric_logout,
	.calc_req_entries	= qla2x00_calc_iocbs_32,
	.build_iocbs		= qla2x00_build_scsi_iocbs_32,
	.prep_ms_iocb		= qla2x00_prep_ms_iocb,
	.prep_ms_fdmi_iocb	= qla2x00_prep_ms_fdmi_iocb,
	.read_nvram		= qla2x00_read_nvram_data,
	.write_nvram		= qla2x00_write_nvram_data,
	.fw_dump		= qla2100_fw_dump,
	.beacon_on		= NULL,
	.beacon_off		= NULL,
	.beacon_blink		= NULL,
	.read_optrom		= qla2x00_read_optrom_data,
	.write_optrom		= qla2x00_write_optrom_data,
	.get_flash_version	= qla2x00_get_flash_version,
1371
	.start_scsi		= qla2x00_start_scsi,
1372 1373 1374
	.wrt_req_reg		= NULL,
	.wrt_rsp_reg		= NULL,
	.rd_req_reg		= NULL,
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
};

static struct isp_operations qla2300_isp_ops = {
	.pci_config		= qla2300_pci_config,
	.reset_chip		= qla2x00_reset_chip,
	.chip_diag		= qla2x00_chip_diag,
	.config_rings		= qla2x00_config_rings,
	.reset_adapter		= qla2x00_reset_adapter,
	.nvram_config		= qla2x00_nvram_config,
	.update_fw_options	= qla2x00_update_fw_options,
	.load_risc		= qla2x00_load_risc,
	.pci_info_str		= qla2x00_pci_info_str,
	.fw_version_str		= qla2x00_fw_version_str,
	.intr_handler		= qla2300_intr_handler,
	.enable_intrs		= qla2x00_enable_intrs,
	.disable_intrs		= qla2x00_disable_intrs,
	.abort_command		= qla2x00_abort_command,
1392 1393
	.target_reset		= qla2x00_abort_target,
	.lun_reset		= qla2x00_lun_reset,
1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
	.fabric_login		= qla2x00_login_fabric,
	.fabric_logout		= qla2x00_fabric_logout,
	.calc_req_entries	= qla2x00_calc_iocbs_32,
	.build_iocbs		= qla2x00_build_scsi_iocbs_32,
	.prep_ms_iocb		= qla2x00_prep_ms_iocb,
	.prep_ms_fdmi_iocb	= qla2x00_prep_ms_fdmi_iocb,
	.read_nvram		= qla2x00_read_nvram_data,
	.write_nvram		= qla2x00_write_nvram_data,
	.fw_dump		= qla2300_fw_dump,
	.beacon_on		= qla2x00_beacon_on,
	.beacon_off		= qla2x00_beacon_off,
	.beacon_blink		= qla2x00_beacon_blink,
	.read_optrom		= qla2x00_read_optrom_data,
	.write_optrom		= qla2x00_write_optrom_data,
	.get_flash_version	= qla2x00_get_flash_version,
1409
	.start_scsi		= qla2x00_start_scsi,
1410 1411 1412
	.wrt_req_reg		= NULL,
	.wrt_rsp_reg		= NULL,
	.rd_req_reg		= NULL,
1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429
};

static struct isp_operations qla24xx_isp_ops = {
	.pci_config		= qla24xx_pci_config,
	.reset_chip		= qla24xx_reset_chip,
	.chip_diag		= qla24xx_chip_diag,
	.config_rings		= qla24xx_config_rings,
	.reset_adapter		= qla24xx_reset_adapter,
	.nvram_config		= qla24xx_nvram_config,
	.update_fw_options	= qla24xx_update_fw_options,
	.load_risc		= qla24xx_load_risc,
	.pci_info_str		= qla24xx_pci_info_str,
	.fw_version_str		= qla24xx_fw_version_str,
	.intr_handler		= qla24xx_intr_handler,
	.enable_intrs		= qla24xx_enable_intrs,
	.disable_intrs		= qla24xx_disable_intrs,
	.abort_command		= qla24xx_abort_command,
1430 1431
	.target_reset		= qla24xx_abort_target,
	.lun_reset		= qla24xx_lun_reset,
1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446
	.fabric_login		= qla24xx_login_fabric,
	.fabric_logout		= qla24xx_fabric_logout,
	.calc_req_entries	= NULL,
	.build_iocbs		= NULL,
	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
	.read_nvram		= qla24xx_read_nvram_data,
	.write_nvram		= qla24xx_write_nvram_data,
	.fw_dump		= qla24xx_fw_dump,
	.beacon_on		= qla24xx_beacon_on,
	.beacon_off		= qla24xx_beacon_off,
	.beacon_blink		= qla24xx_beacon_blink,
	.read_optrom		= qla24xx_read_optrom_data,
	.write_optrom		= qla24xx_write_optrom_data,
	.get_flash_version	= qla24xx_get_flash_version,
1447
	.start_scsi		= qla24xx_start_scsi,
1448 1449 1450
	.wrt_req_reg		= qla24xx_wrt_req_reg,
	.wrt_rsp_reg		= qla24xx_wrt_rsp_reg,
	.rd_req_reg		= qla24xx_rd_req_reg,
1451 1452
};

1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467
static struct isp_operations qla25xx_isp_ops = {
	.pci_config		= qla25xx_pci_config,
	.reset_chip		= qla24xx_reset_chip,
	.chip_diag		= qla24xx_chip_diag,
	.config_rings		= qla24xx_config_rings,
	.reset_adapter		= qla24xx_reset_adapter,
	.nvram_config		= qla24xx_nvram_config,
	.update_fw_options	= qla24xx_update_fw_options,
	.load_risc		= qla24xx_load_risc,
	.pci_info_str		= qla24xx_pci_info_str,
	.fw_version_str		= qla24xx_fw_version_str,
	.intr_handler		= qla24xx_intr_handler,
	.enable_intrs		= qla24xx_enable_intrs,
	.disable_intrs		= qla24xx_disable_intrs,
	.abort_command		= qla24xx_abort_command,
1468 1469
	.target_reset		= qla24xx_abort_target,
	.lun_reset		= qla24xx_lun_reset,
1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
	.fabric_login		= qla24xx_login_fabric,
	.fabric_logout		= qla24xx_fabric_logout,
	.calc_req_entries	= NULL,
	.build_iocbs		= NULL,
	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
	.read_nvram		= qla25xx_read_nvram_data,
	.write_nvram		= qla25xx_write_nvram_data,
	.fw_dump		= qla25xx_fw_dump,
	.beacon_on		= qla24xx_beacon_on,
	.beacon_off		= qla24xx_beacon_off,
	.beacon_blink		= qla24xx_beacon_blink,
1482
	.read_optrom		= qla25xx_read_optrom_data,
1483 1484
	.write_optrom		= qla24xx_write_optrom_data,
	.get_flash_version	= qla24xx_get_flash_version,
1485
	.start_scsi		= qla24xx_start_scsi,
1486 1487 1488
	.wrt_req_reg		= qla24xx_wrt_req_reg,
	.wrt_rsp_reg		= qla24xx_wrt_rsp_reg,
	.rd_req_reg		= qla24xx_rd_req_reg,
1489 1490
};

1491
static inline void
1492
qla2x00_set_isp_flags(struct qla_hw_data *ha)
1493 1494 1495 1496 1497 1498
{
	ha->device_type = DT_EXTENDED_IDS;
	switch (ha->pdev->device) {
	case PCI_DEVICE_ID_QLOGIC_ISP2100:
		ha->device_type |= DT_ISP2100;
		ha->device_type &= ~DT_EXTENDED_IDS;
1499
		ha->fw_srisc_address = RISC_START_ADDRESS_2100;
1500 1501 1502 1503
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2200:
		ha->device_type |= DT_ISP2200;
		ha->device_type &= ~DT_EXTENDED_IDS;
1504
		ha->fw_srisc_address = RISC_START_ADDRESS_2100;
1505 1506 1507
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2300:
		ha->device_type |= DT_ISP2300;
1508
		ha->device_type |= DT_ZIO_SUPPORTED;
1509
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1510 1511 1512
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2312:
		ha->device_type |= DT_ISP2312;
1513
		ha->device_type |= DT_ZIO_SUPPORTED;
1514
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1515 1516 1517
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2322:
		ha->device_type |= DT_ISP2322;
1518
		ha->device_type |= DT_ZIO_SUPPORTED;
1519 1520 1521
		if (ha->pdev->subsystem_vendor == 0x1028 &&
		    ha->pdev->subsystem_device == 0x0170)
			ha->device_type |= DT_OEM_001;
1522
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1523 1524 1525
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP6312:
		ha->device_type |= DT_ISP6312;
1526
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1527 1528 1529
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP6322:
		ha->device_type |= DT_ISP6322;
1530
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1531 1532 1533
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2422:
		ha->device_type |= DT_ISP2422;
1534
		ha->device_type |= DT_ZIO_SUPPORTED;
1535
		ha->device_type |= DT_FWI2;
1536
		ha->device_type |= DT_IIDMA;
1537
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1538 1539 1540
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2432:
		ha->device_type |= DT_ISP2432;
1541
		ha->device_type |= DT_ZIO_SUPPORTED;
1542
		ha->device_type |= DT_FWI2;
1543
		ha->device_type |= DT_IIDMA;
1544
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1545
		break;
1546 1547 1548 1549 1550 1551 1552
	case PCI_DEVICE_ID_QLOGIC_ISP8432:
		ha->device_type |= DT_ISP8432;
		ha->device_type |= DT_ZIO_SUPPORTED;
		ha->device_type |= DT_FWI2;
		ha->device_type |= DT_IIDMA;
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
		break;
1553 1554
	case PCI_DEVICE_ID_QLOGIC_ISP5422:
		ha->device_type |= DT_ISP5422;
1555
		ha->device_type |= DT_FWI2;
1556
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1557
		break;
1558 1559
	case PCI_DEVICE_ID_QLOGIC_ISP5432:
		ha->device_type |= DT_ISP5432;
1560
		ha->device_type |= DT_FWI2;
1561
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1562
		break;
1563 1564 1565 1566 1567
	case PCI_DEVICE_ID_QLOGIC_ISP2532:
		ha->device_type |= DT_ISP2532;
		ha->device_type |= DT_ZIO_SUPPORTED;
		ha->device_type |= DT_FWI2;
		ha->device_type |= DT_IIDMA;
1568
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1569 1570 1571 1572
		break;
	}
}

L
Linus Torvalds 已提交
1573
static int
1574
qla2x00_iospace_config(struct qla_hw_data *ha)
L
Linus Torvalds 已提交
1575
{
1576
	resource_size_t pio;
1577
	uint16_t msix;
L
Linus Torvalds 已提交
1578

1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589
	if (pci_request_selected_regions(ha->pdev, ha->bars,
	    QLA2XXX_DRIVER_NAME)) {
		qla_printk(KERN_WARNING, ha,
		    "Failed to reserve PIO/MMIO regions (%s)\n",
		    pci_name(ha->pdev));

		goto iospace_error_exit;
	}
	if (!(ha->bars & 1))
		goto skip_pio;

L
Linus Torvalds 已提交
1590 1591
	/* We only need PIO for Flash operations on ISP2312 v2 chips. */
	pio = pci_resource_start(ha->pdev, 0);
1592 1593
	if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) {
		if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) {
L
Linus Torvalds 已提交
1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604
			qla_printk(KERN_WARNING, ha,
			    "Invalid PCI I/O region size (%s)...\n",
				pci_name(ha->pdev));
			pio = 0;
		}
	} else {
		qla_printk(KERN_WARNING, ha,
		    "region #0 not a PIO resource (%s)...\n",
		    pci_name(ha->pdev));
		pio = 0;
	}
1605
	ha->pio_address = pio;
L
Linus Torvalds 已提交
1606

1607
skip_pio:
L
Linus Torvalds 已提交
1608
	/* Use MMIO operations for all accesses. */
1609
	if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) {
L
Linus Torvalds 已提交
1610
		qla_printk(KERN_ERR, ha,
1611
		    "region #1 not an MMIO resource (%s), aborting\n",
L
Linus Torvalds 已提交
1612 1613 1614
		    pci_name(ha->pdev));
		goto iospace_error_exit;
	}
1615
	if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) {
L
Linus Torvalds 已提交
1616 1617 1618 1619 1620 1621
		qla_printk(KERN_ERR, ha,
		    "Invalid PCI mem region size (%s), aborting\n",
			pci_name(ha->pdev));
		goto iospace_error_exit;
	}

1622
	ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN);
L
Linus Torvalds 已提交
1623 1624 1625 1626 1627 1628 1629
	if (!ha->iobase) {
		qla_printk(KERN_ERR, ha,
		    "cannot remap MMIO (%s), aborting\n", pci_name(ha->pdev));

		goto iospace_error_exit;
	}

1630 1631
	/* Determine queue resources */
	ha->max_queues = 1;
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
	if (ql2xmaxqueues <= 1 || !IS_QLA25XX(ha))
		goto mqiobase_exit;
	ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
			pci_resource_len(ha->pdev, 3));
	if (ha->mqiobase) {
		/* Read MSIX vector size of the board */
		pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix);
		ha->msix_count = msix;
		/* Max queues are bounded by available msix vectors */
		/* queue 0 uses two msix vectors */
		if (ha->msix_count - 1 < ql2xmaxqueues)
			ha->max_queues = ha->msix_count - 1;
		else if (ql2xmaxqueues > QLA_MQ_SIZE)
			ha->max_queues = QLA_MQ_SIZE;
		else
			ha->max_queues = ql2xmaxqueues;
		qla_printk(KERN_INFO, ha,
			"MSI-X vector count: %d\n", msix);
1650
	}
1651 1652

mqiobase_exit:
1653
	ha->msix_count = ha->max_queues + 1;
L
Linus Torvalds 已提交
1654 1655 1656 1657 1658 1659
	return (0);

iospace_error_exit:
	return (-ENOMEM);
}

1660 1661 1662
static void
qla2xxx_scan_start(struct Scsi_Host *shost)
{
1663
	scsi_qla_host_t *vha = shost_priv(shost);
1664

1665 1666 1667 1668
	set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
	set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
	set_bit(RSCN_UPDATE, &vha->dpc_flags);
	set_bit(NPIV_CONFIG_NEEDED, &vha->dpc_flags);
1669 1670 1671 1672 1673
}

static int
qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time)
{
1674
	scsi_qla_host_t *vha = shost_priv(shost);
1675

1676
	if (!vha->host)
1677
		return 1;
1678
	if (time > vha->hw->loop_reset_delay * HZ)
1679 1680
		return 1;

1681
	return atomic_read(&vha->loop_state) == LOOP_READY;
1682 1683
}

L
Linus Torvalds 已提交
1684 1685 1686
/*
 * PCI driver interface
 */
1687 1688
static int __devinit
qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
L
Linus Torvalds 已提交
1689
{
1690
	int	ret = -ENODEV;
L
Linus Torvalds 已提交
1691
	struct Scsi_Host *host;
1692 1693
	scsi_qla_host_t *base_vha = NULL;
	struct qla_hw_data *ha;
1694
	char pci_info[30];
L
Linus Torvalds 已提交
1695
	char fw_str[30];
1696
	struct scsi_host_template *sht;
1697
	int bars, max_id, mem_only = 0;
1698
	uint16_t req_length = 0, rsp_length = 0;
1699 1700
	struct req_que *req = NULL;
	struct rsp_que *rsp = NULL;
L
Linus Torvalds 已提交
1701

1702
	bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
1703 1704
	sht = &qla2x00_driver_template;
	if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
1705
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
1706
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
1707
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
1708
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
1709 1710
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) {
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
1711
		sht = &qla24xx_driver_template;
1712
		mem_only = 1;
1713 1714
	}

1715 1716 1717 1718 1719 1720 1721
	if (mem_only) {
		if (pci_enable_device_mem(pdev))
			goto probe_out;
	} else {
		if (pci_enable_device(pdev))
			goto probe_out;
	}
1722

1723 1724
	/* This may fail but that's ok */
	pci_enable_pcie_error_reporting(pdev);
1725

1726 1727 1728 1729
	ha = kzalloc(sizeof(struct qla_hw_data), GFP_KERNEL);
	if (!ha) {
		DEBUG(printk("Unable to allocate memory for ha\n"));
		goto probe_out;
L
Linus Torvalds 已提交
1730
	}
1731
	ha->pdev = pdev;
L
Linus Torvalds 已提交
1732 1733

	/* Clear our data area */
1734
	ha->bars = bars;
1735
	ha->mem_only = mem_only;
1736
	spin_lock_init(&ha->hardware_lock);
L
Linus Torvalds 已提交
1737

1738 1739
	/* Set ISP-type information. */
	qla2x00_set_isp_flags(ha);
L
Linus Torvalds 已提交
1740 1741
	/* Configure PCI I/O space */
	ret = qla2x00_iospace_config(ha);
1742
	if (ret)
1743
		goto probe_hw_failed;
L
Linus Torvalds 已提交
1744 1745

	qla_printk(KERN_INFO, ha,
1746 1747
	    "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq,
	    ha->iobase);
L
Linus Torvalds 已提交
1748 1749

	ha->prev_topology = 0;
1750
	ha->init_cb_size = sizeof(init_cb_t);
1751
	ha->link_data_rate = PORT_SPEED_UNKNOWN;
1752
	ha->optrom_size = OPTROM_SIZE_2300;
L
Linus Torvalds 已提交
1753

1754
	/* Assign ISP specific operations. */
1755
	max_id = MAX_TARGETS_2200;
L
Linus Torvalds 已提交
1756
	if (IS_QLA2100(ha)) {
1757
		max_id = MAX_TARGETS_2100;
L
Linus Torvalds 已提交
1758
		ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
1759 1760 1761
		req_length = REQUEST_ENTRY_CNT_2100;
		rsp_length = RESPONSE_ENTRY_CNT_2100;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
1762
		ha->gid_list_info_size = 4;
1763
		ha->isp_ops = &qla2100_isp_ops;
L
Linus Torvalds 已提交
1764 1765
	} else if (IS_QLA2200(ha)) {
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
1766 1767 1768
		req_length = REQUEST_ENTRY_CNT_2200;
		rsp_length = RESPONSE_ENTRY_CNT_2100;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
1769
		ha->gid_list_info_size = 4;
1770
		ha->isp_ops = &qla2100_isp_ops;
1771
	} else if (IS_QLA23XX(ha)) {
L
Linus Torvalds 已提交
1772
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
1773 1774 1775
		req_length = REQUEST_ENTRY_CNT_2200;
		rsp_length = RESPONSE_ENTRY_CNT_2300;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
1776
		ha->gid_list_info_size = 6;
1777 1778
		if (IS_QLA2322(ha) || IS_QLA6322(ha))
			ha->optrom_size = OPTROM_SIZE_2322;
1779
		ha->isp_ops = &qla2300_isp_ops;
1780
	} else if (IS_QLA24XX_TYPE(ha)) {
1781
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
1782 1783 1784
		req_length = REQUEST_ENTRY_CNT_24XX;
		rsp_length = RESPONSE_ENTRY_CNT_2300;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
1785
		ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
1786
		ha->gid_list_info_size = 8;
1787
		ha->optrom_size = OPTROM_SIZE_24XX;
1788
		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA24XX;
1789
		ha->isp_ops = &qla24xx_isp_ops;
1790 1791
	} else if (IS_QLA25XX(ha)) {
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
1792 1793 1794
		req_length = REQUEST_ENTRY_CNT_24XX;
		rsp_length = RESPONSE_ENTRY_CNT_2300;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
1795 1796 1797
		ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
		ha->gid_list_info_size = 8;
		ha->optrom_size = OPTROM_SIZE_25XX;
1798
		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
1799
		ha->isp_ops = &qla25xx_isp_ops;
L
Linus Torvalds 已提交
1800 1801
	}

1802
	mutex_init(&ha->vport_lock);
1803 1804 1805
	init_completion(&ha->mbx_cmd_comp);
	complete(&ha->mbx_cmd_comp);
	init_completion(&ha->mbx_intr_comp);
L
Linus Torvalds 已提交
1806

1807
	set_bit(0, (unsigned long *) ha->vp_idx_map);
L
Linus Torvalds 已提交
1808

1809
	ret = qla2x00_mem_alloc(ha, req_length, rsp_length, &req, &rsp);
1810
	if (!ret) {
L
Linus Torvalds 已提交
1811 1812 1813
		qla_printk(KERN_WARNING, ha,
		    "[ERROR] Failed to allocate memory for adapter\n");

1814 1815 1816
		goto probe_hw_failed;
	}

1817
	req->max_q_depth = MAX_Q_DEPTH;
1818
	if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU)
1819 1820
		req->max_q_depth = ql2xmaxqdepth;

1821 1822 1823 1824 1825 1826

	base_vha = qla2x00_create_host(sht, ha);
	if (!base_vha) {
		qla_printk(KERN_WARNING, ha,
		    "[ERROR] Failed to allocate memory for scsi_host\n");

1827
		ret = -ENOMEM;
1828
		goto probe_hw_failed;
L
Linus Torvalds 已提交
1829 1830
	}

1831 1832 1833 1834 1835
	pci_set_drvdata(pdev, base_vha);

	qla2x00_config_dma_addressing(base_vha);

	host = base_vha->host;
1836 1837 1838
	base_vha->req_ques[0] = req->id;
	host->can_queue = req->length + 128;
	if (IS_QLA2XXX_MIDTYPE(ha))
1839
		base_vha->mgmt_svr_loop_id = 10 + base_vha->vp_idx;
1840
	else
1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853
		base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER +
						base_vha->vp_idx;
	if (IS_QLA2100(ha))
		host->sg_tablesize = 32;
	host->max_id = max_id;
	host->this_id = 255;
	host->cmd_per_lun = 3;
	host->unique_id = host->host_no;
	host->max_cmd_len = MAX_CMDSZ;
	host->max_channel = MAX_BUSES - 1;
	host->max_lun = MAX_LUNS;
	host->transportt = qla2xxx_transport_template;

1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868
	/* Set up the irqs */
	ret = qla2x00_request_irqs(ha, rsp);
	if (ret)
		goto probe_failed;

	/* Alloc arrays of request and response ring ptrs */
	if (!qla2x00_alloc_queues(ha)) {
		qla_printk(KERN_WARNING, ha,
		"[ERROR] Failed to allocate memory for queue"
		" pointers\n");
		goto probe_failed;
	}
	ha->rsp_q_map[0] = rsp;
	ha->req_q_map[0] = req;

1869 1870 1871 1872 1873 1874
	if (ha->mqenable) {
		ha->isp_ops->wrt_req_reg = qla25xx_wrt_req_reg;
		ha->isp_ops->wrt_rsp_reg = qla25xx_wrt_rsp_reg;
		ha->isp_ops->rd_req_reg = qla25xx_rd_req_reg;
	}

1875
	if (qla2x00_initialize_adapter(base_vha)) {
L
Linus Torvalds 已提交
1876 1877 1878 1879 1880
		qla_printk(KERN_WARNING, ha,
		    "Failed to initialize adapter\n");

		DEBUG2(printk("scsi(%ld): Failed to initialize adapter - "
		    "Adapter flags %x.\n",
1881
		    base_vha->host_no, base_vha->device_flags));
L
Linus Torvalds 已提交
1882

1883
		ret = -ENODEV;
L
Linus Torvalds 已提交
1884 1885 1886 1887 1888 1889
		goto probe_failed;
	}

	/*
	 * Startup the kernel thread for this host adapter
	 */
1890
	ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha,
1891
			"%s_dpc", base_vha->host_str);
1892
	if (IS_ERR(ha->dpc_thread)) {
L
Linus Torvalds 已提交
1893 1894
		qla_printk(KERN_WARNING, ha,
		    "Unable to start DPC thread!\n");
1895
		ret = PTR_ERR(ha->dpc_thread);
L
Linus Torvalds 已提交
1896 1897 1898
		goto probe_failed;
	}

1899 1900
	list_add_tail(&base_vha->list, &ha->vp_list);
	base_vha->host->irq = ha->pdev->irq;
L
Linus Torvalds 已提交
1901 1902

	/* Initialized the timer */
1903
	qla2x00_start_timer(base_vha, qla2x00_timer, WATCH_INTERVAL);
L
Linus Torvalds 已提交
1904 1905

	DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n",
1906
	    base_vha->host_no, ha));
1907

1908 1909
	base_vha->flags.init_done = 1;
	base_vha->flags.online = 1;
1910

1911 1912 1913 1914
	ret = scsi_add_host(host, &pdev->dev);
	if (ret)
		goto probe_failed;

1915 1916
	ha->isp_ops->enable_intrs(ha);

1917 1918
	scsi_scan_host(host);

1919
	qla2x00_alloc_sysfs_attr(base_vha);
1920

1921
	qla2x00_init_host_attr(base_vha);
1922

1923
	qla2x00_dfs_setup(base_vha);
1924

L
Linus Torvalds 已提交
1925 1926 1927
	qla_printk(KERN_INFO, ha, "\n"
	    " QLogic Fibre Channel HBA Driver: %s\n"
	    "  QLogic %s - %s\n"
1928 1929
	    "  ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
	    qla2x00_version_str, ha->model_number,
1930 1931 1932 1933
	    ha->model_desc ? ha->model_desc : "", pdev->device,
	    ha->isp_ops->pci_info_str(base_vha, pci_info), pci_name(pdev),
	    ha->flags.enable_64bit_addressing ? '+' : '-', base_vha->host_no,
	    ha->isp_ops->fw_version_str(base_vha, fw_str));
L
Linus Torvalds 已提交
1934 1935 1936 1937

	return 0;

probe_failed:
1938
	qla2x00_free_que(ha, req, rsp);
1939
	qla2x00_free_device(base_vha);
L
Linus Torvalds 已提交
1940

1941
	scsi_host_put(base_vha->host);
L
Linus Torvalds 已提交
1942

1943 1944 1945 1946 1947 1948 1949
probe_hw_failed:
	if (ha->iobase)
		iounmap(ha->iobase);

	pci_release_selected_regions(ha->pdev, ha->bars);
	kfree(ha);
	ha = NULL;
L
Linus Torvalds 已提交
1950

1951
probe_out:
1952
	pci_disable_device(pdev);
1953
	return ret;
L
Linus Torvalds 已提交
1954 1955
}

A
Adrian Bunk 已提交
1956
static void
1957
qla2x00_remove_one(struct pci_dev *pdev)
L
Linus Torvalds 已提交
1958
{
1959 1960 1961 1962 1963 1964 1965 1966 1967 1968
	scsi_qla_host_t *base_vha, *vha, *temp;
	struct qla_hw_data  *ha;

	base_vha = pci_get_drvdata(pdev);
	ha = base_vha->hw;

	list_for_each_entry_safe(vha, temp, &ha->vp_list, list) {
		if (vha && vha->fc_vport)
			fc_vport_terminate(vha->fc_vport);
	}
L
Linus Torvalds 已提交
1969

1970
	set_bit(UNLOADING, &base_vha->dpc_flags);
L
Linus Torvalds 已提交
1971

1972
	qla2x00_dfs_remove(base_vha);
1973

1974
	qla84xx_put_chip(base_vha);
1975

1976
	qla2x00_free_sysfs_attr(base_vha);
1977

1978
	fc_remove_host(base_vha->host);
1979

1980
	scsi_remove_host(base_vha->host);
L
Linus Torvalds 已提交
1981

1982
	qla2x00_free_device(base_vha);
1983

1984
	scsi_host_put(base_vha->host);
L
Linus Torvalds 已提交
1985

1986 1987
	if (ha->iobase)
		iounmap(ha->iobase);
L
Linus Torvalds 已提交
1988

1989 1990 1991
	if (ha->mqiobase)
		iounmap(ha->mqiobase);

1992 1993 1994
	pci_release_selected_regions(ha->pdev, ha->bars);
	kfree(ha);
	ha = NULL;
L
Linus Torvalds 已提交
1995

1996
	pci_disable_device(pdev);
L
Linus Torvalds 已提交
1997 1998 1999 2000
	pci_set_drvdata(pdev, NULL);
}

static void
2001
qla2x00_free_device(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
2002
{
2003 2004
	struct qla_hw_data *ha = vha->hw;
	qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
2005

L
Linus Torvalds 已提交
2006
	/* Disable timer */
2007 2008
	if (vha->timer_active)
		qla2x00_stop_timer(vha);
L
Linus Torvalds 已提交
2009

2010
	vha->flags.online = 0;
2011

L
Linus Torvalds 已提交
2012
	/* Kill the kernel thread for this host */
2013 2014
	if (ha->dpc_thread) {
		struct task_struct *t = ha->dpc_thread;
L
Linus Torvalds 已提交
2015

2016 2017 2018 2019 2020 2021
		/*
		 * qla2xxx_wake_dpc checks for ->dpc_thread
		 * so we need to zero it out.
		 */
		ha->dpc_thread = NULL;
		kthread_stop(t);
L
Linus Torvalds 已提交
2022 2023
	}

2024
	if (ha->flags.fce_enabled)
2025
		qla2x00_disable_fce_trace(vha, NULL, NULL);
2026

2027
	if (ha->eft)
2028
		qla2x00_disable_eft_trace(vha);
2029

2030
	/* Stop currently executing firmware. */
2031
	qla2x00_try_to_stop_firmware(vha);
L
Linus Torvalds 已提交
2032

2033 2034
	/* turn-off interrupts on the card */
	if (ha->interrupts_on)
2035
		ha->isp_ops->disable_intrs(ha);
2036

2037
	qla2x00_free_irqs(vha);
L
Linus Torvalds 已提交
2038

2039
	qla2x00_mem_free(ha);
2040 2041

	qla2x00_free_queues(ha);
L
Linus Torvalds 已提交
2042 2043
}

2044
static inline void
2045
qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
2046 2047 2048 2049 2050 2051 2052 2053 2054
    int defer)
{
	struct fc_rport *rport;

	if (!fcport->rport)
		return;

	rport = fcport->rport;
	if (defer) {
2055
		spin_lock_irq(vha->host->host_lock);
2056
		fcport->drport = rport;
2057 2058 2059
		spin_unlock_irq(vha->host->host_lock);
		set_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags);
		qla2xxx_wake_dpc(vha);
2060
	} else
2061 2062 2063
		fc_remote_port_delete(rport);
}

L
Linus Torvalds 已提交
2064 2065 2066 2067 2068 2069 2070 2071 2072
/*
 * qla2x00_mark_device_lost Updates fcport state when device goes offline.
 *
 * Input: ha = adapter block pointer.  fcport = port structure pointer.
 *
 * Return: None.
 *
 * Context:
 */
2073
void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
2074
    int do_login, int defer)
L
Linus Torvalds 已提交
2075
{
2076
	if (atomic_read(&fcport->state) == FCS_ONLINE &&
2077 2078 2079 2080
	    vha->vp_idx == fcport->vp_idx) {
		atomic_set(&fcport->state, FCS_DEVICE_LOST);
		qla2x00_schedule_rport_del(vha, fcport, defer);
	}
A
Andrew Vasquez 已提交
2081
	/*
L
Linus Torvalds 已提交
2082 2083 2084 2085 2086 2087 2088 2089 2090 2091
	 * We may need to retry the login, so don't change the state of the
	 * port but do the retries.
	 */
	if (atomic_read(&fcport->state) != FCS_DEVICE_DEAD)
		atomic_set(&fcport->state, FCS_DEVICE_LOST);

	if (!do_login)
		return;

	if (fcport->login_retry == 0) {
2092 2093
		fcport->login_retry = vha->hw->login_retry_count;
		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
L
Linus Torvalds 已提交
2094 2095 2096 2097

		DEBUG(printk("scsi(%ld): Port login retry: "
		    "%02x%02x%02x%02x%02x%02x%02x%02x, "
		    "id = 0x%04x retry cnt=%d\n",
2098
		    vha->host_no,
L
Linus Torvalds 已提交
2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125
		    fcport->port_name[0],
		    fcport->port_name[1],
		    fcport->port_name[2],
		    fcport->port_name[3],
		    fcport->port_name[4],
		    fcport->port_name[5],
		    fcport->port_name[6],
		    fcport->port_name[7],
		    fcport->loop_id,
		    fcport->login_retry));
	}
}

/*
 * qla2x00_mark_all_devices_lost
 *	Updates fcport state when device goes offline.
 *
 * Input:
 *	ha = adapter block pointer.
 *	fcport = port structure pointer.
 *
 * Return:
 *	None.
 *
 * Context:
 */
void
2126
qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
L
Linus Torvalds 已提交
2127 2128 2129
{
	fc_port_t *fcport;

2130 2131
	list_for_each_entry(fcport, &vha->vp_fcports, list) {
		if (vha->vp_idx != fcport->vp_idx)
L
Linus Torvalds 已提交
2132 2133 2134 2135 2136 2137 2138
			continue;
		/*
		 * No point in marking the device as lost, if the device is
		 * already DEAD.
		 */
		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
			continue;
2139 2140 2141 2142 2143
		if (atomic_read(&fcport->state) == FCS_ONLINE) {
			atomic_set(&fcport->state, FCS_DEVICE_LOST);
			qla2x00_schedule_rport_del(vha, fcport, defer);
		} else
			atomic_set(&fcport->state, FCS_DEVICE_LOST);
L
Linus Torvalds 已提交
2144 2145 2146 2147 2148 2149 2150 2151 2152
	}
}

/*
* qla2x00_mem_alloc
*      Allocates adapter memory.
*
* Returns:
*      0  = success.
2153
*      !0  = failure.
L
Linus Torvalds 已提交
2154
*/
2155
static int
2156 2157
qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
	struct req_que **req, struct rsp_que **rsp)
L
Linus Torvalds 已提交
2158 2159 2160
{
	char	name[16];

2161 2162 2163
	ha->init_cb_size = sizeof(init_cb_t);
	if (IS_QLA2XXX_MIDTYPE(ha))
		ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
2164 2165

	ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
2166
		&ha->init_cb_dma, GFP_KERNEL);
2167
	if (!ha->init_cb)
2168
		goto fail;
2169

2170 2171 2172
	ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
		&ha->gid_list_dma, GFP_KERNEL);
	if (!ha->gid_list)
2173
		goto fail_free_init_cb;
L
Linus Torvalds 已提交
2174

2175 2176
	ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
	if (!ha->srb_mempool)
2177
		goto fail_free_gid_list;
2178 2179 2180 2181 2182 2183

	/* Get memory for cached NVRAM */
	ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
	if (!ha->nvram)
		goto fail_free_srb_mempool;

2184 2185 2186 2187 2188 2189 2190
	snprintf(name, sizeof(name), "%s_%d", QLA2XXX_DRIVER_NAME,
		ha->pdev->device);
	ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
		DMA_POOL_SIZE, 8, 0);
	if (!ha->s_dma_pool)
		goto fail_free_nvram;

2191 2192
	/* Allocate memory for SNS commands */
	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
2193
	/* Get consistent memory allocated for SNS commands */
2194
		ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
2195
		sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, GFP_KERNEL);
2196
		if (!ha->sns_cmd)
2197
			goto fail_dma_pool;
2198
	} else {
2199
	/* Get consistent memory allocated for MS IOCB */
2200
		ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
2201
			&ha->ms_iocb_dma);
2202
		if (!ha->ms_iocb)
2203 2204
			goto fail_dma_pool;
	/* Get consistent memory allocated for CT SNS commands */
2205
		ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
2206
			sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL);
2207 2208
		if (!ha->ct_sns)
			goto fail_free_ms_iocb;
L
Linus Torvalds 已提交
2209 2210
	}

2211
	/* Allocate memory for request ring */
2212 2213
	*req = kzalloc(sizeof(struct req_que), GFP_KERNEL);
	if (!*req) {
2214 2215 2216
		DEBUG(printk("Unable to allocate memory for req\n"));
		goto fail_req;
	}
2217 2218 2219 2220 2221
	(*req)->length = req_len;
	(*req)->ring = dma_alloc_coherent(&ha->pdev->dev,
		((*req)->length + 1) * sizeof(request_t),
		&(*req)->dma, GFP_KERNEL);
	if (!(*req)->ring) {
2222 2223 2224 2225
		DEBUG(printk("Unable to allocate memory for req_ring\n"));
		goto fail_req_ring;
	}
	/* Allocate memory for response ring */
2226 2227 2228 2229
	*rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL);
	if (!*rsp) {
		qla_printk(KERN_WARNING, ha,
			"Unable to allocate memory for rsp\n");
2230 2231
		goto fail_rsp;
	}
2232 2233 2234 2235 2236 2237 2238 2239
	(*rsp)->hw = ha;
	(*rsp)->length = rsp_len;
	(*rsp)->ring = dma_alloc_coherent(&ha->pdev->dev,
		((*rsp)->length + 1) * sizeof(response_t),
		&(*rsp)->dma, GFP_KERNEL);
	if (!(*rsp)->ring) {
		qla_printk(KERN_WARNING, ha,
			"Unable to allocate memory for rsp_ring\n");
2240 2241
		goto fail_rsp_ring;
	}
2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254
	(*req)->rsp = *rsp;
	(*rsp)->req = *req;
	/* Allocate memory for NVRAM data for vports */
	if (ha->nvram_npiv_size) {
		ha->npiv_info = kzalloc(sizeof(struct qla_npiv_entry) *
					ha->nvram_npiv_size, GFP_KERNEL);
		if (!ha->npiv_info) {
			qla_printk(KERN_WARNING, ha,
				"Unable to allocate memory for npiv info\n");
			goto fail_npiv_info;
		}
	} else
		ha->npiv_info = NULL;
2255

2256 2257 2258
	INIT_LIST_HEAD(&ha->vp_list);
	return 1;

2259 2260 2261 2262 2263
fail_npiv_info:
	dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) *
		sizeof(response_t), (*rsp)->ring, (*rsp)->dma);
	(*rsp)->ring = NULL;
	(*rsp)->dma = 0;
2264
fail_rsp_ring:
2265
	kfree(*rsp);
2266
fail_rsp:
2267 2268 2269 2270
	dma_free_coherent(&ha->pdev->dev, ((*req)->length + 1) *
		sizeof(request_t), (*req)->ring, (*req)->dma);
	(*req)->ring = NULL;
	(*req)->dma = 0;
2271
fail_req_ring:
2272
	kfree(*req);
2273 2274 2275 2276 2277
fail_req:
	dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt),
		ha->ct_sns, ha->ct_sns_dma);
	ha->ct_sns = NULL;
	ha->ct_sns_dma = 0;
2278 2279 2280 2281
fail_free_ms_iocb:
	dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
	ha->ms_iocb = NULL;
	ha->ms_iocb_dma = 0;
2282 2283 2284
fail_dma_pool:
	dma_pool_destroy(ha->s_dma_pool);
	ha->s_dma_pool = NULL;
2285 2286 2287 2288 2289 2290 2291 2292
fail_free_nvram:
	kfree(ha->nvram);
	ha->nvram = NULL;
fail_free_srb_mempool:
	mempool_destroy(ha->srb_mempool);
	ha->srb_mempool = NULL;
fail_free_gid_list:
	dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
2293
	ha->gid_list_dma);
2294 2295
	ha->gid_list = NULL;
	ha->gid_list_dma = 0;
2296 2297 2298 2299 2300
fail_free_init_cb:
	dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb,
	ha->init_cb_dma);
	ha->init_cb = NULL;
	ha->init_cb_dma = 0;
2301
fail:
2302
	DEBUG(printk("%s: Memory allocation failure\n", __func__));
2303
	return -ENOMEM;
L
Linus Torvalds 已提交
2304 2305 2306 2307 2308 2309 2310 2311 2312
}

/*
* qla2x00_mem_free
*      Frees all adapter allocated memory.
*
* Input:
*      ha = adapter block pointer.
*/
A
Adrian Bunk 已提交
2313
static void
2314
qla2x00_mem_free(struct qla_hw_data *ha)
L
Linus Torvalds 已提交
2315
{
2316 2317
	if (ha->srb_mempool)
		mempool_destroy(ha->srb_mempool);
L
Linus Torvalds 已提交
2318

2319 2320
	if (ha->fce)
		dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
2321
		ha->fce_dma);
2322

2323 2324 2325
	if (ha->fw_dump) {
		if (ha->eft)
			dma_free_coherent(&ha->pdev->dev,
2326
			ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma);
2327 2328 2329
		vfree(ha->fw_dump);
	}

L
Linus Torvalds 已提交
2330 2331
	if (ha->sns_cmd)
		dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),
2332
		ha->sns_cmd, ha->sns_cmd_dma);
L
Linus Torvalds 已提交
2333 2334 2335

	if (ha->ct_sns)
		dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt),
2336
		ha->ct_sns, ha->ct_sns_dma);
L
Linus Torvalds 已提交
2337

2338 2339 2340
	if (ha->sfp_data)
		dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);

L
Linus Torvalds 已提交
2341 2342 2343 2344 2345 2346
	if (ha->ms_iocb)
		dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);

	if (ha->s_dma_pool)
		dma_pool_destroy(ha->s_dma_pool);

2347

L
Linus Torvalds 已提交
2348 2349
	if (ha->gid_list)
		dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
2350
		ha->gid_list_dma);
L
Linus Torvalds 已提交
2351 2352


2353 2354 2355 2356 2357
	if (ha->init_cb)
		dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
		ha->init_cb, ha->init_cb_dma);
	vfree(ha->optrom_buffer);
	kfree(ha->nvram);
2358
	kfree(ha->npiv_info);
L
Linus Torvalds 已提交
2359

2360
	ha->srb_mempool = NULL;
2361 2362
	ha->eft = NULL;
	ha->eft_dma = 0;
L
Linus Torvalds 已提交
2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
	ha->sns_cmd = NULL;
	ha->sns_cmd_dma = 0;
	ha->ct_sns = NULL;
	ha->ct_sns_dma = 0;
	ha->ms_iocb = NULL;
	ha->ms_iocb_dma = 0;
	ha->init_cb = NULL;
	ha->init_cb_dma = 0;

	ha->s_dma_pool = NULL;

	ha->gid_list = NULL;
	ha->gid_list_dma = 0;

2377 2378 2379 2380
	ha->fw_dump = NULL;
	ha->fw_dumped = 0;
	ha->fw_dump_reading = 0;
}
L
Linus Torvalds 已提交
2381

2382 2383 2384 2385 2386
struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
						struct qla_hw_data *ha)
{
	struct Scsi_Host *host;
	struct scsi_qla_host *vha = NULL;
2387

2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411
	host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
	if (host == NULL) {
		printk(KERN_WARNING
		"qla2xxx: Couldn't allocate host from scsi layer!\n");
		goto fail;
	}

	/* Clear our data area */
	vha = shost_priv(host);
	memset(vha, 0, sizeof(scsi_qla_host_t));

	vha->host = host;
	vha->host_no = host->host_no;
	vha->hw = ha;

	INIT_LIST_HEAD(&vha->vp_fcports);
	INIT_LIST_HEAD(&vha->work_list);
	INIT_LIST_HEAD(&vha->list);

	sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no);
	return vha;

fail:
	return vha;
L
Linus Torvalds 已提交
2412 2413
}

2414
static struct qla_work_evt *
2415
qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type,
2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430
    int locked)
{
	struct qla_work_evt *e;

	e = kzalloc(sizeof(struct qla_work_evt), locked ? GFP_ATOMIC:
	    GFP_KERNEL);
	if (!e)
		return NULL;

	INIT_LIST_HEAD(&e->list);
	e->type = type;
	e->flags = QLA_EVT_FLAG_FREE;
	return e;
}

2431
static int
2432
qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e, int locked)
2433
{
2434
	unsigned long uninitialized_var(flags);
2435
	struct qla_hw_data *ha = vha->hw;
2436 2437

	if (!locked)
2438 2439 2440
		spin_lock_irqsave(&ha->hardware_lock, flags);
	list_add_tail(&e->list, &vha->work_list);
	qla2xxx_wake_dpc(vha);
2441
	if (!locked)
2442
		spin_unlock_irqrestore(&ha->hardware_lock, flags);
2443 2444 2445 2446
	return QLA_SUCCESS;
}

int
2447
qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code,
2448 2449 2450 2451
    u32 data)
{
	struct qla_work_evt *e;

2452
	e = qla2x00_alloc_work(vha, QLA_EVT_AEN, 1);
2453 2454 2455 2456 2457
	if (!e)
		return QLA_FUNCTION_FAILED;

	e->u.aen.code = code;
	e->u.aen.data = data;
2458
	return qla2x00_post_work(vha, e, 1);
2459 2460 2461
}

static void
2462
qla2x00_do_work(struct scsi_qla_host *vha)
2463 2464
{
	struct qla_work_evt *e;
2465
	struct qla_hw_data *ha = vha->hw;
2466

2467 2468 2469
	spin_lock_irq(&ha->hardware_lock);
	while (!list_empty(&vha->work_list)) {
		e = list_entry(vha->work_list.next, struct qla_work_evt, list);
2470
		list_del_init(&e->list);
2471
		spin_unlock_irq(&ha->hardware_lock);
2472 2473 2474

		switch (e->type) {
		case QLA_EVT_AEN:
2475
			fc_host_post_event(vha->host, fc_get_event_number(),
2476 2477 2478 2479 2480
			    e->u.aen.code, e->u.aen.data);
			break;
		}
		if (e->flags & QLA_EVT_FLAG_FREE)
			kfree(e);
2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541
		spin_lock_irq(&ha->hardware_lock);
	}
	spin_unlock_irq(&ha->hardware_lock);
}
/* Relogins all the fcports of a vport
 * Context: dpc thread
 */
void qla2x00_relogin(struct scsi_qla_host *vha)
{
	fc_port_t       *fcport;
	uint8_t         status;
	uint16_t        next_loopid = 0;
	struct qla_hw_data *ha = vha->hw;

	list_for_each_entry(fcport, &vha->vp_fcports, list) {
	/*
	 * If the port is not ONLINE then try to login
	 * to it if we haven't run out of retries.
	 */
		if (atomic_read(&fcport->state) !=
			FCS_ONLINE && fcport->login_retry) {

			if (fcport->flags & FCF_FABRIC_DEVICE) {
				if (fcport->flags & FCF_TAPE_PRESENT)
					ha->isp_ops->fabric_logout(vha,
							fcport->loop_id,
							fcport->d_id.b.domain,
							fcport->d_id.b.area,
							fcport->d_id.b.al_pa);

				status = qla2x00_fabric_login(vha, fcport,
							&next_loopid);
			} else
				status = qla2x00_local_device_login(vha,
								fcport);

			fcport->login_retry--;
			if (status == QLA_SUCCESS) {
				fcport->old_loop_id = fcport->loop_id;

				DEBUG(printk("scsi(%ld): port login OK: logged "
				"in ID 0x%x\n", vha->host_no, fcport->loop_id));

				qla2x00_update_fcport(vha, fcport);

			} else if (status == 1) {
				set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
				/* retry the login again */
				DEBUG(printk("scsi(%ld): Retrying"
				" %d login again loop_id 0x%x\n",
				vha->host_no, fcport->login_retry,
						fcport->loop_id));
			} else {
				fcport->login_retry = 0;
			}

			if (fcport->login_retry == 0 && status != QLA_SUCCESS)
				fcport->loop_id = FC_NO_LOOP_ID;
		}
		if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
			break;
2542 2543 2544
	}
}

L
Linus Torvalds 已提交
2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560
/**************************************************************************
* qla2x00_do_dpc
*   This kernel thread is a task that is schedule by the interrupt handler
*   to perform the background processing for interrupts.
*
* Notes:
* This task always run in the context of a kernel thread.  It
* is kick-off by the driver's detect code and starts up
* up one per adapter. It immediately goes to sleep and waits for
* some fibre event.  When either the interrupt handler or
* the timer routine detects a event it will one of the task
* bits then wake us up.
**************************************************************************/
static int
qla2x00_do_dpc(void *data)
{
2561
	int		rval;
2562 2563
	scsi_qla_host_t *base_vha;
	struct qla_hw_data *ha;
L
Linus Torvalds 已提交
2564

2565 2566
	ha = (struct qla_hw_data *)data;
	base_vha = pci_get_drvdata(ha->pdev);
L
Linus Torvalds 已提交
2567 2568 2569

	set_user_nice(current, -20);

2570
	while (!kthread_should_stop()) {
L
Linus Torvalds 已提交
2571 2572
		DEBUG3(printk("qla2x00: DPC handler sleeping\n"));

2573 2574 2575
		set_current_state(TASK_INTERRUPTIBLE);
		schedule();
		__set_current_state(TASK_RUNNING);
L
Linus Torvalds 已提交
2576 2577 2578 2579

		DEBUG3(printk("qla2x00: DPC handler waking up\n"));

		/* Initialization not yet finished. Don't do anything yet. */
2580
		if (!base_vha->flags.init_done)
L
Linus Torvalds 已提交
2581 2582
			continue;

2583
		DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no));
L
Linus Torvalds 已提交
2584 2585 2586 2587 2588 2589 2590 2591

		ha->dpc_active = 1;

		if (ha->flags.mbox_busy) {
			ha->dpc_active = 0;
			continue;
		}

2592
		qla2x00_do_work(base_vha);
2593

2594 2595
		if (test_and_clear_bit(ISP_ABORT_NEEDED,
						&base_vha->dpc_flags)) {
L
Linus Torvalds 已提交
2596 2597 2598

			DEBUG(printk("scsi(%ld): dpc: sched "
			    "qla2x00_abort_isp ha = %p\n",
2599
			    base_vha->host_no, ha));
L
Linus Torvalds 已提交
2600
			if (!(test_and_set_bit(ABORT_ISP_ACTIVE,
2601
			    &base_vha->dpc_flags))) {
L
Linus Torvalds 已提交
2602

2603
				if (qla2x00_abort_isp(base_vha)) {
L
Linus Torvalds 已提交
2604 2605
					/* failed. retry later */
					set_bit(ISP_ABORT_NEEDED,
2606
					    &base_vha->dpc_flags);
2607
				}
2608 2609
				clear_bit(ABORT_ISP_ACTIVE,
						&base_vha->dpc_flags);
2610 2611
			}

L
Linus Torvalds 已提交
2612
			DEBUG(printk("scsi(%ld): dpc: qla2x00_abort_isp end\n",
2613
			    base_vha->host_no));
L
Linus Torvalds 已提交
2614 2615
		}

2616 2617 2618
		if (test_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags)) {
			qla2x00_update_fcports(base_vha);
			clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
2619
		}
2620

2621 2622 2623
		if (test_and_clear_bit(RESET_MARKER_NEEDED,
							&base_vha->dpc_flags) &&
		    (!(test_and_set_bit(RESET_ACTIVE, &base_vha->dpc_flags)))) {
L
Linus Torvalds 已提交
2624 2625

			DEBUG(printk("scsi(%ld): qla2x00_reset_marker()\n",
2626
			    base_vha->host_no));
L
Linus Torvalds 已提交
2627

2628 2629
			qla2x00_rst_aen(base_vha);
			clear_bit(RESET_ACTIVE, &base_vha->dpc_flags);
L
Linus Torvalds 已提交
2630 2631 2632
		}

		/* Retry each device up to login retry count */
2633 2634 2635 2636
		if ((test_and_clear_bit(RELOGIN_NEEDED,
						&base_vha->dpc_flags)) &&
		    !test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags) &&
		    atomic_read(&base_vha->loop_state) != LOOP_DOWN) {
L
Linus Torvalds 已提交
2637 2638

			DEBUG(printk("scsi(%ld): qla2x00_port_login()\n",
2639 2640 2641
					base_vha->host_no));
			qla2x00_relogin(base_vha);

L
Linus Torvalds 已提交
2642
			DEBUG(printk("scsi(%ld): qla2x00_port_login - end\n",
2643
			    base_vha->host_no));
L
Linus Torvalds 已提交
2644 2645
		}

2646 2647
		if (test_and_clear_bit(LOOP_RESYNC_NEEDED,
							&base_vha->dpc_flags)) {
L
Linus Torvalds 已提交
2648 2649

			DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n",
2650
				base_vha->host_no));
L
Linus Torvalds 已提交
2651 2652

			if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE,
2653
			    &base_vha->dpc_flags))) {
L
Linus Torvalds 已提交
2654

2655
				rval = qla2x00_loop_resync(base_vha);
L
Linus Torvalds 已提交
2656

2657 2658
				clear_bit(LOOP_RESYNC_ACTIVE,
						&base_vha->dpc_flags);
L
Linus Torvalds 已提交
2659 2660 2661
			}

			DEBUG(printk("scsi(%ld): qla2x00_loop_resync - end\n",
2662
			    base_vha->host_no));
L
Linus Torvalds 已提交
2663 2664
		}

2665 2666 2667 2668
		if (test_bit(NPIV_CONFIG_NEEDED, &base_vha->dpc_flags) &&
		    atomic_read(&base_vha->loop_state) == LOOP_READY) {
			clear_bit(NPIV_CONFIG_NEEDED, &base_vha->dpc_flags);
			qla2xxx_flash_npiv_conf(base_vha);
2669 2670
		}

L
Linus Torvalds 已提交
2671
		if (!ha->interrupts_on)
2672
			ha->isp_ops->enable_intrs(ha);
L
Linus Torvalds 已提交
2673

2674 2675 2676
		if (test_and_clear_bit(BEACON_BLINK_NEEDED,
					&base_vha->dpc_flags))
			ha->isp_ops->beacon_blink(base_vha);
2677

2678
		qla2x00_do_dpc_all_vps(base_vha);
2679

L
Linus Torvalds 已提交
2680 2681 2682
		ha->dpc_active = 0;
	} /* End of while(1) */

2683
	DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no));
L
Linus Torvalds 已提交
2684 2685 2686 2687 2688 2689

	/*
	 * Make sure that nobody tries to wake us up again.
	 */
	ha->dpc_active = 0;

2690 2691 2692 2693
	return 0;
}

void
2694
qla2xxx_wake_dpc(struct scsi_qla_host *vha)
2695
{
2696
	struct qla_hw_data *ha = vha->hw;
2697 2698
	struct task_struct *t = ha->dpc_thread;

2699
	if (!test_bit(UNLOADING, &vha->dpc_flags) && t)
2700
		wake_up_process(t);
L
Linus Torvalds 已提交
2701 2702 2703 2704 2705 2706 2707 2708 2709 2710
}

/*
*  qla2x00_rst_aen
*      Processes asynchronous reset.
*
* Input:
*      ha  = adapter block pointer.
*/
static void
2711
qla2x00_rst_aen(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
2712
{
2713 2714 2715
	if (vha->flags.online && !vha->flags.reset_active &&
	    !atomic_read(&vha->loop_down_timer) &&
	    !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))) {
L
Linus Torvalds 已提交
2716
		do {
2717
			clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
L
Linus Torvalds 已提交
2718 2719 2720 2721 2722

			/*
			 * Issue marker command only when we are going to start
			 * the I/O.
			 */
2723 2724 2725
			vha->marker_needed = 1;
		} while (!atomic_read(&vha->loop_down_timer) &&
		    (test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags)));
L
Linus Torvalds 已提交
2726 2727 2728
	}
}

已提交
2729
static void
2730
qla2x00_sp_free_dma(srb_t *sp)
已提交
2731 2732 2733 2734
{
	struct scsi_cmnd *cmd = sp->cmd;

	if (sp->flags & SRB_DMA_VALID) {
2735
		scsi_dma_unmap(cmd);
已提交
2736 2737
		sp->flags &= ~SRB_DMA_VALID;
	}
2738
	CMD_SP(cmd) = NULL;
已提交
2739 2740 2741
}

void
2742
qla2x00_sp_compl(struct qla_hw_data *ha, srb_t *sp)
已提交
2743 2744 2745
{
	struct scsi_cmnd *cmd = sp->cmd;

2746
	qla2x00_sp_free_dma(sp);
已提交
2747 2748 2749 2750 2751

	mempool_free(sp, ha->srb_mempool);

	cmd->scsi_done(cmd);
}
2752

L
Linus Torvalds 已提交
2753 2754 2755 2756 2757 2758 2759 2760
/**************************************************************************
*   qla2x00_timer
*
* Description:
*   One second timer
*
* Context: Interrupt
***************************************************************************/
2761
void
2762
qla2x00_timer(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
2763 2764 2765 2766 2767 2768
{
	unsigned long	cpu_flags = 0;
	fc_port_t	*fcport;
	int		start_dpc = 0;
	int		index;
	srb_t		*sp;
已提交
2769
	int		t;
2770
	struct qla_hw_data *ha = vha->hw;
2771
	struct req_que *req;
L
Linus Torvalds 已提交
2772 2773 2774 2775 2776
	/*
	 * Ports - Port down timer.
	 *
	 * Whenever, a port is in the LOST state we start decrementing its port
	 * down timer every second until it reaches zero. Once  it reaches zero
A
Andrew Vasquez 已提交
2777
	 * the port it marked DEAD.
L
Linus Torvalds 已提交
2778 2779
	 */
	t = 0;
2780
	list_for_each_entry(fcport, &vha->vp_fcports, list) {
L
Linus Torvalds 已提交
2781 2782 2783 2784 2785 2786 2787 2788
		if (fcport->port_type != FCT_TARGET)
			continue;

		if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {

			if (atomic_read(&fcport->port_down_timer) == 0)
				continue;

A
Andrew Vasquez 已提交
2789
			if (atomic_dec_and_test(&fcport->port_down_timer) != 0)
L
Linus Torvalds 已提交
2790
				atomic_set(&fcport->state, FCS_DEVICE_DEAD);
A
Andrew Vasquez 已提交
2791

L
Linus Torvalds 已提交
2792
			DEBUG(printk("scsi(%ld): fcport-%d - port retry count: "
2793
			    "%d remaining\n",
2794
			    vha->host_no,
L
Linus Torvalds 已提交
2795 2796 2797 2798 2799 2800 2801
			    t, atomic_read(&fcport->port_down_timer)));
		}
		t++;
	} /* End of for fcport  */


	/* Loop down handler. */
2802 2803 2804
	if (atomic_read(&vha->loop_down_timer) > 0 &&
	    !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
		&& vha->flags.online) {
L
Linus Torvalds 已提交
2805

2806 2807
		if (atomic_read(&vha->loop_down_timer) ==
		    vha->loop_down_abort_time) {
L
Linus Torvalds 已提交
2808 2809 2810

			DEBUG(printk("scsi(%ld): Loop Down - aborting the "
			    "queues before time expire\n",
2811
			    vha->host_no));
L
Linus Torvalds 已提交
2812

2813 2814
			if (!IS_QLA2100(ha) && vha->link_down_timeout)
				atomic_set(&vha->loop_state, LOOP_DEAD);
L
Linus Torvalds 已提交
2815 2816

			/* Schedule an ISP abort to return any tape commands. */
2817
			/* NPIV - scan physical port only */
2818
			if (!vha->vp_idx) {
2819 2820
				spin_lock_irqsave(&ha->hardware_lock,
				    cpu_flags);
2821
				req = ha->req_q_map[0];
2822 2823 2824 2825 2826
				for (index = 1;
				    index < MAX_OUTSTANDING_COMMANDS;
				    index++) {
					fc_port_t *sfcp;

2827
					sp = req->outstanding_cmds[index];
2828 2829 2830 2831 2832
					if (!sp)
						continue;
					sfcp = sp->fcport;
					if (!(sfcp->flags & FCF_TAPE_PRESENT))
						continue;
2833

2834
					set_bit(ISP_ABORT_NEEDED,
2835
							&vha->dpc_flags);
2836 2837 2838
					break;
				}
				spin_unlock_irqrestore(&ha->hardware_lock,
2839
								cpu_flags);
L
Linus Torvalds 已提交
2840
			}
2841
			set_bit(ABORT_QUEUES_NEEDED, &vha->dpc_flags);
L
Linus Torvalds 已提交
2842 2843 2844 2845
			start_dpc++;
		}

		/* if the loop has been down for 4 minutes, reinit adapter */
2846
		if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
L
Linus Torvalds 已提交
2847 2848
			DEBUG(printk("scsi(%ld): Loop down exceed 4 mins - "
			    "restarting queues.\n",
2849
			    vha->host_no));
L
Linus Torvalds 已提交
2850

2851
			set_bit(RESTART_QUEUES_NEEDED, &vha->dpc_flags);
L
Linus Torvalds 已提交
2852 2853
			start_dpc++;

2854 2855
			if (!(vha->device_flags & DFLG_NO_CABLE) &&
			    !vha->vp_idx) {
L
Linus Torvalds 已提交
2856 2857
				DEBUG(printk("scsi(%ld): Loop down - "
				    "aborting ISP.\n",
2858
				    vha->host_no));
L
Linus Torvalds 已提交
2859 2860 2861
				qla_printk(KERN_WARNING, ha,
				    "Loop down - aborting ISP.\n");

2862
				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
L
Linus Torvalds 已提交
2863 2864
			}
		}
2865
		DEBUG3(printk("scsi(%ld): Loop Down - seconds remaining %d\n",
2866 2867
		    vha->host_no,
		    atomic_read(&vha->loop_down_timer)));
L
Linus Torvalds 已提交
2868 2869
	}

2870 2871
	/* Check if beacon LED needs to be blinked */
	if (ha->beacon_blink_led == 1) {
2872
		set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags);
2873 2874 2875
		start_dpc++;
	}

2876
	/* Process any deferred work. */
2877
	if (!list_empty(&vha->work_list))
2878 2879
		start_dpc++;

L
Linus Torvalds 已提交
2880
	/* Schedule the DPC routine if needed */
2881 2882 2883
	if ((test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
	    test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) ||
	    test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags) ||
L
Linus Torvalds 已提交
2884
	    start_dpc ||
2885 2886 2887 2888 2889
	    test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) ||
	    test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags) ||
	    test_bit(VP_DPC_NEEDED, &vha->dpc_flags) ||
	    test_bit(RELOGIN_NEEDED, &vha->dpc_flags)))
		qla2xxx_wake_dpc(vha);
L
Linus Torvalds 已提交
2890

2891
	qla2x00_restart_timer(vha, WATCH_INTERVAL);
L
Linus Torvalds 已提交
2892 2893
}

2894 2895
/* Firmware interface routines. */

2896
#define FW_BLOBS	6
2897 2898 2899 2900
#define FW_ISP21XX	0
#define FW_ISP22XX	1
#define FW_ISP2300	2
#define FW_ISP2322	3
2901
#define FW_ISP24XX	4
2902
#define FW_ISP25XX	5
2903

2904 2905 2906 2907 2908
#define FW_FILE_ISP21XX	"ql2100_fw.bin"
#define FW_FILE_ISP22XX	"ql2200_fw.bin"
#define FW_FILE_ISP2300	"ql2300_fw.bin"
#define FW_FILE_ISP2322	"ql2322_fw.bin"
#define FW_FILE_ISP24XX	"ql2400_fw.bin"
2909
#define FW_FILE_ISP25XX	"ql2500_fw.bin"
2910

2911
static DEFINE_MUTEX(qla_fw_lock);
2912 2913

static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
2914 2915 2916 2917 2918
	{ .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, },
	{ .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, },
	{ .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, },
	{ .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
	{ .name = FW_FILE_ISP24XX, },
2919
	{ .name = FW_FILE_ISP25XX, },
2920 2921 2922
};

struct fw_blob *
2923
qla2x00_request_firmware(scsi_qla_host_t *vha)
2924
{
2925
	struct qla_hw_data *ha = vha->hw;
2926 2927 2928 2929 2930 2931 2932
	struct fw_blob *blob;

	blob = NULL;
	if (IS_QLA2100(ha)) {
		blob = &qla_fw_blobs[FW_ISP21XX];
	} else if (IS_QLA2200(ha)) {
		blob = &qla_fw_blobs[FW_ISP22XX];
2933
	} else if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
2934
		blob = &qla_fw_blobs[FW_ISP2300];
2935
	} else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
2936
		blob = &qla_fw_blobs[FW_ISP2322];
2937
	} else if (IS_QLA24XX_TYPE(ha)) {
2938
		blob = &qla_fw_blobs[FW_ISP24XX];
2939 2940
	} else if (IS_QLA25XX(ha)) {
		blob = &qla_fw_blobs[FW_ISP25XX];
2941 2942
	}

2943
	mutex_lock(&qla_fw_lock);
2944 2945 2946 2947 2948
	if (blob->fw)
		goto out;

	if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
		DEBUG2(printk("scsi(%ld): Failed to load firmware image "
2949
		    "(%s).\n", vha->host_no, blob->name));
2950 2951 2952 2953 2954 2955
		blob->fw = NULL;
		blob = NULL;
		goto out;
	}

out:
2956
	mutex_unlock(&qla_fw_lock);
2957 2958 2959 2960 2961 2962 2963 2964
	return blob;
}

static void
qla2x00_release_firmware(void)
{
	int idx;

2965
	mutex_lock(&qla_fw_lock);
2966 2967 2968
	for (idx = 0; idx < FW_BLOBS; idx++)
		if (qla_fw_blobs[idx].fw)
			release_firmware(qla_fw_blobs[idx].fw);
2969
	mutex_unlock(&qla_fw_lock);
2970 2971
}

2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993
static pci_ers_result_t
qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
{
	switch (state) {
	case pci_channel_io_normal:
		return PCI_ERS_RESULT_CAN_RECOVER;
	case pci_channel_io_frozen:
		pci_disable_device(pdev);
		return PCI_ERS_RESULT_NEED_RESET;
	case pci_channel_io_perm_failure:
		qla2x00_remove_one(pdev);
		return PCI_ERS_RESULT_DISCONNECT;
	}
	return PCI_ERS_RESULT_NEED_RESET;
}

static pci_ers_result_t
qla2xxx_pci_mmio_enabled(struct pci_dev *pdev)
{
	int risc_paused = 0;
	uint32_t stat;
	unsigned long flags;
2994 2995
	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
	struct qla_hw_data *ha = base_vha->hw;
2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;

	spin_lock_irqsave(&ha->hardware_lock, flags);
	if (IS_QLA2100(ha) || IS_QLA2200(ha)){
		stat = RD_REG_DWORD(&reg->hccr);
		if (stat & HCCR_RISC_PAUSE)
			risc_paused = 1;
	} else if (IS_QLA23XX(ha)) {
		stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
		if (stat & HSR_RISC_PAUSED)
			risc_paused = 1;
	} else if (IS_FWI2_CAPABLE(ha)) {
		stat = RD_REG_DWORD(&reg24->host_status);
		if (stat & HSRX_RISC_PAUSED)
			risc_paused = 1;
	}
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	if (risc_paused) {
		qla_printk(KERN_INFO, ha, "RISC paused -- mmio_enabled, "
		    "Dumping firmware!\n");
3018
		ha->isp_ops->fw_dump(base_vha, 0);
3019 3020 3021 3022 3023 3024 3025 3026 3027 3028

		return PCI_ERS_RESULT_NEED_RESET;
	} else
		return PCI_ERS_RESULT_RECOVERED;
}

static pci_ers_result_t
qla2xxx_pci_slot_reset(struct pci_dev *pdev)
{
	pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT;
3029 3030
	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
	struct qla_hw_data *ha = base_vha->hw;
3031 3032 3033 3034 3035 3036
	int rc;

	if (ha->mem_only)
		rc = pci_enable_device_mem(pdev);
	else
		rc = pci_enable_device(pdev);
3037

3038
	if (rc) {
3039 3040 3041 3042 3043 3044 3045
		qla_printk(KERN_WARNING, ha,
		    "Can't re-enable PCI device after reset.\n");

		return ret;
	}
	pci_set_master(pdev);

3046
	if (ha->isp_ops->pci_config(base_vha))
3047 3048
		return ret;

3049 3050
	set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
	if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS)
3051
		ret =  PCI_ERS_RESULT_RECOVERED;
3052
	clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
3053 3054 3055 3056 3057 3058 3059

	return ret;
}

static void
qla2xxx_pci_resume(struct pci_dev *pdev)
{
3060 3061
	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
	struct qla_hw_data *ha = base_vha->hw;
3062 3063
	int ret;

3064
	ret = qla2x00_wait_for_hba_online(base_vha);
3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079
	if (ret != QLA_SUCCESS) {
		qla_printk(KERN_ERR, ha,
		    "the device failed to resume I/O "
		    "from slot/link_reset");
	}
	pci_cleanup_aer_uncorrect_error_status(pdev);
}

static struct pci_error_handlers qla2xxx_err_handler = {
	.error_detected = qla2xxx_pci_error_detected,
	.mmio_enabled = qla2xxx_pci_mmio_enabled,
	.slot_reset = qla2xxx_pci_slot_reset,
	.resume = qla2xxx_pci_resume,
};

3080
static struct pci_device_id qla2xxx_pci_tbl[] = {
3081 3082 3083 3084 3085 3086 3087 3088 3089
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) },
3090
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) },
3091 3092
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
3093
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },
3094 3095 3096 3097
	{ 0 },
};
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);

3098
static struct pci_driver qla2xxx_pci_driver = {
3099
	.name		= QLA2XXX_DRIVER_NAME,
3100 3101 3102
	.driver		= {
		.owner		= THIS_MODULE,
	},
3103
	.id_table	= qla2xxx_pci_tbl,
3104
	.probe		= qla2x00_probe_one,
A
Adrian Bunk 已提交
3105
	.remove		= qla2x00_remove_one,
3106
	.err_handler	= &qla2xxx_err_handler,
3107 3108
};

L
Linus Torvalds 已提交
3109 3110 3111 3112 3113 3114
/**
 * qla2x00_module_init - Module initialization.
 **/
static int __init
qla2x00_module_init(void)
{
3115 3116
	int ret = 0;

L
Linus Torvalds 已提交
3117
	/* Allocate cache for SRBs. */
3118
	srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
3119
	    SLAB_HWCACHE_ALIGN, NULL);
L
Linus Torvalds 已提交
3120 3121 3122 3123 3124 3125 3126 3127
	if (srb_cachep == NULL) {
		printk(KERN_ERR
		    "qla2xxx: Unable to allocate SRB cache...Failing load!\n");
		return -ENOMEM;
	}

	/* Derive version string. */
	strcpy(qla2x00_version_str, QLA2XXX_VERSION);
3128
	if (ql2xextended_error_logging)
3129 3130
		strcat(qla2x00_version_str, "-debug");

3131 3132
	qla2xxx_transport_template =
	    fc_attach_transport(&qla2xxx_transport_functions);
3133 3134
	if (!qla2xxx_transport_template) {
		kmem_cache_destroy(srb_cachep);
L
Linus Torvalds 已提交
3135
		return -ENODEV;
3136 3137 3138 3139 3140 3141
	}
	qla2xxx_transport_vport_template =
	    fc_attach_transport(&qla2xxx_transport_vport_functions);
	if (!qla2xxx_transport_vport_template) {
		kmem_cache_destroy(srb_cachep);
		fc_release_transport(qla2xxx_transport_template);
L
Linus Torvalds 已提交
3142
		return -ENODEV;
3143
	}
L
Linus Torvalds 已提交
3144

3145 3146
	printk(KERN_INFO "QLogic Fibre Channel HBA Driver: %s\n",
	    qla2x00_version_str);
3147
	ret = pci_register_driver(&qla2xxx_pci_driver);
3148 3149 3150
	if (ret) {
		kmem_cache_destroy(srb_cachep);
		fc_release_transport(qla2xxx_transport_template);
3151
		fc_release_transport(qla2xxx_transport_vport_template);
3152 3153
	}
	return ret;
L
Linus Torvalds 已提交
3154 3155 3156 3157 3158 3159 3160 3161
}

/**
 * qla2x00_module_exit - Module cleanup.
 **/
static void __exit
qla2x00_module_exit(void)
{
3162
	pci_unregister_driver(&qla2xxx_pci_driver);
3163
	qla2x00_release_firmware();
3164
	kmem_cache_destroy(srb_cachep);
L
Linus Torvalds 已提交
3165
	fc_release_transport(qla2xxx_transport_template);
3166
	fc_release_transport(qla2xxx_transport_vport_template);
L
Linus Torvalds 已提交
3167 3168 3169 3170 3171 3172 3173 3174 3175
}

module_init(qla2x00_module_init);
module_exit(qla2x00_module_exit);

MODULE_AUTHOR("QLogic Corporation");
MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(QLA2XXX_VERSION);
3176 3177 3178 3179 3180
MODULE_FIRMWARE(FW_FILE_ISP21XX);
MODULE_FIRMWARE(FW_FILE_ISP22XX);
MODULE_FIRMWARE(FW_FILE_ISP2300);
MODULE_FIRMWARE(FW_FILE_ISP2322);
MODULE_FIRMWARE(FW_FILE_ISP24XX);
3181
MODULE_FIRMWARE(FW_FILE_ISP25XX);