diff options
Diffstat (limited to 'drivers/scsi')
45 files changed, 907 insertions, 296 deletions
| diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d384f4f86c26..d145e0d90227 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -47,6 +47,17 @@ config SCSI_NETLINK  	default	n  	depends on NET +config SCSI_MQ_DEFAULT +	bool "SCSI: use blk-mq I/O path by default" +	depends on SCSI +	---help--- +	  This option enables the new blk-mq based I/O path for SCSI +	  devices by default.  With the option the scsi_mod.use_blk_mq +	  module/boot option defaults to Y, without it to N, but it can +	  still be overridden either way. + +	  If unsure say N. +  config SCSI_PROC_FS  	bool "legacy /proc/scsi/ support"  	depends on SCSI && PROC_FS @@ -1230,6 +1241,8 @@ config SCSI_LPFC  	tristate "Emulex LightPulse Fibre Channel Support"  	depends on PCI && SCSI  	depends on SCSI_FC_ATTRS +	depends on NVME_TARGET_FC || NVME_TARGET_FC=n +	depends on NVME_FC || NVME_FC=n  	select CRC_T10DIF  	---help---            This lpfc driver supports the Emulex LightPulse diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 707ee2f5954d..a1a2c71e1626 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -549,7 +549,9 @@ static void get_container_name_callback(void *context, struct fib * fibptr)  	if ((le32_to_cpu(get_name_reply->status) == CT_OK)  	 && (get_name_reply->data[0] != '\0')) {  		char *sp = get_name_reply->data; -		sp[sizeof(((struct aac_get_name_resp *)NULL)->data)] = '\0'; +		int data_size = FIELD_SIZEOF(struct aac_get_name_resp, data); + +		sp[data_size - 1] = '\0';  		while (*sp == ' ')  			++sp;  		if (*sp) { @@ -579,12 +581,15 @@ static void get_container_name_callback(void *context, struct fib * fibptr)  static int aac_get_container_name(struct scsi_cmnd * scsicmd)  {  	int status; +	int data_size;  	struct aac_get_name *dinfo;  	struct fib * cmd_fibcontext;  	struct aac_dev * dev;  	dev = (struct aac_dev *)scsicmd->device->host->hostdata; +	data_size = FIELD_SIZEOF(struct aac_get_name_resp, data); +  	cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);  	aac_fib_init(cmd_fibcontext); @@ -593,7 +598,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)  	dinfo->command = cpu_to_le32(VM_ContainerConfig);  	dinfo->type = cpu_to_le32(CT_READ_NAME);  	dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); -	dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); +	dinfo->count = cpu_to_le32(data_size - 1);  	status = aac_fib_send(ContainerCommand,  		  cmd_fibcontext, @@ -3198,10 +3203,11 @@ static int query_disk(struct aac_dev *dev, void __user *arg)  		return -EBUSY;  	if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk)))  		return -EFAULT; -	if (qd.cnum == -1) +	if (qd.cnum == -1) { +		if (qd.id < 0 || qd.id >= dev->maximum_num_containers) +			return -EINVAL;  		qd.cnum = qd.id; -	else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1)) -	{ +	} else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1)) {  		if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers)  			return -EINVAL;  		qd.instance = dev->scsi_host_ptr->host_no; diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index d31a9bc2ba69..ee2667e20e42 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2274,7 +2274,7 @@ struct aac_get_name_resp {  	__le32		parm3;  	__le32		parm4;  	__le32		parm5; -	u8		data[16]; +	u8		data[17];  };  #define CT_CID_TO_32BITS_UID 165 diff --git a/drivers/scsi/aic7xxx/Makefile b/drivers/scsi/aic7xxx/Makefile index 741d81861d17..07b60a780c06 100644 --- a/drivers/scsi/aic7xxx/Makefile +++ b/drivers/scsi/aic7xxx/Makefile @@ -55,9 +55,9 @@ aicasm-7xxx-opts-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) := \  ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)  $(obj)/aic7xxx_seq.h: $(src)/aic7xxx.seq $(src)/aic7xxx.reg $(obj)/aicasm/aicasm -	$(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic7xxx_reg.h \ +	$(obj)/aicasm/aicasm -I$(srctree)/$(src) -r $(obj)/aic7xxx_reg.h \  			      $(aicasm-7xxx-opts-y) -o $(obj)/aic7xxx_seq.h \ -			      $(src)/aic7xxx.seq +			      $(srctree)/$(src)/aic7xxx.seq  $(aic7xxx-gen-y): $(obj)/aic7xxx_seq.h  else @@ -72,14 +72,14 @@ aicasm-79xx-opts-$(CONFIG_AIC79XX_REG_PRETTY_PRINT) := \  ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)  $(obj)/aic79xx_seq.h: $(src)/aic79xx.seq $(src)/aic79xx.reg $(obj)/aicasm/aicasm -	$(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic79xx_reg.h \ +	$(obj)/aicasm/aicasm -I$(srctree)/$(src) -r $(obj)/aic79xx_reg.h \  			      $(aicasm-79xx-opts-y) -o $(obj)/aic79xx_seq.h \ -			      $(src)/aic79xx.seq +			      $(srctree)/$(src)/aic79xx.seq  $(aic79xx-gen-y): $(obj)/aic79xx_seq.h  else  $(obj)/aic79xx_reg_print.c: $(src)/aic79xx_reg_print.c_shipped  endif -$(obj)/aicasm/aicasm: $(src)/aicasm/*.[chyl] -	$(MAKE) -C $(src)/aicasm +$(obj)/aicasm/aicasm: $(srctree)/$(src)/aicasm/*.[chyl] +	$(MAKE) -C $(srctree)/$(src)/aicasm OUTDIR=$(shell pwd)/$(obj)/aicasm/ diff --git a/drivers/scsi/aic7xxx/aicasm/Makefile b/drivers/scsi/aic7xxx/aicasm/Makefile index b98c5c1056c3..45e2d49c1fff 100644 --- a/drivers/scsi/aic7xxx/aicasm/Makefile +++ b/drivers/scsi/aic7xxx/aicasm/Makefile @@ -1,19 +1,21 @@  PROG=	aicasm +OUTDIR ?= ./ +  .SUFFIXES= .l .y .c .h  CSRCS=	aicasm.c aicasm_symbol.c  YSRCS=	aicasm_gram.y aicasm_macro_gram.y  LSRCS=	aicasm_scan.l aicasm_macro_scan.l -GENHDRS=	aicdb.h $(YSRCS:.y=.h) -GENSRCS=	$(YSRCS:.y=.c) $(LSRCS:.l=.c) +GENHDRS=	$(addprefix ${OUTDIR}/,aicdb.h $(YSRCS:.y=.h)) +GENSRCS=	$(addprefix ${OUTDIR}/,$(YSRCS:.y=.c) $(LSRCS:.l=.c))  SRCS=	${CSRCS} ${GENSRCS}  LIBS=	-ldb  clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG)  # Override default kernel CFLAGS.  This is a userland app. -AICASM_CFLAGS:= -I/usr/include -I. +AICASM_CFLAGS:= -I/usr/include -I. -I$(OUTDIR)  LEX= flex  YACC= bison  YFLAGS= -d @@ -32,22 +34,25 @@ YFLAGS+= -t -v  LFLAGS= -d  endif -$(PROG):  ${GENHDRS} $(SRCS) -	$(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG) $(LIBS) +$(PROG):  $(OUTDIR) ${GENHDRS} $(SRCS) +	$(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(OUTDIR)/$(PROG) $(LIBS) + +$(OUTDIR): +	mkdir -p $(OUTDIR) -aicdb.h: +$(OUTDIR)/aicdb.h:  	@if [ -e "/usr/include/db4/db_185.h" ]; then		\ -		echo "#include <db4/db_185.h>" > aicdb.h;	\ +		echo "#include <db4/db_185.h>" > $@;	\  	 elif [ -e "/usr/include/db3/db_185.h" ]; then		\ -		echo "#include <db3/db_185.h>" > aicdb.h;	\ +		echo "#include <db3/db_185.h>" > $@;	\  	 elif [ -e "/usr/include/db2/db_185.h" ]; then		\ -		echo "#include <db2/db_185.h>" > aicdb.h;	\ +		echo "#include <db2/db_185.h>" > $@;	\  	 elif [ -e "/usr/include/db1/db_185.h" ]; then		\ -		echo "#include <db1/db_185.h>" > aicdb.h;	\ +		echo "#include <db1/db_185.h>" > $@;	\  	 elif [ -e "/usr/include/db/db_185.h" ]; then		\ -		echo "#include <db/db_185.h>" > aicdb.h;	\ +		echo "#include <db/db_185.h>" > $@;	\  	 elif [ -e "/usr/include/db_185.h" ]; then		\ -		echo "#include <db_185.h>" > aicdb.h;		\ +		echo "#include <db_185.h>" > $@;		\  	 else							\  		echo "*** Install db development libraries";	\  	 fi @@ -58,23 +63,23 @@ clean:  # Create a dependency chain in generated files  # to avoid concurrent invocations of the single  # rule that builds them all. -aicasm_gram.c: aicasm_gram.h -aicasm_gram.c aicasm_gram.h: aicasm_gram.y +$(OUTDIR)/aicasm_gram.c: $(OUTDIR)/aicasm_gram.h +$(OUTDIR)/aicasm_gram.c $(OUTDIR)/aicasm_gram.h: aicasm_gram.y  	$(YACC) $(YFLAGS) -b $(<:.y=) $< -	mv $(<:.y=).tab.c $(<:.y=.c) -	mv $(<:.y=).tab.h $(<:.y=.h) +	mv $(<:.y=).tab.c $(OUTDIR)/$(<:.y=.c) +	mv $(<:.y=).tab.h $(OUTDIR)/$(<:.y=.h)  # Create a dependency chain in generated files  # to avoid concurrent invocations of the single  # rule that builds them all. -aicasm_macro_gram.c: aicasm_macro_gram.h -aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y +$(OUTDIR)/aicasm_macro_gram.c: $(OUTDIR)/aicasm_macro_gram.h +$(OUTDIR)/aicasm_macro_gram.c $(OUTDIR)/aicasm_macro_gram.h: aicasm_macro_gram.y  	$(YACC) $(YFLAGS) -b $(<:.y=) -p mm $< -	mv $(<:.y=).tab.c $(<:.y=.c) -	mv $(<:.y=).tab.h $(<:.y=.h) +	mv $(<:.y=).tab.c $(OUTDIR)/$(<:.y=.c) +	mv $(<:.y=).tab.h $(OUTDIR)/$(<:.y=.h) -aicasm_scan.c: aicasm_scan.l -	$(LEX) $(LFLAGS) -o$@ $< +$(OUTDIR)/aicasm_scan.c: aicasm_scan.l +	$(LEX) $(LFLAGS) -o $@ $< -aicasm_macro_scan.c: aicasm_macro_scan.l -	$(LEX) $(LFLAGS) -Pmm -o$@ $< +$(OUTDIR)/aicasm_macro_scan.c: aicasm_macro_scan.l +	$(LEX) $(LFLAGS) -Pmm -o $@ $< diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 7dfe709a7138..6844ba361616 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -2624,12 +2624,11 @@ static struct fcoe_transport bnx2fc_transport = {  };  /** - * bnx2fc_percpu_thread_create - Create a receive thread for an - *				 online CPU + * bnx2fc_cpu_online - Create a receive thread for an  online CPU   *   * @cpu: cpu index for the online cpu   */ -static void bnx2fc_percpu_thread_create(unsigned int cpu) +static int bnx2fc_cpu_online(unsigned int cpu)  {  	struct bnx2fc_percpu_s *p;  	struct task_struct *thread; @@ -2639,15 +2638,17 @@ static void bnx2fc_percpu_thread_create(unsigned int cpu)  	thread = kthread_create_on_node(bnx2fc_percpu_io_thread,  					(void *)p, cpu_to_node(cpu),  					"bnx2fc_thread/%d", cpu); +	if (IS_ERR(thread)) +		return PTR_ERR(thread); +  	/* bind thread to the cpu */ -	if (likely(!IS_ERR(thread))) { -		kthread_bind(thread, cpu); -		p->iothread = thread; -		wake_up_process(thread); -	} +	kthread_bind(thread, cpu); +	p->iothread = thread; +	wake_up_process(thread); +	return 0;  } -static void bnx2fc_percpu_thread_destroy(unsigned int cpu) +static int bnx2fc_cpu_offline(unsigned int cpu)  {  	struct bnx2fc_percpu_s *p;  	struct task_struct *thread; @@ -2661,7 +2662,6 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu)  	thread = p->iothread;  	p->iothread = NULL; -  	/* Free all work in the list */  	list_for_each_entry_safe(work, tmp, &p->work_list, list) {  		list_del_init(&work->list); @@ -2673,20 +2673,6 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu)  	if (thread)  		kthread_stop(thread); -} - - -static int bnx2fc_cpu_online(unsigned int cpu) -{ -	printk(PFX "CPU %x online: Create Rx thread\n", cpu); -	bnx2fc_percpu_thread_create(cpu); -	return 0; -} - -static int bnx2fc_cpu_dead(unsigned int cpu) -{ -	printk(PFX "CPU %x offline: Remove Rx thread\n", cpu); -	bnx2fc_percpu_thread_destroy(cpu);  	return 0;  } @@ -2761,30 +2747,16 @@ static int __init bnx2fc_mod_init(void)  		spin_lock_init(&p->fp_work_lock);  	} -	get_online_cpus(); - -	for_each_online_cpu(cpu) -		bnx2fc_percpu_thread_create(cpu); - -	rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, -				       "scsi/bnx2fc:online", -				       bnx2fc_cpu_online, NULL); +	rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "scsi/bnx2fc:online", +			       bnx2fc_cpu_online, bnx2fc_cpu_offline);  	if (rc < 0) -		goto stop_threads; +		goto stop_thread;  	bnx2fc_online_state = rc; -	cpuhp_setup_state_nocalls(CPUHP_SCSI_BNX2FC_DEAD, "scsi/bnx2fc:dead", -				  NULL, bnx2fc_cpu_dead); -	put_online_cpus(); -  	cnic_register_driver(CNIC_ULP_FCOE, &bnx2fc_cnic_cb); -  	return 0; -stop_threads: -	for_each_online_cpu(cpu) -		bnx2fc_percpu_thread_destroy(cpu); -	put_online_cpus(); +stop_thread:  	kthread_stop(l2_thread);  free_wq:  	destroy_workqueue(bnx2fc_wq); @@ -2803,7 +2775,6 @@ static void __exit bnx2fc_mod_exit(void)  	struct fcoe_percpu_s *bg;  	struct task_struct *l2_thread;  	struct sk_buff *skb; -	unsigned int cpu = 0;  	/*  	 * NOTE: Since cnic calls register_driver routine rtnl_lock, @@ -2844,16 +2815,7 @@ static void __exit bnx2fc_mod_exit(void)  	if (l2_thread)  		kthread_stop(l2_thread); -	get_online_cpus(); -	/* Destroy per cpu threads */ -	for_each_online_cpu(cpu) { -		bnx2fc_percpu_thread_destroy(cpu); -	} - -	cpuhp_remove_state_nocalls(bnx2fc_online_state); -	cpuhp_remove_state_nocalls(CPUHP_SCSI_BNX2FC_DEAD); - -	put_online_cpus(); +	cpuhp_remove_state(bnx2fc_online_state);  	destroy_workqueue(bnx2fc_wq);  	/* diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index 913c750205ce..26de61d65a4d 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -1008,6 +1008,28 @@ static struct bnx2fc_work *bnx2fc_alloc_work(struct bnx2fc_rport *tgt, u16 wqe)  	return work;  } +/* Pending work request completion */ +static void bnx2fc_pending_work(struct bnx2fc_rport *tgt, unsigned int wqe) +{ +	unsigned int cpu = wqe % num_possible_cpus(); +	struct bnx2fc_percpu_s *fps; +	struct bnx2fc_work *work; + +	fps = &per_cpu(bnx2fc_percpu, cpu); +	spin_lock_bh(&fps->fp_work_lock); +	if (fps->iothread) { +		work = bnx2fc_alloc_work(tgt, wqe); +		if (work) { +			list_add_tail(&work->list, &fps->work_list); +			wake_up_process(fps->iothread); +			spin_unlock_bh(&fps->fp_work_lock); +			return; +		} +	} +	spin_unlock_bh(&fps->fp_work_lock); +	bnx2fc_process_cq_compl(tgt, wqe); +} +  int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt)  {  	struct fcoe_cqe *cq; @@ -1042,28 +1064,7 @@ int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt)  			/* Unsolicited event notification */  			bnx2fc_process_unsol_compl(tgt, wqe);  		} else { -			/* Pending work request completion */ -			struct bnx2fc_work *work = NULL; -			struct bnx2fc_percpu_s *fps = NULL; -			unsigned int cpu = wqe % num_possible_cpus(); - -			fps = &per_cpu(bnx2fc_percpu, cpu); -			spin_lock_bh(&fps->fp_work_lock); -			if (unlikely(!fps->iothread)) -				goto unlock; - -			work = bnx2fc_alloc_work(tgt, wqe); -			if (work) -				list_add_tail(&work->list, -					      &fps->work_list); -unlock: -			spin_unlock_bh(&fps->fp_work_lock); - -			/* Pending work request completion */ -			if (fps->iothread && work) -				wake_up_process(fps->iothread); -			else -				bnx2fc_process_cq_compl(tgt, wqe); +			bnx2fc_pending_work(tgt, wqe);  			num_free_sqes++;  		}  		cqe++; diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 86afc002814c..4ebcda8d9500 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c @@ -404,12 +404,11 @@ int bnx2i_get_stats(void *handle)  /** - * bnx2i_percpu_thread_create - Create a receive thread for an - *				online CPU + * bnx2i_cpu_online - Create a receive thread for an online CPU   *   * @cpu:	cpu index for the online cpu   */ -static void bnx2i_percpu_thread_create(unsigned int cpu) +static int bnx2i_cpu_online(unsigned int cpu)  {  	struct bnx2i_percpu_s *p;  	struct task_struct *thread; @@ -419,16 +418,17 @@ static void bnx2i_percpu_thread_create(unsigned int cpu)  	thread = kthread_create_on_node(bnx2i_percpu_io_thread, (void *)p,  					cpu_to_node(cpu),  					"bnx2i_thread/%d", cpu); +	if (IS_ERR(thread)) +		return PTR_ERR(thread); +  	/* bind thread to the cpu */ -	if (likely(!IS_ERR(thread))) { -		kthread_bind(thread, cpu); -		p->iothread = thread; -		wake_up_process(thread); -	} +	kthread_bind(thread, cpu); +	p->iothread = thread; +	wake_up_process(thread); +	return 0;  } - -static void bnx2i_percpu_thread_destroy(unsigned int cpu) +static int bnx2i_cpu_offline(unsigned int cpu)  {  	struct bnx2i_percpu_s *p;  	struct task_struct *thread; @@ -451,19 +451,6 @@ static void bnx2i_percpu_thread_destroy(unsigned int cpu)  	spin_unlock_bh(&p->p_work_lock);  	if (thread)  		kthread_stop(thread); -} - -static int bnx2i_cpu_online(unsigned int cpu) -{ -	pr_info("bnx2i: CPU %x online: Create Rx thread\n", cpu); -	bnx2i_percpu_thread_create(cpu); -	return 0; -} - -static int bnx2i_cpu_dead(unsigned int cpu) -{ -	pr_info("CPU %x offline: Remove Rx thread\n", cpu); -	bnx2i_percpu_thread_destroy(cpu);  	return 0;  } @@ -511,27 +498,14 @@ static int __init bnx2i_mod_init(void)  		p->iothread = NULL;  	} -	get_online_cpus(); - -	for_each_online_cpu(cpu) -		bnx2i_percpu_thread_create(cpu); - -	err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, -				       "scsi/bnx2i:online", -				       bnx2i_cpu_online, NULL); +	err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "scsi/bnx2i:online", +				bnx2i_cpu_online, bnx2i_cpu_offline);  	if (err < 0) -		goto remove_threads; +		goto unreg_driver;  	bnx2i_online_state = err; - -	cpuhp_setup_state_nocalls(CPUHP_SCSI_BNX2I_DEAD, "scsi/bnx2i:dead", -				  NULL, bnx2i_cpu_dead); -	put_online_cpus();  	return 0; -remove_threads: -	for_each_online_cpu(cpu) -		bnx2i_percpu_thread_destroy(cpu); -	put_online_cpus(); +unreg_driver:  	cnic_unregister_driver(CNIC_ULP_ISCSI);  unreg_xport:  	iscsi_unregister_transport(&bnx2i_iscsi_transport); @@ -551,7 +525,6 @@ out:  static void __exit bnx2i_mod_exit(void)  {  	struct bnx2i_hba *hba; -	unsigned cpu = 0;  	mutex_lock(&bnx2i_dev_lock);  	while (!list_empty(&adapter_list)) { @@ -569,14 +542,7 @@ static void __exit bnx2i_mod_exit(void)  	}  	mutex_unlock(&bnx2i_dev_lock); -	get_online_cpus(); - -	for_each_online_cpu(cpu) -		bnx2i_percpu_thread_destroy(cpu); - -	cpuhp_remove_state_nocalls(bnx2i_online_state); -	cpuhp_remove_state_nocalls(CPUHP_SCSI_BNX2I_DEAD); -	put_online_cpus(); +	cpuhp_remove_state(bnx2i_online_state);  	iscsi_unregister_transport(&bnx2i_iscsi_transport);  	cnic_unregister_driver(CNIC_ULP_ISCSI); diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index 2029ad225121..5be0086142ca 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -3845,8 +3845,10 @@ csio_hw_start(struct csio_hw *hw)  	if (csio_is_hw_ready(hw))  		return 0; -	else +	else if (csio_match_state(hw, csio_hws_uninit))  		return -EINVAL; +	else +		return -ENODEV;  }  int diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index ea0c31086cc6..dcd074169aa9 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -969,10 +969,14 @@ static int csio_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)  	pci_set_drvdata(pdev, hw); -	if (csio_hw_start(hw) != 0) { -		dev_err(&pdev->dev, -			"Failed to start FW, continuing in debug mode.\n"); -		return 0; +	rv = csio_hw_start(hw); +	if (rv) { +		if (rv == -EINVAL) { +			dev_err(&pdev->dev, +				"Failed to start FW, continuing in debug mode.\n"); +			return 0; +		} +		goto err_lnode_exit;  	}  	sprintf(hw->fwrev_str, "%u.%u.%u.%u\n", diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index a69a9ac836f5..1d02cf9fe06c 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@ -1635,6 +1635,9 @@ static int init_act_open(struct cxgbi_sock *csk)  		goto rel_resource;  	} +	if (!(n->nud_state & NUD_VALID)) +		neigh_event_send(n, NULL); +  	csk->atid = cxgb4_alloc_atid(lldi->tids, csk);  	if (csk->atid < 0) {  		pr_err("%s, NO atid available.\n", ndev->name); diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index e4c83b7c96a8..1a4cfa562a60 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -2128,6 +2128,13 @@ void cxgbi_cleanup_task(struct iscsi_task *task)  	struct iscsi_tcp_task *tcp_task = task->dd_data;  	struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task); +	if (!tcp_task || !tdata || (tcp_task->dd_data != tdata)) { +		pr_info("task 0x%p,0x%p, tcp_task 0x%p, tdata 0x%p/0x%p.\n", +			task, task->sc, tcp_task, +			tcp_task ? tcp_task->dd_data : NULL, tdata); +		return; +	} +  	log_debug(1 << CXGBI_DBG_ISCSI,  		"task 0x%p, skb 0x%p, itt 0x%x.\n",  		task, tdata->skb, task->hdr_itt); diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 077f62e208aa..6a4367cc9caa 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -3401,9 +3401,10 @@ static int cxlflash_afu_debug(struct cxlflash_cfg *cfg,  		if (is_write) {  			req_flags |= SISL_REQ_FLAGS_HOST_WRITE; -			rc = copy_from_user(kbuf, ubuf, ulen); -			if (unlikely(rc)) +			if (copy_from_user(kbuf, ubuf, ulen)) { +				rc = -EFAULT;  				goto out; +			}  		}  	} @@ -3431,8 +3432,10 @@ static int cxlflash_afu_debug(struct cxlflash_cfg *cfg,  		goto out;  	} -	if (ulen && !is_write) -		rc = copy_to_user(ubuf, kbuf, ulen); +	if (ulen && !is_write) { +		if (copy_to_user(ubuf, kbuf, ulen)) +			rc = -EFAULT; +	}  out:  	kfree(buf);  	dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 551d103c27f1..2bfea7082e3a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1693,7 +1693,7 @@ static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba,  static int parse_trans_tx_err_code_v2_hw(u32 err_msk)  { -	const u8 trans_tx_err_code_prio[] = { +	static const u8 trans_tx_err_code_prio[] = {  		TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS,  		TRANS_TX_ERR_PHY_NOT_ENABLE,  		TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION, @@ -1738,7 +1738,7 @@ static int parse_trans_tx_err_code_v2_hw(u32 err_msk)  static int parse_trans_rx_err_code_v2_hw(u32 err_msk)  { -	const u8 trans_rx_err_code_prio[] = { +	static const u8 trans_rx_err_code_prio[] = {  		TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR,  		TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR,  		TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM, @@ -1784,7 +1784,7 @@ static int parse_trans_rx_err_code_v2_hw(u32 err_msk)  static int parse_dma_tx_err_code_v2_hw(u32 err_msk)  { -	const u8 dma_tx_err_code_prio[] = { +	static const u8 dma_tx_err_code_prio[] = {  		DMA_TX_UNEXP_XFER_ERR,  		DMA_TX_UNEXP_RETRANS_ERR,  		DMA_TX_XFER_LEN_OVERFLOW, @@ -1810,7 +1810,7 @@ static int parse_dma_tx_err_code_v2_hw(u32 err_msk)  static int parse_sipc_rx_err_code_v2_hw(u32 err_msk)  { -	const u8 sipc_rx_err_code_prio[] = { +	static const u8 sipc_rx_err_code_prio[] = {  		SIPC_RX_FIS_STATUS_ERR_BIT_VLD,  		SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR,  		SIPC_RX_FIS_STATUS_BSY_BIT_ERR, @@ -1836,7 +1836,7 @@ static int parse_sipc_rx_err_code_v2_hw(u32 err_msk)  static int parse_dma_rx_err_code_v2_hw(u32 err_msk)  { -	const u8 dma_rx_err_code_prio[] = { +	static const u8 dma_rx_err_code_prio[] = {  		DMA_RX_UNKNOWN_FRM_ERR,  		DMA_RX_DATA_LEN_OVERFLOW,  		DMA_RX_DATA_LEN_UNDERFLOW, diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 8914eab84337..4f7cdb28bd38 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -938,7 +938,7 @@ static struct scsi_host_template hpsa_driver_template = {  #endif  	.sdev_attrs = hpsa_sdev_attrs,  	.shost_attrs = hpsa_shost_attrs, -	.max_sectors = 8192, +	.max_sectors = 1024,  	.no_write_same = 1,  }; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b0c68d24db01..da5bdbdcce52 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3351,6 +3351,16 @@ static void ipr_worker_thread(struct work_struct *work)  		return;  	} +	if (ioa_cfg->scsi_unblock) { +		ioa_cfg->scsi_unblock = 0; +		ioa_cfg->scsi_blocked = 0; +		spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); +		scsi_unblock_requests(ioa_cfg->host); +		spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); +		if (ioa_cfg->scsi_blocked) +			scsi_block_requests(ioa_cfg->host); +	} +  	if (!ioa_cfg->scan_enabled) {  		spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);  		return; @@ -7211,9 +7221,8 @@ static int ipr_ioa_bringdown_done(struct ipr_cmnd *ipr_cmd)  	ENTER;  	if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) {  		ipr_trace; -		spin_unlock_irq(ioa_cfg->host->host_lock); -		scsi_unblock_requests(ioa_cfg->host); -		spin_lock_irq(ioa_cfg->host->host_lock); +		ioa_cfg->scsi_unblock = 1; +		schedule_work(&ioa_cfg->work_q);  	}  	ioa_cfg->in_reset_reload = 0; @@ -7287,13 +7296,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd)  	list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);  	wake_up_all(&ioa_cfg->reset_wait_q); -	spin_unlock(ioa_cfg->host->host_lock); -	scsi_unblock_requests(ioa_cfg->host); -	spin_lock(ioa_cfg->host->host_lock); - -	if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) -		scsi_block_requests(ioa_cfg->host); - +	ioa_cfg->scsi_unblock = 1;  	schedule_work(&ioa_cfg->work_q);  	LEAVE;  	return IPR_RC_JOB_RETURN; @@ -9249,8 +9252,11 @@ static void _ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,  		spin_unlock(&ioa_cfg->hrrq[i]._lock);  	}  	wmb(); -	if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) +	if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) { +		ioa_cfg->scsi_unblock = 0; +		ioa_cfg->scsi_blocked = 1;  		scsi_block_requests(ioa_cfg->host); +	}  	ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);  	ioa_cfg->reset_cmd = ipr_cmd; @@ -9306,9 +9312,8 @@ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,  			wake_up_all(&ioa_cfg->reset_wait_q);  			if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) { -				spin_unlock_irq(ioa_cfg->host->host_lock); -				scsi_unblock_requests(ioa_cfg->host); -				spin_lock_irq(ioa_cfg->host->host_lock); +				ioa_cfg->scsi_unblock = 1; +				schedule_work(&ioa_cfg->work_q);  			}  			return;  		} else { diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index e98a87a65335..c7f0e9e3cd7d 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -1488,6 +1488,8 @@ struct ipr_ioa_cfg {  	u8 cfg_locked:1;  	u8 clear_isr:1;  	u8 probe_done:1; +	u8 scsi_unblock:1; +	u8 scsi_blocked:1;  	u8 revid; diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 47f66e949745..ed197bc8e801 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -213,7 +213,7 @@ static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)   * @task_context:   *   */ -static void scu_ssp_reqeust_construct_task_context( +static void scu_ssp_request_construct_task_context(  	struct isci_request *ireq,  	struct scu_task_context *task_context)  { @@ -425,7 +425,7 @@ static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq,  	u8 prot_type = scsi_get_prot_type(scmd);  	u8 prot_op = scsi_get_prot_op(scmd); -	scu_ssp_reqeust_construct_task_context(ireq, task_context); +	scu_ssp_request_construct_task_context(ireq, task_context);  	task_context->ssp_command_iu_length =  		sizeof(struct ssp_cmd_iu) / sizeof(u32); @@ -472,7 +472,7 @@ static void scu_ssp_task_request_construct_task_context(struct isci_request *ire  {  	struct scu_task_context *task_context = ireq->tc; -	scu_ssp_reqeust_construct_task_context(ireq, task_context); +	scu_ssp_request_construct_task_context(ireq, task_context);  	task_context->control_frame                = 1;  	task_context->priority                     = SCU_TASK_PRIORITY_HIGH; @@ -495,7 +495,7 @@ static void scu_ssp_task_request_construct_task_context(struct isci_request *ire   * the command buffer is complete. none Revisit task context construction to   * determine what is common for SSP/SMP/STP task context structures.   */ -static void scu_sata_reqeust_construct_task_context( +static void scu_sata_request_construct_task_context(  	struct isci_request *ireq,  	struct scu_task_context *task_context)  { @@ -562,7 +562,7 @@ static void scu_stp_raw_request_construct_task_context(struct isci_request *ireq  {  	struct scu_task_context *task_context = ireq->tc; -	scu_sata_reqeust_construct_task_context(ireq, task_context); +	scu_sata_request_construct_task_context(ireq, task_context);  	task_context->control_frame         = 0;  	task_context->priority              = SCU_TASK_PRIORITY_NORMAL; @@ -613,7 +613,7 @@ static void sci_stp_optimized_request_construct(struct isci_request *ireq,  	struct scu_task_context *task_context = ireq->tc;  	/* Build the STP task context structure */ -	scu_sata_reqeust_construct_task_context(ireq, task_context); +	scu_sata_request_construct_task_context(ireq, task_context);  	/* Copy over the SGL elements */  	sci_request_build_sgl(ireq); @@ -1401,7 +1401,7 @@ static enum sci_status sci_stp_request_pio_data_out_transmit_data(struct isci_re   * @data_buffer: The buffer of data to be copied.   * @length: The length of the data transfer.   * - * Copy the data from the buffer for the length specified to the IO reqeust SGL + * Copy the data from the buffer for the length specified to the IO request SGL   * specified data region. enum sci_status   */  static enum sci_status diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index fd501f8dbb11..8660f923ace0 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -573,7 +573,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,  		event = DISC_EV_FAILED;  	}  	if (error) -		fc_disc_error(disc, fp); +		fc_disc_error(disc, ERR_PTR(error));  	else if (event != DISC_EV_NONE)  		fc_disc_done(disc, event);  	fc_frame_free(fp); diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 4ed48ed38e79..7ee1a94c0b33 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -205,8 +205,10 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,  				atomic_read(&tgtp->xmt_ls_rsp_error));  		len += snprintf(buf+len, PAGE_SIZE-len, -				"FCP: Rcv %08x Release %08x Drop %08x\n", +				"FCP: Rcv %08x Defer %08x Release %08x " +				"Drop %08x\n",  				atomic_read(&tgtp->rcv_fcp_cmd_in), +				atomic_read(&tgtp->rcv_fcp_cmd_defer),  				atomic_read(&tgtp->xmt_fcp_release),  				atomic_read(&tgtp->rcv_fcp_cmd_drop)); diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 5cc8b0f7d885..744f3f395b64 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -782,8 +782,11 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size)  				atomic_read(&tgtp->xmt_ls_rsp_error));  		len += snprintf(buf + len, size - len, -				"FCP: Rcv %08x Drop %08x\n", +				"FCP: Rcv %08x Defer %08x Release %08x " +				"Drop %08x\n",  				atomic_read(&tgtp->rcv_fcp_cmd_in), +				atomic_read(&tgtp->rcv_fcp_cmd_defer), +				atomic_read(&tgtp->xmt_fcp_release),  				atomic_read(&tgtp->rcv_fcp_cmd_drop));  		if (atomic_read(&tgtp->rcv_fcp_cmd_in) != diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index fbeec344c6cc..bbbd0f84160d 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -841,12 +841,31 @@ lpfc_nvmet_xmt_fcp_release(struct nvmet_fc_target_port *tgtport,  	lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf);  } +static void +lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport, +		     struct nvmefc_tgt_fcp_req *rsp) +{ +	struct lpfc_nvmet_tgtport *tgtp; +	struct lpfc_nvmet_rcv_ctx *ctxp = +		container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); +	struct rqb_dmabuf *nvmebuf = ctxp->rqb_buffer; +	struct lpfc_hba *phba = ctxp->phba; + +	lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n", +			 ctxp->oxid, ctxp->size, smp_processor_id()); + +	tgtp = phba->targetport->private; +	atomic_inc(&tgtp->rcv_fcp_cmd_defer); +	lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */ +} +  static struct nvmet_fc_target_template lpfc_tgttemplate = {  	.targetport_delete = lpfc_nvmet_targetport_delete,  	.xmt_ls_rsp     = lpfc_nvmet_xmt_ls_rsp,  	.fcp_op         = lpfc_nvmet_xmt_fcp_op,  	.fcp_abort      = lpfc_nvmet_xmt_fcp_abort,  	.fcp_req_release = lpfc_nvmet_xmt_fcp_release, +	.defer_rcv	= lpfc_nvmet_defer_rcv,  	.max_hw_queues  = 1,  	.max_sgl_segments = LPFC_NVMET_DEFAULT_SEGS, @@ -1504,6 +1523,17 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,  		return;  	} +	/* Processing of FCP command is deferred */ +	if (rc == -EOVERFLOW) { +		lpfc_nvmeio_data(phba, +				 "NVMET RCV BUSY: xri x%x sz %d from %06x\n", +				 oxid, size, sid); +		/* defer reposting rcv buffer till .defer_rcv callback */ +		ctxp->rqb_buffer = nvmebuf; +		atomic_inc(&tgtp->rcv_fcp_cmd_out); +		return; +	} +  	atomic_inc(&tgtp->rcv_fcp_cmd_drop);  	lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,  			"6159 FCP Drop IO x%x: err x%x: x%x x%x x%x\n", diff --git a/drivers/scsi/lpfc/lpfc_nvmet.h b/drivers/scsi/lpfc/lpfc_nvmet.h index e675ef17be08..48a76788b003 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.h +++ b/drivers/scsi/lpfc/lpfc_nvmet.h @@ -49,6 +49,7 @@ struct lpfc_nvmet_tgtport {  	atomic_t rcv_fcp_cmd_in;  	atomic_t rcv_fcp_cmd_out;  	atomic_t rcv_fcp_cmd_drop; +	atomic_t rcv_fcp_cmd_defer;  	atomic_t xmt_fcp_release;  	/* Stats counters - lpfc_nvmet_xmt_fcp_op */ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 316c3df0c3fd..71c4746341ea 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6228,8 +6228,8 @@ static int megasas_probe_one(struct pci_dev *pdev,  fail_start_aen:  fail_io_attach:  	megasas_mgmt_info.count--; -	megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;  	megasas_mgmt_info.max_index--; +	megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;  	instance->instancet->disable_intr(instance);  	megasas_destroy_irqs(instance); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index f990ab4d45e1..985510628f56 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -425,7 +425,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)  int  megasas_alloc_cmdlist_fusion(struct megasas_instance *instance)  { -	u32 max_mpt_cmd, i; +	u32 max_mpt_cmd, i, j;  	struct fusion_context *fusion;  	fusion = instance->ctrl_context; @@ -450,11 +450,15 @@ megasas_alloc_cmdlist_fusion(struct megasas_instance *instance)  		fusion->cmd_list[i] = kzalloc(sizeof(struct megasas_cmd_fusion),  					      GFP_KERNEL);  		if (!fusion->cmd_list[i]) { +			for (j = 0; j < i; j++) +				kfree(fusion->cmd_list[j]); +			kfree(fusion->cmd_list);  			dev_err(&instance->pdev->dev,  				"Failed from %s %d\n",  __func__, __LINE__);  			return -ENOMEM;  		}  	} +  	return 0;  }  int diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h index 4d038926a455..351f06dfc5a0 100644 --- a/drivers/scsi/qedf/qedf.h +++ b/drivers/scsi/qedf/qedf.h @@ -528,7 +528,8 @@ struct fip_vlan {  #define QEDF_WRITE                    (1 << 0)  #define MAX_FIBRE_LUNS			0xffffffff -#define QEDF_MAX_NUM_CQS		8 +#define MIN_NUM_CPUS_MSIX(x)	min_t(u32, x->dev_info.num_cqs, \ +					num_online_cpus())  /*   * PCI function probe defines diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index b58bba4604e8..1d13c9ca517d 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -1227,7 +1227,7 @@ static void qedf_rport_event_handler(struct fc_lport *lport,  		if (rdata->spp_type != FC_TYPE_FCP) {  			QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, -			    "Not offlading since since spp type isn't FCP\n"); +			    "Not offloading since spp type isn't FCP\n");  			break;  		}  		if (!(rdata->ids.roles & FC_RPORT_ROLE_FCP_TARGET)) { @@ -2760,11 +2760,9 @@ static int qedf_set_fcoe_pf_param(struct qedf_ctx *qedf)  	 * we allocation is the minimum off:  	 *  	 * Number of CPUs -	 * Number of MSI-X vectors -	 * Max number allocated in hardware (QEDF_MAX_NUM_CQS) +	 * Number allocated by qed for our PCI function  	 */ -	qedf->num_queues = min((unsigned int)QEDF_MAX_NUM_CQS, -	    num_online_cpus()); +	qedf->num_queues = MIN_NUM_CPUS_MSIX(qedf);  	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Number of CQs is %d.\n",  		   qedf->num_queues); @@ -2962,6 +2960,13 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)  		goto err1;  	} +	/* Learn information crucial for qedf to progress */ +	rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info); +	if (rc) { +		QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n"); +		goto err1; +	} +  	/* queue allocation code should come here  	 * order should be  	 * 	slowpath_start @@ -2977,13 +2982,6 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)  	}  	qed_ops->common->update_pf_params(qedf->cdev, &qedf->pf_params); -	/* Learn information crucial for qedf to progress */ -	rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info); -	if (rc) { -		QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n"); -		goto err1; -	} -  	/* Record BDQ producer doorbell addresses */  	qedf->bdq_primary_prod = qedf->dev_info.primary_dbq_rq_addr;  	qedf->bdq_secondary_prod = qedf->dev_info.secondary_bdq_rq_addr; diff --git a/drivers/scsi/qedi/Kconfig b/drivers/scsi/qedi/Kconfig index 21331453db7b..2ff753ce6e27 100644 --- a/drivers/scsi/qedi/Kconfig +++ b/drivers/scsi/qedi/Kconfig @@ -5,6 +5,7 @@ config QEDI  	select SCSI_ISCSI_ATTRS  	select QED_LL2  	select QED_ISCSI +	select ISCSI_BOOT_SYSFS  	---help---  	This driver supports iSCSI offload for the QLogic FastLinQ  	41000 Series Converged Network Adapters. diff --git a/drivers/scsi/qedi/qedi.h b/drivers/scsi/qedi/qedi.h index 32632c9b2276..91d2f51c351b 100644 --- a/drivers/scsi/qedi/qedi.h +++ b/drivers/scsi/qedi/qedi.h @@ -23,11 +23,17 @@  #include <linux/qed/qed_iscsi_if.h>  #include <linux/qed/qed_ll2_if.h>  #include "qedi_version.h" +#include "qedi_nvm_iscsi_cfg.h"  #define QEDI_MODULE_NAME		"qedi"  struct qedi_endpoint; +#ifndef GET_FIELD2 +#define GET_FIELD2(value, name) \ +	(((value) & (name ## _MASK)) >> (name ## _OFFSET)) +#endif +  /*   * PCI function probe defines   */ @@ -66,6 +72,11 @@ struct qedi_endpoint;  #define QEDI_HW_DMA_BOUNDARY	0xfff  #define QEDI_PATH_HANDLE	0xFE0000000UL +enum qedi_nvm_tgts { +	QEDI_NVM_TGT_PRI, +	QEDI_NVM_TGT_SEC, +}; +  struct qedi_uio_ctrl {  	/* meta data */  	u32 uio_hsi_version; @@ -283,6 +294,8 @@ struct qedi_ctx {  	void *bdq_pbl_list;  	dma_addr_t bdq_pbl_list_dma;  	u8 bdq_pbl_list_num_entries; +	struct nvm_iscsi_cfg *iscsi_cfg; +	dma_addr_t nvm_buf_dma;  	void __iomem *bdq_primary_prod;  	void __iomem *bdq_secondary_prod;  	u16 bdq_prod_idx; @@ -337,6 +350,10 @@ struct qedi_ctx {  	bool use_fast_sge;  	atomic_t num_offloads; +#define SYSFS_FLAG_FW_SEL_BOOT 2 +#define IPV6_LEN	41 +#define IPV4_LEN	17 +	struct iscsi_boot_kset *boot_kset;  };  struct qedi_work { diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index 19254bd739d9..93d54acd4a22 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c @@ -1411,7 +1411,7 @@ static void qedi_tmf_work(struct work_struct *work)  	list_work = kzalloc(sizeof(*list_work), GFP_ATOMIC);  	if (!list_work) { -		QEDI_ERR(&qedi->dbg_ctx, "Memory alloction failed\n"); +		QEDI_ERR(&qedi->dbg_ctx, "Memory allocation failed\n");  		goto abort_ret;  	} diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index 80edd28b635f..37da9a8b43b1 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c @@ -824,7 +824,7 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,  	u32 iscsi_cid = QEDI_CID_RESERVED;  	u16 len = 0;  	char *buf = NULL; -	int ret; +	int ret, tmp;  	if (!shost) {  		ret = -ENXIO; @@ -940,10 +940,10 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,  ep_rel_conn:  	qedi->ep_tbl[iscsi_cid] = NULL; -	ret = qedi_ops->release_conn(qedi->cdev, qedi_ep->handle); -	if (ret) +	tmp = qedi_ops->release_conn(qedi->cdev, qedi_ep->handle); +	if (tmp)  		QEDI_WARN(&qedi->dbg_ctx, "release_conn returned %d\n", -			  ret); +			  tmp);  ep_free_sq:  	qedi_free_sq(qedi, qedi_ep);  ep_conn_exit: diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 5f5a4ef2e529..2c3783684815 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -19,6 +19,7 @@  #include <linux/mm.h>  #include <linux/if_vlan.h>  #include <linux/cpu.h> +#include <linux/iscsi_boot_sysfs.h>  #include <scsi/scsi_cmnd.h>  #include <scsi/scsi_device.h> @@ -1143,6 +1144,30 @@ exit_setup_int:  	return rc;  } +static void qedi_free_nvm_iscsi_cfg(struct qedi_ctx *qedi) +{ +	if (qedi->iscsi_cfg) +		dma_free_coherent(&qedi->pdev->dev, +				  sizeof(struct nvm_iscsi_cfg), +				  qedi->iscsi_cfg, qedi->nvm_buf_dma); +} + +static int qedi_alloc_nvm_iscsi_cfg(struct qedi_ctx *qedi) +{ +	qedi->iscsi_cfg = dma_zalloc_coherent(&qedi->pdev->dev, +					     sizeof(struct nvm_iscsi_cfg), +					     &qedi->nvm_buf_dma, GFP_KERNEL); +	if (!qedi->iscsi_cfg) { +		QEDI_ERR(&qedi->dbg_ctx, "Could not allocate NVM BUF.\n"); +		return -ENOMEM; +	} +	QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, +		  "NVM BUF addr=0x%p dma=0x%llx.\n", qedi->iscsi_cfg, +		  qedi->nvm_buf_dma); + +	return 0; +} +  static void qedi_free_bdq(struct qedi_ctx *qedi)  {  	int i; @@ -1183,6 +1208,7 @@ static void qedi_free_global_queues(struct qedi_ctx *qedi)  		kfree(gl[i]);  	}  	qedi_free_bdq(qedi); +	qedi_free_nvm_iscsi_cfg(qedi);  }  static int qedi_alloc_bdq(struct qedi_ctx *qedi) @@ -1309,6 +1335,11 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi)  	if (rc)  		goto mem_alloc_failure; +	/* Allocate DMA coherent buffers for NVM_ISCSI_CFG */ +	rc = qedi_alloc_nvm_iscsi_cfg(qedi); +	if (rc) +		goto mem_alloc_failure; +  	/* Allocate a CQ and an associated PBL for each MSI-X  	 * vector.  	 */ @@ -1671,6 +1702,387 @@ void qedi_reset_host_mtu(struct qedi_ctx *qedi, u16 mtu)  	qedi_ops->ll2->start(qedi->cdev, ¶ms);  } +/** + * qedi_get_nvram_block: - Scan through the iSCSI NVRAM block (while accounting + * for gaps) for the matching absolute-pf-id of the QEDI device. + */ +static struct nvm_iscsi_block * +qedi_get_nvram_block(struct qedi_ctx *qedi) +{ +	int i; +	u8 pf; +	u32 flags; +	struct nvm_iscsi_block *block; + +	pf = qedi->dev_info.common.abs_pf_id; +	block = &qedi->iscsi_cfg->block[0]; +	for (i = 0; i < NUM_OF_ISCSI_PF_SUPPORTED; i++, block++) { +		flags = ((block->id) & NVM_ISCSI_CFG_BLK_CTRL_FLAG_MASK) >> +			NVM_ISCSI_CFG_BLK_CTRL_FLAG_OFFSET; +		if (flags & (NVM_ISCSI_CFG_BLK_CTRL_FLAG_IS_NOT_EMPTY | +				NVM_ISCSI_CFG_BLK_CTRL_FLAG_PF_MAPPED) && +			(pf == (block->id & NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_MASK) +				>> NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_OFFSET)) +			return block; +	} +	return NULL; +} + +static ssize_t qedi_show_boot_eth_info(void *data, int type, char *buf) +{ +	struct qedi_ctx *qedi = data; +	struct nvm_iscsi_initiator *initiator; +	char *str = buf; +	int rc = 1; +	u32 ipv6_en, dhcp_en, ip_len; +	struct nvm_iscsi_block *block; +	char *fmt, *ip, *sub, *gw; + +	block = qedi_get_nvram_block(qedi); +	if (!block) +		return 0; + +	initiator = &block->initiator; +	ipv6_en = block->generic.ctrl_flags & +		  NVM_ISCSI_CFG_GEN_IPV6_ENABLED; +	dhcp_en = block->generic.ctrl_flags & +		  NVM_ISCSI_CFG_GEN_DHCP_TCPIP_CONFIG_ENABLED; +	/* Static IP assignments. */ +	fmt = ipv6_en ? "%pI6\n" : "%pI4\n"; +	ip = ipv6_en ? initiator->ipv6.addr.byte : initiator->ipv4.addr.byte; +	ip_len = ipv6_en ? IPV6_LEN : IPV4_LEN; +	sub = ipv6_en ? initiator->ipv6.subnet_mask.byte : +	      initiator->ipv4.subnet_mask.byte; +	gw = ipv6_en ? initiator->ipv6.gateway.byte : +	     initiator->ipv4.gateway.byte; +	/* DHCP IP adjustments. */ +	fmt = dhcp_en ? "%s\n" : fmt; +	if (dhcp_en) { +		ip = ipv6_en ? "0::0" : "0.0.0.0"; +		sub = ip; +		gw = ip; +		ip_len = ipv6_en ? 5 : 8; +	} + +	switch (type) { +	case ISCSI_BOOT_ETH_IP_ADDR: +		rc = snprintf(str, ip_len, fmt, ip); +		break; +	case ISCSI_BOOT_ETH_SUBNET_MASK: +		rc = snprintf(str, ip_len, fmt, sub); +		break; +	case ISCSI_BOOT_ETH_GATEWAY: +		rc = snprintf(str, ip_len, fmt, gw); +		break; +	case ISCSI_BOOT_ETH_FLAGS: +		rc = snprintf(str, 3, "%hhd\n", +			      SYSFS_FLAG_FW_SEL_BOOT); +		break; +	case ISCSI_BOOT_ETH_INDEX: +		rc = snprintf(str, 3, "0\n"); +		break; +	case ISCSI_BOOT_ETH_MAC: +		rc = sysfs_format_mac(str, qedi->mac, ETH_ALEN); +		break; +	case ISCSI_BOOT_ETH_VLAN: +		rc = snprintf(str, 12, "%d\n", +			      GET_FIELD2(initiator->generic_cont0, +					 NVM_ISCSI_CFG_INITIATOR_VLAN)); +		break; +	case ISCSI_BOOT_ETH_ORIGIN: +		if (dhcp_en) +			rc = snprintf(str, 3, "3\n"); +		break; +	default: +		rc = 0; +		break; +	} + +	return rc; +} + +static umode_t qedi_eth_get_attr_visibility(void *data, int type) +{ +	int rc = 1; + +	switch (type) { +	case ISCSI_BOOT_ETH_FLAGS: +	case ISCSI_BOOT_ETH_MAC: +	case ISCSI_BOOT_ETH_INDEX: +	case ISCSI_BOOT_ETH_IP_ADDR: +	case ISCSI_BOOT_ETH_SUBNET_MASK: +	case ISCSI_BOOT_ETH_GATEWAY: +	case ISCSI_BOOT_ETH_ORIGIN: +	case ISCSI_BOOT_ETH_VLAN: +		rc = 0444; +		break; +	default: +		rc = 0; +		break; +	} +	return rc; +} + +static ssize_t qedi_show_boot_ini_info(void *data, int type, char *buf) +{ +	struct qedi_ctx *qedi = data; +	struct nvm_iscsi_initiator *initiator; +	char *str = buf; +	int rc; +	struct nvm_iscsi_block *block; + +	block = qedi_get_nvram_block(qedi); +	if (!block) +		return 0; + +	initiator = &block->initiator; + +	switch (type) { +	case ISCSI_BOOT_INI_INITIATOR_NAME: +		rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n", +			      initiator->initiator_name.byte); +		break; +	default: +		rc = 0; +		break; +	} +	return rc; +} + +static umode_t qedi_ini_get_attr_visibility(void *data, int type) +{ +	int rc; + +	switch (type) { +	case ISCSI_BOOT_INI_INITIATOR_NAME: +		rc = 0444; +		break; +	default: +		rc = 0; +		break; +	} +	return rc; +} + +static ssize_t +qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type, +			char *buf, enum qedi_nvm_tgts idx) +{ +	char *str = buf; +	int rc = 1; +	u32 ctrl_flags, ipv6_en, chap_en, mchap_en, ip_len; +	struct nvm_iscsi_block *block; +	char *chap_name, *chap_secret; +	char *mchap_name, *mchap_secret; + +	block = qedi_get_nvram_block(qedi); +	if (!block) +		goto exit_show_tgt_info; + +	QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_EVT, +		  "Port:%d, tgt_idx:%d\n", +		  GET_FIELD2(block->id, NVM_ISCSI_CFG_BLK_MAPPED_PF_ID), idx); + +	ctrl_flags = block->target[idx].ctrl_flags & +		     NVM_ISCSI_CFG_TARGET_ENABLED; + +	if (!ctrl_flags) { +		QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_EVT, +			  "Target disabled\n"); +		goto exit_show_tgt_info; +	} + +	ipv6_en = block->generic.ctrl_flags & +		  NVM_ISCSI_CFG_GEN_IPV6_ENABLED; +	ip_len = ipv6_en ? IPV6_LEN : IPV4_LEN; +	chap_en = block->generic.ctrl_flags & +		  NVM_ISCSI_CFG_GEN_CHAP_ENABLED; +	chap_name = chap_en ? block->initiator.chap_name.byte : NULL; +	chap_secret = chap_en ? block->initiator.chap_password.byte : NULL; + +	mchap_en = block->generic.ctrl_flags & +		  NVM_ISCSI_CFG_GEN_CHAP_MUTUAL_ENABLED; +	mchap_name = mchap_en ? block->target[idx].chap_name.byte : NULL; +	mchap_secret = mchap_en ? block->target[idx].chap_password.byte : NULL; + +	switch (type) { +	case ISCSI_BOOT_TGT_NAME: +		rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n", +			      block->target[idx].target_name.byte); +		break; +	case ISCSI_BOOT_TGT_IP_ADDR: +		if (ipv6_en) +			rc = snprintf(str, ip_len, "%pI6\n", +				      block->target[idx].ipv6_addr.byte); +		else +			rc = snprintf(str, ip_len, "%pI4\n", +				      block->target[idx].ipv4_addr.byte); +		break; +	case ISCSI_BOOT_TGT_PORT: +		rc = snprintf(str, 12, "%d\n", +			      GET_FIELD2(block->target[idx].generic_cont0, +					 NVM_ISCSI_CFG_TARGET_TCP_PORT)); +		break; +	case ISCSI_BOOT_TGT_LUN: +		rc = snprintf(str, 22, "%.*d\n", +			      block->target[idx].lun.value[1], +			      block->target[idx].lun.value[0]); +		break; +	case ISCSI_BOOT_TGT_CHAP_NAME: +		rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n", +			      chap_name); +		break; +	case ISCSI_BOOT_TGT_CHAP_SECRET: +		rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n", +			      chap_secret); +		break; +	case ISCSI_BOOT_TGT_REV_CHAP_NAME: +		rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n", +			      mchap_name); +		break; +	case ISCSI_BOOT_TGT_REV_CHAP_SECRET: +		rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n", +			      mchap_secret); +		break; +	case ISCSI_BOOT_TGT_FLAGS: +		rc = snprintf(str, 3, "%hhd\n", SYSFS_FLAG_FW_SEL_BOOT); +		break; +	case ISCSI_BOOT_TGT_NIC_ASSOC: +		rc = snprintf(str, 3, "0\n"); +		break; +	default: +		rc = 0; +		break; +	} + +exit_show_tgt_info: +	return rc; +} + +static ssize_t qedi_show_boot_tgt_pri_info(void *data, int type, char *buf) +{ +	struct qedi_ctx *qedi = data; + +	return qedi_show_boot_tgt_info(qedi, type, buf, QEDI_NVM_TGT_PRI); +} + +static ssize_t qedi_show_boot_tgt_sec_info(void *data, int type, char *buf) +{ +	struct qedi_ctx *qedi = data; + +	return qedi_show_boot_tgt_info(qedi, type, buf, QEDI_NVM_TGT_SEC); +} + +static umode_t qedi_tgt_get_attr_visibility(void *data, int type) +{ +	int rc; + +	switch (type) { +	case ISCSI_BOOT_TGT_NAME: +	case ISCSI_BOOT_TGT_IP_ADDR: +	case ISCSI_BOOT_TGT_PORT: +	case ISCSI_BOOT_TGT_LUN: +	case ISCSI_BOOT_TGT_CHAP_NAME: +	case ISCSI_BOOT_TGT_CHAP_SECRET: +	case ISCSI_BOOT_TGT_REV_CHAP_NAME: +	case ISCSI_BOOT_TGT_REV_CHAP_SECRET: +	case ISCSI_BOOT_TGT_NIC_ASSOC: +	case ISCSI_BOOT_TGT_FLAGS: +		rc = 0444; +		break; +	default: +		rc = 0; +		break; +	} +	return rc; +} + +static void qedi_boot_release(void *data) +{ +	struct qedi_ctx *qedi = data; + +	scsi_host_put(qedi->shost); +} + +static int qedi_get_boot_info(struct qedi_ctx *qedi) +{ +	int ret = 1; +	u16 len; + +	len = sizeof(struct nvm_iscsi_cfg); + +	QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, +		  "Get NVM iSCSI CFG image\n"); +	ret = qedi_ops->common->nvm_get_image(qedi->cdev, +					      QED_NVM_IMAGE_ISCSI_CFG, +					      (char *)qedi->iscsi_cfg, len); +	if (ret) +		QEDI_ERR(&qedi->dbg_ctx, +			 "Could not get NVM image. ret = %d\n", ret); + +	return ret; +} + +static int qedi_setup_boot_info(struct qedi_ctx *qedi) +{ +	struct iscsi_boot_kobj *boot_kobj; + +	if (qedi_get_boot_info(qedi)) +		return -EPERM; + +	qedi->boot_kset = iscsi_boot_create_host_kset(qedi->shost->host_no); +	if (!qedi->boot_kset) +		goto kset_free; + +	if (!scsi_host_get(qedi->shost)) +		goto kset_free; + +	boot_kobj = iscsi_boot_create_target(qedi->boot_kset, 0, qedi, +					     qedi_show_boot_tgt_pri_info, +					     qedi_tgt_get_attr_visibility, +					     qedi_boot_release); +	if (!boot_kobj) +		goto put_host; + +	if (!scsi_host_get(qedi->shost)) +		goto kset_free; + +	boot_kobj = iscsi_boot_create_target(qedi->boot_kset, 1, qedi, +					     qedi_show_boot_tgt_sec_info, +					     qedi_tgt_get_attr_visibility, +					     qedi_boot_release); +	if (!boot_kobj) +		goto put_host; + +	if (!scsi_host_get(qedi->shost)) +		goto kset_free; + +	boot_kobj = iscsi_boot_create_initiator(qedi->boot_kset, 0, qedi, +						qedi_show_boot_ini_info, +						qedi_ini_get_attr_visibility, +						qedi_boot_release); +	if (!boot_kobj) +		goto put_host; + +	if (!scsi_host_get(qedi->shost)) +		goto kset_free; + +	boot_kobj = iscsi_boot_create_ethernet(qedi->boot_kset, 0, qedi, +					       qedi_show_boot_eth_info, +					       qedi_eth_get_attr_visibility, +					       qedi_boot_release); +	if (!boot_kobj) +		goto put_host; + +	return 0; + +put_host: +	scsi_host_put(qedi->shost); +kset_free: +	iscsi_boot_destroy_kset(qedi->boot_kset); +	return -ENOMEM; +} +  static void __qedi_remove(struct pci_dev *pdev, int mode)  {  	struct qedi_ctx *qedi = pci_get_drvdata(pdev); @@ -1724,6 +2136,9 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)  			qedi->ll2_recv_thread = NULL;  		}  		qedi_ll2_free_skbs(qedi); + +		if (qedi->boot_kset) +			iscsi_boot_destroy_kset(qedi->boot_kset);  	}  } @@ -1967,6 +2382,10 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)  		/* F/w needs 1st task context memory entry for performance */  		set_bit(QEDI_RESERVE_TASK_ID, qedi->task_idx_map);  		atomic_set(&qedi->num_offloads, 0); + +		if (qedi_setup_boot_info(qedi)) +			QEDI_ERR(&qedi->dbg_ctx, +				 "No iSCSI boot target configured\n");  	}  	return 0; diff --git a/drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h b/drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h new file mode 100644 index 000000000000..df39b69b366d --- /dev/null +++ b/drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h @@ -0,0 +1,210 @@ +/* + * QLogic iSCSI Offload Driver + * Copyright (c) 2016 Cavium Inc. + * + * This software is available under the terms of the GNU General Public License + * (GPL) Version 2, available from the file COPYING in the main directory of + * this source tree. + */ + +#ifndef NVM_ISCSI_CFG_H +#define NVM_ISCSI_CFG_H + +#define NUM_OF_ISCSI_TARGET_PER_PF    4   /* Defined as per the +					   * ISCSI IBFT constraint +					   */ +#define NUM_OF_ISCSI_PF_SUPPORTED     4   /* One PF per Port - +					   * assuming 4 port card +					   */ + +#define NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN  256 + +union nvm_iscsi_dhcp_vendor_id { +	u32 value[NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN / 4]; +	u8  byte[NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN]; +}; + +#define NVM_ISCSI_IPV4_ADDR_BYTE_LEN 4 +union nvm_iscsi_ipv4_addr { +	u32 addr; +	u8  byte[NVM_ISCSI_IPV4_ADDR_BYTE_LEN]; +}; + +#define NVM_ISCSI_IPV6_ADDR_BYTE_LEN 16 +union nvm_iscsi_ipv6_addr { +	u32 addr[4]; +	u8  byte[NVM_ISCSI_IPV6_ADDR_BYTE_LEN]; +}; + +struct nvm_iscsi_initiator_ipv4 { +	union nvm_iscsi_ipv4_addr addr;				/* 0x0 */ +	union nvm_iscsi_ipv4_addr subnet_mask;			/* 0x4 */ +	union nvm_iscsi_ipv4_addr gateway;			/* 0x8 */ +	union nvm_iscsi_ipv4_addr primary_dns;			/* 0xC */ +	union nvm_iscsi_ipv4_addr secondary_dns;		/* 0x10 */ +	union nvm_iscsi_ipv4_addr dhcp_addr;			/* 0x14 */ + +	union nvm_iscsi_ipv4_addr isns_server;			/* 0x18 */ +	union nvm_iscsi_ipv4_addr slp_server;			/* 0x1C */ +	union nvm_iscsi_ipv4_addr primay_radius_server;		/* 0x20 */ +	union nvm_iscsi_ipv4_addr secondary_radius_server;	/* 0x24 */ + +	union nvm_iscsi_ipv4_addr rsvd[4];			/* 0x28 */ +}; + +struct nvm_iscsi_initiator_ipv6 { +	union nvm_iscsi_ipv6_addr addr;				/* 0x0 */ +	union nvm_iscsi_ipv6_addr subnet_mask;			/* 0x10 */ +	union nvm_iscsi_ipv6_addr gateway;			/* 0x20 */ +	union nvm_iscsi_ipv6_addr primary_dns;			/* 0x30 */ +	union nvm_iscsi_ipv6_addr secondary_dns;		/* 0x40 */ +	union nvm_iscsi_ipv6_addr dhcp_addr;			/* 0x50 */ + +	union nvm_iscsi_ipv6_addr isns_server;			/* 0x60 */ +	union nvm_iscsi_ipv6_addr slp_server;			/* 0x70 */ +	union nvm_iscsi_ipv6_addr primay_radius_server;		/* 0x80 */ +	union nvm_iscsi_ipv6_addr secondary_radius_server;	/* 0x90 */ + +	union nvm_iscsi_ipv6_addr rsvd[3];			/* 0xA0 */ + +	u32   config;						/* 0xD0 */ +#define NVM_ISCSI_CFG_INITIATOR_IPV6_SUBNET_MASK_PREFIX_MASK      0x000000FF +#define NVM_ISCSI_CFG_INITIATOR_IPV6_SUBNET_MASK_PREFIX_OFFSET    0 + +	u32   rsvd_1[3]; +}; + +#define NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN  256 +union nvm_iscsi_name { +	u32 value[NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN / 4]; +	u8  byte[NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN]; +}; + +#define NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN  256 +union nvm_iscsi_chap_name { +	u32 value[NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN / 4]; +	u8  byte[NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN]; +}; + +#define NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN  16 /* md5 need per RFC1996 +					    * is 16 octets +					    */ +union nvm_iscsi_chap_password { +	u32 value[NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN / 4]; +	u8 byte[NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN]; +}; + +union nvm_iscsi_lun { +	u8  byte[8]; +	u32 value[2]; +}; + +struct nvm_iscsi_generic { +	u32 ctrl_flags;						/* 0x0 */ +#define NVM_ISCSI_CFG_GEN_CHAP_ENABLED                 BIT(0) +#define NVM_ISCSI_CFG_GEN_DHCP_TCPIP_CONFIG_ENABLED    BIT(1) +#define NVM_ISCSI_CFG_GEN_DHCP_ISCSI_CONFIG_ENABLED    BIT(2) +#define NVM_ISCSI_CFG_GEN_IPV6_ENABLED                 BIT(3) +#define NVM_ISCSI_CFG_GEN_IPV4_FALLBACK_ENABLED        BIT(4) +#define NVM_ISCSI_CFG_GEN_ISNS_WORLD_LOGIN             BIT(5) +#define NVM_ISCSI_CFG_GEN_ISNS_SELECTIVE_LOGIN         BIT(6) +#define NVM_ISCSI_CFG_GEN_ADDR_REDIRECT_ENABLED	       BIT(7) +#define NVM_ISCSI_CFG_GEN_CHAP_MUTUAL_ENABLED          BIT(8) + +	u32 timeout;						/* 0x4 */ +#define NVM_ISCSI_CFG_GEN_DHCP_REQUEST_TIMEOUT_MASK       0x0000FFFF +#define NVM_ISCSI_CFG_GEN_DHCP_REQUEST_TIMEOUT_OFFSET     0 +#define NVM_ISCSI_CFG_GEN_PORT_LOGIN_TIMEOUT_MASK         0xFFFF0000 +#define NVM_ISCSI_CFG_GEN_PORT_LOGIN_TIMEOUT_OFFSET       16 + +	union nvm_iscsi_dhcp_vendor_id  dhcp_vendor_id;		/* 0x8  */ +	u32 rsvd[62];						/* 0x108 */ +}; + +struct nvm_iscsi_initiator { +	struct nvm_iscsi_initiator_ipv4 ipv4;			/* 0x0 */ +	struct nvm_iscsi_initiator_ipv6 ipv6;			/* 0x38 */ + +	union nvm_iscsi_name           initiator_name;		/* 0x118 */ +	union nvm_iscsi_chap_name      chap_name;		/* 0x218 */ +	union nvm_iscsi_chap_password  chap_password;		/* 0x318 */ + +	u32 generic_cont0;					/* 0x398 */ +#define NVM_ISCSI_CFG_INITIATOR_VLAN_MASK		0x0000FFFF +#define NVM_ISCSI_CFG_INITIATOR_VLAN_OFFSET		0 +#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_MASK		0x00030000 +#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_OFFSET	16 +#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_4		1 +#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_6		2 +#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_4_AND_6	3 + +	u32 ctrl_flags; +#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_PRIORITY_V6     BIT(0) +#define NVM_ISCSI_CFG_INITIATOR_VLAN_ENABLED               BIT(1) + +	u32 rsvd[116];						/* 0x32C */ +}; + +struct nvm_iscsi_target { +	u32 ctrl_flags;						/* 0x0 */ +#define NVM_ISCSI_CFG_TARGET_ENABLED            BIT(0) +#define NVM_ISCSI_CFG_BOOT_TIME_LOGIN_STATUS    BIT(1) + +	u32 generic_cont0;					/* 0x4 */ +#define NVM_ISCSI_CFG_TARGET_TCP_PORT_MASK      0x0000FFFF +#define NVM_ISCSI_CFG_TARGET_TCP_PORT_OFFSET    0 + +	u32 ip_ver; +#define NVM_ISCSI_CFG_IPv4       4 +#define NVM_ISCSI_CFG_IPv6       6 + +	u32 rsvd_1[7];						/* 0x24 */ +	union nvm_iscsi_ipv4_addr ipv4_addr;			/* 0x28 */ +	union nvm_iscsi_ipv6_addr ipv6_addr;			/* 0x2C */ +	union nvm_iscsi_lun lun;				/* 0x3C */ + +	union nvm_iscsi_name           target_name;		/* 0x44 */ +	union nvm_iscsi_chap_name      chap_name;		/* 0x144 */ +	union nvm_iscsi_chap_password  chap_password;		/* 0x244 */ + +	u32 rsvd_2[107];					/* 0x2C4 */ +}; + +struct nvm_iscsi_block { +	u32 id;							/* 0x0 */ +#define NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_MASK         0x0000000F +#define NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_OFFSET       0 +#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_MASK            0x00000FF0 +#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_OFFSET          4 +#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_IS_NOT_EMPTY    BIT(0) +#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_PF_MAPPED       BIT(1) + +	u32 rsvd_1[5];						/* 0x4 */ + +	struct nvm_iscsi_generic     generic;			/* 0x18 */ +	struct nvm_iscsi_initiator   initiator;			/* 0x218 */ +	struct nvm_iscsi_target      target[NUM_OF_ISCSI_TARGET_PER_PF]; +								/* 0x718 */ + +	u32 rsvd_2[58];						/* 0x1718 */ +	/* total size - 0x1800 - 6K block */ +}; + +struct nvm_iscsi_cfg { +	u32 id;							/* 0x0 */ +#define NVM_ISCSI_CFG_BLK_VERSION_MINOR_MASK     0x000000FF +#define NVM_ISCSI_CFG_BLK_VERSION_MAJOR_MASK     0x0000FF00 +#define NVM_ISCSI_CFG_BLK_SIGNATURE_MASK         0xFFFF0000 +#define NVM_ISCSI_CFG_BLK_SIGNATURE              0x49430000 /* IC - Iscsi +							     * Config +							     */ + +#define NVM_ISCSI_CFG_BLK_VERSION_MAJOR          0 +#define NVM_ISCSI_CFG_BLK_VERSION_MINOR          10 +#define NVM_ISCSI_CFG_BLK_VERSION ((NVM_ISCSI_CFG_BLK_VERSION_MAJOR << 8) | \ +				   NVM_ISCSI_CFG_BLK_VERSION_MINOR) + +	struct nvm_iscsi_block	block[NUM_OF_ISCSI_PF_SUPPORTED]; /* 0x4 */ +}; + +#endif diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index c2dc836dc484..e101cd3043b9 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -3727,7 +3727,7 @@ static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,  	h &= QLA_CMD_HANDLE_MASK;  	if (h != QLA_TGT_NULL_HANDLE) { -		if (unlikely(h > req->num_outstanding_cmds)) { +		if (unlikely(h >= req->num_outstanding_cmds)) {  			ql_dbg(ql_dbg_tgt, vha, 0xe052,  			    "qla_target(%d): Wrong handle %x received\n",  			    vha->vp_idx, handle); diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c index 33142610882f..b18646d6057f 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.c +++ b/drivers/scsi/qla2xxx/qla_tmpl.c @@ -401,9 +401,6 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,  		for (i = 0; i < vha->hw->max_req_queues; i++) {  			struct req_que *req = vha->hw->req_q_map[i]; -			if (!test_bit(i, vha->hw->req_qid_map)) -				continue; -  			if (req || !buf) {  				length = req ?  				    req->length : REQUEST_ENTRY_CNT_24XX; @@ -418,9 +415,6 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,  		for (i = 0; i < vha->hw->max_rsp_queues; i++) {  			struct rsp_que *rsp = vha->hw->rsp_q_map[i]; -			if (!test_bit(i, vha->hw->rsp_qid_map)) -				continue; -  			if (rsp || !buf) {  				length = rsp ?  				    rsp->length : RESPONSE_ENTRY_CNT_MQ; @@ -660,9 +654,6 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,  		for (i = 0; i < vha->hw->max_req_queues; i++) {  			struct req_que *req = vha->hw->req_q_map[i]; -			if (!test_bit(i, vha->hw->req_qid_map)) -				continue; -  			if (req || !buf) {  				qla27xx_insert16(i, buf, len);  				qla27xx_insert16(1, buf, len); @@ -675,9 +666,6 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,  		for (i = 0; i < vha->hw->max_rsp_queues; i++) {  			struct rsp_que *rsp = vha->hw->rsp_q_map[i]; -			if (!test_bit(i, vha->hw->rsp_qid_map)) -				continue; -  			if (rsp || !buf) {  				qla27xx_insert16(i, buf, len);  				qla27xx_insert16(1, buf, len); diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index b20da0d27ad7..3f82ea1b72dc 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -500,7 +500,6 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,  static void tcm_qla2xxx_handle_data_work(struct work_struct *work)  {  	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); -	unsigned long flags;  	/*  	 * Ensure that the complete FCP WRITE payload has been received. @@ -508,17 +507,6 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)  	 */  	cmd->cmd_in_wq = 0; -	spin_lock_irqsave(&cmd->cmd_lock, flags); -	cmd->data_work = 1; -	if (cmd->aborted) { -		cmd->data_work_free = 1; -		spin_unlock_irqrestore(&cmd->cmd_lock, flags); - -		tcm_qla2xxx_free_cmd(cmd); -		return; -	} -	spin_unlock_irqrestore(&cmd->cmd_lock, flags); -  	cmd->qpair->tgt_counters.qla_core_ret_ctio++;  	if (!cmd->write_data_transferred) {  		/* @@ -765,31 +753,13 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)  	qlt_xmit_tm_rsp(mcmd);  } -#define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free)  static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)  {  	struct qla_tgt_cmd *cmd = container_of(se_cmd,  				struct qla_tgt_cmd, se_cmd); -	unsigned long flags;  	if (qlt_abort_cmd(cmd))  		return; - -	spin_lock_irqsave(&cmd->cmd_lock, flags); -	if ((cmd->state == QLA_TGT_STATE_NEW)|| -	    ((cmd->state == QLA_TGT_STATE_DATA_IN) && -		DATA_WORK_NOT_FREE(cmd))) { -		cmd->data_work_free = 1; -		spin_unlock_irqrestore(&cmd->cmd_lock, flags); -		/* -		 * cmd has not reached fw, Use this trigger to free it. -		 */ -		tcm_qla2xxx_free_cmd(cmd); -		return; -	} -	spin_unlock_irqrestore(&cmd->cmd_lock, flags); -	return; -  }  static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 3d38c6d463b8..1bf274e3b2b6 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -800,7 +800,11 @@ MODULE_LICENSE("GPL");  module_param(scsi_logging_level, int, S_IRUGO|S_IWUSR);  MODULE_PARM_DESC(scsi_logging_level, "a bit mask of logging levels"); +#ifdef CONFIG_SCSI_MQ_DEFAULT  bool scsi_use_blk_mq = true; +#else +bool scsi_use_blk_mq = false; +#endif  module_param_named(use_blk_mq, scsi_use_blk_mq, bool, S_IWUSR | S_IRUGO);  static int __init init_scsi(void) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 7e24aa30c3b0..892fbd9800d9 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -1286,7 +1286,7 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr,  	unsigned long flags;  	spin_lock_irqsave(shost->host_lock, flags); -	if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) { +	if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING | FC_VPORT_DELETING)) {  		spin_unlock_irqrestore(shost->host_lock, flags);  		return -EBUSY;  	} @@ -2430,8 +2430,10 @@ fc_remove_host(struct Scsi_Host *shost)  	spin_lock_irqsave(shost->host_lock, flags);  	/* Remove any vports */ -	list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) +	list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) { +		vport->flags |= FC_VPORT_DELETING;  		fc_queue_work(shost, &vport->vport_delete_work); +	}  	/* Remove any remote ports */  	list_for_each_entry_safe(rport, next_rport, diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index bea36adeee17..e2647f2d4430 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1277,6 +1277,9 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)  {  	struct request *rq = SCpnt->request; +	if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK) +		sd_zbc_write_unlock_zone(SCpnt); +  	if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)  		__free_page(rq->special_vec.bv_page); diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 96855df9f49d..8aa54779aac1 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -294,6 +294,9 @@ int sd_zbc_write_lock_zone(struct scsi_cmnd *cmd)  	    test_and_set_bit(zno, sdkp->zones_wlock))  		return BLKPREP_DEFER; +	WARN_ON_ONCE(cmd->flags & SCMD_ZONE_WRITE_LOCK); +	cmd->flags |= SCMD_ZONE_WRITE_LOCK; +  	return BLKPREP_OK;  } @@ -302,9 +305,10 @@ void sd_zbc_write_unlock_zone(struct scsi_cmnd *cmd)  	struct request *rq = cmd->request;  	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); -	if (sdkp->zones_wlock) { +	if (sdkp->zones_wlock && cmd->flags & SCMD_ZONE_WRITE_LOCK) {  		unsigned int zno = sd_zbc_zone_no(sdkp, blk_rq_pos(rq));  		WARN_ON_ONCE(!test_bit(zno, sdkp->zones_wlock)); +		cmd->flags &= ~SCMD_ZONE_WRITE_LOCK;  		clear_bit_unlock(zno, sdkp->zones_wlock);  		smp_mb__after_atomic();  	} @@ -335,9 +339,6 @@ void sd_zbc_complete(struct scsi_cmnd *cmd,  	case REQ_OP_WRITE_ZEROES:  	case REQ_OP_WRITE_SAME: -		/* Unlock the zone */ -		sd_zbc_write_unlock_zone(cmd); -  		if (result &&  		    sshdr->sense_key == ILLEGAL_REQUEST &&  		    sshdr->asc == 0x21) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index f1cdf32d7514..8927f9f54ad9 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -99,7 +99,7 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,  	ret =  scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,  				NULL, SES_TIMEOUT, SES_RETRIES, NULL); -	if (unlikely(!ret)) +	if (unlikely(ret))  		return ret;  	recv_page_code = ((unsigned char *)buf)[0]; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 21225d62b0c1..d7ff71e0c85c 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -751,29 +751,6 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,  	return count;  } -static bool sg_is_valid_dxfer(sg_io_hdr_t *hp) -{ -	switch (hp->dxfer_direction) { -	case SG_DXFER_NONE: -		if (hp->dxferp || hp->dxfer_len > 0) -			return false; -		return true; -	case SG_DXFER_TO_DEV: -	case SG_DXFER_FROM_DEV: -	case SG_DXFER_TO_FROM_DEV: -		if (!hp->dxferp || hp->dxfer_len == 0) -			return false; -		return true; -	case SG_DXFER_UNKNOWN: -		if ((!hp->dxferp && hp->dxfer_len) || -		    (hp->dxferp && hp->dxfer_len == 0)) -			return false; -		return true; -	default: -		return false; -	} -} -  static int  sg_common_write(Sg_fd * sfp, Sg_request * srp,  		unsigned char *cmnd, int timeout, int blocking) @@ -794,7 +771,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,  			"sg_common_write:  scsi opcode=0x%02x, cmd_size=%d\n",  			(int) cmnd[0], (int) hp->cmd_len)); -	if (!sg_is_valid_dxfer(hp)) +	if (hp->dxfer_len >= SZ_256M)  		return -EINVAL;  	k = sg_start_req(srp, cmnd); diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 07ec8a8877de..e164ffade38a 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -690,7 +690,7 @@ struct pqi_config_table_heartbeat {  #define PQI_MAX_OUTSTANDING_REQUESTS		((u32)~0)  #define PQI_MAX_OUTSTANDING_REQUESTS_KDUMP	32 -#define PQI_MAX_TRANSFER_SIZE			(4 * 1024U * 1024U) +#define PQI_MAX_TRANSFER_SIZE			(1024U * 1024U)  #define PQI_MAX_TRANSFER_SIZE_KDUMP		(512 * 1024U)  #define RAID_MAP_MAX_ENTRIES		1024 diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 8e5013d9cad4..94e402ed30f6 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -4299,11 +4299,11 @@ static int st_probe(struct device *dev)  	kref_init(&tpnt->kref);  	tpnt->disk = disk;  	disk->private_data = &tpnt->driver; -	disk->queue = SDp->request_queue;  	/* SCSI tape doesn't register this gendisk via add_disk().  Manually  	 * take queue reference that release_disk() expects. */ -	if (!blk_get_queue(disk->queue)) +	if (!blk_get_queue(SDp->request_queue))  		goto out_put_disk; +	disk->queue = SDp->request_queue;  	tpnt->driver = &st_template;  	tpnt->device = SDp; diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 8b93197daefe..9be211d68b15 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -837,6 +837,7 @@ static struct scsi_host_template virtscsi_host_template_multi = {  	.eh_abort_handler = virtscsi_abort,  	.eh_device_reset_handler = virtscsi_device_reset,  	.eh_timed_out = virtscsi_eh_timed_out, +	.slave_alloc = virtscsi_device_alloc,  	.can_queue = 1024,  	.dma_boundary = UINT_MAX, |