qla2x00.c

来自「这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自」· C语言 代码 · 共 2,417 行 · 第 1/5 页

C
2,417 行
字号
/****************************************************************************** *                  QLOGIC LINUX SOFTWARE * * QLogic ISP2x00 device driver for Linux 2.4.x * Copyright (C) 2002 Qlogic Corporation * (www.qlogic.com) * * Portions (C) Arjan van de Ven <arjanv@redhat.com> for Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * 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. * ******************************************************************************//****************************************************************************              Please see revision.notes for revision history.*****************************************************************************//** String arrays*/#define LINESIZE    256#define MAXARGS      26/** Include files*/#include <linux/config.h>#if defined(MODULE)#include <linux/module.h>#endif#if !defined(LINUX_VERSION_CODE)#include <linux/version.h>#endif  /* LINUX_VERSION_CODE not defined *//* Restrict compilation to 2.4.0 or greater */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)#error "This driver does not support kernel versions earlier than 2.4.0"#endif/* IP support not available on ISP2100 */#if defined(ISP2100) && defined(FC_IP_SUPPORT)#error "The ISP2100 does not support IP"#endif#include "qla_settings.h"static int num_hosts = 0;       /* ioctl related  */static int apiHBAInstance = 0;  /* ioctl related keeps track of API HBA Instance */#if QL_TRACE_MEMORYstatic unsigned long mem_trace[1000];static unsigned long mem_id[1000];#endif#include <asm/io.h>#include <asm/irq.h>#include <asm/segment.h>#include <asm/byteorder.h>#include <asm/pgtable.h>#include <linux/init.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/timer.h>#include <linux/sched.h>#include <linux/pci.h>#include <linux/proc_fs.h>#include <linux/blk.h>#include <linux/tqueue.h>#include <linux/interrupt.h>#include <linux/stat.h>#include <linux/slab.h>#define  APIDEV        1#define __KERNEL_SYSCALLS__#include <linux/unistd.h>#include <linux/smp_lock.h>#include <asm/system.h>/** We must always allow SHUTDOWN_SIGS.  Even if we are not a module,* the host drivers that we are using may be loaded as modules, and* when we unload these,  we need to ensure that the error handler thread* can be shut down.** Note - when we unload a module, we send a SIGHUP.  We mustn't* enable SIGTERM, as this is how the init shuts things down when you* go to single-user mode.  For that matter, init also sends SIGKILL,* so we mustn't enable that one either.  We use SIGHUP instead.  Other* options would be SIGPWR, I suppose.*/#define SHUTDOWN_SIGS	(sigmask(SIGHUP))#include "sd.h"#include "scsi.h"#include "hosts.h"#if defined(FC_IP_SUPPORT)#include <linux/ip.h>#include <linux/if_arp.h>#include <linux/skbuff.h>#include "qla_ip.h"#endif#if defined(FC_SCTP_SUPPORT)#endif#include "exioct.h"#include "qla2x00.h"#define UNIQUE_FW_NAME                 /* unique F/W array names */#if defined(ISP2100)#include "ql2100_fw.h"                     /* ISP RISC 2100 TP code */#endif#if defined(ISP2200)#if defined(FC_IP_SUPPORT)#include "ql2200ip_fw.h"                   /* ISP RISC 2200 IP code */#else#include "ql2200_fw.h"                     /* ISP RISC 2200 TP code */#endif#endif#if defined(ISP2300)#if defined(FC_IP_SUPPORT)#include "ql2300ip_fw.h"                   /* ISP RISC 2300 IP code */#else#include "ql2300_fw.h"                     /* ISP RISC 2300 TP code */#endif#endif#include "qla_cfg.h"#include "qla_gbl.h"#if NO_LONG_DELAYS#define  SYS_DELAY(x)		qla2x00_sleep(x)#define  QLA2100_DELAY(sec)  qla2x00_sleep(sec * HZ)#define NVRAM_DELAY() qla2x00_sleep(10) /* 10 microsecond delay */#define  UDELAY(x)		qla2x00_sleep(x)#else#define  SYS_DELAY(x)		udelay(x);barrier()#define  QLA2100_DELAY(sec)  mdelay(sec * HZ)#define NVRAM_DELAY() udelay(10) /* 10 microsecond delay */#define  UDELAY(x)		udelay(x)#endif/* 4.10 */#if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G)#define pci_dma_lo32(a) (a & 0xffffffff)#define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff)#else#define pci_dma_lo32(a) (a & 0xffffffff)#define pci_dma_hi32(a) 0#endif#define  CACHE_FLUSH(a) (RD_REG_WORD(a))#define  INVALID_HANDLE    (MAX_OUTSTANDING_COMMANDS+1)#define  ABORTS_ACTIVE  ((test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) || \			(test_bit(DEVICE_RESET_NEEDED, &ha->dpc_flags)) || \			(test_bit(DEVICE_ABORT_NEEDED, &ha->dpc_flags)) || \			(test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)))#define  STATIC static#define  OFFSET(w)   (((u_long) &w) & 0xFFFF)  /* 256 byte offsets *//* * LOCK MACROS */#define QLA_MBX_REG_LOCK(ha)	\    spin_lock_irqsave(&(ha)->mbx_reg_lock, mbx_flags);#define QLA_MBX_REG_UNLOCK(ha)	\    spin_unlock_irqrestore(&(ha)->mbx_reg_lock, mbx_flags);#define	WATCH_INTERVAL		1       /* number of seconds */#define	START_TIMER(f, h, w)	\{ \init_timer(&(h)->timer); \(h)->timer.expires = jiffies + w * HZ;\(h)->timer.data = (unsigned long) h; \(h)->timer.function = (void (*)(unsigned long))f; \add_timer(&(h)->timer); \(h)->timer_active = 1;\}#define	RESTART_TIMER(f, h, w)	\{ \mod_timer(&(h)->timer,jiffies + w * HZ); \}#define	STOP_TIMER(f, h)	\{ \del_timer_sync(&(h)->timer); \(h)->timer_active = 0;\}#define COMPILE 0#if defined(ISP2100)#define DRIVER_NAME "qla2100"#endif#if defined(ISP2200)#define DRIVER_NAME "qla2200"#endif#if defined(ISP2300)#define DRIVER_NAME "qla2300"#endiftypedef unsigned long paddr32_t;/**  Qlogic Driver support Function Prototypes.*/STATIC uint8_t qla2x00_register_with_Linux(scsi_qla_host_t *ha,			uint8_t maxchannels);STATIC int qla2x00_done(scsi_qla_host_t *);STATIC void qla2x00_select_queue_depth(struct Scsi_Host *, Scsi_Device *);STATIC void qla2x00_timer(scsi_qla_host_t *);STATIC uint8_t qla2x00_mem_alloc(scsi_qla_host_t *);static void qla2x00_dump_regs(struct Scsi_Host *host);#if STOP_ON_ERRORstatic void qla2x00_panic(char *, struct Scsi_Host *host);#endifvoid qla2x00_print_scsi_cmd(Scsi_Cmnd *cmd);#if 0STATIC void qla2x00_abort_pending_queue(scsi_qla_host_t *ha, uint32_t stat);#endifSTATIC void qla2x00_mem_free(scsi_qla_host_t *ha);void qla2x00_do_dpc(void *p);static inline void qla2x00_callback(scsi_qla_host_t *ha, Scsi_Cmnd *cmd);static inline void qla2x00_enable_intrs(scsi_qla_host_t *);static inline void qla2x00_disable_intrs(scsi_qla_host_t *);static void qla2x00_extend_timeout(Scsi_Cmnd *cmd, int timeout);static int  qla2x00_get_tokens(char *line, char **argv, int maxargs );/**  QLogic ISP2x00 Hardware Support Function Prototypes.*/STATIC void qla2x00_cfg_persistent_binding(scsi_qla_host_t *ha);STATIC uint8_t qla2x00_initialize_adapter(scsi_qla_host_t *);STATIC uint8_t qla2x00_isp_firmware(scsi_qla_host_t *);STATIC uint8_t qla2x00_pci_config(scsi_qla_host_t *);STATIC uint8_t qla2x00_set_cache_line(scsi_qla_host_t *);STATIC uint8_t qla2x00_chip_diag(scsi_qla_host_t *);STATIC uint8_t qla2x00_setup_chip(scsi_qla_host_t *ha);STATIC uint8_t qla2x00_init_rings(scsi_qla_host_t *ha);STATIC uint8_t qla2x00_fw_ready(scsi_qla_host_t *ha);#if defined(ISP2100)STATIC uint8_t qla2100_nvram_config(scsi_qla_host_t *);#elseSTATIC uint8_t qla2x00_nvram_config(scsi_qla_host_t *);#endifSTATIC uint8_t qla2x00_get_link_status(scsi_qla_host_t *,		uint8_t, void *, uint16_t *);#if USE_FLASH_DATABASESTATIC uint8_t qla2x00_get_database(scsi_qla_host_t *);STATIC uint8_t qla2x00_save_database(scsi_qla_host_t *);STATIC uint8_t qla2x00_program_flash_address(scsi_qla_host_t *,		uint32_t, u_char);STATIC uint8_t qla2x00_erase_flash_sector(scsi_qla_host_t *, uint32_t);STATIC uint8_t qla2x00_poll_flash(scsi_qla_host_t *, uint32_t, u_char);#endifSTATIC uint8_t qla2x00_loop_reset(scsi_qla_host_t *ha);STATIC uint8_t qla2x00_abort_isp(scsi_qla_host_t *, uint8_t);STATIC uint8_t qla2x00_loop_resync(scsi_qla_host_t *);STATIC void qla2x00_nv_write(scsi_qla_host_t *, uint16_t);STATIC void qla2x00_nv_deselect(scsi_qla_host_t *ha);STATIC void qla2x00_poll(scsi_qla_host_t *);STATIC void qla2x00_init_fc_db(scsi_qla_host_t *);STATIC void qla2x00_init_tgt_map(scsi_qla_host_t *);#if USE_FLASH_DATABASESTATIC void qla2x00_flash_enable_database(scsi_qla_host_t *);STATIC void qla2x00_flash_disable_database(scsi_qla_host_t *);STATIC void qla2x00_write_flash_byte(scsi_qla_host_t *, uint32_t, u_char);#endifSTATIC void qla2x00_reset_adapter(scsi_qla_host_t *);STATIC void qla2x00_enable_lun(scsi_qla_host_t *);STATIC void qla2x00_isp_cmd(scsi_qla_host_t *);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7)STATIC void qla2x00_process_risc_intrs(scsi_qla_host_t *);#endifSTATIC void qla2x00_isr(scsi_qla_host_t *, uint16_t,  uint8_t *);STATIC void qla2x00_rst_aen(scsi_qla_host_t *);STATIC void qla2x00_response_pkt(scsi_qla_host_t *, uint16_t);STATIC void qla2x00_status_entry(scsi_qla_host_t *, sts_entry_t *);STATIC void qla2x00_error_entry(scsi_qla_host_t *, response_t *);STATIC void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);STATIC void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);STATIC void qla2x00_abort_queues(scsi_qla_host_t *, uint8_t);STATIC void qla2x00_flash_enable(scsi_qla_host_t *);STATIC void qla2x00_flash_disable(scsi_qla_host_t *);STATIC uint8_t qla2x00_read_flash_byte(scsi_qla_host_t *, uint32_t);STATIC uint16_t qla2x00_get_flash_version(scsi_qla_host_t *);STATIC uint16_t qla2x00_get_nvram_word(scsi_qla_host_t *, uint32_t);STATIC uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t);STATIC uint16_t qla2x00_debounce_register(volatile uint16_t *);STATIC request_t *qla2x00_req_pkt(scsi_qla_host_t *);STATIC request_t *qla2x00_ms_req_pkt(scsi_qla_host_t *, srb_t *);STATIC uint8_t qla2x00_configure_hba(scsi_qla_host_t *ha);STATIC void qla2x00_reset_chip(scsi_qla_host_t *ha);STATIC void qla2x00_display_fc_names(scsi_qla_host_t *ha);void qla2x00_dump_requests(scsi_qla_host_t *ha);static void qla2x00_get_properties(scsi_qla_host_t *ha, char *string);STATIC uint8_t qla2x00_find_propname(scsi_qla_host_t *ha,		char *propname, char *propstr, char *db, int siz);static int qla2x00_get_prop_16chars(scsi_qla_host_t *ha,		char *propname, char *propval, char *cmdline);static char *qla2x00_get_line(char *str, char *line);void qla2x00_check_fabric_devices(scsi_qla_host_t *ha);#if defined(FC_IP_SUPPORT)/* General support routines */static int qla2x00_ip_initialize(scsi_qla_host_t *ha);static void qla2x00_ip_send_complete(scsi_qla_host_t *ha,		uint32_t handle, uint16_t comp_status);static void qla2x00_ip_receive(scsi_qla_host_t *ha, response_t *pkt);static void qla2x00_ip_receive_fastpost(scsi_qla_host_t *ha, uint16_t type);/* IP device list manipulation routines */static int qla2x00_convert_to_arp(scsi_qla_host_t *ha, struct send_cb *scb);static int qla2x00_get_ip_loopid(scsi_qla_host_t *ha,		struct packet_header *packethdr, uint8_t *loop_id);static int qla2x00_reserve_loopid(scsi_qla_host_t *ha, uint16_t *loop_id);static void qla2x00_free_loopid(scsi_qla_host_t *ha, uint16_t loop_id);static int qla2x00_add_new_ip_device(scsi_qla_host_t *ha,		uint16_t loop_id, uint8_t *port_id,		uint8_t *port_name, int force_add, uint32_t ha_locked);static void qla2x00_free_ip_block(scsi_qla_host_t *ha, struct ip_device *ipdev);static int qla2x00_reserve_ip_block(scsi_qla_host_t *ha,		struct ip_device **ipdevblk);static int qla2x00_update_ip_device_data(scsi_qla_host_t *ha, fcdev_t *fcdev);static int qla2x00_ip_send_login_port_iocb(scsi_qla_host_t *ha,		struct ip_device *ipdev, uint32_t ha_locked);static int qla2x00_ip_send_logout_port_iocb(scsi_qla_host_t *ha, 		struct ip_device *ipdev, uint32_t ha_locked);static void qla2x00_ip_mailbox_iocb_done(scsi_qla_host_t *ha,		struct mbx_entry *mbxentry);/* Entry point network driver */#if defined(ISP2200)int  qla2200_ip_inquiry(uint16_t adapter_num, struct bd_inquiry *inq_data);EXPORT_SYMBOL(qla2200_ip_inquiry);#elif defined(ISP2300)int  qla2300_ip_inquiry(uint16_t adapter_num, struct bd_inquiry *inq_data);EXPORT_SYMBOL(qla2300_ip_inquiry);#endif/* Network driver callback routines */static int  qla2x00_ip_enable(scsi_qla_host_t *ha,		struct bd_enable *enable_data);static void qla2x00_ip_disable(scsi_qla_host_t *ha);static void qla2x00_add_buffers(scsi_qla_host_t *ha,		uint16_t rec_count, int ha_locked);static int  qla2x00_send_packet(scsi_qla_host_t *ha, struct send_cb *scb);static int  qla2x00_tx_timeout(scsi_qla_host_t *ha);#endif	/* if defined(FC_IP_SUPPORT) */static void qla2x00_device_resync(scsi_qla_host_t *);STATIC uint8_t qla2x00_update_fc_database(scsi_qla_host_t *, fcdev_t *,		uint8_t);STATIC uint8_t qla2x00_configure_fabric(scsi_qla_host_t *, uint8_t );static uint8_t qla2x00_find_all_fabric_devs(scsi_qla_host_t *,		sns_cmd_rsp_t *, dma_addr_t, struct new_dev *,		uint16_t *, uint8_t *);#if REG_FC4_ENABLEDstatic uint8_t qla2x00_register_fc4(scsi_qla_host_t *, sns_cmd_rsp_t *, dma_addr_t);#endifstatic uint8_t qla2x00_gan(scsi_qla_host_t *, sns_cmd_rsp_t *, dma_addr_t,		fcdev_t *);static uint8_t qla2x00_fabric_login(scsi_qla_host_t *, fcdev_t *);STATIC uint8_t qla2x00_configure_loop(scsi_qla_host_t *);static uint8_t qla2x00_configure_local_loop(scsi_qla_host_t *, uint8_t );STATIC uint8_t qla2x00_32bit_start_scsi(srb_t *sp);STATIC uint8_t qla2x00_64bit_start_scsi(srb_t *sp);/* Routines for Failover */os_tgt_t *qla2x00_tgt_alloc(scsi_qla_host_t *ha, uint16_t t, uint8_t *name);#if APIDEVstatic int apidev_init(struct Scsi_Host*);static int apidev_cleanup(void);#endifvoid qla2x00_tgt_free(scsi_qla_host_t *ha, uint16_t t);os_lun_t *qla2x00_lun_alloc(scsi_qla_host_t *ha, uint16_t t, uint16_t l);static void qla2x00_lun_free(scsi_qla_host_t *ha, uint16_t t, uint16_t l);void qla2x00_next(scsi_qla_host_t *vis_ha);static int qla2x00_build_fcport_list(scsi_qla_host_t *ha);static void qla2x00_config_os(scsi_qla_host_t *ha);static uint16_t qla2x00_fcport_bind(scsi_qla_host_t *ha, fc_port_t *fcport);static int qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport, int);static int qla2x00_lun_discovery(scsi_qla_host_t *ha, fc_port_t *fcport, int);static int qla2x00_rpt_lun_discovery(scsi_qla_host_t *ha, fc_port_t *fcport);static void qla2x00_cfg_lun(fc_port_t *fcport, uint16_t lun);#if MPIO_SUPPORTSTATIC void qla2x00_process_failover(scsi_qla_host_t *ha) ;#endifSTATIC int qla2x00_device_reset(scsi_qla_host_t *, uint16_t, uint16_t);static int qla2x00_is_wwn_zero(uint8_t *nn);void qla2x00_get_lun_mask_from_config(scsi_qla_host_t *ha, fc_port_t *port,                                      uint16_t tgt, uint16_t dev_no);void qla2x00_print_q_info(os_lun_t *q);#if QLA2X_PERFORMANCEvoid qla2x00_done_tasklet(long p);#endif#if MPIO_SUPPORTSTATIC void qla2x00_failover_cleanup(srb_t *);void qla2x00_flush_failover_q(scsi_qla_host_t *, os_lun_t *);#endifvoid qla2x00_chg_endian(uint8_t buf[], size_t size);STATIC uint8_t qla2x00_check_sense(Scsi_Cmnd       *cp, os_lun_t *);STATIC uint8_t qla2x00_suspend_lun(scsi_qla_host_t *, os_lun_t *, int, int);#if MPIO_SUPPORTSTATIC uint8_tqla2x00_check_for_devices_online(scsi_qla_host_t *ha ) ;#endif#if DEBUG_QLA2100#if !defined(QL_DEBUG_ROUTINES)#define QL_DEBUG_ROUTINES#endif#endif#if defined(QL_DEBUG_ROUTINES)/**  Driver Debug Function Prototypes.*/static void qla2x00_dump_buffer(uint8_t *, uint32_t);STATIC uint8_t ql2x_debug_print = 1;#endif/* ra 01/03/02 */#if QLA2100_LIPTESTSTATIC int  mbxtimeout = 0;#endif#if DEBUG_GET_FW_DUMP

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?