Re: [PATCH v3 06/24] mpi3mr: add support of event handling part-1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 4/19/21 1:01 PM, Kashyap Desai wrote:
> Firmware can report various MPI Events.
> Support for certain Events (as listed below) are enabled in the driver
> and their processing in driver is covered in this patch.
> 
> MPI3_EVENT_DEVICE_ADDED
> MPI3_EVENT_DEVICE_INFO_CHANGED
> MPI3_EVENT_DEVICE_STATUS_CHANGE
> MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE
> MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST
> MPI3_EVENT_SAS_DISCOVERY
> MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR
> 
> Key support in this patch is device add/removal.
> 
> Fix some compilation warning reported by kernel test robot.
> 
> Signed-off-by: Kashyap Desai <kashyap.desai@xxxxxxxxxxxx>
> Reported-by: kernel test robot <lkp@xxxxxxxxx>
> Reviewed-by: Tomas Henzl <thenzl@xxxxxxxxxx>
> 
> Cc: sathya.prakash@xxxxxxxxxxxx
> ---
>  drivers/scsi/mpi3mr/mpi/mpi30_api.h  |    2 +
>  drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h | 2721 ++++++++++++++++++++++++++
>  drivers/scsi/mpi3mr/mpi/mpi30_sas.h  |   46 +
>  drivers/scsi/mpi3mr/mpi3mr.h         |  202 ++
>  drivers/scsi/mpi3mr/mpi3mr_fw.c      |  195 +-
>  drivers/scsi/mpi3mr/mpi3mr_os.c      | 1454 +++++++++++++-
>  6 files changed, 4618 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
>  create mode 100644 drivers/scsi/mpi3mr/mpi/mpi30_sas.h
> 
[ .. ]
> @@ -612,7 +1942,25 @@ static void mpi3mr_target_destroy(struct scsi_target *starget)
>   */
>  static int mpi3mr_slave_configure(struct scsi_device *sdev)
>  {
> +	struct scsi_target *starget;
> +	struct Scsi_Host *shost;
> +	struct mpi3mr_ioc *mrioc;
> +	struct mpi3mr_tgt_dev *tgt_dev;
> +	unsigned long flags;
>  	int retval = 0;
> +
> +	starget = scsi_target(sdev);
> +	shost = dev_to_shost(&starget->dev);
> +	mrioc = shost_priv(shost);
> +
> +	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
> +	tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id);
> +	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
> +	if (!tgt_dev)
> +		return retval;
> +

Return '0' on unknown SCSI devices? Really?

> +	mpi3mr_tgtdev_put(tgt_dev);
> +
>  	return retval;
>  }
>  
> @@ -626,7 +1974,37 @@ static int mpi3mr_slave_configure(struct scsi_device *sdev)
>   */
>  static int mpi3mr_slave_alloc(struct scsi_device *sdev)
>  {
> +	struct Scsi_Host *shost;
> +	struct mpi3mr_ioc *mrioc;
> +	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data;
> +	struct mpi3mr_tgt_dev *tgt_dev;
> +	struct mpi3mr_sdev_priv_data *scsi_dev_priv_data;
> +	unsigned long flags;
> +	struct scsi_target *starget;
>  	int retval = 0;
> +
> +	starget = scsi_target(sdev);
> +	shost = dev_to_shost(&starget->dev);
> +	mrioc = shost_priv(shost);
> +	scsi_tgt_priv_data = starget->hostdata;
> +
> +	scsi_dev_priv_data = kzalloc(sizeof(*scsi_dev_priv_data), GFP_KERNEL);
> +	if (!scsi_dev_priv_data)
> +		return -ENOMEM;
> +
> +	scsi_dev_priv_data->lun_id = sdev->lun;
> +	scsi_dev_priv_data->tgt_priv_data = scsi_tgt_priv_data;
> +	sdev->hostdata = scsi_dev_priv_data;
> +
> +	scsi_tgt_priv_data->num_luns++;
> +
> +	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
> +	tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id);
> +	if (tgt_dev && (tgt_dev->starget == NULL))
> +		tgt_dev->starget = starget;
> +	if (tgt_dev)
> +		mpi3mr_tgtdev_put(tgt_dev);
> +	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
>  	return retval;
>  }
>  
Same here. I would have expected -ENXIO to be returned fi the tgt_dev is
not found.
And you can fold the two 'if' clauses into one eg like:

if (tgt_dev) {
  if (tgt_dev->starget == NULL)
    tgt_dev = starget;
  mpi3mr_tgtdev_put(tgt_dev);
  retval = 0;
}

> @@ -640,7 +2018,33 @@ static int mpi3mr_slave_alloc(struct scsi_device *sdev)
>   */
>  static int mpi3mr_target_alloc(struct scsi_target *starget)
>  {
> +	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
> +	struct mpi3mr_ioc *mrioc = shost_priv(shost);
> +	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data;
> +	struct mpi3mr_tgt_dev *tgt_dev;
> +	unsigned long flags;
>  	int retval = -ENODEV;
> +
> +	scsi_tgt_priv_data = kzalloc(sizeof(*scsi_tgt_priv_data), GFP_KERNEL);
> +	if (!scsi_tgt_priv_data)
> +		return -ENOMEM;
> +
> +	starget->hostdata = scsi_tgt_priv_data;
> +	scsi_tgt_priv_data->starget = starget;
> +	scsi_tgt_priv_data->dev_handle = MPI3MR_INVALID_DEV_HANDLE;
> +
> +	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
> +	tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id);
> +	if (tgt_dev && !tgt_dev->is_hidden) {
> +		scsi_tgt_priv_data->dev_handle = tgt_dev->dev_handle;
> +		scsi_tgt_priv_data->perst_id = tgt_dev->perst_id;
> +		scsi_tgt_priv_data->dev_type = tgt_dev->dev_type;
> +		scsi_tgt_priv_data->tgt_dev = tgt_dev;
> +		tgt_dev->starget = starget;
> +		atomic_set(&scsi_tgt_priv_data->block_io, 0);
> +		retval = 0;
> +	}
> +	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
>  	return retval;
>  }
>  
Ah, here is the correct value set.
(But wasn't it ENXIO which should've been returned for unknown targets?)

> @@ -836,7 +2240,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  {
>  	struct mpi3mr_ioc *mrioc = NULL;
>  	struct Scsi_Host *shost = NULL;
> -	int retval = 0;
> +	int retval = 0, i;
>  
>  	shost = scsi_host_alloc(&mpi3mr_driver_template,
>  	    sizeof(struct mpi3mr_ioc));
> @@ -857,11 +2261,21 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  	spin_lock_init(&mrioc->admin_req_lock);
>  	spin_lock_init(&mrioc->reply_free_queue_lock);
>  	spin_lock_init(&mrioc->sbq_lock);
> +	spin_lock_init(&mrioc->fwevt_lock);
> +	spin_lock_init(&mrioc->tgtdev_lock);
>  	spin_lock_init(&mrioc->watchdog_lock);
>  	spin_lock_init(&mrioc->chain_buf_lock);
>  
> +	INIT_LIST_HEAD(&mrioc->fwevt_list);
> +	INIT_LIST_HEAD(&mrioc->tgtdev_list);
> +	INIT_LIST_HEAD(&mrioc->delayed_rmhs_list);
> +
>  	mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS);
>  
> +	for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++)
> +		mpi3mr_init_drv_cmd(&mrioc->dev_rmhs_cmds[i],
> +		    MPI3MR_HOSTTAG_DEVRMCMD_MIN + i);
> +
>  	if (pdev->revision)
>  		mrioc->enable_segqueue = true;
>  
> @@ -877,6 +2291,17 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  	shost->max_channel = 1;
>  	shost->max_id = 0xFFFFFFFF;
>  
> +	snprintf(mrioc->fwevt_worker_name, sizeof(mrioc->fwevt_worker_name),
> +	    "%s%d_fwevt_wrkr", mrioc->driver_name, mrioc->id);
> +	mrioc->fwevt_worker_thread = alloc_ordered_workqueue(
> +	    mrioc->fwevt_worker_name, WQ_MEM_RECLAIM);
> +	if (!mrioc->fwevt_worker_thread) {
> +		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
> +		    __FILE__, __LINE__, __func__);
> +		retval = -ENODEV;
> +		goto out_fwevtthread_failed;
> +	}
> +
>  	mrioc->is_driver_loading = 1;
>  	if (mpi3mr_init_ioc(mrioc)) {
>  		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
> @@ -903,6 +2328,8 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  addhost_failed:
>  	mpi3mr_cleanup_ioc(mrioc);
>  out_iocinit_failed:
> +	destroy_workqueue(mrioc->fwevt_worker_thread);
> +out_fwevtthread_failed:
>  	spin_lock(&mrioc_list_lock);
>  	list_del(&mrioc->list);
>  	spin_unlock(&mrioc_list_lock);
> @@ -924,14 +2351,30 @@ static void mpi3mr_remove(struct pci_dev *pdev)
>  {
>  	struct Scsi_Host *shost = pci_get_drvdata(pdev);
>  	struct mpi3mr_ioc *mrioc;
> +	struct workqueue_struct	*wq;
> +	unsigned long flags;
> +	struct mpi3mr_tgt_dev *tgtdev, *tgtdev_next;
>  
>  	mrioc = shost_priv(shost);
>  	while (mrioc->reset_in_progress || mrioc->is_driver_loading)
>  		ssleep(1);
>  
>  	mrioc->stop_drv_processing = 1;
> +	mpi3mr_cleanup_fwevt_list(mrioc);
> +	spin_lock_irqsave(&mrioc->fwevt_lock, flags);
> +	wq = mrioc->fwevt_worker_thread;
> +	mrioc->fwevt_worker_thread = NULL;
> +	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);
> +	if (wq)
> +		destroy_workqueue(wq);
>  
>  	scsi_remove_host(shost);
> +	list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list,
> +	    list) {
> +		mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);
> +		mpi3mr_tgtdev_del_from_list(mrioc, tgtdev);
> +		mpi3mr_tgtdev_put(tgtdev);
> +	}
>  
>  	mpi3mr_cleanup_ioc(mrioc);
>  
> @@ -955,6 +2398,8 @@ static void mpi3mr_shutdown(struct pci_dev *pdev)
>  {
>  	struct Scsi_Host *shost = pci_get_drvdata(pdev);
>  	struct mpi3mr_ioc *mrioc;
> +	struct workqueue_struct	*wq;
> +	unsigned long flags;
>  
>  	if (!shost)
>  		return;
> @@ -963,6 +2408,13 @@ static void mpi3mr_shutdown(struct pci_dev *pdev)
>  	while (mrioc->reset_in_progress || mrioc->is_driver_loading)
>  		ssleep(1);
>  	mrioc->stop_drv_processing = 1;
> +	mpi3mr_cleanup_fwevt_list(mrioc);
> +	spin_lock_irqsave(&mrioc->fwevt_lock, flags);
> +	wq = mrioc->fwevt_worker_thread;
> +	mrioc->fwevt_worker_thread = NULL;
> +	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);
> +	if (wq)
> +		destroy_workqueue(wq);
>  
>  	mpi3mr_cleanup_ioc(mrioc);
>  
> 
Cheers,

Hannes
-- 
Dr. Hannes Reinecke		        Kernel Storage Architect
hare@xxxxxxx			               +49 911 74053 688
SUSE Software Solutions Germany GmbH, 90409 Nürnberg
GF: F. Imendörffer, HRB 36809 (AG Nürnberg)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux