blob: 54d0776edde4f66b6de826a71d4dc8648ce2b5df [file] [log] [blame]
/******************************************************************************
* QLOGIC LINUX SOFTWARE
*
* QLogic QLA1280 (Ultra2) and QLA12160 (Ultra3) SCSI driver
* Copyright (C) 2000 Qlogic Corporation (www.qlogic.com)
* Copyright (C) 2001-2002 Jes Sorensen, Wild Open Source 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.
*
******************************************************************************/
#define QLA1280_VERSION "3.23.19 Beta"
/******************************************************************************
Revision History:
Rev 3.23.19 Beta April 11, 2002, Linus Torvalds
- Do qla1280_pci_config() before calling request_irq() and
request_region()
- Use pci_dma_hi32() to handle upper word of DMA addresses instead
of large shifts
- Hand correct arguments to free_irq() in case of failure
Rev 3.23.18 Beta April 11, 2002, Jes Sorensen
- Run source through Lindent and clean up the output
Rev 3.23.17 Beta April 11, 2002, Jes Sorensen
- Update SCSI firmware to qla1280 v8.15.00 and qla12160 v10.04.32
Rev 3.23.16 Beta March 19, 2002, Jes Sorensen
- Rely on mailbox commands generating interrupts - do not
run qla1280_isr() from ql1280_mailbox_command()
- Remove device_reg_t
- Integrate ql12160_set_target_parameters() with 1280 version
- Make qla1280_setup() non static
- Do not call qla1280_check_for_dead_scsi_bus() on every I/O request
sent to the card - this command pauses the firmare!!!
Rev 3.23.15 Beta March 19, 2002, Jes Sorensen
- Clean up qla1280.h - remove obsolete QL_DEBUG_LEVEL_x definitions
- Remove a pile of pointless and confusing (srb_t **) and
(scsi_lu_t *) typecasts
- Explicit mark that we do not use the new error handling (for now)
- Remove scsi_qla_host_t and use 'struct' instead
- Remove in_abort, watchdog_enabled, dpc, dpc_sched, bios_enabled,
pci_64bit_slot flags which weren't used for anything anyway
- Grab host->host_lock while calling qla1280_isr() from abort()
- Use spin_lock()/spin_unlock() in qla1280_intr_handler() - we
do not need to save/restore flags in the interrupt handler
- Enable interrupts early (before any mailbox access) in preparation
for cleaning up the mailbox handling
Rev 3.23.14 Beta March 14, 2002, Jes Sorensen
- Further cleanups. Remove all trace of QL_DEBUG_LEVEL_x and replace
it with proper use of dprintk().
- Make qla1280_print_scsi_cmd() and qla1280_dump_buffer() both take
a debug level argument to determine if data is to be printed
- Add KERN_* info to printk()
Rev 3.23.13 Beta March 14, 2002, Jes Sorensen
- Significant cosmetic cleanups
- Change debug code to use dprintk() and remove #if mess
Rev 3.23.12 Beta March 13, 2002, Jes Sorensen
- More cosmetic cleanups, fix places treating return as function
- use cpu_relax() in qla1280_debounce_register()
Rev 3.23.11 Beta March 13, 2002, Jes Sorensen
- Make it compile under 2.5.5
Rev 3.23.10 Beta October 1, 2001, Jes Sorensen
- Do no typecast short * to long * in QL1280BoardTbl, this
broke miserably on big endian boxes
Rev 3.23.9 Beta September 30, 2001, Jes Sorensen
- Remove pre 2.2 hack for checking for reentrance in interrupt handler
- Make data types used to receive from SCSI_{BUS,TCN,LUN}_32
unsigned int to match the types from struct scsi_cmnd
Rev 3.23.8 Beta September 29, 2001, Jes Sorensen
- Remove bogus timer_t typedef from qla1280.h
- Remove obsolete pre 2.2 PCI setup code, use proper #define's
for PCI_ values, call pci_set_master()
- Fix memleak of qla1280_buffer on module unload
- Only compile module parsing code #ifdef MODULE - should be
changed to use individual MODULE_PARM's later
- Remove dummy_buffer that was never modified nor printed
- ENTER()/LEAVE() are noops unless QL_DEBUG_LEVEL_3, hence remove
#ifdef QL_DEBUG_LEVEL_3/#endif around ENTER()/LEAVE() calls
- Remove \r from print statements, this is Linux, not DOS
- Remove obsolete QLA1280_{SCSILU,INTR,RING}_{LOCK,UNLOCK}
dummy macros
- Remove C++ compile hack in header file as Linux driver are not
supposed to be compiled as C++
- Kill MS_64BITS macro as it makes the code more readable
- Remove unnecessary flags.in_interrupts bit
Rev 3.23.7 Beta August 20, 2001, Jes Sorensen
- Dont' check for set flags on q->q_flag one by one in qla1280_next()
- Check whether the interrupt was generated by the QLA1280 before
doing any processing
- qla1280_status_entry(): Only zero out part of sense_buffer that
is not being copied into
- Remove more superflouous typecasts
- qla1280_32bit_start_scsi() replace home-brew memcpy() with memcpy()
Rev 3.23.6 Beta August 20, 2001, Tony Luck, Intel
- Don't walk the entire list in qla1280_putq_t() just to directly
grab the pointer to the last element afterwards
Rev 3.23.5 Beta August 9, 2001, Jes Sorensen
- Don't use SA_INTERRUPT, it's use is deprecated for this kinda driver
Rev 3.23.4 Beta August 8, 2001, Jes Sorensen
- Set dev->max_sectors to 1024
Rev 3.23.3 Beta August 6, 2001, Jes Sorensen
- Provide compat macros for pci_enable_device(), pci_find_subsys()
and scsi_set_pci_device()
- Call scsi_set_pci_device() for all devices
- Reduce size of kernel version dependent device probe code
- Move duplicate probe/init code to separate function
- Handle error if qla1280_mem_alloc() fails
- Kill OFFSET() macro and use Linux's PCI definitions instead
- Kill private structure defining PCI config space (struct config_reg)
- Only allocate I/O port region if not in MMIO mode
- Remove duplicate (unused) sanity check of sife of srb_t
Rev 3.23.2 Beta August 6, 2001, Jes Sorensen
- Change home-brew memset() implementations to use memset()
- Remove all references to COMTRACE() - accessing a PC's COM2 serial
port directly is not legal under Linux.
Rev 3.23.1 Beta April 24, 2001, Jes Sorensen
- Remove pre 2.2 kernel support
- clean up 64 bit DMA setting to use 2.4 API (provide backwards compat)
- Fix MMIO access to use readl/writel instead of directly
dereferencing pointers
- Nuke MSDOS debugging code
- Change true/false data types to int from uint8_t
- Use int for counters instead of uint8_t etc.
- Clean up size & byte order conversion macro usage
Rev 3.23 Beta January 11, 2001 BN Qlogic
- Added check of device_id when handling non
QLA12160s during detect().
Rev 3.22 Beta January 5, 2001 BN Qlogic
- Changed queue_task() to schedule_work()
for kernels 2.4.0 and higher.
Note: 2.4.0-testxx kernels released prior to
the actual 2.4.0 kernel release on January 2001
will get compile/link errors with schedule_work().
Please update your kernel to released 2.4.0 level,
or comment lines in this file flagged with 3.22
to resolve compile/link error of schedule_work().
- Added -DCONFIG_SMP in addition to -D__SMP__
in Makefile for 2.4.0 builds of driver as module.
Rev 3.21 Beta January 4, 2001 BN Qlogic
- Changed criteria of 64/32 Bit mode of HBA
operation according to BITS_PER_LONG rather
than HBA's NVRAM setting of >4Gig memory bit;
so that the HBA auto-configures without the need
to setup each system individually.
Rev 3.20 Beta December 5, 2000 BN Qlogic
- Added priority handling to IA-64 onboard SCSI
ISP12160 chip for kernels greater than 2.3.18.
- Added irqrestore for qla1280_intr_handler.
- Enabled /proc/scsi/qla1280 interface.
- Clear /proc/scsi/qla1280 counters in detect().
Rev 3.19 Beta October 13, 2000 BN Qlogic
- Declare driver_template for new kernel
(2.4.0 and greater) scsi initialization scheme.
- Update /proc/scsi entry for 2.3.18 kernels and
above as qla1280
Rev 3.18 Beta October 10, 2000 BN Qlogic
- Changed scan order of adapters to map
the QLA12160 followed by the QLA1280.
Rev 3.17 Beta September 18, 2000 BN Qlogic
- Removed warnings for 32 bit 2.4.x compiles
- Corrected declared size for request and response
DMA addresses that are kept in each ha
Rev. 3.16 Beta August 25, 2000 BN Qlogic
- Corrected 64 bit addressing issue on IA-64
where the upper 32 bits were not properly
passed to the RISC engine.
Rev. 3.15 Beta August 22, 2000 BN Qlogic
- Modified qla1280_setup_chip to properly load
ISP firmware for greater that 4 Gig memory on IA-64
Rev. 3.14 Beta August 16, 2000 BN Qlogic
- Added setting of dma_mask to full 64 bit
if flags.enable_64bit_addressing is set in NVRAM
Rev. 3.13 Beta August 16, 2000 BN Qlogic
- Use new PCI DMA mapping APIs for 2.4.x kernel
Rev. 3.12 July 18, 2000 Redhat & BN Qlogic
- Added check of pci_enable_device to detect() for 2.3.x
- Use pci_resource_start() instead of
pdev->resource[0].start in detect() for 2.3.x
- Updated driver version
Rev. 3.11 July 14, 2000 BN Qlogic
- Updated SCSI Firmware to following versions:
qla1x80: 8.13.08
qla1x160: 10.04.08
- Updated driver version to 3.11
Rev. 3.10 June 23, 2000 BN Qlogic
- Added filtering of AMI SubSys Vendor ID devices
Rev. 3.9
- DEBUG_QLA1280 undefined and new version BN Qlogic
Rev. 3.08b May 9, 2000 MD Dell
- Added logic to check against AMI subsystem vendor ID
Rev. 3.08 May 4, 2000 DG Qlogic
- Added logic to check for PCI subsystem ID.
Rev. 3.07 Apr 24, 2000 DG & BN Qlogic
- Updated SCSI Firmware to following versions:
qla12160: 10.01.19
qla1280: 8.09.00
Rev. 3.06 Apr 12, 2000 DG & BN Qlogic
- Internal revision; not released
Rev. 3.05 Mar 28, 2000 DG & BN Qlogic
- Edit correction for virt_to_bus and PROC.
Rev. 3.04 Mar 28, 2000 DG & BN Qlogic
- Merge changes from ia64 port.
Rev. 3.03 Mar 28, 2000 BN Qlogic
- Increase version to reflect new code drop with compile fix
of issue with inclusion of linux/spinlock for 2.3 kernels
Rev. 3.02 Mar 15, 2000 BN Qlogic
- Merge qla1280_proc_info from 2.10 code base
Rev. 3.01 Feb 10, 2000 BN Qlogic
- Corrected code to compile on a 2.2.x kernel.
Rev. 3.00 Jan 17, 2000 DG Qlogic
- Added 64-bit support.
Rev. 2.07 Nov 9, 1999 DG Qlogic
- Added new routine to set target parameters for ISP12160.
Rev. 2.06 Sept 10, 1999 DG Qlogic
- Added support for ISP12160 Ultra 3 chip.
Rev. 2.03 August 3, 1999 Fred Lewis, Intel DuPont
- Modified code to remove errors generated when compiling with
Cygnus IA64 Compiler.
- Changed conversion of pointers to unsigned longs instead of integers.
- Changed type of I/O port variables from uint32_t to unsigned long.
- Modified OFFSET macro to work with 64-bit as well as 32-bit.
- Changed sprintf and printk format specifiers for pointers to %p.
- Changed some int to long type casts where needed in sprintf & printk.
- Added l modifiers to sprintf and printk format specifiers for longs.
- Removed unused local variables.
Rev. 1.20 June 8, 1999 DG, Qlogic
Changes to support RedHat release 6.0 (kernel 2.2.5).
- Added SCSI exclusive access lock (io_request_lock) when accessing
the adapter.
- Added changes for the new LINUX interface template. Some new error
handling routines have been added to the template, but for now we
will use the old ones.
- Initial Beta Release.
*****************************************************************************/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/blk.h>
#include <linux/workqueue.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
#include <asm/processor.h>
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18)
#include <linux/pci_ids.h>
#endif
#include "scsi.h"
#include "hosts.h"
#define UNIQUE_FW_NAME
#include "qla1280.h"
#include "ql12160_fw.h" /* ISP RISC codes */
#include "ql1280_fw.h"
/*
* Compile time Options:
* 0 - Disable and 1 - Enable
*/
#define QL1280_TARGET_MODE_SUPPORT 0 /* Target mode support */
#define QL1280_LUN_SUPPORT 0
#define WATCHDOGTIMER 0
#define MEMORY_MAPPED_IO 0
#define DEBUG_QLA1280_INTR 0
#define USE_NVRAM_DEFAULTS 0
#define DEBUG_PRINT_NVRAM 0
#define LOADING_RISC_ACTIVITY 0
#define AUTO_ESCALATE_RESET 0 /* Automatically escalate resets */
#define AUTO_ESCALATE_ABORT 0 /* Automatically escalate aborts */
#define STOP_ON_ERROR 0 /* Stop on aborts and resets */
#define STOP_ON_RESET 0
#define STOP_ON_ABORT 0
#define QLA1280_PROFILE 1 /* 3.20 */
#define DEBUG_QLA1280 0
/*
* Missing PCI ID's
*/
#ifndef PCI_DEVICE_ID_QLOGIC_ISP1080
#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080
#endif
#ifndef PCI_DEVICE_ID_QLOGIC_ISP1240
#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240
#endif
#ifndef PCI_DEVICE_ID_QLOGIC_ISP1280
#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280
#endif
#ifndef PCI_DEVICE_ID_QLOGIC_ISP10160
#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016
#endif
#ifndef PCI_DEVICE_ID_QLOGIC_ISP12160
#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216
#endif
#ifndef PCI_VENDOR_ID_AMI
#define PCI_VENDOR_ID_AMI 0x101e
#endif
#if (BITS_PER_LONG == 64) || defined CONFIG_HIGHMEM
#define QLA_64BIT_PTR 1
#endif
/* 3.16 */
#ifdef QLA_64BIT_PTR
#define pci_dma_lo32(a) (a & 0xffffffff)
#define pci_dma_hi32(a) (a >> 32)
#else
#define pci_dma_lo32(a) (a & 0xffffffff)
#define pci_dma_hi32(a) 0
#endif
#define NVRAM_DELAY() udelay(500) /* 2 microsecond delay */
#define CACHE_FLUSH(a) RD_REG_WORD(a)
#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS + 1)
/*
* Compat macros
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
#define pci_set_dma_mask(dev, mask) dev->dma_mask = mask;
#define pci_present() pcibios_present()
#define pci_enable_device(pdev) 0
#define pci_find_subsys(id, dev, sid, sdev, pdev) pci_find_device(id,dev,pdev)
#define scsi_set_pci_device(host, pdev)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
typedef unsigned long dma_addr_t;
static inline void *
pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t * dma_handle)
{
void *virt_ptr;
virt_ptr = kmalloc(size, GFP_KERNEL);
if (!virt_ptr)
return NULL;
*dma_handle = virt_to_bus(virt_ptr);
return virt_ptr;
}
#define pci_free_consistent(cookie, size, ptr, dma_ptr) kfree(ptr)
#define pci_map_single(cookie, address, size, dir) virt_to_bus(address)
#define pci_map_sg(cookie, scatter, ents, dir) ents
#define pci_unmap_single(cookie, address, size, dir)
#define pci_unmap_sg(cookie, scatter, ents, dir)
#define pci_resource_start(dev, i) dev->base_address[i]
#endif
/*
* QLogic Driver Support Function Prototypes.
*/
static void qla1280_done(struct scsi_qla_host *, srb_t **, srb_t **);
static void qla1280_next(struct scsi_qla_host *, scsi_lu_t *, int);
static void qla1280_putq_t(scsi_lu_t *, srb_t *);
static void qla1280_done_q_put(srb_t *, srb_t **, srb_t **);
static int qla1280_slave_configure(Scsi_Device *);
#if STOP_ON_ERROR
static void qla1280_panic(char *, struct Scsi_Host *host);
#endif
static void qla1280_abort_queue_single(struct scsi_qla_host *, int, int,
int, uint32_t);
static int qla1280_return_status(sts_entry_t * sts, Scsi_Cmnd * cp);
static void qla1280_removeq(scsi_lu_t * q, srb_t * sp);
static void qla1280_mem_free(struct scsi_qla_host *ha);
void qla1280_do_dpc(void *p);
#ifdef MODULE
static char *qla1280_get_token(char *, char *);
#endif
static inline void qla1280_enable_intrs(struct scsi_qla_host *);
static inline void qla1280_disable_intrs(struct scsi_qla_host *);
/*
* QLogic ISP1280 Hardware Support Function Prototypes.
*/
static int qla1280_initialize_adapter(struct scsi_qla_host *ha);
static int qla1280_enable_tgt(struct scsi_qla_host *, int);
static int qla1280_isp_firmware(struct scsi_qla_host *);
static int qla1280_pci_config(struct scsi_qla_host *);
static int qla1280_chip_diag(struct scsi_qla_host *);
static int qla1280_setup_chip(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 *, srb_t *);
static int qla1280_abort_isp(struct scsi_qla_host *);
static int qla1280_64bit_start_scsi(struct scsi_qla_host *, srb_t *);
static int qla1280_32bit_start_scsi(struct scsi_qla_host *, srb_t *);
static 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 *, srb_t **, srb_t **);
static void qla1280_rst_aen(struct scsi_qla_host *);
static void qla1280_status_entry(struct scsi_qla_host *, sts_entry_t *,
srb_t **, srb_t **);
static void qla1280_error_entry(struct scsi_qla_host *, response_t *,
srb_t **, srb_t **);
static void qla1280_restart_queues(struct scsi_qla_host *);
static void qla1280_abort_queues(struct scsi_qla_host *);
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 int qla1280_mem_alloc(struct scsi_qla_host *ha);
static void qla12160_get_target_parameters(struct scsi_qla_host *,
uint32_t, uint32_t, uint32_t);
#if QL1280_LUN_SUPPORT
static void qla1280_enable_lun(struct scsi_qla_host *, int, int);
#endif
#if QL1280_TARGET_MODE_SUPPORT
static void qla1280_notify_ack(struct scsi_qla_host *, notify_entry_t *);
static void qla1280_immed_notify(struct scsi_qla_host *, notify_entry_t *);
static void qla1280_accept_io(struct scsi_qla_host *, ctio_ret_entry_t *);
static void qla1280_64bit_continue_io(struct scsi_qla_host *, atio_entry_t *,
uint32_t, paddr32_t *);
static void qla1280_32bit_continue_io(struct scsi_qla_host *, atio_entry_t *,
uint32_t, paddr32_t *);
static void qla1280_atio_entry(struct scsi_qla_host *, atio_entry_t *);
static void qla1280_notify_entry(struct scsi_qla_host *, notify_entry_t *);
#endif /* QLA1280_TARGET_MODE_SUPPORT */
#ifdef QL_DEBUG_ROUTINES
/*
* Driver Debug Function Prototypes.
*/
static u8 qla1280_getbyte(u8 *);
static u16 qla1280_getword(u16 *);
static u32 qla1280_getdword(u32 *);
static void qla1280_putbyte(u8 *, u8);
static void qla1280_putword(u16 *, u8);
static void qla1280_putdword(u32 *, u32);
static void __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd);
static void __qla1280_dump_buffer(char *, u32);
#endif
/*
* insmod needs to find the variable and make it point to something
*/
#ifdef MODULE
static char *options = NULL;
/* insmod qla1280 options=verbose" */
MODULE_PARM(options, "s");
#endif
MODULE_LICENSE("GPL");
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
/*
* Our directory Entry in /proc/scsi for the user to
* access the driver.
*/
/* Need to add in proc_fs.h PROC_SCSI_QL1280 */
#define PROC_SCSI_QL1280 PROC_SCSI_QLOGICISP
struct proc_dir_entry proc_scsi_qla1280 = {
PROC_SCSI_QL1280, 7, "qla1280",
S_IFDIR | S_IRUGO | S_IXUGO, 2,
0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif
/* We use the Scsi_Pointer structure that's included with each command
* SCSI_Cmnd as a scratchpad for our SRB.
*
* SCp will always point to the SRB structure (defined in qla1280.h).
* It is define as follows:
* - SCp.ptr -- > pointer back to the cmd
* - SCp.this_residual --> used as forward pointer to next srb
* - SCp.buffer --> used as backward pointer to next srb
* - SCp.buffers_residual --> used as flags field
* - SCp.have_data_in --> not used
* - SCp.sent_command --> not used
* - SCp.phase --> not used
*/
#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
/*****************************************/
/* ISP Boards supported by this driver */
/*****************************************/
#define NUM_OF_ISP_DEVICES 6
struct qla_boards {
unsigned char bdName[9]; /* Board ID String */
unsigned long device_id; /* Device PCI ID */
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 */
};
struct qla_boards ql1280_board_tbl[NUM_OF_ISP_DEVICES] = {
/* Name , Board PCI Device ID, Number of ports */
{"QLA12160 ", PCI_DEVICE_ID_QLOGIC_ISP12160, 2,
&fw12160i_code01[0], &fw12160i_length01,
&fw12160i_addr01, &fw12160i_version_str[0]},
{"QLA1080 ", PCI_DEVICE_ID_QLOGIC_ISP1080, 1,
&fw1280ei_code01[0], &fw1280ei_length01,
&fw1280ei_addr01, &fw1280ei_version_str[0]},
{"QLA1240 ", PCI_DEVICE_ID_QLOGIC_ISP1240, 2,
&fw1280ei_code01[0], &fw1280ei_length01,
&fw1280ei_addr01, &fw1280ei_version_str[0]},
{"QLA1280 ", PCI_DEVICE_ID_QLOGIC_ISP1280, 2,
&fw1280ei_code01[0], &fw1280ei_length01,
&fw1280ei_addr01, &fw1280ei_version_str[0]},
{"QLA10160 ", PCI_DEVICE_ID_QLOGIC_ISP10160, 1,
&fw12160i_code01[0], &fw12160i_length01,
&fw12160i_addr01, &fw12160i_version_str[0]},
{" ", 0, 0}
};
static int qla1280_verbose = 1;
static struct scsi_qla_host *qla1280_hostlist = NULL;
#if QLA1280_PROFILE
static int qla1280_buffer_size = 0;
static char *qla1280_buffer = NULL;
#endif
#if DEBUG_QLA1280
static int ql_debug_print = 1;
char debug_buff[80];
#define DEBUG(x) x
static int ql_debug_level = 0;
#define dprintk(level, format, a...) \
if ((ql_debug_level >= level) && ql_debug_print) printk(KERN_DEBUG format, ##a)
#define qla1280_dump_buffer(level, buf, size) \
if (ql_debug_level >= level) __qla1280_dump_buffer(buf, size)
#define qla1280_dump_print_cmd(level, cmd) \
if (ql_debug_level >= level) __qla1280_print_scsi_cmd(cmd)
#else
#define DEBUG(x)
#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(3, "qla1280 : Entering %s()\n", x);
#define LEAVE_INTR(x) dprintk(3, "qla1280 : Leaving %s()\n", x);
#define SCSI_BUS_32(scp) scp->device->channel
#define SCSI_TCN_32(scp) scp->device->id
#define SCSI_LUN_32(scp) scp->device->lun
/****************************************************************************/
/* LINUX - Loadable Module Functions. */
/****************************************************************************/
/*************************************************************************
* qla1280_set_info
*
* Description:
* Set parameters for the driver from the /proc filesystem.
*
* Returns:
*************************************************************************/
int
qla1280_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
{
return -ENOSYS; /* Currently this is a no-op */
}
/*************************************************************************
* 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]
int
qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
int hostno, int inout)
{
#if QLA1280_PROFILE
struct Scsi_Host *host;
struct scsi_qla_host *ha;
int size = 0;
scsi_lu_t *up;
int len = 0;
struct qla_boards *bdp;
uint32_t b, t, l;
host = NULL;
/* Find the host that was specified */
for (ha = qla1280_hostlist; (ha != NULL) && ha->host->host_no != hostno;
ha = ha->next) ;
/* if host wasn't found then exit */
if (!ha) {
size = sprintf(buffer, "Can't find adapter for host "
"number %d\n", hostno);
if (size > length) {
return size;
} else {
return 0;
}
}
host = ha->host;
if (inout == TRUE) { /* Has data been written to the file? */
printk(KERN_INFO
"qla1280_proc: has data been written to the file.\n");
return qla1280_set_info(buffer, length, host);
}
/*
* 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 */
bdp = &ql1280_board_tbl[ha->devnum];
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->bdName);
len += size;
size = sprintf(PROC_BUF, "Request Queue = 0x%p, Response Queue = 0x%p\n",
(void *)ha->request_dma, (void *)ha->response_dma);
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 queued commands = 0x%lx\n",
ha->qthreads);
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;
size = sprintf(PROC_BUF, "SCSI device Information:\n");
len += size;
/* scan for all equipment stats */
for (b = 0; b < MAX_BUSES; b++)
for (t = 0; t < MAX_TARGETS; t++) {
for (l = 0; l < MAX_LUNS; l++) {
up = LU_Q(ha, b, t, l);
if (up == NULL)
continue;
/* unused device/lun */
if (up->io_cnt == 0 || up->io_cnt < 2)
continue;
/* total reads since boot */
/* total writes since boot */
/* total requests since boot */
size = sprintf (PROC_BUF,
"(%2d:%2d:%2d): Total reqs %ld,",
b, t, l, up->io_cnt);
len += size;
/* current number of pending requests */
size = sprintf(PROC_BUF, " Pend reqs %d,",
up->q_outcnt);
len += size;
#if 0
/* avg response time */
size = sprintf(PROC_BUF, " Avg resp time %ld%%,",
(up->resp_time / up->io_cnt) *
100);
len += size;
/* avg active time */
size = sprintf(PROC_BUF,
" Avg active time %ld%%\n",
(up->act_time / up->io_cnt) * 100);
#else
size = sprintf(PROC_BUF, "\n");
#endif
len += size;
}
if (len >= qla1280_buffer_size)
break;
}
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;
#else
return 0;
#endif
}
/**************************************************************************
* qla1280_do_device_init
* This routine will register the device with the SCSI subsystem,
* initialize the host adapter structure and call the device init
* routines.
*
* Input:
* pdev - pointer to struct pci_dev for adapter
* template - pointer to SCSI template
* devnum - the device number
* bdp - pointer to struct _qlaboards
* num_hosts - the host number
*
* Returns:
* host - pointer to SCSI host structure
**************************************************************************/
struct Scsi_Host *
qla1280_do_device_init(struct pci_dev *pdev,
Scsi_Host_Template * template,
int devnum, struct qla_boards *bdp, int num_hosts)
{
struct Scsi_Host *host;
struct scsi_qla_host *ha;
struct device_reg *reg;
printk("qla1x160: Initializing ISP12160 on PCI bus %i, dev %i, irq %i\n",
pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->irq);
host = scsi_register(template, sizeof(struct scsi_qla_host));
if (!host) {
printk(KERN_WARNING
"qla1280: Failed to register host, aborting.\n");
goto error;
}
scsi_set_device(host, &pdev->dev);
ha = (struct scsi_qla_host *)host->hostdata;
/* Clear our data area */
memset(ha, 0, sizeof(struct scsi_qla_host));
/* Sanitize the information from PCI BIOS. */
host->irq = pdev->irq;
ha->pci_bus = pdev->bus->number;
ha->pci_device_fn = pdev->devfn;
ha->pdev = pdev;
ha->device_id = bdp->device_id;
ha->devnum = devnum; /* specifies microcode load address */
if (qla1280_mem_alloc(ha)) {
printk(KERN_INFO "qla1x160: Failed to get memory\n");
goto error;
}
ha->ports = bdp->numPorts;
/* following needed for all cases of OS versions */
ha->host = host;
ha->host_no = host->host_no;
host->can_queue = 0xfffff; /* unlimited */
host->cmd_per_lun = 1;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
host->base = (unsigned char *)ha->mmpbase;
#else
host->base = (unsigned long)ha->mmpbase;
#endif
host->max_channel = bdp->numPorts - 1;
host->max_lun = MAX_LUNS - 1;
host->max_id = MAX_TARGETS;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
host->max_sectors = 1024;
#endif
ha->instance = num_hosts;
host->unique_id = ha->instance;
if (qla1280_pci_config(ha)) {
printk(KERN_INFO "qla1x160: Unable to configure PCI\n");
goto error_mem_alloced;
}
/* Disable ISP interrupts. */
qla1280_disable_intrs(ha);
/* Register the IRQ with Linux (sharable) */
if (request_irq(host->irq, qla1280_intr_handler, SA_SHIRQ,
"qla1280", ha)) {
printk("qla1280 : Failed to reserve interrupt %d already "
"in use\n", host->irq);
goto error_unmap;
}
#if !MEMORY_MAPPED_IO
/* Register the I/O space with Linux */
if (!request_region(host->io_port, 0xff, "qla1280")) {
printk("qla1280 : Failed to reserve i/o region 0x%04lx-0x%04lx"
" already in use\n",
host->io_port, host->io_port + 0xff);
goto error_irq;
}
#endif
reg = ha->iobase;
/* load the F/W, read paramaters, and init the H/W */
if (qla1280_initialize_adapter(ha)) {
printk(KERN_INFO "qla1x160:Failed to initialize adapter\n");
goto error_region;
}
/* set our host ID (need to do something about our two IDs) */
host->this_id = ha->bus_settings[0].id;
return host;
error_region:
#if !MEMORY_MAPPED_IO
release_region(host->io_port, 0xff);
#endif
error_irq:
free_irq(host->irq, ha);
error_unmap:
#if MEMORY_MAPPED_IO
if (ha->mmpbase)
iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
#endif
error_mem_alloced:
qla1280_mem_free(ha);
error:
if (host) {
scsi_unregister(host);
}
return NULL;
}
/**************************************************************************
* qla1280_detect
* This routine will probe for Qlogic 1280 SCSI host adapters.
* It returns the number of host adapters of a particular
* type that were found. It also initialize all data necessary for
* the driver. It is passed-in the host number, so that it
* knows where its first entry is in the scsi_hosts[] array.
*
* Input:
* template - pointer to SCSI template
*
* Returns:
* num - number of host adapters found.
**************************************************************************/
int
qla1280_detect(Scsi_Host_Template * template)
{
struct pci_dev *pdev = NULL;
struct Scsi_Host *host;
struct scsi_qla_host *ha, *cur_ha;
struct qla_boards *bdp;
uint16_t subsys_vendor, subsys_device;
int num_hosts = 0;
int devnum = 0;
ENTER("qla1280_detect");
if (sizeof(srb_t) > sizeof(Scsi_Pointer)) {
printk(KERN_WARNING
"qla1280_detect: [WARNING] srb_t too big\n");
return 0;
}
#ifdef MODULE
dprintk(1, "DEBUG: qla1280_detect starts at address = %p\n",
qla1280_detect);
/*
* If we are called as a module, the qla1280 pointer may not be null
* and it would point to our bootup string, just like on the lilo
* command line. IF not NULL, then process this config string with
* qla1280_setup
*
* Boot time Options
* To add options at boot time add a line to your lilo.conf file like:
* append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
* which will result in the first four devices on the first two
* controllers being set to a tagged queue depth of 32.
*/
if (options)
qla1280_setup(options, NULL);
printk(KERN_WARNING
"qla1280: Please read the file /usr/src/linux/Documentation"
"/scsi/qla1280.txt\n"
"qla1280: to see the proper way to specify options to the qla1280 "
"module\n"
"qla1280: Specifically, don't use any commas when passing "
"arguments to\n"
"qla1280: insmod or else it might trash certain memory areas.\n");
#endif
if (!pci_present()) {
printk(KERN_INFO "scsi: PCI not present\n");
return 0;
}
bdp = &ql1280_board_tbl[0];
qla1280_hostlist = NULL;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
template->proc_dir = &proc_scsi_qla1280;
#else
template->proc_name = "qla1280";
#endif
/* 3.20 */
/* First Initialize QLA12160 on PCI Bus 1 Dev 2 */
while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, bdp->device_id,
PCI_ANY_ID, PCI_ANY_ID, pdev))) {
/* find QLA12160 device on PCI bus=1 slot=2 */
if ((pdev->bus->number != 1) || (PCI_SLOT(pdev->devfn) != 2))
continue;
/* Bypass all AMI SUBSYS VENDOR IDs */
if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) {
printk(KERN_INFO
"qla1x160: Skip AMI SubSys Vendor ID Chip\n");
continue;
}
if (pci_enable_device(pdev))
goto find_devices;
host = qla1280_do_device_init(pdev, template, devnum,
bdp, num_hosts);
if (!host)
continue;
ha = (struct scsi_qla_host *)host->hostdata;
/* this preferred device will always be the first one found */
cur_ha = qla1280_hostlist = ha;
num_hosts++;
}
find_devices:
pdev = NULL;
/* Try and find each different type of adapter we support */
for (devnum = 0; bdp->device_id != 0 && devnum < NUM_OF_ISP_DEVICES;
devnum++, bdp++) {
/* PCI_SUBSYSTEM_IDS supported */
while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC,
bdp->device_id, PCI_ANY_ID,
PCI_ANY_ID, pdev))) {
if (pci_enable_device(pdev))
continue;
/* found an adapter */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18)
subsys_vendor = pdev->subsystem_vendor;
subsys_device = pdev->subsystem_device;
#else
pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID,
&subsys_vendor);
pci_read_config_word(pdev, PCI_SUBSYSTEM_ID,
&subsys_device);
#endif
/*
* skip QLA12160 already initialized on
* PCI Bus 1 Dev 2 since we already initialized
* and presented it
*/
if ((bdp->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160)&&
(pdev->bus->number == 1) &&
(PCI_SLOT(pdev->devfn) == 2))
continue;
/* Bypass all AMI SUBSYS VENDOR IDs */
if (subsys_vendor == PCI_VENDOR_ID_AMI) {
printk(KERN_INFO
"qla1x160: Skip AMI SubSys Vendor ID Chip\n");
continue;
}
printk(KERN_INFO
"qla1x160: Supported Device Found VID=%x "
"DID=%x SSVID=%x SSDID=%x\n", pdev->vendor,
pdev->device, subsys_vendor, subsys_device);
host = qla1280_do_device_init(pdev, template,
devnum, bdp, num_hosts);
if (!host)
continue;
ha = (struct scsi_qla_host *)host->hostdata;
if (qla1280_hostlist == NULL) {
cur_ha = qla1280_hostlist = ha;
} else {
cur_ha = qla1280_hostlist;
while (cur_ha->next != NULL)
cur_ha = cur_ha->next;
cur_ha->next = ha;
}
num_hosts++;
} /* end of WHILE */
} /* end of FOR */
LEAVE("qla1280_detect");
return num_hosts;
}
/**************************************************************************
* qla1280_release
* Free the passed in Scsi_Host memory structures prior to unloading the
* module.
**************************************************************************/
int
qla1280_release(struct Scsi_Host *host)
{
struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
ENTER("qla1280_release");
if (!ha->flags.online)
return 0;
/* turn-off interrupts on the card */
WRT_REG_WORD(&ha->iobase->ictrl, 0);
/* Detach interrupts */
if (host->irq)
free_irq(host->irq, ha);
#if MEMORY_MAPPED_IO
if (ha->mmpbase)
iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
#else
/* release io space registers */
if (host->io_port)
release_region(host->io_port, 0xff);
#endif /* MEMORY_MAPPED_IO */
qla1280_mem_free(ha);
ENTER("qla1280_release");
return 0;
}
/**************************************************************************
* qla1280_info
* Return a string describing the driver.
**************************************************************************/
const char *
qla1280_info(struct Scsi_Host *host)
{
static char qla1280_scsi_name_buffer[125];
char *bp;
struct scsi_qla_host *ha;
struct qla_boards *bdp;
bp = &qla1280_scsi_name_buffer[0];
ha = (struct scsi_qla_host *)host->hostdata;
bdp = &ql1280_board_tbl[ha->devnum];
memset(bp, 0, sizeof(qla1280_scsi_name_buffer));
sprintf (bp,
"QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n"
" Firmware version: %2d.%02d.%02d, Driver version %s",
&bdp->bdName[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3,
host->irq, bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
QLA1280_VERSION);
return bp;
}
/**************************************************************************
* qla1200_queuecommand
* Queue a command to the controller.
*
* Note:
* The mid-level driver tries to ensures that queuecommand never gets invoked
* concurrently with itself or the interrupt handler (although the
* interrupt handler may call this routine as part of request-completion
* handling). Unfortunely, it sometimes calls the scheduler in interrupt
* context which is a big NO! NO!.
**************************************************************************/
int
qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *))
{
struct scsi_qla_host *ha;
srb_t *sp;
struct Scsi_Host *host;
int bus, target, lun;
scsi_lu_t *q;
/*ENTER("qla1280_queuecommand");
*/
host = cmd->device->host;
ha = (struct scsi_qla_host *)host->hostdata;
/* send command to adapter */
sp = (srb_t *)CMD_SP(cmd);
sp->cmd = cmd;
cmd->scsi_done = fn;
if (cmd->flags == 0) { /* new command */
sp->flags = 0;
}
qla1280_print_scsi_cmd(5, cmd);
/* Generate LU queue on bus, target, LUN */
bus = SCSI_BUS_32(cmd);
target = SCSI_TCN_32(cmd);
lun = SCSI_LUN_32(cmd);
if ((q = LU_Q(ha, bus, target, lun)) == NULL) {
if ((q = (scsi_lu_t *)kmalloc(sizeof(struct scsi_lu),
GFP_ATOMIC))) {
LU_Q(ha, bus, target, lun) = q;
memset(q, 0, sizeof(struct scsi_lu));
dprintk(1, "Allocate new device queue 0x%p\n",
(void *)q);
} else {
CMD_RESULT(cmd) = DID_BUS_BUSY << 16;
qla1280_done_q_put(sp, &ha->done_q_first,
&ha->done_q_last);
/* 3.22 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) /* 3.22 */
schedule_work(&ha->run_qla_bh);
#else /* 3.22 */
schedule_work(&ha->run_qla_bh); /* 3.22 */
#endif /* 3.22 */
return 0;
}
}
/* Set an invalid handle until we issue the command to ISP */
/* then we will set the real handle value. */
CMD_HANDLE(cmd) = (unsigned char *)INVALID_HANDLE;
/* add the command to our queue */
ha->qthreads++;
qla1280_putq_t(q, sp);
dprintk(1, "qla1280_QC: t=%x CDB=%x I/OSize=0x%x haQueueCount=0x%lx\n",
target, cmd->cmnd[0], cmd->request_bufflen, ha->qthreads);
/* send command to adapter */
if (q->q_outcnt == 0)
qla1280_restart_queues(ha);
/*LEAVE("qla1280_queuecommand"); */
return 0;
}
/**************************************************************************
* qla1200_abort
* Abort the speciifed SCSI command(s).
**************************************************************************/
int
qla1280_abort(Scsi_Cmnd * cmd)
{
struct scsi_qla_host *ha;
srb_t *sp;
struct Scsi_Host *host;
unsigned int bus, target, lun;
scsi_lu_t *q;
int return_status = SCSI_ABORT_SUCCESS;
int found = 0;
int i;
unsigned char *handle;
u16 data;
ENTER("qla1280_abort");
ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
host = cmd->device->host;
/* Get the SCSI request ptr */
sp = (srb_t *)CMD_SP(cmd);
handle = CMD_HANDLE(cmd);
if (qla1280_verbose)
printk(KERN_ERR "scsi(%li): ABORT Command=0x%p, handle=0x%p\n",
ha->host_no, (void *) cmd, (void *) handle);
/* Check for pending interrupts. */
if (handle == NULL) {
/* we never got this command */
printk(KERN_INFO "qla1280: Aborting a NULL handle\n");
return SCSI_ABORT_NOT_RUNNING; /* no action - we don't have command */
}
data = qla1280_debounce_register(&ha->iobase->istatus);
/*
* The io_request_lock is held when the reset handler is called, hence
* the interrupt handler cannot be running in parallel as it also
* grabs the lock. No reason to play funny games with set_bit() in
* order to test for interrupt handler entry as the driver used to
* do here.
* /Jes
*/
if (data & RISC_INT) {
/* put any pending command in done queue */
qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
}
/*
* This seems unnecessary, it's not used below! / Jes
*/
#ifdef UNUSED
handle = CMD_HANDLE(cmd);
#endif
/* Generate LU queue on bus, target, LUN */
bus = SCSI_BUS_32(cmd);
target = SCSI_TCN_32(cmd);
lun = SCSI_LUN_32(cmd);
if ((q = LU_Q(ha, bus, target, lun)) == NULL) {
/* No lun queue -- command must not be active */
printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the "
"specified device\n", bus, target, lun);
return SCSI_ABORT_NOT_RUNNING; /* no action - we don't have command */
}
#if AUTO_ESCALATE_ABORT
if ((sp->flags & SRB_ABORTED)) {
dprintk(1, "qla1280_abort: Abort escalayted - returning "
"SCSI_ABORT_SNOOZE.\n");
return SCSI_ABORT_SNOOZE;
}
#endif
if ((sp->flags & SRB_ABORT_PENDING)) {
if (qla1280_verbose)
printk(KERN_WARNING
"scsi(): Command has a pending abort "
"message - ABORT_PENDING.\n");
return SCSI_ABORT_PENDING;
}
#if STOP_ON_ABORT
printk(KERN_WARNING "Scsi layer issued a ABORT command= 0x%p\n", cmd);
qla1280_print_scsi_cmd(2, cmd);
#endif
/*
* Normally, would would need to search our queue for the specified command
* but; since our sp contains the cmd ptr, we can just remove it from our
* LUN queue.
*/
if (!(sp->flags & SRB_SENT)) {
found++;
if (qla1280_verbose)
printk(KERN_WARNING
"scsi(): Command returned from queue "
"aborted.\n");
/* Remove srb from SCSI LU queue. */
qla1280_removeq(q, sp);
sp->flags |= SRB_ABORTED;
CMD_RESULT(cmd) = DID_ABORT << 16;
qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last);
return_status = SCSI_ABORT_SUCCESS;
} else { /* find the command in our active list */
for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
if (sp == ha->outstanding_cmds[i]) {
found++;
dprintk(1,
"qla1280: RISC aborting command.\n");
qla1280_abort_command(ha, sp);
return_status = SCSI_ABORT_PENDING;
break;
}
}
}
#if STOP_ON_ABORT
qla1280_panic("qla1280_abort", ha->host);
#endif
if (found == 0)
return_status = SCSI_ABORT_NOT_RUNNING; /* no action - we don't have command */
dprintk(1, "qla1280_abort: Aborted status returned = 0x%x.\n",
return_status);
if (ha->done_q_first)
qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
if (found)
qla1280_restart_queues(ha);
LEAVE("qla1280_abort");
return return_status;
}
int
qla1280_new_abort(Scsi_Cmnd * cmd)
{
struct scsi_qla_host *ha;
srb_t *sp;
struct Scsi_Host *host;
int bus, target, lun;
scsi_lu_t *q;
unsigned long cpu_flags;
int return_status = SCSI_ABORT_SUCCESS;
int found = 0;
int i;
unsigned char *handle;
u16 data;
ENTER("qla1280_abort");
host = cmd->device->host;
ha = (struct scsi_qla_host *)host->hostdata;
/* Get the SCSI request ptr */
sp = (srb_t *) CMD_SP(cmd);
handle = CMD_HANDLE(cmd);
if (qla1280_verbose)
printk(KERN_ERR "scsi(%li): ABORT Command=0x%p, handle=0x%p\n",
ha->host_no, cmd, handle);
/* Check for pending interrupts. */
if (handle == NULL) {
/* we never got this command */
printk(KERN_INFO "qla1280: Aborting a NULL handle\n");
return SUCCESS; /* no action - we don't have command */
}
spin_lock_irqsave (ha->host->host_lock, cpu_flags);
data = qla1280_debounce_register(&ha->iobase->istatus);
/*
* We grab the host lock in the interrupt handler to
* prevent racing here.
*
* Then again, running the interrupt handler from here is somewhat
* questionable.
* /Jes
*/
if (data & RISC_INT) {
/* put any pending command in done queue */
qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
}
/* Generate LU queue on bus, target, LUN */
bus = SCSI_BUS_32(cmd);
target = SCSI_TCN_32(cmd);
lun = SCSI_LUN_32(cmd);
if ((q = LU_Q(ha, bus, target, lun)) == NULL) {
/* No lun queue -- command must not be active */
printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the "
"specified device\n", bus, target, lun);
return_status = SUCCESS; /* no action - we don't have command */
goto out;
}
if ((sp->flags & SRB_ABORT_PENDING)) {
if (qla1280_verbose)
printk(KERN_WARNING
"scsi(): Command has a pending abort "
"message - ABORT_PENDING.\n");
return_status = SCSI_ABORT_PENDING;
goto out;
}
#if STOP_ON_ABORT
printk(KERN_WARNING "Scsi layer issued a ABORT command= 0x%p\n", cmd);
qla1280_print_scsi_cmd(2, cmd);
#endif
/*
* Normally, would would need to search our queue for the specified command
* but; since our sp contains the cmd ptr, we can just remove it from our
* LUN queue.
*/
if (!(sp->flags & SRB_SENT)) {
found++;
if (qla1280_verbose)
printk(KERN_WARNING
"scsi(): Command returned from queue "
"aborted.\n");
/* Remove srb from SCSI LU queue. */
qla1280_removeq(q, sp);
sp->flags |= SRB_ABORTED;
CMD_RESULT(cmd) = DID_ABORT << 16;
qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last);
return_status = SUCCESS;
} else { /* find the command in our active list */
for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
if (sp == ha->outstanding_cmds[i]) {
found++;
dprintk(1,
"qla1280: RISC aborting command.\n");
qla1280_abort_command(ha, sp);
return_status = SCSI_ABORT_PENDING;
break;
}
}
}
#if STOP_ON_ABORT
qla1280_panic("qla1280_abort", ha->host);
#endif
if (found == 0)
return_status = SUCCESS; /* no action - we don't have the command */
dprintk(1, "qla1280_abort: Aborted status returned = 0x%x.\n",
return_status);
if (ha->done_q_first)
qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
if (found)
qla1280_restart_queues(ha);
out:
spin_unlock_irqrestore(ha->host->host_lock, cpu_flags);
LEAVE("qla1280_abort");
return return_status;
}
/**************************************************************************
* qla1200_reset
* The reset function will reset the SCSI bus and abort any executing
* commands.
*
* Input:
* cmd = Linux SCSI command packet of the command that cause the
* bus reset.
* flags = SCSI bus reset option flags (see scsi.h)
*
* Returns:
* DID_RESET in cmd.host_byte of aborted command(s)
*
* Note:
* Resetting the bus always succeeds - is has to, otherwise the
* kernel will panic! Try a surgical technique - sending a BUS
* DEVICE RESET message - on the offending target before pulling
* the SCSI bus reset line.
**************************************************************************/
int
qla1280_reset(Scsi_Cmnd * cmd, unsigned int flags)
{
struct scsi_qla_host *ha;
int bus, target, lun;
srb_t *sp;
typedef enum {
ABORT_DEVICE = 1,
DEVICE_RESET = 2,
BUS_RESET = 3,
ADAPTER_RESET = 4,
RESET_DELAYED = 5,
FAIL = 6
} action_t;
action_t action = ADAPTER_RESET;
u16 data;
scsi_lu_t *q;
int result;
ENTER("qla1280_reset");
if (qla1280_verbose)
printk(KERN_INFO "scsi(): Resetting Cmnd=0x%p, Handle=0x%p, "
"flags=0x%x\n", cmd, CMD_HANDLE(cmd), flags);
if (cmd == NULL) {
printk(KERN_WARNING
"(scsi?:?:?:?) Reset called with NULL Scsi_Cmnd "
"pointer, failing.\n");
return SCSI_RESET_SNOOZE;
}
ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
sp = (srb_t *)CMD_SP(cmd);
#if STOP_ON_RESET
qla1280_panic("qla1280_reset", ha->host);
#endif
/* Check for pending interrupts. */
data = qla1280_debounce_register(&ha->iobase->istatus);
/*
* The io_request_lock is held when the reset handler is called, hence
* the interrupt handler cannot be running in parallel as it also
* grabs the lock. /Jes
*/
if (data & RISC_INT)
qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
/*
* Determine the suggested action that the mid-level driver wants
* us to perform.
*/
if (CMD_HANDLE(cmd) == NULL) {
/*
* if mid-level driver called reset with a orphan SCSI_Cmnd
* (i.e. a command that's not pending), so perform the
* function specified.
*/
if (flags & SCSI_RESET_SUGGEST_HOST_RESET)
action = ADAPTER_RESET;
else
action = BUS_RESET;
} else {
/*
* Mid-level driver has called reset with this SCSI_Cmnd and
* its pending.
*/
if (flags & SCSI_RESET_SUGGEST_HOST_RESET)
action = ADAPTER_RESET;
else if (flags & SCSI_RESET_SUGGEST_BUS_RESET)
action = BUS_RESET;
else
action = DEVICE_RESET;
}
bus = SCSI_BUS_32(cmd);
target = SCSI_TCN_32(cmd);
lun = SCSI_LUN_32(cmd);
q = LU_Q(ha, bus, target, lun);
#if AUTO_ESCALATE_RESET
if ((action & DEVICE_RESET) && (q->q_flag & QLA1280_QRESET)) {
printk(KERN_INFO
"qla1280(%ld): Bus device reset already sent to "
"device, escalating.\n", ha->host_no);
action = BUS_RESET;
}
if ((action & DEVICE_RESET) && (sp->flags & SRB_ABORT_PENDING)) {
printk(KERN_INFO
"qla1280(%ld):Have already attempted to reach "
"device with abort device\n", ha->host_no);
printk(KERN_INFO "qla1280(%ld):message, will escalate to BUS "
"RESET.\n", ha->host_no);
action = BUS_RESET;
}
#endif
/*
* By this point, we want to already know what we are going to do,
* so we only need to perform the course of action.
*/
result = SCSI_RESET_ERROR;
switch (action) {
case FAIL:
break;
case RESET_DELAYED:
result = SCSI_RESET_PENDING;
break;
case ABORT_DEVICE:
ha->flags.in_reset = TRUE;
if (qla1280_verbose)
printk(KERN_INFO
"scsi(%ld:%d:%d:%d): Queueing abort device "
"command.\n", ha->host_no, bus, target, lun);
qla1280_abort_queue_single(ha, bus, target, lun, DID_ABORT);
if (qla1280_abort_device(ha, bus, target, lun) == 0)
result = SCSI_RESET_PENDING;
break;
case DEVICE_RESET:
if (qla1280_verbose)
printk(KERN_INFO
"scsi(%ld:%d:%d:%d): Queueing device reset "
"command.\n", ha->host_no, bus, target, lun);
ha->flags.in_reset = TRUE;
for (lun = 0; lun < MAX_LUNS; lun++)
qla1280_abort_queue_single(ha, bus, target, lun,
DID_ABORT);
if (qla1280_device_reset(ha, bus, target) == 0)
result = SCSI_RESET_PENDING;
q->q_flag |= QLA1280_QRESET;
break;
case BUS_RESET:
if (qla1280_verbose)
printk(KERN_INFO "qla1280(%ld:%d:%d:%d): Issuing BUS "
"DEVICE RESET.\n", ha->host_no, bus, target,
lun);
ha->flags.in_reset = TRUE;
for (target = 0; target < MAX_TARGETS; target++)
for (lun = 0; lun < MAX_LUNS; lun++)
qla1280_abort_queue_single(ha, bus, target,
lun, DID_RESET);
qla1280_bus_reset(ha, bus);
/*
* The bus reset routine returns all the outstanding commands
* back with "DID_RESET" in the status field after a short
* delay by the firmware. If the mid-level time out the SCSI
* reset before our delay we may need to ignore it.
*/
/* result = SCSI_RESET_PENDING | SCSI_RESET_BUS_RESET; */
result = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
/*
* Wheeeee!!!
*/
mdelay(4 * 1000);
barrier();
if (flags & SCSI_RESET_SYNCHRONOUS) {
CMD_RESULT(cmd) = DID_BUS_BUSY << 16;
(*(cmd)->scsi_done)(cmd);
}
/* ha->reset_start = jiffies; */
break;
case ADAPTER_RESET:
default:
if (qla1280_verbose) {
printk(KERN_INFO
"scsi(%ld:%d:%d:%d): Issued an ADAPTER "
"RESET.\n", ha->host_no, bus, target, lun);
printk(KERN_INFO
"scsi(%ld:%d:%d:%d): I/O processing will "
"continue automatically.\n", ha->host_no, bus,
target, lun);
}
ha->flags.reset_active = TRUE;
/*
* We restarted all of the commands automatically, so the
* mid-level code can expect completions momentitarily.
*/
if (qla1280_abort_isp(ha) == 0)
result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
ha->flags.reset_active = FALSE;
}
if (ha->done_q_first)
qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
qla1280_restart_queues(ha);
ha->flags.in_reset = FALSE;
dprintk(1, "RESET returning %d\n", result);
LEAVE("qla1280_reset");
return result;
}
/**************************************************************************
* qla1280_biosparam
* Return the disk geometry for the given SCSI device.
**************************************************************************/
int
qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int geom[])
{
int heads, sectors, cylinders;
heads = 64;
sectors = 32;
cylinders = (unsigned long)capacity / (heads * sectors);
if (cylinders > 1024) {
heads = 255;
sectors = 63;
cylinders = (unsigned long)capacity / (heads * sectors);
/* if (cylinders > 1023)
cylinders = 1023; */
}
geom[0] = heads;
geom[1] = sectors;
geom[2] = cylinders;
return 0;
}
/**************************************************************************
* qla1280_intr_handler
* Handles the H/W interrupt
**************************************************************************/
void
qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
{
struct scsi_qla_host *ha;
struct device_reg *reg;
u16 data;
ENTER_INTR ("qla1280_intr_handler");
ha = (struct scsi_qla_host *)dev_id;
spin_lock(ha->host->host_lock);
ha->isr_count++;
reg = ha->iobase;
WRT_REG_WORD(&reg->ictrl, 0); /* disable our interrupt. */
data = qla1280_debounce_register(&reg->istatus);
/* Check for pending interrupts. */
if (data & RISC_INT) {
qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
} else {
/* spurious interrupts can happen legally */
dprintk(1, "scsi(%ld): Spurious interrupt - ignoring\n",
ha->host_no);
}
if (ha->done_q_first)
qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
spin_unlock(ha->host->host_lock);
/* enable our interrupt. */
WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT | ISP_EN_RISC));
LEAVE_INTR("qla1280_intr_handler");
}
/**************************************************************************
* qla1280_do_dpc
*
* Description:
* This routine is a task that is schedule by the interrupt handler
* to perform the background processing for interrupts. We put it
* on a task queue that is consumed whenever the scheduler runs; that's
* so you can do anything (i.e. put the process to sleep etc). In fact, the
* mid-level tries to sleep when it reaches the driver threshold
* "host->can_queue". This can cause a panic if we were in our interrupt
* code .
**************************************************************************/
void
qla1280_do_dpc(void *p)
{
struct scsi_qla_host *ha = (struct scsi_qla_host *) p;
unsigned long cpu_flags;
spin_lock_irqsave(ha->host->host_lock, cpu_flags);
if (ha->flags.isp_abort_needed)
qla1280_abort_isp(ha);
if (ha->flags.reset_marker)
qla1280_rst_aen(ha);
if (ha->done_q_first)
qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
spin_unlock_irqrestore(ha->host->host_lock, cpu_flags);
}
/**************************************************************************
* qla1280_slave_configure
*
* Description:
* Determines the queue depth for a given device. There are two ways
* a queue depth can be obtained for a tagged queueing device. One
* way is the default queue depth which is determined by whether
* If it is defined, then it is used
* as the default queue depth. Otherwise, we use either 4 or 8 as the
* default queue depth (dependent on the number of hardware SCBs).
**************************************************************************/
static int
qla1280_slave_configure(Scsi_Device * device)
{
struct scsi_qla_host *p = (struct scsi_qla_host *)device->host->hostdata;
int bus = device->channel;
int target = device->id;
if (qla1280_check_for_dead_scsi_bus(p, bus))
return 1;
if (device->tagged_supported &&
(p->bus_settings[bus].qtag_enables & (BIT_0 << target))) {
scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
p->bus_settings[bus].hiwat);
/* device->queue_depth = 20; */
printk(KERN_INFO "scsi(%li:%d:%d:%d): Enabled tagged queuing, "
"queue depth %d.\n", p->host_no, device->channel,
device->id, device->lun, device->queue_depth);
} else {
scsi_adjust_queue_depth(device, 0 /* TCQ off */, 3);
}
qla12160_get_target_parameters(p, bus, target, device->lun);
return 0;
}
/*
* Driver Support Routines
*/
/*
* qla1280_done
* Process completed commands.
*
* Input:
* ha = adapter block pointer.
* done_q_first = done queue first pointer.
* done_q_last = done queue last pointer.
*/
static void
qla1280_done(struct scsi_qla_host *ha, srb_t ** done_q_first,
srb_t ** done_q_last)
{
srb_t *sp;
scsi_lu_t *q;
int bus, target, lun;
Scsi_Cmnd *cmd;
ENTER("qla1280_done");
while (*done_q_first != NULL) {
/* remove command from done list */
sp = *done_q_first;
if (!(*done_q_first = sp->s_next))
*done_q_last = NULL;
else
(*done_q_first)->s_prev = NULL;
cmd = sp->cmd;
bus = SCSI_BUS_32(cmd);
target = SCSI_TCN_32(cmd);
lun = SCSI_LUN_32(cmd);
q = LU_Q(ha, bus, target, lun);
/* Decrement outstanding commands on device. */
if (q->q_outcnt)
q->q_outcnt--;
if (q->q_outcnt < ha->bus_settings[bus].hiwat) {
q->q_flag &= ~QLA1280_QBUSY;
}
q->io_cnt++;
if (sp->dir & BIT_5)
q->r_cnt++;
else
q->w_cnt++;
switch ((CMD_RESULT(cmd) >> 16)) {
case DID_RESET:
q->q_flag &= ~QLA1280_QRESET;
/* Issue marker command. */
qla1280_marker(ha, bus, target, 0, MK_SYNC_ID);
break;
case DID_ABORT:
sp->flags &= ~SRB_ABORT_PENDING;
sp->flags |= SRB_ABORTED;
if (sp->flags & SRB_TIMEOUT)
CMD_RESULT(sp->cmd) = DID_TIME_OUT << 16;
break;
default:
break;
}
/* 3.13 64 and 32 bit */
/* Release memory used for this I/O */
if (cmd->use_sg) {
dprintk(1, "S/G unmap_sg cmd=%p\n", cmd);
pci_unmap_sg(ha->pdev, cmd->request_buffer,
cmd->use_sg,
scsi_to_pci_dma_dir(cmd->sc_data_direction));
} else if (cmd->request_bufflen) {
/*dprintk(1, "No S/G unmap_single cmd=%x saved_dma_handle=%lx\n",
cmd, sp->saved_dma_handle); */
pci_unmap_single(ha->pdev, sp->saved_dma_handle,
cmd->request_bufflen,
scsi_to_pci_dma_dir(cmd->sc_data_direction));
}
/* Call the mid-level driver interrupt handler */
CMD_HANDLE(sp->cmd) = NULL;
ha->actthreads--;
(*(cmd)->scsi_done)(cmd);
qla1280_next(ha, q, bus);
}
LEAVE("qla1280_done");
}
/*
* Translates a ISP error to a Linux SCSI error
*/
static int
qla1280_return_status(sts_entry_t * sts, Scsi_Cmnd * cp)
{
int host_status = DID_ERROR;
#if DEBUG_QLA1280_INTR
static char *reason[] = {
"DID_OK",
"DID_NO_CONNECT",
"DID_BUS_BUSY",
"DID_TIME_OUT",
"DID_BAD_TARGET",
"DID_ABORT",
"DID_PARITY",
"DID_ERROR",
"DID_RESET",
"DID_BAD_INTR"
};
#endif /* DEBUG_QLA1280_INTR */
ENTER("qla1280_return_status");
#if DEBUG_QLA1280_INTR
/*
dprintk(1, "qla1280_return_status: compl status = 0x%04x\n",
sts->comp_status);
*/
#endif
switch (sts->comp_status) {
case CS_COMPLETE:
host_status = DID_OK;
break;
case CS_INCOMPLETE:
if (!(sts->state_flags & SF_GOT_BUS))
host_status = DID_NO_CONNECT;
else if (!(sts->state_flags & SF_GOT_TARGET))
host_status = DID_BAD_TARGET;
else if (!(sts->state_flags & SF_SENT_CDB))
host_status = DID_ERROR;
else if (!(sts->state_flags & SF_TRANSFERRED_DATA))
host_status = DID_ERROR;
else if (!(sts->state_flags & SF_GOT_STATUS))
host_status = DID_ERROR;
else if (!(sts->state_flags & SF_GOT_SENSE))
host_status = DID_ERROR;
break;
case CS_RESET:
host_status = DID_RESET;
break;
case CS_ABORTED:
host_status = DID_ABORT;
break;
case CS_TIMEOUT:
host_status = DID_TIME_OUT;
break;
case CS_DATA_OVERRUN:
dprintk(2, "Data overrun 0x%x\n", sts->residual_length);
dprintk(2, "qla1280_isr: response packet data\n");
qla1280_dump_buffer(2, (char *)sts, RESPONSE_ENTRY_SIZE);
host_status = DID_ERROR;
break;
case CS_DATA_UNDERRUN:
if ((cp->request_bufflen - sts->residual_length) <
cp->underflow) {
printk(KERN_WARNING
"scsi: Underflow detected - retrying "
"command.\n");
host_status = DID_ERROR;
} else
host_status = DID_OK;
break;
default:
host_status = DID_ERROR;
break;
}
#if DEBUG_QLA1280_INTR
dprintk(1, "qla1280 ISP status: host status (%s) scsi status %x\n",
reason[host_status], sts->scsi_status);
#endif
LEAVE("qla1280_return_status");
return (sts->scsi_status & 0xff) | (host_status << 16);
}
/*
* qla1280_done_q_put
* Place SRB command on done queue.
*
* Input:
* sp = srb pointer.
* done_q_first = done queue first pointer.
* done_q_last = done queue last pointer.
*/
static void
qla1280_done_q_put(srb_t * sp, srb_t ** done_q_first, srb_t ** done_q_last)
{
ENTER("qla1280_put_done_q");
/* Place block on done queue */
sp->s_next = NULL;
sp->s_prev = *done_q_last;
if (!*done_q_first)
*done_q_first = sp;
else
(*done_q_last)->s_next = sp;
*done_q_last = sp;
LEAVE("qla1280_put_done_q");
}
/*
* qla1280_next
* Retrieve and process next job in the queue.
*
* Input:
* ha = adapter block pointer.
* q = SCSI LU pointer.
* bus = SCSI bus number.
* SCSI_LU_Qlock must be already obtained and no other locks.
*
* Output:
* Releases SCSI_LU_Qupon exit.
*/
static void
qla1280_next(struct scsi_qla_host *ha, scsi_lu_t * q, int bus)
{
srb_t *sp;
int cnt, status;
ENTER("qla1280_next");
while (((sp = q->q_first) != NULL) && /* we have a queue pending */
/* device not busy/suspended */
!(q->q_flag & (QLA1280_QBUSY | QLA1280_QSUSP)) && !ha->flags.abort_isp_active) { /* not resetting the adapter */
/* Remove srb from SCSI LU queue. */
qla1280_removeq(q, sp);
dprintk(1, "starting request 0x%p<-(0x%p)\n", q, sp);
{
/* Set busy flag if reached high water mark. */
q->q_outcnt++;
if (q->q_outcnt >= ha->bus_settings[bus].hiwat)
q->q_flag |= QLA1280_QBUSY;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
if (ha->flags.enable_64bit_addressing)
status = qla1280_64bit_start_scsi(ha, sp);
else
#endif
status = qla1280_32bit_start_scsi(ha, sp);
if (status) { /* if couldn't start the request */
if (q->q_outcnt == 1) {
/* Wait for 30 sec for command to be accepted. */
for (cnt = 6000000; cnt; cnt--) {
#if QLA_64BIT_PTR
if (ha->flags.enable_64bit_addressing)
status =
qla1280_64bit_start_scsi(ha, sp);
else
#endif
status =
qla1280_32bit_start_scsi(ha, sp);
if (!status)
break;
/* Go check for pending interrupts. */
qla1280_poll(ha);
udelay(5); /* 10 */
}
if (!cnt) {
/* Set timeout status */
CMD_RESULT(sp->cmd) =
DID_TIME_OUT << 16;
#if WATCHDOGTIMER
/* Remove command from watchdog queue. */
if (sp->flags & SRB_WATCHDOG)
qla1280_timeout_remove
(ha, sp);
#endif
CMD_HANDLE(sp->cmd) = NULL;
/* Call the mid-level driver interrupt handler */
(*(sp->cmd)->scsi_done)(sp->cmd);
if (q->q_outcnt)
q->q_outcnt--;
}
} else { /* Place request back on top of device queue. */
qla1280_putq_t(q, sp);
if (q->q_outcnt)
q->q_outcnt--;
if (q->q_outcnt <
ha->bus_settings[bus].hiwat)
q->q_flag &= ~QLA1280_QBUSY;
break;
}
}
}
}
LEAVE("qla1280_next");
}
/*
* qla1280_putq_t
* Add the standard SCB job to the top of standard SCB commands.
*
* Input:
* q = SCSI LU pointer.
* sp = srb pointer.
* SCSI_LU_Qlock must be already obtained.
*/
static void
qla1280_putq_t(scsi_lu_t * q, srb_t * sp)
{
ENTER("qla1280_putq_t");
dprintk(1, "Adding to device q=0x%p<-(0x%p)sp\n", (void *) q,
(void *) sp);
sp->s_next = NULL;
if (!q->q_first) { /* If queue empty */
sp->s_prev = NULL;
q->q_first = sp;
q->q_last = sp;
} else {
sp->s_prev = q->q_last;
q->q_last->s_next = sp;
q->q_last = sp;
}
LEAVE("qla1280_putq_t");
}
/*
* qla1280_removeq
* Function used to remove a command block from the
* LU queue.
*
* Input:
* q = SCSI LU pointer.
* sp = srb pointer.
* SCSI_LU_Qlock must be already obtained.
*/
static void
qla1280_removeq(scsi_lu_t * q, srb_t * sp)
{
dprintk(1, "Removing from device_q (0x%p)->(0x%p)\n", q, sp);
if (sp->s_prev) {
if ((sp->s_prev->s_next = sp->s_next) != NULL)
sp->s_next->s_prev = sp->s_prev;
else
q->q_last = sp->s_prev;
} else if (!(q->q_first = sp->s_next))
q->q_last = NULL;
else
q->q_first->s_prev = NULL;
}
/*
* qla1280_mem_alloc
* Allocates adapter memory.
*
* Returns:
* 0 = success.
* 1 = failure.
*/
static int
qla1280_mem_alloc(struct scsi_qla_host *ha)
{
int status = 1;
dma_addr_t dma_handle;
ENTER("qla1280_mem_alloc");
/* 3.13 */
/* get consistent memory allocated for request and response rings */
ha->request_ring = pci_alloc_consistent(ha->pdev,
((REQUEST_ENTRY_CNT + 1) *
(sizeof(request_t))),
&dma_handle);
if (!ha->request_ring)
goto error;
ha->request_dma = dma_handle;
ha->response_ring = pci_alloc_consistent(ha->pdev,
((RESPONSE_ENTRY_CNT + 1) *
(sizeof(response_t))),
&dma_handle);
if (!ha->request_ring)
goto error;
ha->response_dma = dma_handle;
status = 0;
error:
if (status)
dprintk(2, "qla1280_mem_alloc: **** FAILED ****\n");
LEAVE("qla1280_mem_alloc");
return status;
}
/*
* qla1280_mem_free
* Frees adapter allocated memory.
*
* Input:
* ha = adapter block pointer.
*/
static void
qla1280_mem_free(struct scsi_qla_host *ha)
{
scsi_lu_t *q;
int bus, target, lun;
ENTER("qlc1280_mem_free");
if (ha) {
/* Free device queues. */
for (bus = 0; bus < MAX_BUSES; bus++) {
q = LU_Q(ha, bus, ha->bus_settings[bus].id, 0);
for (target = 0; target < MAX_TARGETS; target++)
for (lun = 0; lun < MAX_LUNS; lun++)
if (LU_Q(ha, bus, target, lun) != NULL
&& LU_Q(ha, bus, target, lun) != q)
kfree(LU_Q(ha, bus, target, lun));
kfree(q);
}
for (bus = 0; bus < MAX_EQ; bus++)
ha->dev[bus] = NULL;
}
/* 3.13 */
/* free consistent memory allocated for request and response rings */
if (ha->request_ring)
pci_free_consistent(ha->pdev,
((REQUEST_ENTRY_CNT + 1) *
(sizeof(request_t))),
ha->request_ring, ha->request_dma);
if (ha->response_ring)
pci_free_consistent(ha->pdev,
((RESPONSE_ENTRY_CNT + 1) *
(sizeof(response_t))),
ha->response_ring, ha->response_dma);
if (qla1280_buffer) {
free_page((unsigned long) qla1280_buffer);
qla1280_buffer = NULL;
}
LEAVE("qlc1280_mem_free");
}
/****************************************************************************/
/* QLogic ISP1280 Hardware Support Functions. */
/****************************************************************************/
/*
* qla2100_enable_intrs
* qla2100_disable_intrs
*
* Input:
* ha = adapter block pointer.
*
* Returns:
* None
*/
static inline void
qla1280_enable_intrs(struct scsi_qla_host *ha)
{
struct device_reg *reg;
reg = ha->iobase;
/* enable risc and host interrupts */
WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT | ISP_EN_RISC));
ha->flags.ints_enabled = 1;
#if 0
printk("Enabling ints\n");
#endif
}
static inline void
qla1280_disable_intrs(struct scsi_qla_host *ha)
{
struct device_reg *reg;
reg = ha->iobase;
/* disable risc and host interrupts */
WRT_REG_WORD(&reg->ictrl, 0);
ha->flags.ints_enabled = 0;
#if 0
printk("Disabling ints\n");
#endif
}
/*
* qla1280_initialize_adapter
* Initialize board.
*
* Input:
* ha = adapter block pointer.
*
* Returns:
* 0 = success
*/
static int
qla1280_initialize_adapter(struct scsi_qla_host *ha)
{
struct device_reg *reg;
int status;
int bus;
ENTER("qla1280_initialize_adapter");
/* Clear adapter flags. */
ha->flags.online = FALSE;
ha->flags.isp_abort_needed = FALSE;
ha->flags.disable_host_adapter = FALSE;
ha->flags.reset_active = FALSE;
ha->flags.abort_isp_active = FALSE;
ha->flags.ints_enabled = FALSE;
dprintk(1, "Configure PCI space for adapter...\n");
reg = ha->iobase;
/* Insure mailbox registers are free. */
WRT_REG_WORD(&reg->semaphore, 0);
WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
WRT_REG_WORD(&reg->host_cmd, HC_CLR_HOST_INT);
/* If firmware needs to be loaded */
if (qla1280_verbose)
printk(KERN_INFO "scsi(%li): Determining if RISC is "
"loaded...\n", ha->host_no);
if (qla1280_isp_firmware(ha)) {
if (qla1280_verbose)
printk(KERN_INFO "scsi(%ld): Verifying chip...\n",
ha->host_no);
if (!(status = qla1280_chip_diag (ha))) {
if (qla1280_verbose)
printk(KERN_INFO "scsi(%ld): Setup chip...\n",
ha->host_no);
status = qla1280_setup_chip(ha);
}
} else {
printk(KERN_ERR "initialize: isp_firmware() failed!\n");
status = 1;
}
if (!status) {
/* Setup adapter based on NVRAM parameters. */
if (qla1280_verbose)
printk(KERN_INFO
"scsi(%ld): Configure NVRAM parameters...\n",
ha->host_no);
qla1280_nvram_config(ha);
if (!ha->flags.disable_host_adapter
&& !qla1280_init_rings(ha)) {
/* Issue SCSI reset. */
/* dg 03/13 if we can't reset twice then bus is dead */
for (bus = 0; bus < ha->ports; bus++) {
if (!ha->bus_settings[bus].disable_scsi_reset){
if (qla1280_bus_reset(ha, bus)) {
if (qla1280_bus_reset(ha, bus)) {
ha->bus_settings[bus].scsi_bus_dead = TRUE;
}
}
}
}
do {
/* Issue marker command. */
ha->flags.reset_marker = FALSE;
for (bus = 0; bus < ha->ports; bus++) {
ha->bus_settings[bus].reset_marker = FALSE;
qla1280_marker(ha, bus, 0, 0,
MK_SYNC_ALL);
}
} while (ha->flags.reset_marker);
ha->flags.online = TRUE;
/* Enable host adapter target mode. */
for (bus = 0; bus < ha->ports; bus++) {
if (!(status = qla1280_enable_tgt(ha, bus))) {
#if 0
int cnt;
for (cnt = 0; cnt < MAX_LUNS; cnt++) {
qla1280_enable_lun(ha, bus,
cnt);
qla1280_poll(ha);
}
#endif
} else
break;
}
} else
status = 1;
} else
printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n",
ha->host_no);
if (status)
dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n");
LEAVE("qla1280_initialize_adapter");
return status;
}
/*
* qla1280_enable_tgt
* Enable target mode.
*
* Input:
* ha = adapter block pointer.
* bus = SCSI bus number.
*
* Returns:
* 0 = success.
*/
static int
qla1280_enable_tgt(struct scsi_qla_host *ha, int bus)
{
int status = 0;
/* uint16_t mb[MAILBOX_REGISTER_COUNT]; */
dprintk(3, "qla1280_enable_tgt: entered\n");
/* Enable target mode. */
#if 0
mb[0] = MBC_ENABLE_TARGET_MODE;
mb[1] = BIT_15;
mb[2] = (uint16_t) (bus << 15);
status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
#endif
if (status)
dprintk(2, "qla1280_enable_tgt: **** FAILED ****\n");
else
dprintk(3, "qla1280_enable_tgt: exiting normally\n");
return status;
}
/*
* ISP Firmware Test
* Checks if present version of RISC firmware is older than
* driver firmware.
*
* Input:
* ha = adapter block pointer.
*
* Returns:
* 0 = firmware does not need to be loaded.
*/
static int
qla1280_isp_firmware(struct scsi_qla_host *ha)
{
nvram_t *nv = (nvram_t *) ha->response_ring;
uint16_t *wptr;
int status = 0; /* dg 2/27 always loads RISC */
int cnt;
uint8_t chksum;
uint16_t mb[MAILBOX_REGISTER_COUNT];
ENTER("qla1280_isp_firmware");
/* Verify valid NVRAM checksum. */
wptr = (uint16_t *) ha->response_ring;
dprintk(1, "qla1280_isp_firmware: Reading NVRAM\n");
chksum = 0;
for (cnt = 0; cnt < sizeof(nvram_t) / 2; cnt++) {
*wptr = qla1280_get_nvram_word (ha, cnt);
chksum += (uint8_t) * wptr;
chksum += (uint8_t) (*wptr >> 8);
wptr++;
}
dprintk(1, "qla1280_isp_firmware: Completed Reading NVRAM\n");
dprintk(3, "qla1280_isp_firmware: NVRAM Magic ID= %c %c %c\n",
(char *)nv->id[0], nv->id[1], nv->id[2]);
/* Bad NVRAM data, load RISC code. */
if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1) {
printk(KERN_INFO "qla1280_isp_firmware: Bad checksum or magic "
"number or version in NVRAM.\n");
ha->flags.disable_risc_code_load = FALSE;
} else
ha->flags.disable_risc_code_load =
nv->cntr_flags_1.disable_loading_risc_code;
if (ha->flags.disable_risc_code_load) {
dprintk(3,
"qla1280_isp_firmware: Telling RISC to verify checksum "
"of loaded BIOS code.\n");
/* Verify checksum of loaded RISC code. */
mb[0] = MBC_VERIFY_CHECKSUM;
/* mb[1] = ql12_risc_code_addr01; */
mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
if (!
(status =
qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) {
/* Start firmware execution. */
dprintk(3, "qla1280_isp_firmware: Startng F/W "
"execution.\n");
mb[0] = MBC_EXECUTE_FIRMWARE;
/* mb[1] = ql12_risc_code_addr01; */
mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
} else
printk(KERN_INFO "qla1280: RISC checksum failed.\n");
} else {
dprintk(1, "qla1280: NVRAM configured to load RISC load.\n");
status = 1;
}
if (status)
dprintk(2, "qla1280_isp_firmware: **** Load RISC code ****\n");
LEAVE("qla1280_isp_firmware");
return status;
}
/*
* PCI configuration
* Setup device PCI configuration registers.
*
* Input:
* ha = adapter block pointer.
*
* Returns:
* 0 = success.
*/
static int
qla1280_pci_config(struct scsi_qla_host *ha)
{
#if MEMORY_MAPPED_IO
uint32_t page_offset, base;
uint32_t mmapbase;
#endif
uint16_t buf_wd;
int status = 1;
ENTER("qla1280_pci_config");
pci_set_master(ha->pdev);
/*
* Set Bus Master Enable, Memory Address Space Enable and
* reset any error bits, in the command register.
*/
pci_read_config_word (ha->pdev, PCI_COMMAND, &buf_wd);
#if MEMORY_MAPPED_IO
dprintk(1, "qla1280: MEMORY MAPPED IO is enabled.\n");
buf_wd |= PCI_COMMAND_MEMORY + PCI_COMMAND_IO;
#else
buf_wd |= PCI_COMMAND_IO;
#endif
pci_write_config_word (ha->pdev, PCI_COMMAND, buf_wd);
/*
* Reset expansion ROM address decode enable.
*/
pci_read_config_word (ha->pdev, PCI_ROM_ADDRESS, &buf_wd);
buf_wd &= ~PCI_ROM_ADDRESS_ENABLE;
pci_write_config_word (ha->pdev, PCI_ROM_ADDRESS, buf_wd);
ha->host->io_port = pci_resource_start(ha->pdev, 0);
ha->host->io_port &= PCI_BASE_ADDRESS_IO_MASK;
ha->iobase = (struct device_reg *) ha->host->io_port;
#if MEMORY_MAPPED_IO
/*
* Get memory mapped I/O address.
*/
pci_read_config_word (ha->pdev, PCI_BASE_ADDRESS_1, &mmapbase);
mmapbase &= PCI_BASE_ADDRESS_MEM_MASK;
/*
* Find proper memory chunk for memory map I/O reg.
*/
base = mmapbase & PAGE_MASK;
page_offset = mmapbase - base;
/*
* Get virtual address for I/O registers.
*/
ha->mmpbase = ioremap(base, page_offset + 256);
if (ha->mmpbase) {
ha->mmpbase += page_offset;
/* ha->iobase = ha->mmpbase; */
status = 0;
}
#else /* MEMORY_MAPPED_IO */
status = 0;
#endif /* MEMORY_MAPPED_IO */
LEAVE("qla1280_pci_config");
return status;
}
/*
* Chip diagnostics
* Test chip for proper operation.
*
* Input:
* ha = adapter block pointer.
*
* Returns:
* 0 = success.
*/
static int
qla1280_chip_diag(struct scsi_qla_host *ha)
{
uint16_t mb[MAILBOX_REGISTER_COUNT];
struct device_reg *reg = ha->iobase;
int status = 0;
int cnt;
uint16_t data;
dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", &reg->id_l);
/* Soft reset chip and wait for it to finish. */
WRT_REG_WORD(&reg->ictrl, ISP_RESET);
data = qla1280_debounce_register(&reg->ictrl);
/*
* This is *AWESOME*
*/
for (cnt = 6000000; cnt && data & ISP_RESET; cnt--) {
udelay(5);
data = RD_REG_WORD(&reg->ictrl);
}
if (cnt) {
/* Reset register not cleared by chip reset. */
dprintk(3,
"qla1280_chip_diag: reset register cleared by chip reset\n");
WRT_REG_WORD(&reg->cfg_1, 0);
/* Reset RISC and disable BIOS which
allows RISC to execute out of RAM. */
WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC);
WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
WRT_REG_WORD(&reg->host_cmd, HC_DISABLE_BIOS);
data = qla1280_debounce_register(&reg->mailbox0);
/*
* I *LOVE* this code!
*/
for (cnt = 6000000; cnt && data == MBS_BUSY; cnt--) {
udelay(5);
data = RD_REG_WORD(&reg->mailbox0);
}
if (cnt) {
/* Check product ID of chip */
dprintk(3,
"qla1280_chip_diag: Checking product ID of chip\n");
if (RD_REG_WORD(&reg->mailbox1) != PROD_ID_1 ||
(RD_REG_WORD(&reg->mailbox2) != PROD_ID_2 &&
RD_REG_WORD(&reg->mailbox2) != PROD_ID_2a) ||
RD_REG_WORD(&reg->mailbox3) != PROD_ID_3 ||
RD_REG_WORD(&reg->mailbox4) != PROD_ID_4) {
printk(KERN_INFO
"qla1280: Wrong product ID = 0x%x,0x%x,0x%x,"
"0x%x\n", RD_REG_WORD(&reg->mailbox1),
RD_REG_WORD(&reg->mailbox2),
RD_REG_WORD(&reg->mailbox3),
RD_REG_WORD(&reg->mailbox4));
status = 1;
} else {
/*
* Enable ints early!!!
*/
qla1280_enable_intrs(ha);
dprintk(1,
"qla1280_chip_diag: Checking mailboxes of chip\n");
/* Wrap Incoming Mailboxes Test. */
mb[0] = MBC_MAILBOX_REGISTER_TEST;
mb[1] = 0xAAAA;
mb[2] = 0x5555;
mb[3] = 0xAA55;
mb[4] = 0x55AA;
mb[5] = 0xA5A5;
mb[6] = 0x5A5A;
mb[7] = 0x2525;
if (!(status = qla1280_mailbox_command(ha,
BIT_7 |
BIT_6 |
BIT_5 |
BIT_4 |
BIT_3 |
BIT_2 |
BIT_1 |
BIT_0,
&mb
[0]))) {
if (mb[1] != 0xAAAA ||
mb[2] != 0x5555 ||
mb[3] != 0xAA55 ||
mb[4] != 0x55AA ||
mb[5] != 0xA5A5 ||
mb[6] != 0x5A5A ||
mb[7] != 0x2525)
status = 1;
if (status == 1)
printk(KERN_INFO
"qla1280: Failed mailbox check\n");
}
}
} else
status = 1;
} else
status = 1;
if (status)
dprintk(2, "qla1280_chip_diag: **** FAILED ****\n");
else
dprintk(3, "qla1280_chip_diag: exiting normally\n");
return status;
}
/*
* Setup chip
* Load and start RISC firmware.
*
* Input:
* ha = adapter block pointer.
*
* Returns:
* 0 = success.
*/
#define DUMP_IT_BACK 0 /* for debug of RISC loading */
static int
qla1280_setup_chip(struct scsi_qla_host *ha)
{
int status = 0;
uint16_t risc_address;
uint16_t *risc_code_address;
int risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT];
uint16_t cnt;
int num;
#if DUMP_IT_BACK
int i;
uint8_t *sp;
uint8_t *tbuf;
#ifdef QLA_64BIT_PTR
dma_addr_t p_tbuf;
#else
uint32_t p_tbuf;
#endif
#endif
ENTER("qla1280_setup_chip");
/* 3.13 */
#if DUMP_IT_BACK
/* get consistent memory allocated for setup_chip */
tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf);
#endif
/* Load RISC code. */
risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
risc_code_size = (int) *ql1280_board_tbl[ha->devnum].fwlen;
dprintk(1, "qla1280_setup_chip: DMA RISC code (%i) words\n",
risc_code_size);
num = 0;
while (risc_code_size > 0 && !status) {
cnt = 2000 >> 1;
if (cnt > risc_code_size)
cnt = risc_code_size;
dprintk(1, "qla1280_setup_chip: loading risc @ =(0x%p),"
"%d,%d(0x%x)\n",
risc_code_address, cnt, num, risc_address);
memcpy(ha->request_ring, risc_code_address, (cnt << 1));
flush_cache_all();
mb[0] = MBC_LOAD_RAM;
mb[1] = risc_address;
mb[4] = cnt;
mb[3] = ha->request_dma & 0xffff;
mb[2] = (ha->request_dma >> 16) & 0xffff;
mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff;
mb[6] = pci_dma_hi32(ha->request_dma) >> 16;
dprintk(1, "qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x,"
"0x%4x,0x%4x\n",
mb[0], ha->request_dma, mb[6], mb[7], mb[2], mb[3]);
if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 |
BIT_2 | BIT_1 | BIT_0,
&mb[0]))) {
printk(KERN_ERR
"Failed to load partial segment of f/w\n");
break;
}
#if DUMP_IT_BACK
mb[0] = MBC_READ_RAM_WORD;
mb[1] = risc_address;
mb[4] = cnt;
mb[3] = p_tbuf & 0xffff;
mb[2] = (p_tbuf >> 16) & 0xffff;
mb[7] = pci_dma_hi32(p_tbuf) &