⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qla1280.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
#if (BITS_PER_LONG == 64) || defined CONFIG_HIGHMEM#define QLA_64BIT_PTR	1#endif#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)#include <asm/sn/pci/pciio.h>/* Ugly hack needed for the virtual channel fix on SN2 */extern int snia_pcibr_rrb_alloc(struct pci_dev *pci_dev,				int *count_vchan0, int *count_vchan1);#endif#ifdef QLA_64BIT_PTR#define pci_dma_hi32(a)			((a >> 16) >> 16)#else#define pci_dma_hi32(a)			0#endif#define pci_dma_lo32(a)			(a & 0xffffffff)#define NVRAM_DELAY()			udelay(500)	/* 2 microseconds */#if LINUX_VERSION_CODE < 0x020500#define HOST_LOCK			&io_request_lock#define irqreturn_t			void#define IRQ_RETVAL(foo)#define MSG_ORDERED_TAG			1#define DMA_BIDIRECTIONAL	SCSI_DATA_UNKNOWN#define DMA_TO_DEVICE		SCSI_DATA_WRITE#define DMA_FROM_DEVICE		SCSI_DATA_READ#define DMA_NONE		SCSI_DATA_NONE#ifndef HAVE_SECTOR_Ttypedef unsigned int sector_t;#endifstatic inline voidscsi_adjust_queue_depth(struct scsi_device *device, int tag, int depth){	if (tag) {		device->tagged_queue = tag;		device->current_tag = 0;	}	device->queue_depth = depth;}static inline struct Scsi_Host *scsi_host_alloc(Scsi_Host_Template *t, size_t s){	return scsi_register(t, s);}static inline void scsi_host_put(struct Scsi_Host *h){	scsi_unregister(h);}#else#define HOST_LOCK			ha->host->host_lock#endif#if LINUX_VERSION_CODE < 0x020600#define DEV_SIMPLE_TAGS(device)		device->tagged_queue/* * Hack around that qla1280_remove_one is called from * qla1280_release in 2.4 */#undef __devexit#define __devexit#else#define DEV_SIMPLE_TAGS(device)		device->simple_tags#endif#if defined(__ia64__) && !defined(ia64_platform_is)#define ia64_platform_is(foo)		(!strcmp(x, platform_name))#endif#define IS_ISP1040(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020)#define IS_ISP1x40(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020 || \			ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1240)#define IS_ISP1x160(ha)        (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160 || \				ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160)static int qla1280_probe_one(struct pci_dev *, const struct pci_device_id *);static void qla1280_remove_one(struct pci_dev *);/* *  QLogic Driver Support Function Prototypes. */static void qla1280_done(struct scsi_qla_host *);#if LINUX_VERSION_CODE < 0x020545static void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *);#endifstatic int qla1280_get_token(char *);static int qla1280_setup(char *s) __init;/* *  QLogic ISP1280 Hardware Support Function Prototypes. */static int qla1280_load_firmware(struct scsi_qla_host *);static int qla1280_init_rings(struct scsi_qla_host *);static int qla1280_nvram_config(struct scsi_qla_host *);static int qla1280_mailbox_command(struct scsi_qla_host *,				   uint8_t, uint16_t *);static int qla1280_bus_reset(struct scsi_qla_host *, int);static int qla1280_device_reset(struct scsi_qla_host *, int, int);static int qla1280_abort_device(struct scsi_qla_host *, int, int, int);static int qla1280_abort_command(struct scsi_qla_host *, struct srb *, int);static int qla1280_abort_isp(struct scsi_qla_host *);#ifdef QLA_64BIT_PTRstatic int qla1280_64bit_start_scsi(struct scsi_qla_host *, struct srb *);#elsestatic int qla1280_32bit_start_scsi(struct scsi_qla_host *, struct srb *);#endifstatic void qla1280_nv_write(struct scsi_qla_host *, uint16_t);static void qla1280_poll(struct scsi_qla_host *);static void qla1280_reset_adapter(struct scsi_qla_host *);static void qla1280_marker(struct scsi_qla_host *, int, int, int, u8);static void qla1280_isp_cmd(struct scsi_qla_host *);static void qla1280_isr(struct scsi_qla_host *, struct list_head *);static void qla1280_rst_aen(struct scsi_qla_host *);static void qla1280_status_entry(struct scsi_qla_host *, struct response *,				 struct list_head *);static void qla1280_error_entry(struct scsi_qla_host *, struct response *,				struct list_head *);static uint16_t qla1280_get_nvram_word(struct scsi_qla_host *, uint32_t);static uint16_t qla1280_nvram_request(struct scsi_qla_host *, uint32_t);static uint16_t qla1280_debounce_register(volatile uint16_t *);static request_t *qla1280_req_pkt(struct scsi_qla_host *);static int qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *,					   unsigned int);static void qla1280_get_target_parameters(struct scsi_qla_host *,					   struct scsi_device *);static int qla1280_set_target_parameters(struct scsi_qla_host *, int, int);static struct qla_driver_setup driver_setup __initdata;/* * convert scsi data direction to request_t control flags */static inline uint16_tqla1280_data_direction(struct scsi_cmnd *cmnd){	switch(cmnd->sc_data_direction) {	case DMA_FROM_DEVICE:		return BIT_5;	case DMA_TO_DEVICE:		return BIT_6;	case DMA_BIDIRECTIONAL:		return BIT_5 | BIT_6;	/*	 * We could BUG() on default here if one of the four cases aren't	 * met, but then again if we receive something like that from the	 * SCSI layer we have more serious problems. This shuts up GCC.	 */	case DMA_NONE:	default:		return 0;	}}		#if DEBUG_QLA1280static void __qla1280_print_scsi_cmd(struct scsi_cmnd * cmd);static void __qla1280_dump_buffer(char *, int);#endif/* * insmod needs to find the variable and make it point to something */#ifdef MODULEstatic char *qla1280;/* insmod qla1280 options=verbose" */MODULE_PARM(qla1280, "s");#else__setup("qla1280=", qla1280_setup);#endif/* * We use the scsi_pointer structure that's included with each scsi_command * to overlay our struct srb over it. qla1280_init() checks that a srb is not * bigger than a scsi_pointer. */#define	CMD_SP(Cmnd)		&Cmnd->SCp#define	CMD_CDBLEN(Cmnd)	Cmnd->cmd_len#define	CMD_CDBP(Cmnd)		Cmnd->cmnd#define	CMD_SNSP(Cmnd)		Cmnd->sense_buffer#define	CMD_SNSLEN(Cmnd)	sizeof(Cmnd->sense_buffer)#define	CMD_RESULT(Cmnd)	Cmnd->result#define	CMD_HANDLE(Cmnd)	Cmnd->host_scribble#if LINUX_VERSION_CODE < 0x020545#define CMD_REQUEST(Cmnd)	Cmnd->request.cmd#else#define CMD_REQUEST(Cmnd)	Cmnd->request->cmd#endif#define CMD_HOST(Cmnd)		Cmnd->device->host#define SCSI_BUS_32(Cmnd)	Cmnd->device->channel#define SCSI_TCN_32(Cmnd)	Cmnd->device->id#define SCSI_LUN_32(Cmnd)	Cmnd->device->lun/*****************************************//*   ISP Boards supported by this driver *//*****************************************/struct qla_boards {	unsigned char name[9];	/* Board ID String */	int numPorts;		/* Number of SCSI ports */	unsigned short *fwcode;	/* pointer to FW array         */	unsigned short *fwlen;	/* number of words in array    */	unsigned short *fwstart;	/* start address for F/W       */	unsigned char *fwver;	/* Ptr to F/W version array    */};/* NOTE: qla1280_pci_tbl and ql1280_board_tbl must be in the same order */static struct pci_device_id qla1280_pci_tbl[] = {	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP12160,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},	{0,}};MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);static struct qla_boards ql1280_board_tbl[] = {	/* Name ,  Number of ports, FW details */	{"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01,	 &fw12160i_addr01, &fw12160i_version_str[0]},	{"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01,	 &fw1280ei_addr01, &fw1280ei_version_str[0]},	{"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01,	 &fw1280ei_addr01, &fw1280ei_version_str[0]},	{"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01,	 &fw1280ei_addr01, &fw1280ei_version_str[0]},	{"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01,	 &fw12160i_addr01, &fw12160i_version_str[0]},	{"        ", 0}};static int qla1280_verbose = 1;static int qla1280_buffer_size;static char *qla1280_buffer;#if DEBUG_QLA1280static int ql_debug_level = 1;#define dprintk(level, format, a...)	\	do { if (ql_debug_level >= level) printk(KERN_ERR format, ##a); } while(0)#define qla1280_dump_buffer(level, buf, size)	\	if (ql_debug_level >= level) __qla1280_dump_buffer(buf, size)#define qla1280_print_scsi_cmd(level, cmd)	\	if (ql_debug_level >= level) __qla1280_print_scsi_cmd(cmd)#else#define ql_debug_level			0#define dprintk(level, format, a...)	do{}while(0)#define qla1280_dump_buffer(a, b, c)	do{}while(0)#define qla1280_print_scsi_cmd(a, b)	do{}while(0)#endif#define ENTER(x)		dprintk(3, "qla1280 : Entering %s()\n", x);#define LEAVE(x)		dprintk(3, "qla1280 : Leaving %s()\n", x);#define ENTER_INTR(x)		dprintk(4, "qla1280 : Entering %s()\n", x);#define LEAVE_INTR(x)		dprintk(4, "qla1280 : Leaving %s()\n", x);/************************************************************************* * qla1280_proc_info * * Description: *   Return information to handle /proc support for the driver. * * buffer - ptrs to a page buffer * * Returns: *************************************************************************/#define	PROC_BUF	&qla1280_buffer[len]static int qla1280_proc_info(struct Scsi_Host *host, char *buffer,			     char **start, off_t offset, int length, int inout){	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;	struct qla_boards *bdp = &ql1280_board_tbl[ha->devnum];	int size = 0;	int len = 0;	if (inout)		return -ENOSYS;	/*	 * if our old buffer is the right size use it otherwise	 * allocate a new one.	 */	if (qla1280_buffer_size != PAGE_SIZE) {		/* deallocate this buffer and get a new one */		if (qla1280_buffer != NULL) {			free_page((unsigned long)qla1280_buffer);			qla1280_buffer_size = 0;		}		qla1280_buffer = (char *)get_zeroed_page(GFP_KERNEL);	}	if (qla1280_buffer == NULL) {		size = sprintf(buffer, "qla1280 - kmalloc error at line %d\n",			       __LINE__);		return size;	}	/* save the size of our buffer */	qla1280_buffer_size = PAGE_SIZE;	/* 3.20 clear the buffer we use for proc display */	memset(qla1280_buffer, 0, PAGE_SIZE);	/* start building the print buffer */	size = sprintf(PROC_BUF,		       "QLogic PCI to SCSI Adapter for ISP 1280/12160:\n"		       "        Firmware version: %2d.%02d.%02d, Driver version %s\n",		       bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],		       QLA1280_VERSION);	len += size;	size = sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n",		       bdp->name);	len += size;	size = sprintf(PROC_BUF, "Request Queue count= 0x%x, Response "		       "Queue count= 0x%x\n",		       REQUEST_ENTRY_CNT, RESPONSE_ENTRY_CNT);	len += size;	size = sprintf(PROC_BUF, "Number of pending commands = 0x%lx\n",		       ha->actthreads);	len += size;	size = sprintf(PROC_BUF, "Number of free request entries = %d\n",		       ha->req_q_cnt);	len += size;	size = sprintf(PROC_BUF, "\n");	/* 1       */	len += size;	if (len >= qla1280_buffer_size) {		printk(KERN_WARNING		       "qla1280: Overflow buffer in qla1280_proc.c\n");	}	if (offset > len - 1) {		free_page((unsigned long) qla1280_buffer);		qla1280_buffer = NULL;		qla1280_buffer_size = length = 0;		*start = NULL;	} else {		*start = &qla1280_buffer[offset];	/* Start of wanted data */		if (len - offset < length) {			length = len - offset;		}	}	return length;}static int qla1280_read_nvram(struct scsi_qla_host *ha){	uint16_t *wptr;	uint8_t chksum;	int cnt, i;	struct nvram *nv;	ENTER("qla1280_read_nvram");	if (driver_setup.no_nvram)		return 1;	printk(KERN_INFO "scsi(%ld): Reading NVRAM\n", ha->host_no);	wptr = (uint16_t *)&ha->nvram;	nv = &ha->nvram;	chksum = 0;	for (cnt = 0; cnt < 3; cnt++) {		*wptr = qla1280_get_nvram_word(ha, cnt);		chksum += *wptr & 0xff;		chksum += (*wptr >> 8) & 0xff;		wptr++;	}	if (nv->id0 != 'I' || nv->id1 != 'S' ||	    nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) {		dprintk(2, "Invalid nvram ID or version!\n");		chksum = 1;	} else {		for (; cnt < sizeof(struct nvram); cnt++) {			*wptr = qla1280_get_nvram_word(ha, cnt);			chksum += *wptr & 0xff;			chksum += (*wptr >> 8) & 0xff;			wptr++;		}	}	dprintk(3, "qla1280_read_nvram: NVRAM Magic ID= %c %c %c %02x"	       " version %i\n", nv->id0, nv->id1, nv->id2, nv->id3,	       nv->version);	if (chksum) {		if (!driver_setup.no_nvram)			printk(KERN_WARNING "scsi(%ld): Unable to identify or "			       "validate NVRAM checksum, using default "			       "settings\n", ha->host_no);		ha->nvram_valid = 0;	} else		ha->nvram_valid = 1;	/* The firmware interface is, um, interesting, in that the	 * actual firmware image on the chip is little endian, thus,	 * the process of taking that image to the CPU would end up	 * little endian.  However, the firmare interface requires it	 * to be read a word (two bytes) at a time.	 *	 * The net result of this would be that the word (and	 * doubleword) quantites in the firmware would be correct, but

⌨️ 快捷键说明

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