qla_os.c 108.9 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
A
Andrew Vasquez 已提交
2
 * QLogic Fibre Channel HBA Driver
3
 * Copyright (c)  2003-2010 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>
14
#include <linux/kobject.h>
15
#include <linux/slab.h>
L
Linus Torvalds 已提交
16 17 18 19 20 21 22 23 24 25 26

#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];

27 28
static int apidev_major;

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

34 35 36 37 38
/*
 * CT6 CTX allocation cache
 */
static struct kmem_cache *ctx_cachep;

L
Linus Torvalds 已提交
39
int ql2xlogintimeout = 20;
40
module_param(ql2xlogintimeout, int, S_IRUGO);
L
Linus Torvalds 已提交
41 42 43
MODULE_PARM_DESC(ql2xlogintimeout,
		"Login timeout value in seconds.");

44
int qlport_down_retry;
45
module_param(qlport_down_retry, int, S_IRUGO);
L
Linus Torvalds 已提交
46
MODULE_PARM_DESC(qlport_down_retry,
47
		"Maximum number of command retries to a port that returns "
L
Linus Torvalds 已提交
48 49 50 51 52 53
		"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 "
54
		"a Fabric scan.  This is needed for several broken switches. "
L
Linus Torvalds 已提交
55 56 57
		"Default is 0 - no PLOGI. 1 - perfom PLOGI.");

int ql2xloginretrycount = 0;
58
module_param(ql2xloginretrycount, int, S_IRUGO);
L
Linus Torvalds 已提交
59 60 61
MODULE_PARM_DESC(ql2xloginretrycount,
		"Specify an alternate value for the NVRAM login retry count.");

62
int ql2xallocfwdump = 1;
63
module_param(ql2xallocfwdump, int, S_IRUGO);
64 65 66 67 68
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.");

69
int ql2xextended_error_logging;
70
module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR);
71
MODULE_PARM_DESC(ql2xextended_error_logging,
72 73 74
		"Option to enable extended error logging, "
		"Default is 0 - no logging. 1 - log errors.");

75
int ql2xshiftctondsd = 6;
76
module_param(ql2xshiftctondsd, int, S_IRUGO);
77 78 79 80
MODULE_PARM_DESC(ql2xshiftctondsd,
		"Set to control shifting of command type processing "
		"based on total number of SG elements.");

L
Linus Torvalds 已提交
81 82
static void qla2x00_free_device(scsi_qla_host_t *);

83
int ql2xfdmienable=1;
84
module_param(ql2xfdmienable, int, S_IRUGO);
85
MODULE_PARM_DESC(ql2xfdmienable,
86 87
		"Enables FDMI registrations. "
		"0 - no FDMI. Default is 1 - perform FDMI.");
88

89 90 91 92 93 94
#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.");

95 96 97 98 99 100 101 102 103 104 105 106 107
/* Do not change the value of this after module load */
int ql2xenabledif = 1;
module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xenabledif,
		" Enable T10-CRC-DIF "
		" Default is 0 - No DIF Support. 1 - Enable it");

int ql2xenablehba_err_chk;
module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(ql2xenablehba_err_chk,
		" Enable T10-CRC-DIF Error isolation by HBA"
		" Default is 0 - Error isolation disabled, 1 - Enable it");

108
int ql2xiidmaenable=1;
109
module_param(ql2xiidmaenable, int, S_IRUGO);
110 111 112 113
MODULE_PARM_DESC(ql2xiidmaenable,
		"Enables iIDMA settings "
		"Default is 1 - perform iIDMA. 0 - no iIDMA.");

114
int ql2xmaxqueues = 1;
115
module_param(ql2xmaxqueues, int, S_IRUGO);
116 117
MODULE_PARM_DESC(ql2xmaxqueues,
		"Enables MQ settings "
118 119
		"Default is 1 for single queue. Set it to number "
		"of queues in MQ mode.");
120 121

int ql2xmultique_tag;
122
module_param(ql2xmultique_tag, int, S_IRUGO);
123 124 125 126
MODULE_PARM_DESC(ql2xmultique_tag,
		"Enables CPU affinity settings for the driver "
		"Default is 0 for no affinity of request and response IO. "
		"Set it to 1 to turn on the cpu affinity.");
127 128

int ql2xfwloadbin;
129
module_param(ql2xfwloadbin, int, S_IRUGO);
130 131 132 133 134 135 136
MODULE_PARM_DESC(ql2xfwloadbin,
		"Option to specify location from which to load ISP firmware:\n"
		" 2 -- load firmware via the request_firmware() (hotplug)\n"
		"      interface.\n"
		" 1 -- load firmware from flash.\n"
		" 0 -- use default semantics.\n");

137
int ql2xetsenable;
138
module_param(ql2xetsenable, int, S_IRUGO);
139 140 141 142
MODULE_PARM_DESC(ql2xetsenable,
		"Enables firmware ETS burst."
		"Default is 0 - skip ETS enablement.");

143
int ql2xdbwr = 1;
144
module_param(ql2xdbwr, int, S_IRUGO);
145 146 147 148 149
MODULE_PARM_DESC(ql2xdbwr,
	"Option to specify scheme for request queue posting\n"
	" 0 -- Regular doorbell.\n"
	" 1 -- CAMRAM doorbell (faster).\n");

150
int ql2xtargetreset = 1;
151
module_param(ql2xtargetreset, int, S_IRUGO);
152 153 154 155
MODULE_PARM_DESC(ql2xtargetreset,
		 "Enable target reset."
		 "Default is 1 - use hw defaults.");

156
int ql2xgffidenable;
157
module_param(ql2xgffidenable, int, S_IRUGO);
158 159 160
MODULE_PARM_DESC(ql2xgffidenable,
		"Enables GFF_ID checks of port type. "
		"Default is 0 - Do not use GFF_ID information.");
161

162
int ql2xasynctmfenable;
163
module_param(ql2xasynctmfenable, int, S_IRUGO);
164 165 166
MODULE_PARM_DESC(ql2xasynctmfenable,
		"Enables issue of TM IOCBs asynchronously via IOCB mechanism"
		"Default is 0 - Issue TM IOCBs via mailbox mechanism.");
L
Linus Torvalds 已提交
167
/*
A
Andrew Vasquez 已提交
168
 * SCSI host template entry points
L
Linus Torvalds 已提交
169 170
 */
static int qla2xxx_slave_configure(struct scsi_device * device);
已提交
171
static int qla2xxx_slave_alloc(struct scsi_device *);
172 173
static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
static void qla2xxx_scan_start(struct Scsi_Host *);
已提交
174
static void qla2xxx_slave_destroy(struct scsi_device *);
J
Jeff Garzik 已提交
175
static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
L
Linus Torvalds 已提交
176 177
static int qla2xxx_eh_abort(struct scsi_cmnd *);
static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
178
static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
L
Linus Torvalds 已提交
179 180 181
static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
static int qla2xxx_eh_host_reset(struct scsi_cmnd *);

182
static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
183 184
static int qla2x00_change_queue_type(struct scsi_device *, int);

185
struct scsi_host_template qla2xxx_driver_template = {
L
Linus Torvalds 已提交
186
	.module			= THIS_MODULE,
187
	.name			= QLA2XXX_DRIVER_NAME,
188
	.queuecommand		= qla2xxx_queuecommand,
189 190 191

	.eh_abort_handler	= qla2xxx_eh_abort,
	.eh_device_reset_handler = qla2xxx_eh_device_reset,
192
	.eh_target_reset_handler = qla2xxx_eh_target_reset,
193 194 195 196 197 198 199
	.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,
200 201
	.scan_finished		= qla2xxx_scan_finished,
	.scan_start		= qla2xxx_scan_start,
202 203
	.change_queue_depth	= qla2x00_change_queue_depth,
	.change_queue_type	= qla2x00_change_queue_type,
204 205 206 207 208 209
	.this_id		= -1,
	.cmd_per_lun		= 3,
	.use_clustering		= ENABLE_CLUSTERING,
	.sg_tablesize		= SG_ALL,

	.max_sectors		= 0xFFFF,
210
	.shost_attrs		= qla2x00_host_attrs,
211 212
};

L
Linus Torvalds 已提交
213
static struct scsi_transport_template *qla2xxx_transport_template = NULL;
214
struct scsi_transport_template *qla2xxx_transport_vport_template = NULL;
L
Linus Torvalds 已提交
215 216 217 218 219 220

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

221
__inline__ void
222
qla2x00_start_timer(scsi_qla_host_t *vha, void *func, unsigned long interval)
L
Linus Torvalds 已提交
223
{
224 225 226 227 228 229
	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 已提交
230 231 232
}

static inline void
233
qla2x00_restart_timer(scsi_qla_host_t *vha, unsigned long interval)
L
Linus Torvalds 已提交
234
{
235 236 237 238
	/* Currently used for 82XX only. */
	if (vha->device_flags & DFLG_DEV_FAILED)
		return;

239
	mod_timer(&vha->timer, jiffies + interval * HZ);
L
Linus Torvalds 已提交
240 241
}

A
Adrian Bunk 已提交
242
static __inline__ void
243
qla2x00_stop_timer(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
244
{
245 246
	del_timer_sync(&vha->timer);
	vha->timer_active = 0;
L
Linus Torvalds 已提交
247 248 249 250 251 252
}

static int qla2x00_do_dpc(void *data);

static void qla2x00_rst_aen(scsi_qla_host_t *);

253 254
static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
	struct req_que **, struct rsp_que **);
255
static void qla2x00_free_fw_dump(struct qla_hw_data *);
256 257
static void qla2x00_mem_free(struct qla_hw_data *);
static void qla2x00_sp_free_dma(srb_t *);
L
Linus Torvalds 已提交
258 259

/* -------------------------------------------------------------------------- */
260 261
static int qla2x00_alloc_queues(struct qla_hw_data *ha)
{
262
	ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_req_queues,
263 264 265 266 267 268 269
				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;
	}

270
	ha->rsp_q_map = kzalloc(sizeof(struct rsp_que *) * ha->max_rsp_queues,
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
				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;
}

288
static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
289 290 291 292 293 294 295 296 297 298
{
	if (req && req->ring)
		dma_free_coherent(&ha->pdev->dev,
		(req->length + 1) * sizeof(request_t),
		req->ring, req->dma);

	kfree(req);
	req = NULL;
}

299 300 301 302 303 304 305 306 307 308 309
static void qla2x00_free_rsp_que(struct qla_hw_data *ha, 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;
}

310 311 312 313 314 315
static void qla2x00_free_queues(struct qla_hw_data *ha)
{
	struct req_que *req;
	struct rsp_que *rsp;
	int cnt;

316
	for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
317
		req = ha->req_q_map[cnt];
318
		qla2x00_free_req_que(ha, req);
319 320 321
	}
	kfree(ha->req_q_map);
	ha->req_q_map = NULL;
322 323 324 325 326 327 328

	for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) {
		rsp = ha->rsp_q_map[cnt];
		qla2x00_free_rsp_que(ha, rsp);
	}
	kfree(ha->rsp_q_map);
	ha->rsp_q_map = NULL;
329 330
}

331 332 333 334 335 336
static int qla25xx_setup_mode(struct scsi_qla_host *vha)
{
	uint16_t options = 0;
	int ques, req, ret;
	struct qla_hw_data *ha = vha->hw;

337 338 339 340 341
	if (!(ha->fw_attributes & BIT_6)) {
		qla_printk(KERN_INFO, ha,
			"Firmware is not multi-queue capable\n");
		goto fail;
	}
342 343 344 345 346 347 348 349 350 351
	if (ql2xmultique_tag) {
		/* create a request queue for IO */
		options |= BIT_7;
		req = qla25xx_create_req_que(ha, options, 0, 0, -1,
			QLA_DEFAULT_QUE_QOS);
		if (!req) {
			qla_printk(KERN_WARNING, ha,
				"Can't create request queue\n");
			goto fail;
		}
352
		ha->wq = create_workqueue("qla2xxx_wq");
353 354 355 356 357 358 359 360 361 362
		vha->req = ha->req_q_map[req];
		options |= BIT_1;
		for (ques = 1; ques < ha->max_rsp_queues; ques++) {
			ret = qla25xx_create_rsp_que(ha, options, 0, 0, req);
			if (!ret) {
				qla_printk(KERN_WARNING, ha,
					"Response Queue create failed\n");
				goto fail2;
			}
		}
363 364
		ha->flags.cpu_affinity_enabled = 1;

365 366 367 368 369 370 371 372
		DEBUG2(qla_printk(KERN_INFO, ha,
			"CPU affinity mode enabled, no. of response"
			" queues:%d, no. of request queues:%d\n",
			ha->max_rsp_queues, ha->max_req_queues));
	}
	return 0;
fail2:
	qla25xx_delete_queues(vha);
373 374
	destroy_workqueue(ha->wq);
	ha->wq = NULL;
375 376
fail:
	ha->mqenable = 0;
377 378 379
	kfree(ha->req_q_map);
	kfree(ha->rsp_q_map);
	ha->max_req_queues = ha->max_rsp_queues = 1;
380 381 382
	return 1;
}

L
Linus Torvalds 已提交
383
static char *
384
qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str)
L
Linus Torvalds 已提交
385
{
386
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
	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);
}

407
static char *
408
qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str)
409 410
{
	static char *pci_bus_modes[] = { "33", "66", "100", "133", };
411
	struct qla_hw_data *ha = vha->hw;
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
	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)
428
			strcat(str, "2.5GT/s ");
429
		else if (lspeed == 2)
430
			strcat(str, "5.0GT/s ");
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
		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;
}

458
static char *
459
qla2x00_fw_version_str(struct scsi_qla_host *vha, char *str)
L
Linus Torvalds 已提交
460 461
{
	char un_str[10];
462
	struct qla_hw_data *ha = vha->hw;
A
Andrew Vasquez 已提交
463

L
Linus Torvalds 已提交
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
	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);
}

497
static char *
498
qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str)
499
{
500
	struct qla_hw_data *ha = vha->hw;
501

502 503
	sprintf(str, "%d.%02d.%02d (%x)", ha->fw_major_version,
	    ha->fw_minor_version, ha->fw_subminor_version, ha->fw_attributes);
504 505 506 507
	return str;
}

static inline srb_t *
508
qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
509 510 511
    struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
	srb_t *sp;
512
	struct qla_hw_data *ha = vha->hw;
513 514 515 516 517

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

518
	atomic_set(&sp->ref_count, 1);
519 520 521 522 523
	sp->fcport = fcport;
	sp->cmd = cmd;
	sp->flags = 0;
	CMD_SP(cmd) = (void *)sp;
	cmd->scsi_done = done;
524
	sp->ctx = NULL;
525 526 527 528

	return sp;
}

L
Linus Torvalds 已提交
529
static int
J
Jeff Garzik 已提交
530
qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
531
{
532
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
533
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
534
	struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
535 536
	struct qla_hw_data *ha = vha->hw;
	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
537 538 539
	srb_t *sp;
	int rval;

540
	spin_unlock_irq(vha->host->host_lock);
541 542
	if (ha->flags.eeh_busy) {
		if (ha->flags.pci_channel_io_perm_failure)
543
			cmd->result = DID_NO_CONNECT << 16;
544 545
		else
			cmd->result = DID_REQUEUE << 16;
546 547 548
		goto qc24_fail_command;
	}

549 550 551
	rval = fc_remote_port_chkready(rport);
	if (rval) {
		cmd->result = rval;
552 553 554
		goto qc24_fail_command;
	}

555 556 557 558 559 560 561 562
	if (!vha->flags.difdix_supported &&
		scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) {
			DEBUG2(qla_printk(KERN_ERR, ha,
			    "DIF Cap Not Reg, fail DIF capable cmd's:%x\n",
			    cmd->cmnd[0]));
			cmd->result = DID_NO_CONNECT << 16;
			goto qc24_fail_command;
	}
563 564
	if (atomic_read(&fcport->state) != FCS_ONLINE) {
		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
565 566
			atomic_read(&fcport->state) == FCS_DEVICE_LOST ||
			atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
567 568 569
			cmd->result = DID_NO_CONNECT << 16;
			goto qc24_fail_command;
		}
570
		goto qc24_target_busy;
571 572
	}

573
	sp = qla2x00_get_new_sp(base_vha, fcport, cmd, done);
574 575 576
	if (!sp)
		goto qc24_host_busy_lock;

577
	rval = ha->isp_ops->start_scsi(sp);
578 579 580
	if (rval != QLA_SUCCESS)
		goto qc24_host_busy_free_sp;

581
	spin_lock_irq(vha->host->host_lock);
582 583 584 585

	return 0;

qc24_host_busy_free_sp:
586 587
	qla2x00_sp_free_dma(sp);
	mempool_free(sp, ha->srb_mempool);
588 589

qc24_host_busy_lock:
590
	spin_lock_irq(vha->host->host_lock);
591 592
	return SCSI_MLQUEUE_HOST_BUSY;

593
qc24_target_busy:
594
	spin_lock_irq(vha->host->host_lock);
595 596
	return SCSI_MLQUEUE_TARGET_BUSY;

597
qc24_fail_command:
598
	spin_lock_irq(vha->host->host_lock);
599 600 601 602 603
	done(cmd);

	return 0;
}

J
Jeff Garzik 已提交
604 605
static DEF_SCSI_QCMD(qla2xxx_queuecommand)

606

L
Linus Torvalds 已提交
607 608 609 610 611 612 613 614 615 616 617 618 619
/*
 * 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
620
qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
L
Linus Torvalds 已提交
621
{
622 623
#define ABORT_POLLING_PERIOD	1000
#define ABORT_WAIT_ITER		((10 * 1000) / (ABORT_POLLING_PERIOD))
已提交
624
	unsigned long wait_iter = ABORT_WAIT_ITER;
625 626
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
	struct qla_hw_data *ha = vha->hw;
已提交
627
	int ret = QLA_SUCCESS;
L
Linus Torvalds 已提交
628

629 630 631 632 633
	if (unlikely(pci_channel_offline(ha->pdev)) || ha->flags.eeh_busy) {
		DEBUG17(qla_printk(KERN_WARNING, ha, "return:eh_wait\n"));
		return ret;
	}

634
	while (CMD_SP(cmd) && wait_iter--) {
635
		msleep(ABORT_POLLING_PERIOD);
已提交
636 637 638
	}
	if (CMD_SP(cmd))
		ret = QLA_FUNCTION_FAILED;
L
Linus Torvalds 已提交
639

已提交
640
	return ret;
L
Linus Torvalds 已提交
641 642 643 644
}

/*
 * qla2x00_wait_for_hba_online
A
Andrew Vasquez 已提交
645
 *    Wait till the HBA is online after going through
L
Linus Torvalds 已提交
646 647 648 649 650
 *    <= MAX_RETRIES_OF_ISP_ABORT  or
 *    finally HBA is disabled ie marked offline
 *
 * Input:
 *     ha - pointer to host adapter structure
A
Andrew Vasquez 已提交
651 652
 *
 * Note:
L
Linus Torvalds 已提交
653 654 655 656 657 658 659
 *    Does context switching-Release SPIN_LOCK
 *    (if any) before calling this routine.
 *
 * Return:
 *    Success (Adapter is online) : 0
 *    Failed  (Adapter is offline/disabled) : 1
 */
660
int
661
qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
662
{
663 664
	int		return_status;
	unsigned long	wait_online;
665 666
	struct qla_hw_data *ha = vha->hw;
	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
L
Linus Torvalds 已提交
667

A
Andrew Vasquez 已提交
668
	wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
669 670 671 672
	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 已提交
673 674 675

		msleep(1000);
	}
676
	if (base_vha->flags.online)
A
Andrew Vasquez 已提交
677
		return_status = QLA_SUCCESS;
L
Linus Torvalds 已提交
678 679 680 681 682 683
	else
		return_status = QLA_FUNCTION_FAILED;

	return (return_status);
}

684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
/*
 * qla2x00_wait_for_reset_ready
 *    Wait till the HBA is online after going through
 *    <= MAX_RETRIES_OF_ISP_ABORT  or
 *    finally HBA is disabled ie marked offline or flash
 *    operations are in progress.
 *
 * Input:
 *     ha - pointer to host adapter structure
 *
 * Note:
 *    Does context switching-Release SPIN_LOCK
 *    (if any) before calling this routine.
 *
 * Return:
 *    Success (Adapter is online/no flash ops) : 0
 *    Failed  (Adapter is offline/disabled/flash ops in progress) : 1
 */
702
static int
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
qla2x00_wait_for_reset_ready(scsi_qla_host_t *vha)
{
	int		return_status;
	unsigned long	wait_online;
	struct qla_hw_data *ha = vha->hw;
	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);

	wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
	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->optrom_state != QLA_SWAITING ||
	    ha->dpc_active) && time_before(jiffies, wait_online))
		msleep(1000);

	if (base_vha->flags.online &&  ha->optrom_state == QLA_SWAITING)
		return_status = QLA_SUCCESS;
	else
		return_status = QLA_FUNCTION_FAILED;

	DEBUG2(printk("%s return_status=%d\n", __func__, return_status));

	return return_status;
}

728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
int
qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
{
	int		return_status;
	unsigned long	wait_reset;
	struct qla_hw_data *ha = vha->hw;
	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);

	wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ);
	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_reset)) {

		msleep(1000);

		if (!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
		    ha->flags.chip_reset_done)
			break;
	}
	if (ha->flags.chip_reset_done)
		return_status = QLA_SUCCESS;
	else
		return_status = QLA_FUNCTION_FAILED;

	return return_status;
}

L
Linus Torvalds 已提交
756 757 758
/*
 * qla2x00_wait_for_loop_ready
 *    Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
A
Andrew Vasquez 已提交
759
 *    to be in LOOP_READY state.
L
Linus Torvalds 已提交
760 761
 * Input:
 *     ha - pointer to host adapter structure
A
Andrew Vasquez 已提交
762 763
 *
 * Note:
L
Linus Torvalds 已提交
764 765
 *    Does context switching-Release SPIN_LOCK
 *    (if any) before calling this routine.
A
Andrew Vasquez 已提交
766
 *
L
Linus Torvalds 已提交
767 768 769 770 771
 *
 * Return:
 *    Success (LOOP_READY) : 0
 *    Failed  (LOOP_NOT_READY) : 1
 */
A
Andrew Vasquez 已提交
772
static inline int
773
qla2x00_wait_for_loop_ready(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
774 775 776
{
	int 	 return_status = QLA_SUCCESS;
	unsigned long loop_timeout ;
777 778
	struct qla_hw_data *ha = vha->hw;
	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
L
Linus Torvalds 已提交
779 780

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

783 784 785 786
	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) {
787 788 789
			return_status = QLA_FUNCTION_FAILED;
			break;
		}
L
Linus Torvalds 已提交
790 791 792 793 794 795
		msleep(1000);
		if (time_after_eq(jiffies, loop_timeout)) {
			return_status = QLA_FUNCTION_FAILED;
			break;
		}
	}
A
Andrew Vasquez 已提交
796
	return (return_status);
L
Linus Torvalds 已提交
797 798
}

799 800 801 802 803 804
static void
sp_get(struct srb *sp)
{
	atomic_inc(&sp->ref_count);
}

L
Linus Torvalds 已提交
805 806 807 808 809 810 811 812 813 814 815 816 817
/**************************************************************************
* 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:
818
*    Only return FAILED if command not returned by firmware.
L
Linus Torvalds 已提交
819
**************************************************************************/
820
static int
L
Linus Torvalds 已提交
821 822
qla2xxx_eh_abort(struct scsi_cmnd *cmd)
{
823
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
已提交
824
	srb_t *sp;
825
	int ret = SUCCESS;
已提交
826
	unsigned int id, lun;
827
	unsigned long flags;
828
	int wait = 0;
829
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
830

831
	fc_block_scsi_eh(cmd);
832

已提交
833
	if (!CMD_SP(cmd))
834
		return SUCCESS;
L
Linus Torvalds 已提交
835

已提交
836 837
	id = cmd->device->id;
	lun = cmd->device->lun;
L
Linus Torvalds 已提交
838

839
	spin_lock_irqsave(&ha->hardware_lock, flags);
840 841 842 843 844
	sp = (srb_t *) CMD_SP(cmd);
	if (!sp) {
		spin_unlock_irqrestore(&ha->hardware_lock, flags);
		return SUCCESS;
	}
L
Linus Torvalds 已提交
845

846 847
	DEBUG2(printk("%s(%ld): aborting sp %p from RISC.",
	    __func__, vha->host_no, sp));
848

849 850
	/* Get a reference to the sp and drop the lock.*/
	sp_get(sp);
851

852
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
853 854 855 856 857 858 859 860 861 862
	if (ha->isp_ops->abort_command(sp)) {
		DEBUG2(printk("%s(%ld): abort_command "
		"mbx failed.\n", __func__, vha->host_no));
		ret = FAILED;
	} else {
		DEBUG3(printk("%s(%ld): abort_command "
		"mbx success.\n", __func__, vha->host_no));
		wait = 1;
	}
	qla2x00_sp_compl(ha, sp);
L
Linus Torvalds 已提交
863

已提交
864
	/* Wait for the command to be returned. */
865
	if (wait) {
866
		if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) {
A
Andrew Vasquez 已提交
867
			qla_printk(KERN_ERR, ha,
868 869
			    "scsi(%ld:%d:%d): Abort handler timed out -- %x.\n",
			    vha->host_no, id, lun, ret);
870
			ret = FAILED;
已提交
871
		}
L
Linus Torvalds 已提交
872 873
	}

A
Andrew Vasquez 已提交
874
	qla_printk(KERN_INFO, ha,
875 876
	    "scsi(%ld:%d:%d): Abort command issued -- %d %x.\n",
	    vha->host_no, id, lun, wait, ret);
L
Linus Torvalds 已提交
877

已提交
878 879
	return ret;
}
L
Linus Torvalds 已提交
880

881
int
882
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
883
	unsigned int l, enum nexus_wait_type type)
已提交
884
{
885
	int cnt, match, status;
886
	unsigned long flags;
887
	struct qla_hw_data *ha = vha->hw;
888
	struct req_que *req;
889
	srb_t *sp;
L
Linus Torvalds 已提交
890

891
	status = QLA_SUCCESS;
892

893
	spin_lock_irqsave(&ha->hardware_lock, flags);
894
	req = vha->req;
895 896 897 898
	for (cnt = 1; status == QLA_SUCCESS &&
		cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
		sp = req->outstanding_cmds[cnt];
		if (!sp)
899
			continue;
900
		if ((sp->ctx) && !IS_PROT_IO(sp))
901
			continue;
902 903 904 905 906 907 908 909 910 911 912 913 914 915
		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;
916
		}
917 918 919 920 921 922
		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 已提交
923
	}
924
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
925 926

	return status;
L
Linus Torvalds 已提交
927 928
}

929 930 931 932 933 934
static char *reset_errors[] = {
	"HBA not online",
	"HBA not ready",
	"Task management failed",
	"Waiting for command completions",
};
L
Linus Torvalds 已提交
935

936
static int
937
__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
938
    struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int, int))
L
Linus Torvalds 已提交
939
{
940
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
941
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
942
	int err;
L
Linus Torvalds 已提交
943

944
	fc_block_scsi_eh(cmd);
945

946
	if (!fcport)
947
		return FAILED;
L
Linus Torvalds 已提交
948

949 950
	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 已提交
951

952
	err = 0;
953
	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
954 955
		goto eh_reset_failed;
	err = 1;
956
	if (qla2x00_wait_for_loop_ready(vha) != QLA_SUCCESS)
957 958
		goto eh_reset_failed;
	err = 2;
959 960
	if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1)
		!= QLA_SUCCESS)
961 962
		goto eh_reset_failed;
	err = 3;
963
	if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
964
	    cmd->device->lun, type) != QLA_SUCCESS)
965 966
		goto eh_reset_failed;

967 968
	qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n",
	    vha->host_no, cmd->device->id, cmd->device->lun, name);
969 970 971

	return SUCCESS;

972
eh_reset_failed:
973 974
	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,
975 976 977
	    reset_errors[err]);
	return FAILED;
}
L
Linus Torvalds 已提交
978

979 980 981
static int
qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
{
982 983
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
984

985 986
	return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
	    ha->isp_ops->lun_reset);
L
Linus Torvalds 已提交
987 988 989
}

static int
990
qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
L
Linus Torvalds 已提交
991
{
992 993
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
994

995 996
	return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
	    ha->isp_ops->target_reset);
L
Linus Torvalds 已提交
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
}

/**************************************************************************
* 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).
*
**************************************************************************/
1014
static int
L
Linus Torvalds 已提交
1015 1016
qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
{
1017
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
1018
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
1019
	int ret = FAILED;
已提交
1020 1021
	unsigned int id, lun;

1022
	fc_block_scsi_eh(cmd);
1023

已提交
1024 1025
	id = cmd->device->id;
	lun = cmd->device->lun;
L
Linus Torvalds 已提交
1026

1027
	if (!fcport)
已提交
1028
		return ret;
L
Linus Torvalds 已提交
1029

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

1033
	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
L
Linus Torvalds 已提交
1034
		DEBUG2(printk("%s failed:board disabled\n",__func__));
已提交
1035
		goto eh_bus_reset_done;
L
Linus Torvalds 已提交
1036 1037
	}

1038 1039
	if (qla2x00_wait_for_loop_ready(vha) == QLA_SUCCESS) {
		if (qla2x00_loop_reset(vha) == QLA_SUCCESS)
已提交
1040
			ret = SUCCESS;
L
Linus Torvalds 已提交
1041
	}
已提交
1042 1043
	if (ret == FAILED)
		goto eh_bus_reset_done;
L
Linus Torvalds 已提交
1044

1045
	/* Flush outstanding commands. */
1046
	if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) !=
1047
	    QLA_SUCCESS)
1048
		ret = FAILED;
L
Linus Torvalds 已提交
1049

已提交
1050
eh_bus_reset_done:
1051
	qla_printk(KERN_INFO, vha->hw, "%s: reset %s\n", __func__,
已提交
1052
	    (ret == FAILED) ? "failed" : "succeded");
L
Linus Torvalds 已提交
1053

已提交
1054
	return ret;
L
Linus Torvalds 已提交
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
}

/**************************************************************************
* 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:
**************************************************************************/
1072
static int
L
Linus Torvalds 已提交
1073 1074
qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
{
1075
	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
1076
	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
1077
	struct qla_hw_data *ha = vha->hw;
1078
	int ret = FAILED;
已提交
1079
	unsigned int id, lun;
1080
	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
L
Linus Torvalds 已提交
1081

1082
	fc_block_scsi_eh(cmd);
1083

已提交
1084 1085 1086
	id = cmd->device->id;
	lun = cmd->device->lun;

1087
	if (!fcport)
已提交
1088
		return ret;
L
Linus Torvalds 已提交
1089 1090

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

1093
	if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS)
已提交
1094
		goto eh_host_reset_lock;
L
Linus Torvalds 已提交
1095 1096 1097

	/*
	 * Fixme-may be dpc thread is active and processing
A
Andrew Vasquez 已提交
1098
	 * loop_resync,so wait a while for it to
L
Linus Torvalds 已提交
1099 1100 1101 1102 1103
	 * 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.
	 */
1104 1105 1106
	qla2x00_wait_for_loop_ready(vha);
	if (vha != base_vha) {
		if (qla2x00_vp_abort_isp(vha))
已提交
1107
			goto eh_host_reset_lock;
1108
	} else {
1109 1110 1111 1112 1113 1114 1115 1116
		if (IS_QLA82XX(vha->hw)) {
			if (!qla82xx_fcoe_ctx_reset(vha)) {
				/* Ctx reset success */
				ret = SUCCESS;
				goto eh_host_reset_lock;
			}
			/* fall thru if ctx reset failed */
		}
1117 1118 1119
		if (ha->wq)
			flush_workqueue(ha->wq);

1120
		set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
1121
		if (ha->isp_ops->abort_isp(base_vha)) {
1122 1123 1124 1125 1126 1127 1128 1129
			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 已提交
1130
	}
L
Linus Torvalds 已提交
1131

1132
	/* Waiting for command to be returned to OS.*/
1133
	if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) ==
1134
		QLA_SUCCESS)
已提交
1135
		ret = SUCCESS;
L
Linus Torvalds 已提交
1136

已提交
1137 1138 1139
eh_host_reset_lock:
	qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
	    (ret == FAILED) ? "failed" : "succeded");
L
Linus Torvalds 已提交
1140

已提交
1141 1142
	return ret;
}
L
Linus Torvalds 已提交
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153

/*
* qla2x00_loop_reset
*      Issue loop reset.
*
* Input:
*      ha = adapter block pointer.
*
* Returns:
*      0 = success
*/
1154
int
1155
qla2x00_loop_reset(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
1156
{
1157
	int ret;
1158
	struct fc_port *fcport;
1159
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
1160

1161
	if (ql2xtargetreset == 1 && ha->flags.enable_target_reset) {
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
		list_for_each_entry(fcport, &vha->vp_fcports, list) {
			if (fcport->port_type != FCT_TARGET)
				continue;

			ret = ha->isp_ops->target_reset(fcport, 0, 0);
			if (ret != QLA_SUCCESS) {
				DEBUG2_3(printk("%s(%ld): bus_reset failed: "
				    "target_reset=%d d_id=%x.\n", __func__,
				    vha->host_no, ret, fcport->d_id.b24));
			}
		}
	}

1175
	if (ha->flags.enable_lip_full_login && !IS_QLA8XXX_TYPE(ha)) {
1176
		ret = qla2x00_full_login_lip(vha);
1177
		if (ret != QLA_SUCCESS) {
1178
			DEBUG2_3(printk("%s(%ld): failed: "
1179
			    "full_login_lip=%d.\n", __func__, vha->host_no,
1180
			    ret));
1181 1182 1183 1184 1185
		}
		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);
1186 1187
	}

1188
	if (ha->flags.enable_lip_reset) {
1189
		ret = qla2x00_lip_reset(vha);
1190
		if (ret != QLA_SUCCESS) {
1191
			DEBUG2_3(printk("%s(%ld): failed: "
1192 1193 1194
			    "lip_reset=%d.\n", __func__, vha->host_no, ret));
		} else
			qla2x00_wait_for_loop_ready(vha);
L
Linus Torvalds 已提交
1195 1196 1197
	}

	/* Issue marker command only when we are going to start the I/O */
1198
	vha->marker_needed = 1;
L
Linus Torvalds 已提交
1199

1200
	return QLA_SUCCESS;
L
Linus Torvalds 已提交
1201 1202
}

1203
void
1204
qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1205
{
1206
	int que, cnt;
1207 1208
	unsigned long flags;
	srb_t *sp;
1209
	struct srb_ctx *ctx;
1210
	struct qla_hw_data *ha = vha->hw;
1211
	struct req_que *req;
1212 1213

	spin_lock_irqsave(&ha->hardware_lock, flags);
1214
	for (que = 0; que < ha->max_req_queues; que++) {
1215
		req = ha->req_q_map[que];
1216 1217 1218 1219
		if (!req)
			continue;
		for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
			sp = req->outstanding_cmds[cnt];
1220
			if (sp) {
1221
				req->outstanding_cmds[cnt] = NULL;
1222
				if (!sp->ctx ||
1223 1224
					(sp->flags & SRB_FCP_CMND_DMA_VALID) ||
					IS_PROT_IO(sp)) {
1225 1226 1227 1228
					sp->cmd->result = res;
					qla2x00_sp_compl(ha, sp);
				} else {
					ctx = sp->ctx;
1229 1230
					if (ctx->type == SRB_LOGIN_CMD ||
					    ctx->type == SRB_LOGOUT_CMD) {
1231
						ctx->u.iocb_cmd->free(sp);
1232
					} else {
1233
						struct fc_bsg_job *bsg_job =
1234
						    ctx->u.bsg_job;
1235 1236
						if (bsg_job->request->msgcode
						    == FC_BSG_HST_CT)
1237
							kfree(sp->fcport);
1238 1239
						bsg_job->req->errors = 0;
						bsg_job->reply->result = res;
1240
						bsg_job->job_done(bsg_job);
1241
						kfree(sp->ctx);
1242
						mempool_free(sp,
1243
							ha->srb_mempool);
1244
					}
1245
				}
1246
			}
1247 1248 1249 1250 1251
		}
	}
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

已提交
1252 1253
static int
qla2xxx_slave_alloc(struct scsi_device *sdev)
L
Linus Torvalds 已提交
1254
{
1255
	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
L
Linus Torvalds 已提交
1256

1257
	if (!rport || fc_remote_port_chkready(rport))
已提交
1258
		return -ENXIO;
1259

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

已提交
1262 1263
	return 0;
}
L
Linus Torvalds 已提交
1264

已提交
1265 1266 1267
static int
qla2xxx_slave_configure(struct scsi_device *sdev)
{
1268
	scsi_qla_host_t *vha = shost_priv(sdev->host);
1269
	struct req_que *req = vha->req;
已提交
1270

已提交
1271
	if (sdev->tagged_supported)
1272
		scsi_activate_tcq(sdev, req->max_q_depth);
已提交
1273
	else
1274
		scsi_deactivate_tcq(sdev, req->max_q_depth);
已提交
1275 1276
	return 0;
}
L
Linus Torvalds 已提交
1277

已提交
1278 1279 1280 1281
static void
qla2xxx_slave_destroy(struct scsi_device *sdev)
{
	sdev->hostdata = NULL;
L
Linus Torvalds 已提交
1282 1283
}

1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth)
{
	fc_port_t *fcport = (struct fc_port *) sdev->hostdata;

	if (!scsi_track_queue_full(sdev, qdepth))
		return;

	DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw,
		"scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
		fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
		sdev->queue_depth));
}

static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth)
{
	fc_port_t *fcport = sdev->hostdata;
	struct scsi_qla_host *vha = fcport->vha;
	struct qla_hw_data *ha = vha->hw;
	struct req_que *req = NULL;

	req = vha->req;
	if (!req)
		return;

	if (req->max_q_depth <= sdev->queue_depth || req->max_q_depth < qdepth)
		return;

	if (sdev->ordered_tags)
		scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, qdepth);
	else
		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, qdepth);

	DEBUG2(qla_printk(KERN_INFO, ha,
	       "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n",
	       fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun,
	       sdev->queue_depth));
}

1322
static int
1323
qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
1324
{
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335
	switch (reason) {
	case SCSI_QDEPTH_DEFAULT:
		scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
		break;
	case SCSI_QDEPTH_QFULL:
		qla2x00_handle_queue_full(sdev, qdepth);
		break;
	case SCSI_QDEPTH_RAMP_UP:
		qla2x00_adjust_sdev_qdepth_up(sdev, qdepth);
		break;
	default:
1336
		return -EOPNOTSUPP;
1337
	}
1338

1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356
	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 已提交
1357 1358 1359 1360 1361 1362 1363 1364
/**
 * 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
1365
qla2x00_config_dma_addressing(struct qla_hw_data *ha)
L
Linus Torvalds 已提交
1366
{
1367
	/* Assume a 32bit DMA mask. */
L
Linus Torvalds 已提交
1368 1369
	ha->flags.enable_64bit_addressing = 0;

1370
	if (!dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(64))) {
1371 1372
		/* Any upper-dword bits set? */
		if (MSD(dma_get_required_mask(&ha->pdev->dev)) &&
1373
		    !pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(64))) {
1374
			/* Ok, a 64bit DMA mask is applicable. */
L
Linus Torvalds 已提交
1375
			ha->flags.enable_64bit_addressing = 1;
1376 1377
			ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64;
			ha->isp_ops->build_iocbs = qla2x00_build_scsi_iocbs_64;
1378
			return;
L
Linus Torvalds 已提交
1379 1380
		}
	}
1381

1382 1383
	dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(32));
	pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(32));
L
Linus Torvalds 已提交
1384 1385
}

1386
static void
1387
qla2x00_enable_intrs(struct qla_hw_data *ha)
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
{
	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
1402
qla2x00_disable_intrs(struct qla_hw_data *ha)
1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415
{
	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
1416
qla24xx_enable_intrs(struct qla_hw_data *ha)
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428
{
	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
1429
qla24xx_disable_intrs(struct qla_hw_data *ha)
1430 1431 1432 1433
{
	unsigned long flags = 0;
	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;

1434 1435
	if (IS_NOPOLLING_TYPE(ha))
		return;
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457
	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,
1458 1459
	.target_reset		= qla2x00_abort_target,
	.lun_reset		= qla2x00_lun_reset,
1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474
	.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,
1475
	.start_scsi		= qla2x00_start_scsi,
1476
	.abort_isp		= qla2x00_abort_isp,
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493
};

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,
1494 1495
	.target_reset		= qla2x00_abort_target,
	.lun_reset		= qla2x00_lun_reset,
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510
	.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,
1511
	.start_scsi		= qla2x00_start_scsi,
1512
	.abort_isp		= qla2x00_abort_isp,
1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
};

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,
1530 1531
	.target_reset		= qla24xx_abort_target,
	.lun_reset		= qla24xx_lun_reset,
1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546
	.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,
1547
	.start_scsi		= qla24xx_start_scsi,
1548
	.abort_isp		= qla2x00_abort_isp,
1549 1550
};

1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
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,
1566 1567
	.target_reset		= qla24xx_abort_target,
	.lun_reset		= qla24xx_lun_reset,
1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
	.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,
1580
	.read_optrom		= qla25xx_read_optrom_data,
1581 1582
	.write_optrom		= qla24xx_write_optrom_data,
	.get_flash_version	= qla24xx_get_flash_version,
1583
	.start_scsi		= qla24xx_dif_start_scsi,
1584
	.abort_isp		= qla2x00_abort_isp,
1585 1586
};

1587 1588 1589 1590 1591 1592 1593 1594
static struct isp_operations qla81xx_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		= qla81xx_nvram_config,
	.update_fw_options	= qla81xx_update_fw_options,
1595
	.load_risc		= qla81xx_load_risc,
1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609
	.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,
	.target_reset		= qla24xx_abort_target,
	.lun_reset		= qla24xx_lun_reset,
	.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,
1610 1611
	.read_nvram		= NULL,
	.write_nvram		= NULL,
1612 1613 1614 1615 1616 1617 1618
	.fw_dump		= qla81xx_fw_dump,
	.beacon_on		= qla24xx_beacon_on,
	.beacon_off		= qla24xx_beacon_off,
	.beacon_blink		= qla24xx_beacon_blink,
	.read_optrom		= qla25xx_read_optrom_data,
	.write_optrom		= qla24xx_write_optrom_data,
	.get_flash_version	= qla24xx_get_flash_version,
1619
	.start_scsi		= qla24xx_dif_start_scsi,
1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656
	.abort_isp		= qla2x00_abort_isp,
};

static struct isp_operations qla82xx_isp_ops = {
	.pci_config		= qla82xx_pci_config,
	.reset_chip		= qla82xx_reset_chip,
	.chip_diag		= qla24xx_chip_diag,
	.config_rings		= qla82xx_config_rings,
	.reset_adapter		= qla24xx_reset_adapter,
	.nvram_config		= qla81xx_nvram_config,
	.update_fw_options	= qla24xx_update_fw_options,
	.load_risc		= qla82xx_load_risc,
	.pci_info_str		= qla82xx_pci_info_str,
	.fw_version_str		= qla24xx_fw_version_str,
	.intr_handler		= qla82xx_intr_handler,
	.enable_intrs		= qla82xx_enable_intrs,
	.disable_intrs		= qla82xx_disable_intrs,
	.abort_command		= qla24xx_abort_command,
	.target_reset		= qla24xx_abort_target,
	.lun_reset		= qla24xx_lun_reset,
	.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		= qla82xx_read_optrom_data,
	.write_optrom		= qla82xx_write_optrom_data,
	.get_flash_version	= qla24xx_get_flash_version,
	.start_scsi             = qla82xx_start_scsi,
	.abort_isp		= qla82xx_abort_isp,
1657 1658
};

1659
static inline void
1660
qla2x00_set_isp_flags(struct qla_hw_data *ha)
1661 1662 1663 1664 1665 1666
{
	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;
1667
		ha->fw_srisc_address = RISC_START_ADDRESS_2100;
1668 1669 1670 1671
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2200:
		ha->device_type |= DT_ISP2200;
		ha->device_type &= ~DT_EXTENDED_IDS;
1672
		ha->fw_srisc_address = RISC_START_ADDRESS_2100;
1673 1674 1675
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2300:
		ha->device_type |= DT_ISP2300;
1676
		ha->device_type |= DT_ZIO_SUPPORTED;
1677
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1678 1679 1680
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2312:
		ha->device_type |= DT_ISP2312;
1681
		ha->device_type |= DT_ZIO_SUPPORTED;
1682
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1683 1684 1685
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2322:
		ha->device_type |= DT_ISP2322;
1686
		ha->device_type |= DT_ZIO_SUPPORTED;
1687 1688 1689
		if (ha->pdev->subsystem_vendor == 0x1028 &&
		    ha->pdev->subsystem_device == 0x0170)
			ha->device_type |= DT_OEM_001;
1690
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1691 1692 1693
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP6312:
		ha->device_type |= DT_ISP6312;
1694
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1695 1696 1697
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP6322:
		ha->device_type |= DT_ISP6322;
1698
		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
1699 1700 1701
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2422:
		ha->device_type |= DT_ISP2422;
1702
		ha->device_type |= DT_ZIO_SUPPORTED;
1703
		ha->device_type |= DT_FWI2;
1704
		ha->device_type |= DT_IIDMA;
1705
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1706 1707 1708
		break;
	case PCI_DEVICE_ID_QLOGIC_ISP2432:
		ha->device_type |= DT_ISP2432;
1709
		ha->device_type |= DT_ZIO_SUPPORTED;
1710
		ha->device_type |= DT_FWI2;
1711
		ha->device_type |= DT_IIDMA;
1712
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1713
		break;
1714 1715 1716 1717 1718 1719 1720
	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;
1721 1722
	case PCI_DEVICE_ID_QLOGIC_ISP5422:
		ha->device_type |= DT_ISP5422;
1723
		ha->device_type |= DT_FWI2;
1724
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1725
		break;
1726 1727
	case PCI_DEVICE_ID_QLOGIC_ISP5432:
		ha->device_type |= DT_ISP5432;
1728
		ha->device_type |= DT_FWI2;
1729
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1730
		break;
1731 1732 1733 1734 1735
	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;
1736
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1737
		break;
1738 1739 1740 1741 1742 1743 1744
	case PCI_DEVICE_ID_QLOGIC_ISP8001:
		ha->device_type |= DT_ISP8001;
		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;
1745 1746 1747 1748 1749 1750 1751 1752
	case PCI_DEVICE_ID_QLOGIC_ISP8021:
		ha->device_type |= DT_ISP8021;
		ha->device_type |= DT_ZIO_SUPPORTED;
		ha->device_type |= DT_FWI2;
		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
		/* Initialize 82XX ISP flags */
		qla82xx_init_flags(ha);
		break;
1753
	}
1754

1755 1756 1757 1758 1759 1760
	if (IS_QLA82XX(ha))
		ha->port_no = !(ha->portnum & 1);
	else
		/* Get adapter physical port no from interrupt pin register. */
		pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no);

1761 1762 1763 1764
	if (ha->port_no & 1)
		ha->flags.port0 = 1;
	else
		ha->flags.port0 = 0;
1765 1766
}

L
Linus Torvalds 已提交
1767
static int
1768
qla2x00_iospace_config(struct qla_hw_data *ha)
L
Linus Torvalds 已提交
1769
{
1770
	resource_size_t pio;
1771
	uint16_t msix;
1772
	int cpus;
L
Linus Torvalds 已提交
1773

1774 1775 1776
	if (IS_QLA82XX(ha))
		return qla82xx_iospace_config(ha);

1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787
	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 已提交
1788 1789
	/* We only need PIO for Flash operations on ISP2312 v2 chips. */
	pio = pci_resource_start(ha->pdev, 0);
1790 1791
	if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) {
		if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) {
L
Linus Torvalds 已提交
1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802
			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;
	}
1803
	ha->pio_address = pio;
L
Linus Torvalds 已提交
1804

1805
skip_pio:
L
Linus Torvalds 已提交
1806
	/* Use MMIO operations for all accesses. */
1807
	if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) {
L
Linus Torvalds 已提交
1808
		qla_printk(KERN_ERR, ha,
1809
		    "region #1 not an MMIO resource (%s), aborting\n",
L
Linus Torvalds 已提交
1810 1811 1812
		    pci_name(ha->pdev));
		goto iospace_error_exit;
	}
1813
	if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) {
L
Linus Torvalds 已提交
1814 1815 1816 1817 1818 1819
		qla_printk(KERN_ERR, ha,
		    "Invalid PCI mem region size (%s), aborting\n",
			pci_name(ha->pdev));
		goto iospace_error_exit;
	}

1820
	ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN);
L
Linus Torvalds 已提交
1821 1822 1823 1824 1825 1826 1827
	if (!ha->iobase) {
		qla_printk(KERN_ERR, ha,
		    "cannot remap MMIO (%s), aborting\n", pci_name(ha->pdev));

		goto iospace_error_exit;
	}

1828
	/* Determine queue resources */
1829
	ha->max_req_queues = ha->max_rsp_queues = 1;
1830 1831
	if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) ||
		(ql2xmaxqueues > 1 && ql2xmultique_tag) ||
1832
		(!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
1833
		goto mqiobase_exit;
1834

1835 1836 1837 1838 1839 1840
	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;
1841 1842 1843 1844
		/* Max queues are bounded by available msix vectors */
		/* queue 0 uses two msix vectors */
		if (ql2xmultique_tag) {
			cpus = num_online_cpus();
1845
			ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ?
1846 1847 1848
				(cpus + 1) : (ha->msix_count - 1);
			ha->max_req_queues = 2;
		} else if (ql2xmaxqueues > 1) {
1849 1850 1851 1852 1853
			ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ?
						QLA_MQ_SIZE : ql2xmaxqueues;
			DEBUG2(qla_printk(KERN_INFO, ha, "QoS mode set, max no"
			" of request queues:%d\n", ha->max_req_queues));
		}
1854 1855
		qla_printk(KERN_INFO, ha,
			"MSI-X vector count: %d\n", msix);
1856 1857
	} else
		qla_printk(KERN_INFO, ha, "BAR 3 not enabled\n");
1858 1859

mqiobase_exit:
1860
	ha->msix_count = ha->max_rsp_queues + 1;
L
Linus Torvalds 已提交
1861 1862 1863 1864 1865 1866
	return (0);

iospace_error_exit:
	return (-ENOMEM);
}

1867 1868 1869
static void
qla2xxx_scan_start(struct Scsi_Host *shost)
{
1870
	scsi_qla_host_t *vha = shost_priv(shost);
1871

1872 1873 1874
	if (vha->hw->flags.running_gold_fw)
		return;

1875 1876 1877 1878
	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);
1879 1880 1881 1882 1883
}

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

1886
	if (!vha->host)
1887
		return 1;
1888
	if (time > vha->hw->loop_reset_delay * HZ)
1889 1890
		return 1;

1891
	return atomic_read(&vha->loop_state) == LOOP_READY;
1892 1893
}

L
Linus Torvalds 已提交
1894 1895 1896
/*
 * PCI driver interface
 */
1897 1898
static int __devinit
qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
L
Linus Torvalds 已提交
1899
{
1900
	int	ret = -ENODEV;
L
Linus Torvalds 已提交
1901
	struct Scsi_Host *host;
1902 1903
	scsi_qla_host_t *base_vha = NULL;
	struct qla_hw_data *ha;
1904
	char pci_info[30];
L
Linus Torvalds 已提交
1905
	char fw_str[30];
1906
	struct scsi_host_template *sht;
1907
	int bars, max_id, mem_only = 0;
1908
	uint16_t req_length = 0, rsp_length = 0;
1909 1910
	struct req_que *req = NULL;
	struct rsp_que *rsp = NULL;
L
Linus Torvalds 已提交
1911

1912
	bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
1913
	sht = &qla2xxx_driver_template;
1914
	if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
1915
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
1916
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
1917
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
1918
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
1919
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532 ||
1920 1921
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8001 ||
	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8021) {
1922
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
1923
		mem_only = 1;
1924 1925
	}

1926 1927 1928 1929 1930 1931 1932
	if (mem_only) {
		if (pci_enable_device_mem(pdev))
			goto probe_out;
	} else {
		if (pci_enable_device(pdev))
			goto probe_out;
	}
1933

1934 1935
	/* This may fail but that's ok */
	pci_enable_pcie_error_reporting(pdev);
1936

1937 1938 1939 1940
	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 已提交
1941
	}
1942
	ha->pdev = pdev;
L
Linus Torvalds 已提交
1943 1944

	/* Clear our data area */
1945
	ha->bars = bars;
1946
	ha->mem_only = mem_only;
1947
	spin_lock_init(&ha->hardware_lock);
1948
	spin_lock_init(&ha->vport_slock);
L
Linus Torvalds 已提交
1949

1950 1951
	/* Set ISP-type information. */
	qla2x00_set_isp_flags(ha);
1952 1953 1954 1955 1956 1957

	/* Set EEH reset type to fundamental if required by hba */
	if ( IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) {
		pdev->needs_freset = 1;
	}

L
Linus Torvalds 已提交
1958 1959
	/* Configure PCI I/O space */
	ret = qla2x00_iospace_config(ha);
1960
	if (ret)
1961
		goto probe_hw_failed;
L
Linus Torvalds 已提交
1962 1963

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

	ha->prev_topology = 0;
1968
	ha->init_cb_size = sizeof(init_cb_t);
1969
	ha->link_data_rate = PORT_SPEED_UNKNOWN;
1970
	ha->optrom_size = OPTROM_SIZE_2300;
L
Linus Torvalds 已提交
1971

1972
	/* Assign ISP specific operations. */
1973
	max_id = MAX_TARGETS_2200;
L
Linus Torvalds 已提交
1974
	if (IS_QLA2100(ha)) {
1975
		max_id = MAX_TARGETS_2100;
L
Linus Torvalds 已提交
1976
		ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
1977 1978 1979
		req_length = REQUEST_ENTRY_CNT_2100;
		rsp_length = RESPONSE_ENTRY_CNT_2100;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
1980
		ha->gid_list_info_size = 4;
1981 1982 1983 1984
		ha->flash_conf_off = ~0;
		ha->flash_data_off = ~0;
		ha->nvram_conf_off = ~0;
		ha->nvram_data_off = ~0;
1985
		ha->isp_ops = &qla2100_isp_ops;
L
Linus Torvalds 已提交
1986 1987
	} else if (IS_QLA2200(ha)) {
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
1988 1989 1990
		req_length = REQUEST_ENTRY_CNT_2200;
		rsp_length = RESPONSE_ENTRY_CNT_2100;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
1991
		ha->gid_list_info_size = 4;
1992 1993 1994 1995
		ha->flash_conf_off = ~0;
		ha->flash_data_off = ~0;
		ha->nvram_conf_off = ~0;
		ha->nvram_data_off = ~0;
1996
		ha->isp_ops = &qla2100_isp_ops;
1997
	} else if (IS_QLA23XX(ha)) {
L
Linus Torvalds 已提交
1998
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
1999 2000 2001
		req_length = REQUEST_ENTRY_CNT_2200;
		rsp_length = RESPONSE_ENTRY_CNT_2300;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
2002
		ha->gid_list_info_size = 6;
2003 2004
		if (IS_QLA2322(ha) || IS_QLA6322(ha))
			ha->optrom_size = OPTROM_SIZE_2322;
2005 2006 2007 2008
		ha->flash_conf_off = ~0;
		ha->flash_data_off = ~0;
		ha->nvram_conf_off = ~0;
		ha->nvram_data_off = ~0;
2009
		ha->isp_ops = &qla2300_isp_ops;
2010
	} else if (IS_QLA24XX_TYPE(ha)) {
2011
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
2012 2013 2014
		req_length = REQUEST_ENTRY_CNT_24XX;
		rsp_length = RESPONSE_ENTRY_CNT_2300;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
2015
		ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
2016
		ha->gid_list_info_size = 8;
2017
		ha->optrom_size = OPTROM_SIZE_24XX;
2018
		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA24XX;
2019
		ha->isp_ops = &qla24xx_isp_ops;
2020 2021 2022 2023
		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
2024 2025
	} else if (IS_QLA25XX(ha)) {
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
2026 2027 2028
		req_length = REQUEST_ENTRY_CNT_24XX;
		rsp_length = RESPONSE_ENTRY_CNT_2300;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
2029 2030 2031
		ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
		ha->gid_list_info_size = 8;
		ha->optrom_size = OPTROM_SIZE_25XX;
2032
		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
2033
		ha->isp_ops = &qla25xx_isp_ops;
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045
		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
	} else if (IS_QLA81XX(ha)) {
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
		req_length = REQUEST_ENTRY_CNT_24XX;
		rsp_length = RESPONSE_ENTRY_CNT_2300;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
		ha->gid_list_info_size = 8;
		ha->optrom_size = OPTROM_SIZE_81XX;
2046
		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
2047 2048 2049 2050 2051
		ha->isp_ops = &qla81xx_isp_ops;
		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_81XX;
		ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX;
		ha->nvram_conf_off = ~0;
		ha->nvram_data_off = ~0;
2052 2053 2054 2055 2056 2057 2058 2059
	} else if (IS_QLA82XX(ha)) {
		ha->mbx_count = MAILBOX_REGISTER_COUNT;
		req_length = REQUEST_ENTRY_CNT_82XX;
		rsp_length = RESPONSE_ENTRY_CNT_82XX;
		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
		ha->gid_list_info_size = 8;
		ha->optrom_size = OPTROM_SIZE_82XX;
2060
		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
2061 2062 2063 2064 2065
		ha->isp_ops = &qla82xx_isp_ops;
		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
L
Linus Torvalds 已提交
2066 2067
	}

2068
	mutex_init(&ha->vport_lock);
2069 2070 2071
	init_completion(&ha->mbx_cmd_comp);
	complete(&ha->mbx_cmd_comp);
	init_completion(&ha->mbx_intr_comp);
2072
	init_completion(&ha->dcbx_comp);
L
Linus Torvalds 已提交
2073

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

2076
	qla2x00_config_dma_addressing(ha);
2077
	ret = qla2x00_mem_alloc(ha, req_length, rsp_length, &req, &rsp);
2078
	if (!ret) {
L
Linus Torvalds 已提交
2079 2080 2081
		qla_printk(KERN_WARNING, ha,
		    "[ERROR] Failed to allocate memory for adapter\n");

2082 2083 2084
		goto probe_hw_failed;
	}

2085
	req->max_q_depth = MAX_Q_DEPTH;
2086
	if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU)
2087 2088
		req->max_q_depth = ql2xmaxqdepth;

2089 2090 2091 2092 2093 2094

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

2095
		ret = -ENOMEM;
2096
		qla2x00_mem_free(ha);
2097 2098
		qla2x00_free_req_que(ha, req);
		qla2x00_free_rsp_que(ha, rsp);
2099
		goto probe_hw_failed;
L
Linus Torvalds 已提交
2100 2101
	}

2102 2103 2104
	pci_set_drvdata(pdev, base_vha);

	host = base_vha->host;
2105
	base_vha->req = req;
2106 2107
	host->can_queue = req->length + 128;
	if (IS_QLA2XXX_MIDTYPE(ha))
2108
		base_vha->mgmt_svr_loop_id = 10 + base_vha->vp_idx;
2109
	else
2110 2111
		base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER +
						base_vha->vp_idx;
2112 2113 2114 2115 2116 2117 2118 2119 2120 2121

	/* Set the SG table size based on ISP type */
	if (!IS_FWI2_CAPABLE(ha)) {
		if (IS_QLA2100(ha))
			host->sg_tablesize = 32;
	} else {
		if (!IS_QLA82XX(ha))
			host->sg_tablesize = QLA_SG_ALL;
	}

2122 2123 2124 2125
	host->max_id = max_id;
	host->this_id = 255;
	host->cmd_per_lun = 3;
	host->unique_id = host->host_no;
2126 2127 2128 2129
	if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif)
		host->max_cmd_len = 32;
	else
		host->max_cmd_len = MAX_CMDSZ;
2130 2131 2132
	host->max_channel = MAX_BUSES - 1;
	host->max_lun = MAX_LUNS;
	host->transportt = qla2xxx_transport_template;
2133
	sht->vendor_id = (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC);
2134

2135 2136 2137
	/* Set up the irqs */
	ret = qla2x00_request_irqs(ha, rsp);
	if (ret)
2138
		goto probe_init_failed;
2139 2140 2141

	pci_save_state(pdev);

2142
	/* Alloc arrays of request and response ring ptrs */
2143
que_init:
2144 2145 2146 2147
	if (!qla2x00_alloc_queues(ha)) {
		qla_printk(KERN_WARNING, ha,
		"[ERROR] Failed to allocate memory for queue"
		" pointers\n");
2148
		goto probe_init_failed;
2149
	}
2150

2151 2152
	ha->rsp_q_map[0] = rsp;
	ha->req_q_map[0] = req;
2153 2154 2155 2156
	rsp->req = req;
	req->rsp = rsp;
	set_bit(0, ha->req_qid_map);
	set_bit(0, ha->rsp_qid_map);
2157 2158 2159 2160 2161
	/* FWI2-capable only. */
	req->req_q_in = &ha->iobase->isp24.req_q_in;
	req->req_q_out = &ha->iobase->isp24.req_q_out;
	rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in;
	rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out;
2162
	if (ha->mqenable) {
2163 2164 2165 2166
		req->req_q_in = &ha->mqiobase->isp25mq.req_q_in;
		req->req_q_out = &ha->mqiobase->isp25mq.req_q_out;
		rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in;
		rsp->rsp_q_out =  &ha->mqiobase->isp25mq.rsp_q_out;
2167 2168
	}

2169 2170 2171 2172 2173 2174
	if (IS_QLA82XX(ha)) {
		req->req_q_out = &ha->iobase->isp82.req_q_out[0];
		rsp->rsp_q_in = &ha->iobase->isp82.rsp_q_in[0];
		rsp->rsp_q_out = &ha->iobase->isp82.rsp_q_out[0];
	}

2175
	if (qla2x00_initialize_adapter(base_vha)) {
L
Linus Torvalds 已提交
2176 2177 2178 2179 2180
		qla_printk(KERN_WARNING, ha,
		    "Failed to initialize adapter\n");

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

2183 2184 2185 2186 2187 2188 2189 2190
		if (IS_QLA82XX(ha)) {
			qla82xx_idc_lock(ha);
			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
				QLA82XX_DEV_FAILED);
			qla82xx_idc_unlock(ha);
			qla_printk(KERN_INFO, ha, "HW State: FAILED\n");
		}

2191
		ret = -ENODEV;
L
Linus Torvalds 已提交
2192 2193 2194
		goto probe_failed;
	}

2195 2196
	if (ha->mqenable) {
		if (qla25xx_setup_mode(base_vha)) {
2197 2198 2199
			qla_printk(KERN_WARNING, ha,
				"Can't create queues, falling back to single"
				" queue mode\n");
2200 2201 2202
			goto que_init;
		}
	}
2203

2204 2205 2206
	if (ha->flags.running_gold_fw)
		goto skip_dpc;

L
Linus Torvalds 已提交
2207 2208 2209
	/*
	 * Startup the kernel thread for this host adapter
	 */
2210
	ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha,
2211
			"%s_dpc", base_vha->host_str);
2212
	if (IS_ERR(ha->dpc_thread)) {
L
Linus Torvalds 已提交
2213 2214
		qla_printk(KERN_WARNING, ha,
		    "Unable to start DPC thread!\n");
2215
		ret = PTR_ERR(ha->dpc_thread);
L
Linus Torvalds 已提交
2216 2217 2218
		goto probe_failed;
	}

2219
skip_dpc:
2220 2221
	list_add_tail(&base_vha->list, &ha->vp_list);
	base_vha->host->irq = ha->pdev->irq;
L
Linus Torvalds 已提交
2222 2223

	/* Initialized the timer */
2224
	qla2x00_start_timer(base_vha, qla2x00_timer, WATCH_INTERVAL);
L
Linus Torvalds 已提交
2225 2226

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

2229
	if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) {
2230 2231 2232 2233 2234 2235 2236
		if (ha->fw_attributes & BIT_4) {
			base_vha->flags.difdix_supported = 1;
			DEBUG18(qla_printk(KERN_INFO, ha,
			    "Registering for DIF/DIX type 1 and 3"
			    " protection.\n"));
			scsi_host_set_prot(host,
			    SHOST_DIF_TYPE1_PROTECTION
2237
			    | SHOST_DIF_TYPE2_PROTECTION
2238 2239
			    | SHOST_DIF_TYPE3_PROTECTION
			    | SHOST_DIX_TYPE1_PROTECTION
2240
			    | SHOST_DIX_TYPE2_PROTECTION
2241 2242 2243 2244 2245 2246
			    | SHOST_DIX_TYPE3_PROTECTION);
			scsi_host_set_guard(host, SHOST_DIX_GUARD_CRC);
		} else
			base_vha->flags.difdix_supported = 0;
	}

2247 2248
	ha->isp_ops->enable_intrs(ha);

2249 2250 2251 2252
	ret = scsi_add_host(host, &pdev->dev);
	if (ret)
		goto probe_failed;

2253 2254 2255
	base_vha->flags.init_done = 1;
	base_vha->flags.online = 1;

2256 2257
	scsi_scan_host(host);

2258
	qla2x00_alloc_sysfs_attr(base_vha);
2259

2260
	qla2x00_init_host_attr(base_vha);
2261

2262
	qla2x00_dfs_setup(base_vha);
2263

L
Linus Torvalds 已提交
2264 2265 2266
	qla_printk(KERN_INFO, ha, "\n"
	    " QLogic Fibre Channel HBA Driver: %s\n"
	    "  QLogic %s - %s\n"
2267 2268
	    "  ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
	    qla2x00_version_str, ha->model_number,
2269 2270 2271 2272
	    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 已提交
2273 2274 2275

	return 0;

2276
probe_init_failed:
2277 2278 2279
	qla2x00_free_req_que(ha, req);
	qla2x00_free_rsp_que(ha, rsp);
	ha->max_req_queues = ha->max_rsp_queues = 0;
2280

L
Linus Torvalds 已提交
2281
probe_failed:
2282 2283 2284 2285 2286 2287 2288 2289 2290 2291
	if (base_vha->timer_active)
		qla2x00_stop_timer(base_vha);
	base_vha->flags.online = 0;
	if (ha->dpc_thread) {
		struct task_struct *t = ha->dpc_thread;

		ha->dpc_thread = NULL;
		kthread_stop(t);
	}

2292
	qla2x00_free_device(base_vha);
L
Linus Torvalds 已提交
2293

2294
	scsi_host_put(base_vha->host);
L
Linus Torvalds 已提交
2295

2296
probe_hw_failed:
2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307
	if (IS_QLA82XX(ha)) {
		qla82xx_idc_lock(ha);
		qla82xx_clear_drv_active(ha);
		qla82xx_idc_unlock(ha);
		iounmap((device_reg_t __iomem *)ha->nx_pcibase);
		if (!ql2xdbwr)
			iounmap((device_reg_t __iomem *)ha->nxdb_wr_ptr);
	} else {
		if (ha->iobase)
			iounmap(ha->iobase);
	}
2308 2309 2310
	pci_release_selected_regions(ha->pdev, ha->bars);
	kfree(ha);
	ha = NULL;
L
Linus Torvalds 已提交
2311

2312
probe_out:
2313
	pci_disable_device(pdev);
2314
	return ret;
L
Linus Torvalds 已提交
2315 2316
}

2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352
static void
qla2x00_shutdown(struct pci_dev *pdev)
{
	scsi_qla_host_t *vha;
	struct qla_hw_data  *ha;

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

	/* Turn-off FCE trace */
	if (ha->flags.fce_enabled) {
		qla2x00_disable_fce_trace(vha, NULL, NULL);
		ha->flags.fce_enabled = 0;
	}

	/* Turn-off EFT trace */
	if (ha->eft)
		qla2x00_disable_eft_trace(vha);

	/* Stop currently executing firmware. */
	qla2x00_try_to_stop_firmware(vha);

	/* Turn adapter off line */
	vha->flags.online = 0;

	/* turn-off interrupts on the card */
	if (ha->interrupts_on) {
		vha->flags.init_done = 0;
		ha->isp_ops->disable_intrs(ha);
	}

	qla2x00_free_irqs(vha);

	qla2x00_free_fw_dump(ha);
}

A
Adrian Bunk 已提交
2353
static void
2354
qla2x00_remove_one(struct pci_dev *pdev)
L
Linus Torvalds 已提交
2355
{
2356
	scsi_qla_host_t *base_vha, *vha;
2357
	struct qla_hw_data  *ha;
2358
	unsigned long flags;
2359 2360 2361 2362

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

2363 2364 2365 2366
	spin_lock_irqsave(&ha->vport_slock, flags);
	list_for_each_entry(vha, &ha->vp_list, list) {
		atomic_inc(&vha->vref_count);

2367
		if (vha->fc_vport) {
2368 2369
			spin_unlock_irqrestore(&ha->vport_slock, flags);

2370
			fc_vport_terminate(vha->fc_vport);
2371 2372 2373 2374 2375

			spin_lock_irqsave(&ha->vport_slock, flags);
		}

		atomic_dec(&vha->vref_count);
2376
	}
2377
	spin_unlock_irqrestore(&ha->vport_slock, flags);
L
Linus Torvalds 已提交
2378

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

2381 2382
	qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);

2383
	qla2x00_dfs_remove(base_vha);
2384

2385
	qla84xx_put_chip(base_vha);
2386

2387 2388 2389 2390 2391 2392
	/* Disable timer */
	if (base_vha->timer_active)
		qla2x00_stop_timer(base_vha);

	base_vha->flags.online = 0;

2393 2394 2395 2396 2397 2398 2399
	/* Flush the work queue and remove it */
	if (ha->wq) {
		flush_workqueue(ha->wq);
		destroy_workqueue(ha->wq);
		ha->wq = NULL;
	}

2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411
	/* Kill the kernel thread for this host */
	if (ha->dpc_thread) {
		struct task_struct *t = ha->dpc_thread;

		/*
		 * qla2xxx_wake_dpc checks for ->dpc_thread
		 * so we need to zero it out.
		 */
		ha->dpc_thread = NULL;
		kthread_stop(t);
	}

2412
	qla2x00_free_sysfs_attr(base_vha);
2413

2414
	fc_remove_host(base_vha->host);
2415

2416
	scsi_remove_host(base_vha->host);
L
Linus Torvalds 已提交
2417

2418
	qla2x00_free_device(base_vha);
2419

2420
	scsi_host_put(base_vha->host);
L
Linus Torvalds 已提交
2421

2422
	if (IS_QLA82XX(ha)) {
2423 2424 2425 2426
		qla82xx_idc_lock(ha);
		qla82xx_clear_drv_active(ha);
		qla82xx_idc_unlock(ha);

2427 2428 2429 2430 2431 2432
		iounmap((device_reg_t __iomem *)ha->nx_pcibase);
		if (!ql2xdbwr)
			iounmap((device_reg_t __iomem *)ha->nxdb_wr_ptr);
	} else {
		if (ha->iobase)
			iounmap(ha->iobase);
L
Linus Torvalds 已提交
2433

2434 2435 2436
		if (ha->mqiobase)
			iounmap(ha->mqiobase);
	}
2437

2438 2439 2440
	pci_release_selected_regions(ha->pdev, ha->bars);
	kfree(ha);
	ha = NULL;
L
Linus Torvalds 已提交
2441

2442 2443
	pci_disable_pcie_error_reporting(pdev);

2444
	pci_disable_device(pdev);
L
Linus Torvalds 已提交
2445 2446 2447 2448
	pci_set_drvdata(pdev, NULL);
}

static void
2449
qla2x00_free_device(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
2450
{
2451
	struct qla_hw_data *ha = vha->hw;
L
Linus Torvalds 已提交
2452

2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470
	qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);

	/* Disable timer */
	if (vha->timer_active)
		qla2x00_stop_timer(vha);

	/* Kill the kernel thread for this host */
	if (ha->dpc_thread) {
		struct task_struct *t = ha->dpc_thread;

		/*
		 * qla2xxx_wake_dpc checks for ->dpc_thread
		 * so we need to zero it out.
		 */
		ha->dpc_thread = NULL;
		kthread_stop(t);
	}

2471 2472
	qla25xx_delete_queues(vha);

2473
	if (ha->flags.fce_enabled)
2474
		qla2x00_disable_fce_trace(vha, NULL, NULL);
2475

2476
	if (ha->eft)
2477
		qla2x00_disable_eft_trace(vha);
2478

2479
	/* Stop currently executing firmware. */
2480
	qla2x00_try_to_stop_firmware(vha);
L
Linus Torvalds 已提交
2481

2482 2483
	vha->flags.online = 0;

2484
	/* turn-off interrupts on the card */
2485 2486
	if (ha->interrupts_on) {
		vha->flags.init_done = 0;
2487
		ha->isp_ops->disable_intrs(ha);
2488
	}
2489

2490
	qla2x00_free_irqs(vha);
L
Linus Torvalds 已提交
2491

2492 2493
	qla2x00_free_fcports(vha);

2494
	qla2x00_mem_free(ha);
2495 2496

	qla2x00_free_queues(ha);
L
Linus Torvalds 已提交
2497 2498
}

2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509
void qla2x00_free_fcports(struct scsi_qla_host *vha)
{
	fc_port_t *fcport, *tfcport;

	list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) {
		list_del(&fcport->list);
		kfree(fcport);
		fcport = NULL;
	}
}

2510
static inline void
2511
qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
2512 2513 2514
    int defer)
{
	struct fc_rport *rport;
2515
	scsi_qla_host_t *base_vha;
2516 2517 2518 2519 2520 2521

	if (!fcport->rport)
		return;

	rport = fcport->rport;
	if (defer) {
2522
		base_vha = pci_get_drvdata(vha->hw->pdev);
2523
		spin_lock_irq(vha->host->host_lock);
2524
		fcport->drport = rport;
2525
		spin_unlock_irq(vha->host->host_lock);
2526 2527
		set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
		qla2xxx_wake_dpc(base_vha);
2528
	} else
2529 2530 2531
		fc_remote_port_delete(rport);
}

L
Linus Torvalds 已提交
2532 2533 2534 2535 2536 2537 2538 2539 2540
/*
 * qla2x00_mark_device_lost Updates fcport state when device goes offline.
 *
 * Input: ha = adapter block pointer.  fcport = port structure pointer.
 *
 * Return: None.
 *
 * Context:
 */
2541
void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
2542
    int do_login, int defer)
L
Linus Torvalds 已提交
2543
{
2544
	if (atomic_read(&fcport->state) == FCS_ONLINE &&
2545 2546 2547 2548
	    vha->vp_idx == fcport->vp_idx) {
		atomic_set(&fcport->state, FCS_DEVICE_LOST);
		qla2x00_schedule_rport_del(vha, fcport, defer);
	}
A
Andrew Vasquez 已提交
2549
	/*
L
Linus Torvalds 已提交
2550 2551 2552 2553 2554 2555 2556 2557 2558 2559
	 * 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) {
2560 2561
		fcport->login_retry = vha->hw->login_retry_count;
		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
L
Linus Torvalds 已提交
2562 2563 2564 2565

		DEBUG(printk("scsi(%ld): Port login retry: "
		    "%02x%02x%02x%02x%02x%02x%02x%02x, "
		    "id = 0x%04x retry cnt=%d\n",
2566
		    vha->host_no,
L
Linus Torvalds 已提交
2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593
		    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
2594
qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
L
Linus Torvalds 已提交
2595 2596 2597
{
	fc_port_t *fcport;

2598
	list_for_each_entry(fcport, &vha->vp_fcports, list) {
2599
		if (vha->vp_idx != 0 && vha->vp_idx != fcport->vp_idx)
L
Linus Torvalds 已提交
2600
			continue;
2601

L
Linus Torvalds 已提交
2602 2603 2604 2605 2606 2607
		/*
		 * No point in marking the device as lost, if the device is
		 * already DEAD.
		 */
		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
			continue;
2608
		if (atomic_read(&fcport->state) == FCS_ONLINE) {
2609
			atomic_set(&fcport->state, FCS_DEVICE_LOST);
2610 2611 2612 2613 2614
			if (defer)
				qla2x00_schedule_rport_del(vha, fcport, defer);
			else if (vha->vp_idx == fcport->vp_idx)
				qla2x00_schedule_rport_del(vha, fcport, defer);
		}
L
Linus Torvalds 已提交
2615 2616 2617 2618 2619 2620 2621 2622 2623
	}
}

/*
* qla2x00_mem_alloc
*      Allocates adapter memory.
*
* Returns:
*      0  = success.
2624
*      !0  = failure.
L
Linus Torvalds 已提交
2625
*/
2626
static int
2627 2628
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 已提交
2629 2630 2631
{
	char	name[16];

2632
	ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
2633
		&ha->init_cb_dma, GFP_KERNEL);
2634
	if (!ha->init_cb)
2635
		goto fail;
2636

2637 2638 2639
	ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
		&ha->gid_list_dma, GFP_KERNEL);
	if (!ha->gid_list)
2640
		goto fail_free_init_cb;
L
Linus Torvalds 已提交
2641

2642 2643
	ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
	if (!ha->srb_mempool)
2644
		goto fail_free_gid_list;
2645

2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660
	if (IS_QLA82XX(ha)) {
		/* Allocate cache for CT6 Ctx. */
		if (!ctx_cachep) {
			ctx_cachep = kmem_cache_create("qla2xxx_ctx",
				sizeof(struct ct6_dsd), 0,
				SLAB_HWCACHE_ALIGN, NULL);
			if (!ctx_cachep)
				goto fail_free_gid_list;
		}
		ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ,
			ctx_cachep);
		if (!ha->ctx_mempool)
			goto fail_free_srb_mempool;
	}

2661 2662 2663
	/* Get memory for cached NVRAM */
	ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
	if (!ha->nvram)
2664
		goto fail_free_ctx_mempool;
2665

2666 2667 2668 2669 2670 2671 2672
	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;

2673
	if (IS_QLA82XX(ha) || ql2xenabledif) {
2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690
		ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev,
			DSD_LIST_DMA_POOL_SIZE, 8, 0);
		if (!ha->dl_dma_pool) {
			qla_printk(KERN_WARNING, ha,
			    "Memory Allocation failed - dl_dma_pool\n");
			goto fail_s_dma_pool;
		}

		ha->fcp_cmnd_dma_pool = dma_pool_create(name, &ha->pdev->dev,
			FCP_CMND_DMA_POOL_SIZE, 8, 0);
		if (!ha->fcp_cmnd_dma_pool) {
			qla_printk(KERN_WARNING, ha,
			    "Memory Allocation failed - fcp_cmnd_dma_pool\n");
			goto fail_dl_dma_pool;
		}
	}

2691 2692
	/* Allocate memory for SNS commands */
	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
2693
	/* Get consistent memory allocated for SNS commands */
2694
		ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
2695
		sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, GFP_KERNEL);
2696
		if (!ha->sns_cmd)
2697
			goto fail_dma_pool;
2698
	} else {
2699
	/* Get consistent memory allocated for MS IOCB */
2700
		ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
2701
			&ha->ms_iocb_dma);
2702
		if (!ha->ms_iocb)
2703 2704
			goto fail_dma_pool;
	/* Get consistent memory allocated for CT SNS commands */
2705
		ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
2706
			sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL);
2707 2708
		if (!ha->ct_sns)
			goto fail_free_ms_iocb;
L
Linus Torvalds 已提交
2709 2710
	}

2711
	/* Allocate memory for request ring */
2712 2713
	*req = kzalloc(sizeof(struct req_que), GFP_KERNEL);
	if (!*req) {
2714 2715 2716
		DEBUG(printk("Unable to allocate memory for req\n"));
		goto fail_req;
	}
2717 2718 2719 2720 2721
	(*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) {
2722 2723 2724 2725
		DEBUG(printk("Unable to allocate memory for req_ring\n"));
		goto fail_req_ring;
	}
	/* Allocate memory for response ring */
2726 2727 2728 2729
	*rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL);
	if (!*rsp) {
		qla_printk(KERN_WARNING, ha,
			"Unable to allocate memory for rsp\n");
2730 2731
		goto fail_rsp;
	}
2732 2733 2734 2735 2736 2737 2738 2739
	(*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");
2740 2741
		goto fail_rsp_ring;
	}
2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754
	(*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;
2755

2756
	/* Get consistent memory allocated for EX-INIT-CB. */
2757
	if (IS_QLA8XXX_TYPE(ha)) {
2758 2759 2760 2761 2762 2763
		ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
		    &ha->ex_init_cb_dma);
		if (!ha->ex_init_cb)
			goto fail_ex_init_cb;
	}

2764 2765
	INIT_LIST_HEAD(&ha->gbl_dsd_list);

2766 2767 2768 2769 2770 2771 2772 2773
	/* Get consistent memory allocated for Async Port-Database. */
	if (!IS_FWI2_CAPABLE(ha)) {
		ha->async_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
			&ha->async_pd_dma);
		if (!ha->async_pd)
			goto fail_async_pd;
	}

2774 2775 2776
	INIT_LIST_HEAD(&ha->vp_list);
	return 1;

2777 2778
fail_async_pd:
	dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
2779 2780
fail_ex_init_cb:
	kfree(ha->npiv_info);
2781 2782 2783 2784 2785
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;
2786
fail_rsp_ring:
2787
	kfree(*rsp);
2788
fail_rsp:
2789 2790 2791 2792
	dma_free_coherent(&ha->pdev->dev, ((*req)->length + 1) *
		sizeof(request_t), (*req)->ring, (*req)->dma);
	(*req)->ring = NULL;
	(*req)->dma = 0;
2793
fail_req_ring:
2794
	kfree(*req);
2795 2796 2797 2798 2799
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;
2800 2801 2802 2803
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;
2804
fail_dma_pool:
2805
	if (IS_QLA82XX(ha) || ql2xenabledif) {
2806 2807 2808 2809
		dma_pool_destroy(ha->fcp_cmnd_dma_pool);
		ha->fcp_cmnd_dma_pool = NULL;
	}
fail_dl_dma_pool:
2810
	if (IS_QLA82XX(ha) || ql2xenabledif) {
2811 2812 2813 2814
		dma_pool_destroy(ha->dl_dma_pool);
		ha->dl_dma_pool = NULL;
	}
fail_s_dma_pool:
2815 2816
	dma_pool_destroy(ha->s_dma_pool);
	ha->s_dma_pool = NULL;
2817 2818 2819
fail_free_nvram:
	kfree(ha->nvram);
	ha->nvram = NULL;
2820 2821 2822
fail_free_ctx_mempool:
	mempool_destroy(ha->ctx_mempool);
	ha->ctx_mempool = NULL;
2823 2824 2825 2826 2827
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,
2828
	ha->gid_list_dma);
2829 2830
	ha->gid_list = NULL;
	ha->gid_list_dma = 0;
2831 2832 2833 2834 2835
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;
2836
fail:
2837
	DEBUG(printk("%s: Memory allocation failure\n", __func__));
2838
	return -ENOMEM;
L
Linus Torvalds 已提交
2839 2840 2841
}

/*
2842 2843
* qla2x00_free_fw_dump
*	Frees fw dump stuff.
L
Linus Torvalds 已提交
2844 2845
*
* Input:
2846
*	ha = adapter block pointer.
L
Linus Torvalds 已提交
2847
*/
A
Adrian Bunk 已提交
2848
static void
2849
qla2x00_free_fw_dump(struct qla_hw_data *ha)
L
Linus Torvalds 已提交
2850
{
2851 2852
	if (ha->fce)
		dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
2853
		    ha->fce_dma);
2854

2855 2856 2857
	if (ha->fw_dump) {
		if (ha->eft)
			dma_free_coherent(&ha->pdev->dev,
2858
			    ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma);
2859 2860
		vfree(ha->fw_dump);
	}
2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883
	ha->fce = NULL;
	ha->fce_dma = 0;
	ha->eft = NULL;
	ha->eft_dma = 0;
	ha->fw_dump = NULL;
	ha->fw_dumped = 0;
	ha->fw_dump_reading = 0;
}

/*
* qla2x00_mem_free
*      Frees all adapter allocated memory.
*
* Input:
*      ha = adapter block pointer.
*/
static void
qla2x00_mem_free(struct qla_hw_data *ha)
{
	qla2x00_free_fw_dump(ha);

	if (ha->srb_mempool)
		mempool_destroy(ha->srb_mempool);
2884

2885 2886 2887 2888
	if (ha->dcbx_tlv)
		dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE,
		    ha->dcbx_tlv, ha->dcbx_tlv_dma);

2889 2890 2891 2892
	if (ha->xgmac_data)
		dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE,
		    ha->xgmac_data, ha->xgmac_data_dma);

L
Linus Torvalds 已提交
2893 2894
	if (ha->sns_cmd)
		dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),
2895
		ha->sns_cmd, ha->sns_cmd_dma);
L
Linus Torvalds 已提交
2896 2897 2898

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

2901 2902 2903
	if (ha->sfp_data)
		dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);

2904 2905 2906
	if (ha->edc_data)
		dma_pool_free(ha->s_dma_pool, ha->edc_data, ha->edc_data_dma);

L
Linus Torvalds 已提交
2907 2908 2909
	if (ha->ms_iocb)
		dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);

2910
	if (ha->ex_init_cb)
2911 2912
		dma_pool_free(ha->s_dma_pool,
			ha->ex_init_cb, ha->ex_init_cb_dma);
2913

2914 2915 2916
	if (ha->async_pd)
		dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);

L
Linus Torvalds 已提交
2917 2918 2919 2920 2921
	if (ha->s_dma_pool)
		dma_pool_destroy(ha->s_dma_pool);

	if (ha->gid_list)
		dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
2922
		ha->gid_list_dma);
L
Linus Torvalds 已提交
2923

2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947
	if (IS_QLA82XX(ha)) {
		if (!list_empty(&ha->gbl_dsd_list)) {
			struct dsd_dma *dsd_ptr, *tdsd_ptr;

			/* clean up allocated prev pool */
			list_for_each_entry_safe(dsd_ptr,
				tdsd_ptr, &ha->gbl_dsd_list, list) {
				dma_pool_free(ha->dl_dma_pool,
				dsd_ptr->dsd_addr, dsd_ptr->dsd_list_dma);
				list_del(&dsd_ptr->list);
				kfree(dsd_ptr);
			}
		}
	}

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

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

	if (ha->ctx_mempool)
		mempool_destroy(ha->ctx_mempool);

2948 2949
	if (ha->init_cb)
		dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
2950
			ha->init_cb, ha->init_cb_dma);
2951 2952
	vfree(ha->optrom_buffer);
	kfree(ha->nvram);
2953
	kfree(ha->npiv_info);
L
Linus Torvalds 已提交
2954

2955
	ha->srb_mempool = NULL;
2956
	ha->ctx_mempool = NULL;
L
Linus Torvalds 已提交
2957 2958 2959 2960 2961 2962 2963 2964
	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;
2965 2966
	ha->ex_init_cb = NULL;
	ha->ex_init_cb_dma = 0;
2967 2968
	ha->async_pd = NULL;
	ha->async_pd_dma = 0;
L
Linus Torvalds 已提交
2969 2970

	ha->s_dma_pool = NULL;
2971 2972
	ha->dl_dma_pool = NULL;
	ha->fcp_cmnd_dma_pool = NULL;
L
Linus Torvalds 已提交
2973 2974 2975

	ha->gid_list = NULL;
	ha->gid_list_dma = 0;
2976
}
L
Linus Torvalds 已提交
2977

2978 2979 2980 2981 2982
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;
2983

2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002
	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);

3003 3004
	spin_lock_init(&vha->work_lock);

3005 3006 3007 3008 3009
	sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no);
	return vha;

fail:
	return vha;
L
Linus Torvalds 已提交
3010 3011
}

3012
static struct qla_work_evt *
3013
qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type)
3014 3015
{
	struct qla_work_evt *e;
3016 3017 3018 3019 3020
	uint8_t bail;

	QLA_VHA_MARK_BUSY(vha, bail);
	if (bail)
		return NULL;
3021

3022
	e = kzalloc(sizeof(struct qla_work_evt), GFP_ATOMIC);
3023 3024
	if (!e) {
		QLA_VHA_MARK_NOT_BUSY(vha);
3025
		return NULL;
3026
	}
3027 3028 3029 3030 3031 3032 3033

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

3034
static int
3035
qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e)
3036
{
3037
	unsigned long flags;
3038

3039
	spin_lock_irqsave(&vha->work_lock, flags);
3040
	list_add_tail(&e->list, &vha->work_list);
3041
	spin_unlock_irqrestore(&vha->work_lock, flags);
3042
	qla2xxx_wake_dpc(vha);
3043

3044 3045 3046 3047
	return QLA_SUCCESS;
}

int
3048
qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code,
3049 3050 3051 3052
    u32 data)
{
	struct qla_work_evt *e;

3053
	e = qla2x00_alloc_work(vha, QLA_EVT_AEN);
3054 3055 3056 3057 3058
	if (!e)
		return QLA_FUNCTION_FAILED;

	e->u.aen.code = code;
	e->u.aen.data = data;
3059
	return qla2x00_post_work(vha, e);
3060 3061
}

3062 3063 3064 3065 3066
int
qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
{
	struct qla_work_evt *e;

3067
	e = qla2x00_alloc_work(vha, QLA_EVT_IDC_ACK);
3068 3069 3070 3071
	if (!e)
		return QLA_FUNCTION_FAILED;

	memcpy(e->u.idc_ack.mb, mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3072
	return qla2x00_post_work(vha, e);
3073 3074
}

3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097
#define qla2x00_post_async_work(name, type)	\
int qla2x00_post_async_##name##_work(		\
    struct scsi_qla_host *vha,			\
    fc_port_t *fcport, uint16_t *data)		\
{						\
	struct qla_work_evt *e;			\
						\
	e = qla2x00_alloc_work(vha, type);	\
	if (!e)					\
		return QLA_FUNCTION_FAILED;	\
						\
	e->u.logio.fcport = fcport;		\
	if (data) {				\
		e->u.logio.data[0] = data[0];	\
		e->u.logio.data[1] = data[1];	\
	}					\
	return qla2x00_post_work(vha, e);	\
}

qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN);
qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
3098 3099
qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC);
qla2x00_post_async_work(adisc_done, QLA_EVT_ASYNC_ADISC_DONE);
3100

3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131
int
qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code)
{
	struct qla_work_evt *e;

	e = qla2x00_alloc_work(vha, QLA_EVT_UEVENT);
	if (!e)
		return QLA_FUNCTION_FAILED;

	e->u.uevent.code = code;
	return qla2x00_post_work(vha, e);
}

static void
qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code)
{
	char event_string[40];
	char *envp[] = { event_string, NULL };

	switch (code) {
	case QLA_UEVENT_CODE_FW_DUMP:
		snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld",
		    vha->host_no);
		break;
	default:
		/* do nothing */
		break;
	}
	kobject_uevent_env(&vha->hw->pdev->dev.kobj, KOBJ_CHANGE, envp);
}

3132
void
3133
qla2x00_do_work(struct scsi_qla_host *vha)
3134
{
3135 3136 3137
	struct qla_work_evt *e, *tmp;
	unsigned long flags;
	LIST_HEAD(work);
3138

3139 3140 3141 3142 3143
	spin_lock_irqsave(&vha->work_lock, flags);
	list_splice_init(&vha->work_list, &work);
	spin_unlock_irqrestore(&vha->work_lock, flags);

	list_for_each_entry_safe(e, tmp, &work, list) {
3144 3145 3146 3147
		list_del_init(&e->list);

		switch (e->type) {
		case QLA_EVT_AEN:
3148
			fc_host_post_event(vha->host, fc_get_event_number(),
3149 3150
			    e->u.aen.code, e->u.aen.data);
			break;
3151 3152 3153
		case QLA_EVT_IDC_ACK:
			qla81xx_idc_ack(vha, e->u.idc_ack.mb);
			break;
3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168
		case QLA_EVT_ASYNC_LOGIN:
			qla2x00_async_login(vha, e->u.logio.fcport,
			    e->u.logio.data);
			break;
		case QLA_EVT_ASYNC_LOGIN_DONE:
			qla2x00_async_login_done(vha, e->u.logio.fcport,
			    e->u.logio.data);
			break;
		case QLA_EVT_ASYNC_LOGOUT:
			qla2x00_async_logout(vha, e->u.logio.fcport);
			break;
		case QLA_EVT_ASYNC_LOGOUT_DONE:
			qla2x00_async_logout_done(vha, e->u.logio.fcport,
			    e->u.logio.data);
			break;
3169 3170 3171 3172 3173 3174 3175 3176
		case QLA_EVT_ASYNC_ADISC:
			qla2x00_async_adisc(vha, e->u.logio.fcport,
			    e->u.logio.data);
			break;
		case QLA_EVT_ASYNC_ADISC_DONE:
			qla2x00_async_adisc_done(vha, e->u.logio.fcport,
			    e->u.logio.data);
			break;
3177 3178 3179
		case QLA_EVT_UEVENT:
			qla2x00_uevent_emit(vha, e->u.uevent.code);
			break;
3180 3181 3182
		}
		if (e->flags & QLA_EVT_FLAG_FREE)
			kfree(e);
3183 3184 3185

		/* For each work completed decrement vha ref count */
		QLA_VHA_MARK_NOT_BUSY(vha);
3186 3187
	}
}
3188

3189 3190 3191 3192 3193 3194
/* Relogins all the fcports of a vport
 * Context: dpc thread
 */
void qla2x00_relogin(struct scsi_qla_host *vha)
{
	fc_port_t       *fcport;
3195
	int status;
3196 3197
	uint16_t        next_loopid = 0;
	struct qla_hw_data *ha = vha->hw;
3198
	uint16_t data[2];
3199 3200 3201 3202 3203 3204

	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.
	 */
3205 3206
		if (atomic_read(&fcport->state) != FCS_ONLINE &&
		    fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) {
3207
			fcport->login_retry--;
3208
			if (fcport->flags & FCF_FABRIC_DEVICE) {
3209
				if (fcport->flags & FCF_FCP2_DEVICE)
3210 3211 3212 3213 3214 3215
					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);

3216
				if (IS_ALOGIO_CAPABLE(ha)) {
3217
					fcport->flags |= FCF_ASYNC_SENT;
3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228
					data[0] = 0;
					data[1] = QLA_LOGIO_LOGIN_RETRIED;
					status = qla2x00_post_async_login_work(
					    vha, fcport, data);
					if (status == QLA_SUCCESS)
						continue;
					/* Attempt a retry. */
					status = 1;
				} else
					status = qla2x00_fabric_login(vha,
					    fcport, &next_loopid);
3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256
			} else
				status = qla2x00_local_device_login(vha,
								fcport);

			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;
3257 3258 3259
	}
}

L
Linus Torvalds 已提交
3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275
/**************************************************************************
* 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)
{
3276
	int		rval;
3277 3278
	scsi_qla_host_t *base_vha;
	struct qla_hw_data *ha;
L
Linus Torvalds 已提交
3279

3280 3281
	ha = (struct qla_hw_data *)data;
	base_vha = pci_get_drvdata(ha->pdev);
L
Linus Torvalds 已提交
3282 3283 3284

	set_user_nice(current, -20);

3285
	while (!kthread_should_stop()) {
L
Linus Torvalds 已提交
3286 3287
		DEBUG3(printk("qla2x00: DPC handler sleeping\n"));

3288 3289 3290
		set_current_state(TASK_INTERRUPTIBLE);
		schedule();
		__set_current_state(TASK_RUNNING);
L
Linus Torvalds 已提交
3291 3292 3293 3294

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

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

3298 3299 3300 3301 3302 3303 3304
		if (ha->flags.eeh_busy) {
			DEBUG17(qla_printk(KERN_WARNING, ha,
			    "qla2x00_do_dpc: dpc_flags: %lx\n",
			    base_vha->dpc_flags));
			continue;
		}

3305
		DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no));
L
Linus Torvalds 已提交
3306 3307 3308 3309 3310 3311 3312 3313

		ha->dpc_active = 1;

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

3314
		qla2x00_do_work(base_vha);
3315

3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354
		if (IS_QLA82XX(ha)) {
			if (test_and_clear_bit(ISP_UNRECOVERABLE,
				&base_vha->dpc_flags)) {
				qla82xx_idc_lock(ha);
				qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
					QLA82XX_DEV_FAILED);
				qla82xx_idc_unlock(ha);
				qla_printk(KERN_INFO, ha,
					"HW State: FAILED\n");
				qla82xx_device_state_handler(base_vha);
				continue;
			}

			if (test_and_clear_bit(FCOE_CTX_RESET_NEEDED,
				&base_vha->dpc_flags)) {

				DEBUG(printk(KERN_INFO
					"scsi(%ld): dpc: sched "
					"qla82xx_fcoe_ctx_reset ha = %p\n",
					base_vha->host_no, ha));
				if (!(test_and_set_bit(ABORT_ISP_ACTIVE,
					&base_vha->dpc_flags))) {
					if (qla82xx_fcoe_ctx_reset(base_vha)) {
						/* FCoE-ctx reset failed.
						 * Escalate to chip-reset
						 */
						set_bit(ISP_ABORT_NEEDED,
							&base_vha->dpc_flags);
					}
					clear_bit(ABORT_ISP_ACTIVE,
						&base_vha->dpc_flags);
				}

				DEBUG(printk("scsi(%ld): dpc:"
					" qla82xx_fcoe_ctx_reset end\n",
					base_vha->host_no));
			}
		}

3355 3356
		if (test_and_clear_bit(ISP_ABORT_NEEDED,
						&base_vha->dpc_flags)) {
L
Linus Torvalds 已提交
3357 3358 3359

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

3364
				if (ha->isp_ops->abort_isp(base_vha)) {
L
Linus Torvalds 已提交
3365 3366
					/* failed. retry later */
					set_bit(ISP_ABORT_NEEDED,
3367
					    &base_vha->dpc_flags);
3368
				}
3369 3370
				clear_bit(ABORT_ISP_ACTIVE,
						&base_vha->dpc_flags);
3371 3372
			}

L
Linus Torvalds 已提交
3373
			DEBUG(printk("scsi(%ld): dpc: qla2x00_abort_isp end\n",
3374
			    base_vha->host_no));
L
Linus Torvalds 已提交
3375 3376
		}

3377 3378 3379
		if (test_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags)) {
			qla2x00_update_fcports(base_vha);
			clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
3380
		}
3381

3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396
		if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) {
			DEBUG(printk(KERN_INFO "scsi(%ld): dpc: sched "
			    "qla2x00_quiesce_needed ha = %p\n",
			    base_vha->host_no, ha));
			qla82xx_device_state_handler(base_vha);
			clear_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags);
			if (!ha->flags.quiesce_owner) {
				qla2x00_perform_loop_resync(base_vha);

				qla82xx_idc_lock(ha);
				qla82xx_clear_qsnt_ready(base_vha);
				qla82xx_idc_unlock(ha);
			}
		}

3397 3398 3399
		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 已提交
3400 3401

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

3404 3405
			qla2x00_rst_aen(base_vha);
			clear_bit(RESET_ACTIVE, &base_vha->dpc_flags);
L
Linus Torvalds 已提交
3406 3407 3408
		}

		/* Retry each device up to login retry count */
3409 3410 3411 3412
		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 已提交
3413 3414

			DEBUG(printk("scsi(%ld): qla2x00_port_login()\n",
3415 3416 3417
					base_vha->host_no));
			qla2x00_relogin(base_vha);

L
Linus Torvalds 已提交
3418
			DEBUG(printk("scsi(%ld): qla2x00_port_login - end\n",
3419
			    base_vha->host_no));
L
Linus Torvalds 已提交
3420 3421
		}

3422 3423
		if (test_and_clear_bit(LOOP_RESYNC_NEEDED,
							&base_vha->dpc_flags)) {
L
Linus Torvalds 已提交
3424 3425

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

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

3431
				rval = qla2x00_loop_resync(base_vha);
L
Linus Torvalds 已提交
3432

3433 3434
				clear_bit(LOOP_RESYNC_ACTIVE,
						&base_vha->dpc_flags);
L
Linus Torvalds 已提交
3435 3436 3437
			}

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

3441 3442 3443 3444
		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);
3445 3446
		}

L
Linus Torvalds 已提交
3447
		if (!ha->interrupts_on)
3448
			ha->isp_ops->enable_intrs(ha);
L
Linus Torvalds 已提交
3449

3450 3451 3452
		if (test_and_clear_bit(BEACON_BLINK_NEEDED,
					&base_vha->dpc_flags))
			ha->isp_ops->beacon_blink(base_vha);
3453

3454
		qla2x00_do_dpc_all_vps(base_vha);
3455

L
Linus Torvalds 已提交
3456 3457 3458
		ha->dpc_active = 0;
	} /* End of while(1) */

3459
	DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no));
L
Linus Torvalds 已提交
3460 3461 3462 3463 3464 3465

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

3466 3467 3468
	/* Cleanup any residual CTX SRBs. */
	qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);

3469 3470 3471 3472
	return 0;
}

void
3473
qla2xxx_wake_dpc(struct scsi_qla_host *vha)
3474
{
3475
	struct qla_hw_data *ha = vha->hw;
3476 3477
	struct task_struct *t = ha->dpc_thread;

3478
	if (!test_bit(UNLOADING, &vha->dpc_flags) && t)
3479
		wake_up_process(t);
L
Linus Torvalds 已提交
3480 3481 3482 3483 3484 3485 3486 3487 3488 3489
}

/*
*  qla2x00_rst_aen
*      Processes asynchronous reset.
*
* Input:
*      ha  = adapter block pointer.
*/
static void
3490
qla2x00_rst_aen(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
3491
{
3492 3493 3494
	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 已提交
3495
		do {
3496
			clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
L
Linus Torvalds 已提交
3497 3498 3499 3500 3501

			/*
			 * Issue marker command only when we are going to start
			 * the I/O.
			 */
3502 3503 3504
			vha->marker_needed = 1;
		} while (!atomic_read(&vha->loop_down_timer) &&
		    (test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags)));
L
Linus Torvalds 已提交
3505 3506 3507
	}
}

已提交
3508
static void
3509
qla2x00_sp_free_dma(srb_t *sp)
已提交
3510 3511
{
	struct scsi_cmnd *cmd = sp->cmd;
3512
	struct qla_hw_data *ha = sp->fcport->vha->hw;
已提交
3513 3514

	if (sp->flags & SRB_DMA_VALID) {
3515
		scsi_dma_unmap(cmd);
已提交
3516 3517
		sp->flags &= ~SRB_DMA_VALID;
	}
3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536

	if (sp->flags & SRB_CRC_PROT_DMA_VALID) {
		dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
		    scsi_prot_sg_count(cmd), cmd->sc_data_direction);
		sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
	}

	if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
		/* List assured to be having elements */
		qla2x00_clean_dsd_pool(ha, sp);
		sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
	}

	if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
		dma_pool_free(ha->dl_dma_pool, sp->ctx,
		    ((struct crc_context *)sp->ctx)->crc_ctx_dma);
		sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
	}

3537
	CMD_SP(cmd) = NULL;
已提交
3538 3539
}

3540
static void
3541
qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
已提交
3542 3543 3544
{
	struct scsi_cmnd *cmd = sp->cmd;

3545
	qla2x00_sp_free_dma(sp);
已提交
3546

3547 3548 3549 3550 3551 3552 3553 3554 3555 3556
	if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
		struct ct6_dsd *ctx = sp->ctx;
		dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd,
			ctx->fcp_cmnd_dma);
		list_splice(&ctx->dsd_list, &ha->gbl_dsd_list);
		ha->gbl_dsd_inuse -= ctx->dsd_use_cnt;
		ha->gbl_dsd_avail += ctx->dsd_use_cnt;
		mempool_free(sp->ctx, ha->ctx_mempool);
		sp->ctx = NULL;
	}
已提交
3557

3558
	mempool_free(sp, ha->srb_mempool);
已提交
3559 3560
	cmd->scsi_done(cmd);
}
3561

3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575
void
qla2x00_sp_compl(struct qla_hw_data *ha, srb_t *sp)
{
	if (atomic_read(&sp->ref_count) == 0) {
		DEBUG2(qla_printk(KERN_WARNING, ha,
		    "SP reference-count to ZERO -- sp=%p\n", sp));
		DEBUG2(BUG());
		return;
	}
	if (!atomic_dec_and_test(&sp->ref_count))
		return;
	qla2x00_sp_final_compl(ha, sp);
}

L
Linus Torvalds 已提交
3576 3577 3578 3579 3580 3581 3582 3583
/**************************************************************************
*   qla2x00_timer
*
* Description:
*   One second timer
*
* Context: Interrupt
***************************************************************************/
3584
void
3585
qla2x00_timer(scsi_qla_host_t *vha)
L
Linus Torvalds 已提交
3586 3587 3588 3589 3590
{
	unsigned long	cpu_flags = 0;
	int		start_dpc = 0;
	int		index;
	srb_t		*sp;
3591
	uint16_t        w;
3592
	struct qla_hw_data *ha = vha->hw;
3593
	struct req_que *req;
3594

3595 3596 3597 3598 3599
	if (ha->flags.eeh_busy) {
		qla2x00_restart_timer(vha, WATCH_INTERVAL);
		return;
	}

3600 3601 3602
	/* Hardware read to raise pending EEH errors during mailbox waits. */
	if (!pci_channel_offline(ha->pdev))
		pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
L
Linus Torvalds 已提交
3603

3604 3605 3606 3607 3608 3609
	if (IS_QLA82XX(ha)) {
		if (test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags))
			start_dpc++;
		qla82xx_watchdog(vha);
	}

L
Linus Torvalds 已提交
3610
	/* Loop down handler. */
3611 3612 3613
	if (atomic_read(&vha->loop_down_timer) > 0 &&
	    !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
		&& vha->flags.online) {
L
Linus Torvalds 已提交
3614

3615 3616
		if (atomic_read(&vha->loop_down_timer) ==
		    vha->loop_down_abort_time) {
L
Linus Torvalds 已提交
3617 3618 3619

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

3622 3623
			if (!IS_QLA2100(ha) && vha->link_down_timeout)
				atomic_set(&vha->loop_state, LOOP_DEAD);
L
Linus Torvalds 已提交
3624

3625 3626 3627 3628
			/*
			 * Schedule an ISP abort to return any FCP2-device
			 * commands.
			 */
3629
			/* NPIV - scan physical port only */
3630
			if (!vha->vp_idx) {
3631 3632
				spin_lock_irqsave(&ha->hardware_lock,
				    cpu_flags);
3633
				req = ha->req_q_map[0];
3634 3635 3636 3637 3638
				for (index = 1;
				    index < MAX_OUTSTANDING_COMMANDS;
				    index++) {
					fc_port_t *sfcp;

3639
					sp = req->outstanding_cmds[index];
3640 3641
					if (!sp)
						continue;
3642
					if (sp->ctx && !IS_PROT_IO(sp))
3643
						continue;
3644
					sfcp = sp->fcport;
3645
					if (!(sfcp->flags & FCF_FCP2_DEVICE))
3646
						continue;
3647

3648
					set_bit(ISP_ABORT_NEEDED,
3649
							&vha->dpc_flags);
3650 3651 3652
					break;
				}
				spin_unlock_irqrestore(&ha->hardware_lock,
3653
								cpu_flags);
L
Linus Torvalds 已提交
3654 3655 3656 3657 3658
			}
			start_dpc++;
		}

		/* if the loop has been down for 4 minutes, reinit adapter */
3659
		if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
3660
			if (!(vha->device_flags & DFLG_NO_CABLE)) {
L
Linus Torvalds 已提交
3661 3662
				DEBUG(printk("scsi(%ld): Loop down - "
				    "aborting ISP.\n",
3663
				    vha->host_no));
L
Linus Torvalds 已提交
3664 3665 3666
				qla_printk(KERN_WARNING, ha,
				    "Loop down - aborting ISP.\n");

3667
				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
L
Linus Torvalds 已提交
3668 3669
			}
		}
3670
		DEBUG3(printk("scsi(%ld): Loop Down - seconds remaining %d\n",
3671 3672
		    vha->host_no,
		    atomic_read(&vha->loop_down_timer)));
L
Linus Torvalds 已提交
3673 3674
	}

3675 3676
	/* Check if beacon LED needs to be blinked */
	if (ha->beacon_blink_led == 1) {
3677
		set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags);
3678 3679 3680
		start_dpc++;
	}

3681
	/* Process any deferred work. */
3682
	if (!list_empty(&vha->work_list))
3683 3684
		start_dpc++;

L
Linus Torvalds 已提交
3685
	/* Schedule the DPC routine if needed */
3686 3687 3688
	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 已提交
3689
	    start_dpc ||
3690 3691
	    test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) ||
	    test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags) ||
3692 3693
	    test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) ||
	    test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) ||
3694 3695 3696
	    test_bit(VP_DPC_NEEDED, &vha->dpc_flags) ||
	    test_bit(RELOGIN_NEEDED, &vha->dpc_flags)))
		qla2xxx_wake_dpc(vha);
L
Linus Torvalds 已提交
3697

3698
	qla2x00_restart_timer(vha, WATCH_INTERVAL);
L
Linus Torvalds 已提交
3699 3700
}

3701 3702
/* Firmware interface routines. */

3703
#define FW_BLOBS	8
3704 3705 3706 3707
#define FW_ISP21XX	0
#define FW_ISP22XX	1
#define FW_ISP2300	2
#define FW_ISP2322	3
3708
#define FW_ISP24XX	4
3709
#define FW_ISP25XX	5
3710
#define FW_ISP81XX	6
3711
#define FW_ISP82XX	7
3712

3713 3714 3715 3716 3717
#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"
3718
#define FW_FILE_ISP25XX	"ql2500_fw.bin"
3719
#define FW_FILE_ISP81XX	"ql8100_fw.bin"
3720
#define FW_FILE_ISP82XX	"ql8200_fw.bin"
3721

3722
static DEFINE_MUTEX(qla_fw_lock);
3723 3724

static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
3725 3726 3727 3728 3729
	{ .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, },
3730
	{ .name = FW_FILE_ISP25XX, },
3731
	{ .name = FW_FILE_ISP81XX, },
3732
	{ .name = FW_FILE_ISP82XX, },
3733 3734 3735
};

struct fw_blob *
3736
qla2x00_request_firmware(scsi_qla_host_t *vha)
3737
{
3738
	struct qla_hw_data *ha = vha->hw;
3739 3740 3741 3742 3743 3744 3745
	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];
3746
	} else if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
3747
		blob = &qla_fw_blobs[FW_ISP2300];
3748
	} else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
3749
		blob = &qla_fw_blobs[FW_ISP2322];
3750
	} else if (IS_QLA24XX_TYPE(ha)) {
3751
		blob = &qla_fw_blobs[FW_ISP24XX];
3752 3753
	} else if (IS_QLA25XX(ha)) {
		blob = &qla_fw_blobs[FW_ISP25XX];
3754 3755
	} else if (IS_QLA81XX(ha)) {
		blob = &qla_fw_blobs[FW_ISP81XX];
3756 3757
	} else if (IS_QLA82XX(ha)) {
		blob = &qla_fw_blobs[FW_ISP82XX];
3758 3759
	}

3760
	mutex_lock(&qla_fw_lock);
3761 3762 3763 3764 3765
	if (blob->fw)
		goto out;

	if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
		DEBUG2(printk("scsi(%ld): Failed to load firmware image "
3766
		    "(%s).\n", vha->host_no, blob->name));
3767 3768 3769 3770 3771 3772
		blob->fw = NULL;
		blob = NULL;
		goto out;
	}

out:
3773
	mutex_unlock(&qla_fw_lock);
3774 3775 3776 3777 3778 3779 3780 3781
	return blob;
}

static void
qla2x00_release_firmware(void)
{
	int idx;

3782
	mutex_lock(&qla_fw_lock);
3783 3784 3785
	for (idx = 0; idx < FW_BLOBS; idx++)
		if (qla_fw_blobs[idx].fw)
			release_firmware(qla_fw_blobs[idx].fw);
3786
	mutex_unlock(&qla_fw_lock);
3787 3788
}

3789 3790 3791
static pci_ers_result_t
qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
{
3792 3793 3794 3795 3796
	scsi_qla_host_t *vha = pci_get_drvdata(pdev);
	struct qla_hw_data *ha = vha->hw;

	DEBUG2(qla_printk(KERN_WARNING, ha, "error_detected:state %x\n",
	    state));
3797

3798 3799
	switch (state) {
	case pci_channel_io_normal:
3800
		ha->flags.eeh_busy = 0;
3801 3802
		return PCI_ERS_RESULT_CAN_RECOVER;
	case pci_channel_io_frozen:
3803
		ha->flags.eeh_busy = 1;
3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814
		/* For ISP82XX complete any pending mailbox cmd */
		if (IS_QLA82XX(ha)) {
			ha->flags.fw_hung = 1;
			if (ha->flags.mbox_busy) {
				ha->flags.mbox_int = 1;
				DEBUG2(qla_printk(KERN_ERR, ha,
					"Due to pci channel io frozen, doing premature "
					"completion of mbx command\n"));
				complete(&ha->mbx_intr_comp);
			}
		}
3815
		qla2x00_free_irqs(vha);
3816
		pci_disable_device(pdev);
3817 3818
		/* Return back all IOs */
		qla2x00_abort_all_cmds(vha, DID_RESET << 16);
3819 3820
		return PCI_ERS_RESULT_NEED_RESET;
	case pci_channel_io_perm_failure:
3821 3822
		ha->flags.pci_channel_io_perm_failure = 1;
		qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833
		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;
3834 3835
	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
	struct qla_hw_data *ha = base_vha->hw;
3836 3837 3838
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;

3839 3840 3841
	if (IS_QLA82XX(ha))
		return PCI_ERS_RESULT_RECOVERED;

3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860
	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");
3861
		ha->isp_ops->fw_dump(base_vha, 0);
3862 3863 3864 3865 3866 3867

		return PCI_ERS_RESULT_NEED_RESET;
	} else
		return PCI_ERS_RESULT_RECOVERED;
}

3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970
uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha)
{
	uint32_t rval = QLA_FUNCTION_FAILED;
	uint32_t drv_active = 0;
	struct qla_hw_data *ha = base_vha->hw;
	int fn;
	struct pci_dev *other_pdev = NULL;

	DEBUG17(qla_printk(KERN_INFO, ha,
	    "scsi(%ld): In qla82xx_error_recovery\n", base_vha->host_no));

	set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);

	if (base_vha->flags.online) {
		/* Abort all outstanding commands,
		 * so as to be requeued later */
		qla2x00_abort_isp_cleanup(base_vha);
	}


	fn = PCI_FUNC(ha->pdev->devfn);
	while (fn > 0) {
		fn--;
		DEBUG17(qla_printk(KERN_INFO, ha,
		    "Finding pci device at function = 0x%x\n", fn));
		other_pdev =
		    pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus),
		    ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn),
		    fn));

		if (!other_pdev)
			continue;
		if (atomic_read(&other_pdev->enable_cnt)) {
			DEBUG17(qla_printk(KERN_INFO, ha,
			    "Found PCI func availabe and enabled at 0x%x\n",
			    fn));
			pci_dev_put(other_pdev);
			break;
		}
		pci_dev_put(other_pdev);
	}

	if (!fn) {
		/* Reset owner */
		DEBUG17(qla_printk(KERN_INFO, ha,
		    "This devfn is reset owner = 0x%x\n", ha->pdev->devfn));
		qla82xx_idc_lock(ha);

		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
		    QLA82XX_DEV_INITIALIZING);

		qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
		    QLA82XX_IDC_VERSION);

		drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
		DEBUG17(qla_printk(KERN_INFO, ha,
		    "drv_active = 0x%x\n", drv_active));

		qla82xx_idc_unlock(ha);
		/* Reset if device is not already reset
		 * drv_active would be 0 if a reset has already been done
		 */
		if (drv_active)
			rval = qla82xx_start_firmware(base_vha);
		else
			rval = QLA_SUCCESS;
		qla82xx_idc_lock(ha);

		if (rval != QLA_SUCCESS) {
			qla_printk(KERN_INFO, ha, "HW State: FAILED\n");
			qla82xx_clear_drv_active(ha);
			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
			    QLA82XX_DEV_FAILED);
		} else {
			qla_printk(KERN_INFO, ha, "HW State: READY\n");
			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
			    QLA82XX_DEV_READY);
			qla82xx_idc_unlock(ha);
			ha->flags.fw_hung = 0;
			rval = qla82xx_restart_isp(base_vha);
			qla82xx_idc_lock(ha);
			/* Clear driver state register */
			qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0);
			qla82xx_set_drv_active(base_vha);
		}
		qla82xx_idc_unlock(ha);
	} else {
		DEBUG17(qla_printk(KERN_INFO, ha,
		    "This devfn is not reset owner = 0x%x\n", ha->pdev->devfn));
		if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
		    QLA82XX_DEV_READY)) {
			ha->flags.fw_hung = 0;
			rval = qla82xx_restart_isp(base_vha);
			qla82xx_idc_lock(ha);
			qla82xx_set_drv_active(base_vha);
			qla82xx_idc_unlock(ha);
		}
	}
	clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);

	return rval;
}

3971 3972 3973 3974
static pci_ers_result_t
qla2xxx_pci_slot_reset(struct pci_dev *pdev)
{
	pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT;
3975 3976
	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
	struct qla_hw_data *ha = base_vha->hw;
3977 3978
	struct rsp_que *rsp;
	int rc, retries = 10;
3979

3980 3981
	DEBUG17(qla_printk(KERN_WARNING, ha, "slot_reset\n"));

3982 3983 3984 3985 3986 3987 3988 3989
	/* Workaround: qla2xxx driver which access hardware earlier
	 * needs error state to be pci_channel_io_online.
	 * Otherwise mailbox command timesout.
	 */
	pdev->error_state = pci_channel_io_normal;

	pci_restore_state(pdev);

3990 3991 3992 3993 3994
	/* pci_restore_state() clears the saved_state flag of the device
	 * save restored state which resets saved_state flag
	 */
	pci_save_state(pdev);

3995 3996 3997 3998
	if (ha->mem_only)
		rc = pci_enable_device_mem(pdev);
	else
		rc = pci_enable_device(pdev);
3999

4000
	if (rc) {
4001 4002
		qla_printk(KERN_WARNING, ha,
		    "Can't re-enable PCI device after reset.\n");
4003
		goto exit_slot_reset;
4004 4005
	}

4006 4007
	rsp = ha->rsp_q_map[0];
	if (qla2x00_request_irqs(ha, rsp))
4008
		goto exit_slot_reset;
4009

4010
	if (ha->isp_ops->pci_config(base_vha))
4011 4012 4013 4014 4015 4016 4017 4018 4019
		goto exit_slot_reset;

	if (IS_QLA82XX(ha)) {
		if (qla82xx_error_recovery(base_vha) == QLA_SUCCESS) {
			ret = PCI_ERS_RESULT_RECOVERED;
			goto exit_slot_reset;
		} else
			goto exit_slot_reset;
	}
4020

4021 4022
	while (ha->flags.mbox_busy && retries--)
		msleep(1000);
4023

4024
	set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
4025
	if (ha->isp_ops->abort_isp(base_vha) == QLA_SUCCESS)
4026
		ret =  PCI_ERS_RESULT_RECOVERED;
4027
	clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
4028

4029

4030
exit_slot_reset:
4031 4032 4033
	DEBUG17(qla_printk(KERN_WARNING, ha,
	    "slot_reset-return:ret=%x\n", ret));

4034 4035 4036 4037 4038 4039
	return ret;
}

static void
qla2xxx_pci_resume(struct pci_dev *pdev)
{
4040 4041
	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
	struct qla_hw_data *ha = base_vha->hw;
4042 4043
	int ret;

4044 4045
	DEBUG17(qla_printk(KERN_WARNING, ha, "pci_resume\n"));

4046
	ret = qla2x00_wait_for_hba_online(base_vha);
4047 4048 4049 4050 4051
	if (ret != QLA_SUCCESS) {
		qla_printk(KERN_ERR, ha,
		    "the device failed to resume I/O "
		    "from slot/link_reset");
	}
4052

4053 4054
	pci_cleanup_aer_uncorrect_error_status(pdev);

4055
	ha->flags.eeh_busy = 0;
4056 4057 4058 4059 4060 4061 4062 4063 4064
}

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,
};

4065
static struct pci_device_id qla2xxx_pci_tbl[] = {
4066 4067 4068 4069 4070 4071 4072 4073 4074
	{ 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) },
4075
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) },
4076 4077
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
4078
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },
4079
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8001) },
4080
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8021) },
4081 4082 4083 4084
	{ 0 },
};
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);

4085
static struct pci_driver qla2xxx_pci_driver = {
4086
	.name		= QLA2XXX_DRIVER_NAME,
4087 4088 4089
	.driver		= {
		.owner		= THIS_MODULE,
	},
4090
	.id_table	= qla2xxx_pci_tbl,
4091
	.probe		= qla2x00_probe_one,
A
Adrian Bunk 已提交
4092
	.remove		= qla2x00_remove_one,
4093
	.shutdown	= qla2x00_shutdown,
4094
	.err_handler	= &qla2xxx_err_handler,
4095 4096
};

4097 4098
static struct file_operations apidev_fops = {
	.owner = THIS_MODULE,
4099
	.llseek = noop_llseek,
4100 4101
};

L
Linus Torvalds 已提交
4102 4103 4104 4105 4106 4107
/**
 * qla2x00_module_init - Module initialization.
 **/
static int __init
qla2x00_module_init(void)
{
4108 4109
	int ret = 0;

L
Linus Torvalds 已提交
4110
	/* Allocate cache for SRBs. */
4111
	srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
4112
	    SLAB_HWCACHE_ALIGN, NULL);
L
Linus Torvalds 已提交
4113 4114 4115 4116 4117 4118 4119 4120
	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);
4121
	if (ql2xextended_error_logging)
4122 4123
		strcat(qla2x00_version_str, "-debug");

4124 4125
	qla2xxx_transport_template =
	    fc_attach_transport(&qla2xxx_transport_functions);
4126 4127
	if (!qla2xxx_transport_template) {
		kmem_cache_destroy(srb_cachep);
L
Linus Torvalds 已提交
4128
		return -ENODEV;
4129
	}
4130 4131 4132 4133 4134 4135 4136

	apidev_major = register_chrdev(0, QLA2XXX_APIDEV, &apidev_fops);
	if (apidev_major < 0) {
		printk(KERN_WARNING "qla2xxx: Unable to register char device "
		    "%s\n", QLA2XXX_APIDEV);
	}

4137 4138 4139 4140 4141
	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 已提交
4142
		return -ENODEV;
4143
	}
L
Linus Torvalds 已提交
4144

4145 4146
	printk(KERN_INFO "QLogic Fibre Channel HBA Driver: %s\n",
	    qla2x00_version_str);
4147
	ret = pci_register_driver(&qla2xxx_pci_driver);
4148 4149 4150
	if (ret) {
		kmem_cache_destroy(srb_cachep);
		fc_release_transport(qla2xxx_transport_template);
4151
		fc_release_transport(qla2xxx_transport_vport_template);
4152 4153
	}
	return ret;
L
Linus Torvalds 已提交
4154 4155 4156 4157 4158 4159 4160 4161
}

/**
 * qla2x00_module_exit - Module cleanup.
 **/
static void __exit
qla2x00_module_exit(void)
{
4162
	unregister_chrdev(apidev_major, QLA2XXX_APIDEV);
4163
	pci_unregister_driver(&qla2xxx_pci_driver);
4164
	qla2x00_release_firmware();
4165
	kmem_cache_destroy(srb_cachep);
4166 4167
	if (ctx_cachep)
		kmem_cache_destroy(ctx_cachep);
L
Linus Torvalds 已提交
4168
	fc_release_transport(qla2xxx_transport_template);
4169
	fc_release_transport(qla2xxx_transport_vport_template);
L
Linus Torvalds 已提交
4170 4171 4172 4173 4174 4175 4176 4177 4178
}

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);
4179 4180 4181 4182 4183
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);
4184
MODULE_FIRMWARE(FW_FILE_ISP25XX);