PageRenderTime 110ms CodeModel.GetById 9ms app.highlight 90ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/scsi/qla2xxx/qla_mid.c

https://bitbucket.org/abioy/linux
C | 773 lines | 612 code | 108 blank | 53 comment | 91 complexity | 4d7fde08d20bcc880baa9484ab205ee3 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, GPL-2.0, LGPL-2.0, AGPL-1.0
  1/*
  2 * QLogic Fibre Channel HBA Driver
  3 * Copyright (c)  2003-2008 QLogic Corporation
  4 *
  5 * See LICENSE.qla2xxx for copyright and licensing details.
  6 */
  7#include "qla_def.h"
  8#include "qla_gbl.h"
  9
 10#include <linux/moduleparam.h>
 11#include <linux/vmalloc.h>
 12#include <linux/slab.h>
 13#include <linux/list.h>
 14
 15#include <scsi/scsi_tcq.h>
 16#include <scsi/scsicam.h>
 17#include <linux/delay.h>
 18
 19void
 20qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
 21{
 22	if (vha->vp_idx && vha->timer_active) {
 23		del_timer_sync(&vha->timer);
 24		vha->timer_active = 0;
 25	}
 26}
 27
 28static uint32_t
 29qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
 30{
 31	uint32_t vp_id;
 32	struct qla_hw_data *ha = vha->hw;
 33
 34	/* Find an empty slot and assign an vp_id */
 35	mutex_lock(&ha->vport_lock);
 36	vp_id = find_first_zero_bit(ha->vp_idx_map, ha->max_npiv_vports + 1);
 37	if (vp_id > ha->max_npiv_vports) {
 38		DEBUG15(printk ("vp_id %d is bigger than max-supported %d.\n",
 39		    vp_id, ha->max_npiv_vports));
 40		mutex_unlock(&ha->vport_lock);
 41		return vp_id;
 42	}
 43
 44	set_bit(vp_id, ha->vp_idx_map);
 45	ha->num_vhosts++;
 46	vha->vp_idx = vp_id;
 47	list_add_tail(&vha->list, &ha->vp_list);
 48	mutex_unlock(&ha->vport_lock);
 49	return vp_id;
 50}
 51
 52void
 53qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
 54{
 55	uint16_t vp_id;
 56	struct qla_hw_data *ha = vha->hw;
 57
 58	mutex_lock(&ha->vport_lock);
 59	vp_id = vha->vp_idx;
 60	ha->num_vhosts--;
 61	clear_bit(vp_id, ha->vp_idx_map);
 62	list_del(&vha->list);
 63	mutex_unlock(&ha->vport_lock);
 64}
 65
 66static scsi_qla_host_t *
 67qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name)
 68{
 69	scsi_qla_host_t *vha;
 70	struct scsi_qla_host *tvha;
 71
 72	/* Locate matching device in database. */
 73	list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) {
 74		if (!memcmp(port_name, vha->port_name, WWN_SIZE))
 75			return vha;
 76	}
 77	return NULL;
 78}
 79
 80/*
 81 * qla2x00_mark_vp_devices_dead
 82 *	Updates fcport state when device goes offline.
 83 *
 84 * Input:
 85 *	ha = adapter block pointer.
 86 *	fcport = port structure pointer.
 87 *
 88 * Return:
 89 *	None.
 90 *
 91 * Context:
 92 */
 93static void
 94qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
 95{
 96	fc_port_t *fcport;
 97
 98	list_for_each_entry(fcport, &vha->vp_fcports, list) {
 99		DEBUG15(printk("scsi(%ld): Marking port dead, "
100		    "loop_id=0x%04x :%x\n",
101		    vha->host_no, fcport->loop_id, fcport->vp_idx));
102
103		atomic_set(&fcport->state, FCS_DEVICE_DEAD);
104		qla2x00_mark_device_lost(vha, fcport, 0, 0);
105		atomic_set(&fcport->state, FCS_UNCONFIGURED);
106	}
107}
108
109int
110qla24xx_disable_vp(scsi_qla_host_t *vha)
111{
112	int ret;
113
114	ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
115	atomic_set(&vha->loop_state, LOOP_DOWN);
116	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
117
118	qla2x00_mark_vp_devices_dead(vha);
119	atomic_set(&vha->vp_state, VP_FAILED);
120	vha->flags.management_server_logged_in = 0;
121	if (ret == QLA_SUCCESS) {
122		fc_vport_set_state(vha->fc_vport, FC_VPORT_DISABLED);
123	} else {
124		fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
125		return -1;
126	}
127	return 0;
128}
129
130int
131qla24xx_enable_vp(scsi_qla_host_t *vha)
132{
133	int ret;
134	struct qla_hw_data *ha = vha->hw;
135	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
136
137	/* Check if physical ha port is Up */
138	if (atomic_read(&base_vha->loop_state) == LOOP_DOWN  ||
139		atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
140		vha->vp_err_state =  VP_ERR_PORTDWN;
141		fc_vport_set_state(vha->fc_vport, FC_VPORT_LINKDOWN);
142		goto enable_failed;
143	}
144
145	/* Initialize the new vport unless it is a persistent port */
146	mutex_lock(&ha->vport_lock);
147	ret = qla24xx_modify_vp_config(vha);
148	mutex_unlock(&ha->vport_lock);
149
150	if (ret != QLA_SUCCESS) {
151		fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
152		goto enable_failed;
153	}
154
155	DEBUG15(qla_printk(KERN_INFO, ha,
156	    "Virtual port with id: %d - Enabled\n", vha->vp_idx));
157	return 0;
158
159enable_failed:
160	DEBUG15(qla_printk(KERN_INFO, ha,
161	    "Virtual port with id: %d - Disabled\n", vha->vp_idx));
162	return 1;
163}
164
165static void
166qla24xx_configure_vp(scsi_qla_host_t *vha)
167{
168	struct fc_vport *fc_vport;
169	int ret;
170
171	fc_vport = vha->fc_vport;
172
173	DEBUG15(printk("scsi(%ld): %s: change request #3 for this host.\n",
174	    vha->host_no, __func__));
175	ret = qla2x00_send_change_request(vha, 0x3, vha->vp_idx);
176	if (ret != QLA_SUCCESS) {
177		DEBUG15(qla_printk(KERN_ERR, vha->hw, "Failed to enable "
178		    "receiving of RSCN requests: 0x%x\n", ret));
179		return;
180	} else {
181		/* Corresponds to SCR enabled */
182		clear_bit(VP_SCR_NEEDED, &vha->vp_flags);
183	}
184
185	vha->flags.online = 1;
186	if (qla24xx_configure_vhba(vha))
187		return;
188
189	atomic_set(&vha->vp_state, VP_ACTIVE);
190	fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
191}
192
193void
194qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
195{
196	scsi_qla_host_t *vha, *tvha;
197	struct qla_hw_data *ha = rsp->hw;
198	int i = 0;
199
200	list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) {
201		if (vha->vp_idx) {
202			switch (mb[0]) {
203			case MBA_LIP_OCCURRED:
204			case MBA_LOOP_UP:
205			case MBA_LOOP_DOWN:
206			case MBA_LIP_RESET:
207			case MBA_POINT_TO_POINT:
208			case MBA_CHG_IN_CONNECTION:
209			case MBA_PORT_UPDATE:
210			case MBA_RSCN_UPDATE:
211				DEBUG15(printk("scsi(%ld)%s: Async_event for"
212				" VP[%d], mb = 0x%x, vha=%p\n",
213				vha->host_no, __func__, i, *mb, vha));
214				qla2x00_async_event(vha, rsp, mb);
215				break;
216			}
217		}
218		i++;
219	}
220}
221
222int
223qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
224{
225	/*
226	 * Physical port will do most of the abort and recovery work. We can
227	 * just treat it as a loop down
228	 */
229	if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
230		atomic_set(&vha->loop_state, LOOP_DOWN);
231		qla2x00_mark_all_devices_lost(vha, 0);
232	} else {
233		if (!atomic_read(&vha->loop_down_timer))
234			atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
235	}
236
237	/*
238	 * To exclusively reset vport, we need to log it out first.  Note: this
239	 * control_vp can fail if ISP reset is already issued, this is
240	 * expected, as the vp would be already logged out due to ISP reset.
241	 */
242	if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
243		qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
244
245	DEBUG15(printk("scsi(%ld): Scheduling enable of Vport %d...\n",
246	    vha->host_no, vha->vp_idx));
247	return qla24xx_enable_vp(vha);
248}
249
250static int
251qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
252{
253	qla2x00_do_work(vha);
254
255	if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
256		/* VP acquired. complete port configuration */
257		qla24xx_configure_vp(vha);
258		return 0;
259	}
260
261	if (test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) {
262		qla2x00_update_fcports(vha);
263		clear_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags);
264	}
265
266	if ((test_and_clear_bit(RELOGIN_NEEDED, &vha->dpc_flags)) &&
267		!test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) &&
268		atomic_read(&vha->loop_state) != LOOP_DOWN) {
269
270		DEBUG(printk("scsi(%ld): qla2x00_port_login()\n",
271						vha->host_no));
272		qla2x00_relogin(vha);
273
274		DEBUG(printk("scsi(%ld): qla2x00_port_login - end\n",
275							vha->host_no));
276	}
277
278	if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) &&
279	    (!(test_and_set_bit(RESET_ACTIVE, &vha->dpc_flags)))) {
280		clear_bit(RESET_ACTIVE, &vha->dpc_flags);
281	}
282
283	if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
284		if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) {
285			qla2x00_loop_resync(vha);
286			clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags);
287		}
288	}
289
290	return 0;
291}
292
293void
294qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
295{
296	int ret;
297	struct qla_hw_data *ha = vha->hw;
298	scsi_qla_host_t *vp;
299	struct scsi_qla_host *tvp;
300
301	if (vha->vp_idx)
302		return;
303	if (list_empty(&ha->vp_list))
304		return;
305
306	clear_bit(VP_DPC_NEEDED, &vha->dpc_flags);
307
308	if (!(ha->current_topology & ISP_CFG_F))
309		return;
310
311	list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
312		if (vp->vp_idx)
313			ret = qla2x00_do_dpc_vp(vp);
314	}
315}
316
317int
318qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport)
319{
320	scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
321	struct qla_hw_data *ha = base_vha->hw;
322	scsi_qla_host_t *vha;
323	uint8_t port_name[WWN_SIZE];
324
325	if (fc_vport->roles != FC_PORT_ROLE_FCP_INITIATOR)
326		return VPCERR_UNSUPPORTED;
327
328	/* Check up the F/W and H/W support NPIV */
329	if (!ha->flags.npiv_supported)
330		return VPCERR_UNSUPPORTED;
331
332	/* Check up whether npiv supported switch presented */
333	if (!(ha->switch_cap & FLOGI_MID_SUPPORT))
334		return VPCERR_NO_FABRIC_SUPP;
335
336	/* Check up unique WWPN */
337	u64_to_wwn(fc_vport->port_name, port_name);
338	if (!memcmp(port_name, base_vha->port_name, WWN_SIZE))
339		return VPCERR_BAD_WWN;
340	vha = qla24xx_find_vhost_by_name(ha, port_name);
341	if (vha)
342		return VPCERR_BAD_WWN;
343
344	/* Check up max-npiv-supports */
345	if (ha->num_vhosts > ha->max_npiv_vports) {
346		DEBUG15(printk("scsi(%ld): num_vhosts %ud is bigger than "
347		    "max_npv_vports %ud.\n", base_vha->host_no,
348		    ha->num_vhosts, ha->max_npiv_vports));
349		return VPCERR_UNSUPPORTED;
350	}
351	return 0;
352}
353
354scsi_qla_host_t *
355qla24xx_create_vhost(struct fc_vport *fc_vport)
356{
357	scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
358	struct qla_hw_data *ha = base_vha->hw;
359	scsi_qla_host_t *vha;
360	struct scsi_host_template *sht = &qla2xxx_driver_template;
361	struct Scsi_Host *host;
362
363	vha = qla2x00_create_host(sht, ha);
364	if (!vha) {
365		DEBUG(printk("qla2xxx: scsi_host_alloc() failed for vport\n"));
366		return(NULL);
367	}
368
369	host = vha->host;
370	fc_vport->dd_data = vha;
371	/* New host info */
372	u64_to_wwn(fc_vport->node_name, vha->node_name);
373	u64_to_wwn(fc_vport->port_name, vha->port_name);
374
375	vha->fc_vport = fc_vport;
376	vha->device_flags = 0;
377	vha->vp_idx = qla24xx_allocate_vp_id(vha);
378	if (vha->vp_idx > ha->max_npiv_vports) {
379		DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n",
380			vha->host_no));
381		goto create_vhost_failed;
382	}
383	vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
384
385	vha->dpc_flags = 0L;
386
387	/*
388	 * To fix the issue of processing a parent's RSCN for the vport before
389	 * its SCR is complete.
390	 */
391	set_bit(VP_SCR_NEEDED, &vha->vp_flags);
392	atomic_set(&vha->loop_state, LOOP_DOWN);
393	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
394
395	qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL);
396
397	vha->req = base_vha->req;
398	host->can_queue = base_vha->req->length + 128;
399	host->this_id = 255;
400	host->cmd_per_lun = 3;
401	host->max_cmd_len = MAX_CMDSZ;
402	host->max_channel = MAX_BUSES - 1;
403	host->max_lun = MAX_LUNS;
404	host->unique_id = host->host_no;
405	host->max_id = MAX_TARGETS_2200;
406	host->transportt = qla2xxx_transport_vport_template;
407
408	DEBUG15(printk("DEBUG: detect vport hba %ld at address = %p\n",
409	    vha->host_no, vha));
410
411	vha->flags.init_done = 1;
412
413	mutex_lock(&ha->vport_lock);
414	set_bit(vha->vp_idx, ha->vp_idx_map);
415	ha->cur_vport_count++;
416	mutex_unlock(&ha->vport_lock);
417
418	return vha;
419
420create_vhost_failed:
421	return NULL;
422}
423
424static void
425qla25xx_free_req_que(struct scsi_qla_host *vha, struct req_que *req)
426{
427	struct qla_hw_data *ha = vha->hw;
428	uint16_t que_id = req->id;
429
430	dma_free_coherent(&ha->pdev->dev, (req->length + 1) *
431		sizeof(request_t), req->ring, req->dma);
432	req->ring = NULL;
433	req->dma = 0;
434	if (que_id) {
435		ha->req_q_map[que_id] = NULL;
436		mutex_lock(&ha->vport_lock);
437		clear_bit(que_id, ha->req_qid_map);
438		mutex_unlock(&ha->vport_lock);
439	}
440	kfree(req);
441	req = NULL;
442}
443
444static void
445qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
446{
447	struct qla_hw_data *ha = vha->hw;
448	uint16_t que_id = rsp->id;
449
450	if (rsp->msix && rsp->msix->have_irq) {
451		free_irq(rsp->msix->vector, rsp);
452		rsp->msix->have_irq = 0;
453		rsp->msix->rsp = NULL;
454	}
455	dma_free_coherent(&ha->pdev->dev, (rsp->length + 1) *
456		sizeof(response_t), rsp->ring, rsp->dma);
457	rsp->ring = NULL;
458	rsp->dma = 0;
459	if (que_id) {
460		ha->rsp_q_map[que_id] = NULL;
461		mutex_lock(&ha->vport_lock);
462		clear_bit(que_id, ha->rsp_qid_map);
463		mutex_unlock(&ha->vport_lock);
464	}
465	kfree(rsp);
466	rsp = NULL;
467}
468
469int
470qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req)
471{
472	int ret = -1;
473
474	if (req) {
475		req->options |= BIT_0;
476		ret = qla25xx_init_req_que(vha, req);
477	}
478	if (ret == QLA_SUCCESS)
479		qla25xx_free_req_que(vha, req);
480
481	return ret;
482}
483
484int
485qla25xx_delete_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
486{
487	int ret = -1;
488
489	if (rsp) {
490		rsp->options |= BIT_0;
491		ret = qla25xx_init_rsp_que(vha, rsp);
492	}
493	if (ret == QLA_SUCCESS)
494		qla25xx_free_rsp_que(vha, rsp);
495
496	return ret;
497}
498
499int qla25xx_update_req_que(struct scsi_qla_host *vha, uint8_t que, uint8_t qos)
500{
501	int ret = 0;
502	struct qla_hw_data *ha = vha->hw;
503	struct req_que *req = ha->req_q_map[que];
504
505	req->options |= BIT_3;
506	req->qos = qos;
507	ret = qla25xx_init_req_que(vha, req);
508	if (ret != QLA_SUCCESS)
509		DEBUG2_17(printk(KERN_WARNING "%s failed\n", __func__));
510	/* restore options bit */
511	req->options &= ~BIT_3;
512	return ret;
513}
514
515
516/* Delete all queues for a given vhost */
517int
518qla25xx_delete_queues(struct scsi_qla_host *vha)
519{
520	int cnt, ret = 0;
521	struct req_que *req = NULL;
522	struct rsp_que *rsp = NULL;
523	struct qla_hw_data *ha = vha->hw;
524
525	/* Delete request queues */
526	for (cnt = 1; cnt < ha->max_req_queues; cnt++) {
527		req = ha->req_q_map[cnt];
528		if (req) {
529			ret = qla25xx_delete_req_que(vha, req);
530			if (ret != QLA_SUCCESS) {
531				qla_printk(KERN_WARNING, ha,
532				"Couldn't delete req que %d\n",
533				req->id);
534				return ret;
535			}
536		}
537	}
538
539	/* Delete response queues */
540	for (cnt = 1; cnt < ha->max_rsp_queues; cnt++) {
541		rsp = ha->rsp_q_map[cnt];
542		if (rsp) {
543			ret = qla25xx_delete_rsp_que(vha, rsp);
544			if (ret != QLA_SUCCESS) {
545				qla_printk(KERN_WARNING, ha,
546				"Couldn't delete rsp que %d\n",
547				rsp->id);
548				return ret;
549			}
550		}
551	}
552	return ret;
553}
554
555int
556qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
557	uint8_t vp_idx, uint16_t rid, int rsp_que, uint8_t qos)
558{
559	int ret = 0;
560	struct req_que *req = NULL;
561	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
562	uint16_t que_id = 0;
563	device_reg_t __iomem *reg;
564	uint32_t cnt;
565
566	req = kzalloc(sizeof(struct req_que), GFP_KERNEL);
567	if (req == NULL) {
568		qla_printk(KERN_WARNING, ha, "could not allocate memory"
569			"for request que\n");
570		goto failed;
571	}
572
573	req->length = REQUEST_ENTRY_CNT_24XX;
574	req->ring = dma_alloc_coherent(&ha->pdev->dev,
575			(req->length + 1) * sizeof(request_t),
576			&req->dma, GFP_KERNEL);
577	if (req->ring == NULL) {
578		qla_printk(KERN_WARNING, ha,
579		"Memory Allocation failed - request_ring\n");
580		goto que_failed;
581	}
582
583	mutex_lock(&ha->vport_lock);
584	que_id = find_first_zero_bit(ha->req_qid_map, ha->max_req_queues);
585	if (que_id >= ha->max_req_queues) {
586		mutex_unlock(&ha->vport_lock);
587		qla_printk(KERN_INFO, ha, "No resources to create "
588			 "additional request queue\n");
589		goto que_failed;
590	}
591	set_bit(que_id, ha->req_qid_map);
592	ha->req_q_map[que_id] = req;
593	req->rid = rid;
594	req->vp_idx = vp_idx;
595	req->qos = qos;
596
597	if (rsp_que < 0)
598		req->rsp = NULL;
599	else
600		req->rsp = ha->rsp_q_map[rsp_que];
601	/* Use alternate PCI bus number */
602	if (MSB(req->rid))
603		options |= BIT_4;
604	/* Use alternate PCI devfn */
605	if (LSB(req->rid))
606		options |= BIT_5;
607	req->options = options;
608
609	for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
610		req->outstanding_cmds[cnt] = NULL;
611	req->current_outstanding_cmd = 1;
612
613	req->ring_ptr = req->ring;
614	req->ring_index = 0;
615	req->cnt = req->length;
616	req->id = que_id;
617	reg = ISP_QUE_REG(ha, que_id);
618	req->max_q_depth = ha->req_q_map[0]->max_q_depth;
619	mutex_unlock(&ha->vport_lock);
620
621	ret = qla25xx_init_req_que(base_vha, req);
622	if (ret != QLA_SUCCESS) {
623		qla_printk(KERN_WARNING, ha, "%s failed\n", __func__);
624		mutex_lock(&ha->vport_lock);
625		clear_bit(que_id, ha->req_qid_map);
626		mutex_unlock(&ha->vport_lock);
627		goto que_failed;
628	}
629
630	return req->id;
631
632que_failed:
633	qla25xx_free_req_que(base_vha, req);
634failed:
635	return 0;
636}
637
638static void qla_do_work(struct work_struct *work)
639{
640	unsigned long flags;
641	struct rsp_que *rsp = container_of(work, struct rsp_que, q_work);
642	struct scsi_qla_host *vha;
643	struct qla_hw_data *ha = rsp->hw;
644
645	spin_lock_irqsave(&rsp->hw->hardware_lock, flags);
646	vha = pci_get_drvdata(ha->pdev);
647	qla24xx_process_response_queue(vha, rsp);
648	spin_unlock_irqrestore(&rsp->hw->hardware_lock, flags);
649}
650
651/* create response queue */
652int
653qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
654	uint8_t vp_idx, uint16_t rid, int req)
655{
656	int ret = 0;
657	struct rsp_que *rsp = NULL;
658	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
659	uint16_t que_id = 0;
660	device_reg_t __iomem *reg;
661
662	rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL);
663	if (rsp == NULL) {
664		qla_printk(KERN_WARNING, ha, "could not allocate memory for"
665				" response que\n");
666		goto failed;
667	}
668
669	rsp->length = RESPONSE_ENTRY_CNT_MQ;
670	rsp->ring = dma_alloc_coherent(&ha->pdev->dev,
671			(rsp->length + 1) * sizeof(response_t),
672			&rsp->dma, GFP_KERNEL);
673	if (rsp->ring == NULL) {
674		qla_printk(KERN_WARNING, ha,
675		"Memory Allocation failed - response_ring\n");
676		goto que_failed;
677	}
678
679	mutex_lock(&ha->vport_lock);
680	que_id = find_first_zero_bit(ha->rsp_qid_map, ha->max_rsp_queues);
681	if (que_id >= ha->max_rsp_queues) {
682		mutex_unlock(&ha->vport_lock);
683		qla_printk(KERN_INFO, ha, "No resources to create "
684			 "additional response queue\n");
685		goto que_failed;
686	}
687	set_bit(que_id, ha->rsp_qid_map);
688
689	if (ha->flags.msix_enabled)
690		rsp->msix = &ha->msix_entries[que_id + 1];
691	else
692		qla_printk(KERN_WARNING, ha, "msix not enabled\n");
693
694	ha->rsp_q_map[que_id] = rsp;
695	rsp->rid = rid;
696	rsp->vp_idx = vp_idx;
697	rsp->hw = ha;
698	/* Use alternate PCI bus number */
699	if (MSB(rsp->rid))
700		options |= BIT_4;
701	/* Use alternate PCI devfn */
702	if (LSB(rsp->rid))
703		options |= BIT_5;
704	/* Enable MSIX handshake mode on for uncapable adapters */
705	if (!IS_MSIX_NACK_CAPABLE(ha))
706		options |= BIT_6;
707
708	rsp->options = options;
709	rsp->id = que_id;
710	reg = ISP_QUE_REG(ha, que_id);
711	rsp->rsp_q_in = &reg->isp25mq.rsp_q_in;
712	rsp->rsp_q_out = &reg->isp25mq.rsp_q_out;
713	mutex_unlock(&ha->vport_lock);
714
715	ret = qla25xx_request_irq(rsp);
716	if (ret)
717		goto que_failed;
718
719	ret = qla25xx_init_rsp_que(base_vha, rsp);
720	if (ret != QLA_SUCCESS) {
721		qla_printk(KERN_WARNING, ha, "%s failed\n", __func__);
722		mutex_lock(&ha->vport_lock);
723		clear_bit(que_id, ha->rsp_qid_map);
724		mutex_unlock(&ha->vport_lock);
725		goto que_failed;
726	}
727	if (req >= 0)
728		rsp->req = ha->req_q_map[req];
729	else
730		rsp->req = NULL;
731
732	qla2x00_init_response_q_entries(rsp);
733	if (rsp->hw->wq)
734		INIT_WORK(&rsp->q_work, qla_do_work);
735	return rsp->id;
736
737que_failed:
738	qla25xx_free_rsp_que(base_vha, rsp);
739failed:
740	return 0;
741}
742
743int
744qla25xx_create_queues(struct scsi_qla_host *vha, uint8_t qos)
745{
746	uint16_t options = 0;
747	uint8_t ret = 0;
748	struct qla_hw_data *ha = vha->hw;
749	struct rsp_que *rsp;
750
751	options |= BIT_1;
752	ret = qla25xx_create_rsp_que(ha, options, vha->vp_idx, 0, -1);
753	if (!ret) {
754		qla_printk(KERN_WARNING, ha, "Response Que create failed\n");
755		return ret;
756	} else
757		qla_printk(KERN_INFO, ha, "Response Que:%d created.\n", ret);
758	rsp = ha->rsp_q_map[ret];
759
760	options = 0;
761	if (qos & BIT_7)
762		options |= BIT_8;
763	ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, ret,
764					qos & ~BIT_7);
765	if (ret) {
766		vha->req = ha->req_q_map[ret];
767		qla_printk(KERN_INFO, ha, "Request Que:%d created.\n", ret);
768	} else
769		qla_printk(KERN_WARNING, ha, "Request Que create failed\n");
770	rsp->req = ha->req_q_map[ret];
771
772	return ret;
773}