linux/drivers/scsi/arcmsr/arcmsr_hba.c

/*
*******************************************************************************
**        O.S   : Linux
**   FILE NAME  : arcmsr_hba.c
**        BY    : Nick Cheng, C.L. Huang
**   Description: SCSI RAID Device Driver for Areca RAID Controller
*******************************************************************************
** Copyright (C) 2002 - 2014, Areca Technology Corporation All rights reserved
**
**     Web site: www.areca.com.tw
**       E-mail: [email protected]
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 2 as
** published by the Free Software Foundation.
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*******************************************************************************
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
**    notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
**    notice, this list of conditions and the following disclaimer in the
**    documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
**    derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING,BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
** For history of changes, see Documentation/scsi/ChangeLog.arcmsr
**     Firmware Specification, see Documentation/scsi/arcmsr_spec.rst
*******************************************************************************
*/
#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/spinlock.h>
#include <linux/pci_ids.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/circ_buf.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsicam.h>
#include "arcmsr.h"
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_VERSION();

static int msix_enable =;
module_param(msix_enable, int, S_IRUGO);
MODULE_PARM_DESC();

static int msi_enable =;
module_param(msi_enable, int, S_IRUGO);
MODULE_PARM_DESC();

static int host_can_queue =;
module_param(host_can_queue, int, S_IRUGO);
MODULE_PARM_DESC();

static int cmd_per_lun =;
module_param(cmd_per_lun, int, S_IRUGO);
MODULE_PARM_DESC();

static int dma_mask_64 =;
module_param(dma_mask_64, int, S_IRUGO);
MODULE_PARM_DESC();

static int set_date_time =;
module_param(set_date_time, int, S_IRUGO);
MODULE_PARM_DESC();

static int cmd_timeout =;
module_param(cmd_timeout, int, S_IRUGO);
MODULE_PARM_DESC();

#define ARCMSR_SLEEPTIME
#define ARCMSR_RETRYCOUNT

static wait_queue_head_t wait_q;
static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
					struct scsi_cmnd *cmd);
static int arcmsr_iop_confirm(struct AdapterControlBlock *acb);
static int arcmsr_abort(struct scsi_cmnd *);
static int arcmsr_bus_reset(struct scsi_cmnd *);
static int arcmsr_bios_param(struct scsi_device *sdev,
		struct block_device *bdev, sector_t capacity, int *info);
static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
static int arcmsr_probe(struct pci_dev *pdev,
				const struct pci_device_id *id);
static int __maybe_unused arcmsr_suspend(struct device *dev);
static int __maybe_unused arcmsr_resume(struct device *dev);
static void arcmsr_remove(struct pci_dev *pdev);
static void arcmsr_shutdown(struct pci_dev *pdev);
static void arcmsr_iop_init(struct AdapterControlBlock *acb);
static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb);
static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb);
static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
	u32 intmask_org);
static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb);
static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb);
static void arcmsr_request_device_map(struct timer_list *t);
static void arcmsr_message_isr_bh_fn(struct work_struct *work);
static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb);
static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
static void arcmsr_hbaC_message_isr(struct AdapterControlBlock *pACB);
static void arcmsr_hbaD_message_isr(struct AdapterControlBlock *acb);
static void arcmsr_hbaE_message_isr(struct AdapterControlBlock *acb);
static void arcmsr_hbaE_postqueue_isr(struct AdapterControlBlock *acb);
static void arcmsr_hbaF_postqueue_isr(struct AdapterControlBlock *acb);
static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
static const char *arcmsr_info(struct Scsi_Host *);
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *);
static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb);
static void arcmsr_set_iop_datetime(struct timer_list *);
static int arcmsr_slave_config(struct scsi_device *sdev);
static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth)
{}

static const struct scsi_host_template arcmsr_scsi_host_template =;

static struct pci_device_id arcmsr_device_id_table[] =;
MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table);

static SIMPLE_DEV_PM_OPS(arcmsr_pm_ops, arcmsr_suspend, arcmsr_resume);

static struct pci_driver arcmsr_pci_driver =;
/*
****************************************************************************
****************************************************************************
*/

static void arcmsr_free_io_queue(struct AdapterControlBlock *acb)
{}

static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
{}

static void arcmsr_unmap_pciregion(struct AdapterControlBlock *acb)
{}

static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id)
{}

static int arcmsr_bios_param(struct scsi_device *sdev,
		struct block_device *bdev, sector_t capacity, int *geom)
{}

static uint8_t arcmsr_hbaA_wait_msgint_ready(struct AdapterControlBlock *acb)
{}

static uint8_t arcmsr_hbaB_wait_msgint_ready(struct AdapterControlBlock *acb)
{}

static uint8_t arcmsr_hbaC_wait_msgint_ready(struct AdapterControlBlock *pACB)
{}

static bool arcmsr_hbaD_wait_msgint_ready(struct AdapterControlBlock *pACB)
{}

static bool arcmsr_hbaE_wait_msgint_ready(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaC_flush_cache(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaD_flush_cache(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaE_flush_cache(struct AdapterControlBlock *pACB)
{}

static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaB_assign_regAddr(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaD_assign_regAddr(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaF_assign_regAddr(struct AdapterControlBlock *acb)
{}

static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
{}

static int arcmsr_alloc_xor_buffer(struct AdapterControlBlock *acb)
{}

static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
{}

static void arcmsr_message_isr_bh_fn(struct work_struct *work) 
{}

static int
arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb)
{}

static void arcmsr_init_get_devmap_timer(struct AdapterControlBlock *pacb)
{}

static void arcmsr_init_set_datetime_timer(struct AdapterControlBlock *pacb)
{}

static int arcmsr_set_dma_mask(struct AdapterControlBlock *acb)
{}

static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{}

static void arcmsr_free_irq(struct pci_dev *pdev,
		struct AdapterControlBlock *acb)
{}

static int __maybe_unused arcmsr_suspend(struct device *dev)
{}

static int __maybe_unused arcmsr_resume(struct device *dev)
{}

static uint8_t arcmsr_hbaA_abort_allcmd(struct AdapterControlBlock *acb)
{}

static uint8_t arcmsr_hbaB_abort_allcmd(struct AdapterControlBlock *acb)
{}
static uint8_t arcmsr_hbaC_abort_allcmd(struct AdapterControlBlock *pACB)
{}

static uint8_t arcmsr_hbaD_abort_allcmd(struct AdapterControlBlock *pACB)
{}

static uint8_t arcmsr_hbaE_abort_allcmd(struct AdapterControlBlock *pACB)
{}

static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
{}

static void arcmsr_ccb_complete(struct CommandControlBlock *ccb)
{}

static void arcmsr_report_sense_info(struct CommandControlBlock *ccb)
{}

static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb)
{}

static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, 
			struct CommandControlBlock *ccb, bool error)
{}

static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct CommandControlBlock *pCCB, bool error)
{}

static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
{}

static void arcmsr_remove_scsi_devices(struct AdapterControlBlock *acb)
{}

static void arcmsr_free_pcidev(struct AdapterControlBlock *acb)
{}

static void arcmsr_remove(struct pci_dev *pdev)
{}

static void arcmsr_shutdown(struct pci_dev *pdev)
{}

static int __init arcmsr_module_init(void)
{}

static void __exit arcmsr_module_exit(void)
{}
module_init();
module_exit(arcmsr_module_exit);

static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
						u32 intmask_org)
{}

static int arcmsr_build_ccb(struct AdapterControlBlock *acb,
	struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd)
{}

static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb)
{}

static void arcmsr_hbaA_stop_bgrb(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaB_stop_bgrb(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaC_stop_bgrb(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaD_stop_bgrb(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaE_stop_bgrb(struct AdapterControlBlock *pACB)
{}

static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
{}

static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb)
{}

static void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
{}

static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
{}

struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb)
{}

static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb)
{}

static uint32_t
arcmsr_Read_iop_rqbuffer_in_DWORD(struct AdapterControlBlock *acb,
		struct QBUFFER __iomem *prbuffer)
{}

uint32_t
arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
	struct QBUFFER __iomem *prbuffer) {}

static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
{}

static void arcmsr_write_ioctldata2iop_in_DWORD(struct AdapterControlBlock *acb)
{}

void
arcmsr_write_ioctldata2iop(struct AdapterControlBlock *acb)
{}

static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaA_doorbell_isr(struct AdapterControlBlock *acb)
{}
static void arcmsr_hbaC_doorbell_isr(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaD_doorbell_isr(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaE_doorbell_isr(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaA_postqueue_isr(struct AdapterControlBlock *acb)
{}
static void arcmsr_hbaB_postqueue_isr(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaC_postqueue_isr(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaE_postqueue_isr(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaF_postqueue_isr(struct AdapterControlBlock *acb)
{}

/*
**********************************************************************************
** Handle a message interrupt
**
** The only message interrupt we expect is in response to a query for the current adapter config.  
** We want this in order to compare the drivemap so that we can detect newly-attached drives.
**********************************************************************************
*/
static void arcmsr_hbaA_message_isr(struct AdapterControlBlock *acb)
{}
static void arcmsr_hbaB_message_isr(struct AdapterControlBlock *acb)
{}
/*
**********************************************************************************
** Handle a message interrupt
**
** The only message interrupt we expect is in response to a query for the
** current adapter config.
** We want this in order to compare the drivemap so that we can detect newly-attached drives.
**********************************************************************************
*/
static void arcmsr_hbaC_message_isr(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaD_message_isr(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaE_message_isr(struct AdapterControlBlock *acb)
{}

static int arcmsr_hbaA_handle_isr(struct AdapterControlBlock *acb)
{}

static int arcmsr_hbaB_handle_isr(struct AdapterControlBlock *acb)
{}

static int arcmsr_hbaC_handle_isr(struct AdapterControlBlock *pACB)
{}

static irqreturn_t arcmsr_hbaD_handle_isr(struct AdapterControlBlock *pACB)
{}

static irqreturn_t arcmsr_hbaE_handle_isr(struct AdapterControlBlock *pACB)
{}

static irqreturn_t arcmsr_hbaF_handle_isr(struct AdapterControlBlock *pACB)
{}

static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
{}

static void arcmsr_iop_parking(struct AdapterControlBlock *acb)
{}


void arcmsr_clear_iop2drv_rqueue_buffer(struct AdapterControlBlock *acb)
{}

static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
		struct scsi_cmnd *cmd)
{}

static struct CommandControlBlock *arcmsr_get_freeccb(struct AdapterControlBlock *acb)
{}

static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
		struct scsi_cmnd *cmd)
{}

static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd)
{}

static DEF_SCSI_QCMD(arcmsr_queue_command)

static int arcmsr_slave_config(struct scsi_device *sdev)
{}

static void arcmsr_get_adapter_config(struct AdapterControlBlock *pACB, uint32_t *rwbuffer)
{}

static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb)
{}
static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
{}

static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB)
{}

static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb)
{}

static bool arcmsr_hbaE_get_config(struct AdapterControlBlock *pACB)
{}

static bool arcmsr_hbaF_get_config(struct AdapterControlBlock *pACB)
{}

static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
{}

static int arcmsr_hbaA_polling_ccbdone(struct AdapterControlBlock *acb,
	struct CommandControlBlock *poll_ccb)
{}

static int arcmsr_hbaB_polling_ccbdone(struct AdapterControlBlock *acb,
					struct CommandControlBlock *poll_ccb)
{}

static int arcmsr_hbaC_polling_ccbdone(struct AdapterControlBlock *acb,
		struct CommandControlBlock *poll_ccb)
{}

static int arcmsr_hbaD_polling_ccbdone(struct AdapterControlBlock *acb,
				struct CommandControlBlock *poll_ccb)
{}

static int arcmsr_hbaE_polling_ccbdone(struct AdapterControlBlock *acb,
				struct CommandControlBlock *poll_ccb)
{}

static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
					struct CommandControlBlock *poll_ccb)
{}

static void arcmsr_set_iop_datetime(struct timer_list *t)
{}

static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
{}

static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
{}

static void arcmsr_request_device_map(struct timer_list *t)
{}

static void arcmsr_hbaA_start_bgrb(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaB_start_bgrb(struct AdapterControlBlock *acb)
{}

static void arcmsr_hbaC_start_bgrb(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaD_start_bgrb(struct AdapterControlBlock *pACB)
{}

static void arcmsr_hbaE_start_bgrb(struct AdapterControlBlock *pACB)
{}

static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
{}

static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb)
{}

static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
{}

static void arcmsr_hardware_reset(struct AdapterControlBlock *acb)
{}

static bool arcmsr_reset_in_progress(struct AdapterControlBlock *acb)
{}

static void arcmsr_iop_init(struct AdapterControlBlock *acb)
{}

static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb)
{}

static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
{}

static int arcmsr_abort_one_cmd(struct AdapterControlBlock *acb,
		struct CommandControlBlock *ccb)
{}

static int arcmsr_abort(struct scsi_cmnd *cmd)
{}

static const char *arcmsr_info(struct Scsi_Host *host)
{}