Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (74 commits) [SCSI] sg: fix q->queue_lock on scsi_error_handler path [SCSI] replace __inline with inline [SCSI] a2091: make 2 functions static [SCSI] a3000: make 2 functions static [SCSI] ses: #if 0 the unused ses_match_host() [SCSI] use kmem_cache_zalloc instead of kmem_cache_alloc/memset [SCSI] sg: fix iovec bugs introduced by the block layer conversion [SCSI] qlogicpti: use request_firmware [SCSI] advansys: use request_firmware [SCSI] qla1280: use request_firmware [SCSI] libiscsi: fix iscsi pool error path [SCSI] cxgb3i: call ddp release function directly [SCSI] cxgb3i: merge cxgb3i_ddp into cxgb3i module [SCSI] cxgb3i: close all tcp connections upon chip reset [SCSI] cxgb3i: re-read ddp settings information after chip reset [SCSI] cxgb3i: re-initialize ddp settings after chip reset [SCSI] cxgb3i: subscribe to error notification from cxgb3 driver [SCSI] aacraid driver update [SCSI] mptsas: remove unneeded check [SCSI] config: Make need for SCSI_CDROM clearer ...
This commit is contained in:
commit
22eb5aa6c7
@ -60,17 +60,9 @@ Supported Cards/Chipsets
|
||||
9005:0285:9005:02d5 Adaptec ASR-2405 (Voodoo40 Lite)
|
||||
9005:0285:9005:02d6 Adaptec ASR-2445 (Voodoo44 Lite)
|
||||
9005:0285:9005:02d7 Adaptec ASR-2805 (Voodoo80 Lite)
|
||||
9005:0285:9005:02d8 Adaptec 5405G (Voodoo40 PM)
|
||||
9005:0285:9005:02d9 Adaptec 5445G (Voodoo44 PM)
|
||||
9005:0285:9005:02da Adaptec 5805G (Voodoo80 PM)
|
||||
9005:0285:9005:02db Adaptec 5085G (Voodoo08 PM)
|
||||
9005:0285:9005:02dc Adaptec 51245G (Voodoo124 PM)
|
||||
9005:0285:9005:02dd Adaptec 51645G (Voodoo164 PM)
|
||||
9005:0285:9005:02de Adaptec 52445G (Voodoo244 PM)
|
||||
9005:0285:9005:02df Adaptec ASR-2045G (Voodoo04 Lite PM)
|
||||
9005:0285:9005:02e0 Adaptec ASR-2405G (Voodoo40 Lite PM)
|
||||
9005:0285:9005:02e1 Adaptec ASR-2445G (Voodoo44 Lite PM)
|
||||
9005:0285:9005:02e2 Adaptec ASR-2805G (Voodoo80 Lite PM)
|
||||
9005:0285:9005:02d8 Adaptec 5405Z (Voodoo40 BLBU)
|
||||
9005:0285:9005:02d9 Adaptec 5445Z (Voodoo44 BLBU)
|
||||
9005:0285:9005:02da Adaptec 5805Z (Voodoo80 BLBU)
|
||||
1011:0046:9005:0364 Adaptec 5400S (Mustang)
|
||||
1011:0046:9005:0365 Adaptec 5400S (Mustang)
|
||||
9005:0287:9005:0800 Adaptec Themisto (Jupiter)
|
||||
@ -140,6 +132,7 @@ Deanna Bonds (non-DASD support, PAE fibs and 64 bit,
|
||||
where fibs that go to the hardware are consistently called hw_fibs and
|
||||
not just fibs like the name of the driver tracking structure)
|
||||
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
|
||||
Achim Leubner <Achim_Leubner@adaptec.com>
|
||||
|
||||
Original Driver
|
||||
-------------------------
|
||||
|
@ -2279,9 +2279,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
|
||||
mutex_lock(&ioc->sas_topology_mutex);
|
||||
list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
|
||||
|
||||
if (port_info->phy_info &&
|
||||
(!(port_info->phy_info[0].identify.device_info &
|
||||
MPI_SAS_DEVICE_INFO_SMP_TARGET)))
|
||||
if (!(port_info->phy_info[0].identify.device_info &
|
||||
MPI_SAS_DEVICE_INFO_SMP_TARGET))
|
||||
continue;
|
||||
|
||||
if (mptsas_sas_expander_pg0(ioc, &buffer,
|
||||
|
@ -121,10 +121,11 @@ config BLK_DEV_SR
|
||||
tristate "SCSI CDROM support"
|
||||
depends on SCSI
|
||||
---help---
|
||||
If you want to use a SCSI or FireWire CD-ROM under Linux,
|
||||
say Y and read the SCSI-HOWTO and the CDROM-HOWTO at
|
||||
<http://www.tldp.org/docs.html#howto>. Also make sure to say
|
||||
Y or M to "ISO 9660 CD-ROM file system support" later.
|
||||
If you want to use a CD or DVD drive attached to your computer
|
||||
by SCSI, FireWire, USB or ATAPI, say Y and read the SCSI-HOWTO
|
||||
and the CDROM-HOWTO at <http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
Make sure to say Y or M to "ISO 9660 CD-ROM file system support".
|
||||
|
||||
To compile this driver as a module, choose M here and read
|
||||
<file:Documentation/scsi/scsi.txt>.
|
||||
@ -614,10 +615,16 @@ config LIBFC
|
||||
---help---
|
||||
Fibre Channel library module
|
||||
|
||||
config LIBFCOE
|
||||
tristate "LibFCoE module"
|
||||
select LIBFC
|
||||
---help---
|
||||
Library for Fibre Channel over Ethernet module
|
||||
|
||||
config FCOE
|
||||
tristate "FCoE module"
|
||||
depends on PCI
|
||||
select LIBFC
|
||||
select LIBFCOE
|
||||
---help---
|
||||
Fibre Channel over Ethernet module
|
||||
|
||||
|
@ -37,6 +37,7 @@ obj-$(CONFIG_SCSI_SRP_ATTRS) += scsi_transport_srp.o
|
||||
obj-$(CONFIG_SCSI_DH) += device_handler/
|
||||
|
||||
obj-$(CONFIG_LIBFC) += libfc/
|
||||
obj-$(CONFIG_LIBFCOE) += fcoe/
|
||||
obj-$(CONFIG_FCOE) += fcoe/
|
||||
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o
|
||||
obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o
|
||||
|
@ -23,6 +23,8 @@
|
||||
#define DMA(ptr) ((a2091_scsiregs *)((ptr)->base))
|
||||
#define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
|
||||
|
||||
static int a2091_release(struct Scsi_Host *instance);
|
||||
|
||||
static irqreturn_t a2091_intr (int irq, void *_instance)
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -144,7 +146,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
|
||||
}
|
||||
}
|
||||
|
||||
int __init a2091_detect(struct scsi_host_template *tpnt)
|
||||
static int __init a2091_detect(struct scsi_host_template *tpnt)
|
||||
{
|
||||
static unsigned char called = 0;
|
||||
struct Scsi_Host *instance;
|
||||
@ -233,7 +235,7 @@ static struct scsi_host_template driver_template = {
|
||||
|
||||
#include "scsi_module.c"
|
||||
|
||||
int a2091_release(struct Scsi_Host *instance)
|
||||
static int a2091_release(struct Scsi_Host *instance)
|
||||
{
|
||||
#ifdef MODULE
|
||||
DMA(instance)->CNTR = 0;
|
||||
|
@ -11,9 +11,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
int a2091_detect(struct scsi_host_template *);
|
||||
int a2091_release(struct Scsi_Host *);
|
||||
|
||||
#ifndef CMD_PER_LUN
|
||||
#define CMD_PER_LUN 2
|
||||
#endif
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
static struct Scsi_Host *a3000_host = NULL;
|
||||
|
||||
static int a3000_release(struct Scsi_Host *instance);
|
||||
|
||||
static irqreturn_t a3000_intr (int irq, void *dummy)
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -157,7 +159,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
|
||||
}
|
||||
}
|
||||
|
||||
int __init a3000_detect(struct scsi_host_template *tpnt)
|
||||
static int __init a3000_detect(struct scsi_host_template *tpnt)
|
||||
{
|
||||
wd33c93_regs regs;
|
||||
|
||||
@ -232,7 +234,7 @@ static struct scsi_host_template driver_template = {
|
||||
|
||||
#include "scsi_module.c"
|
||||
|
||||
int a3000_release(struct Scsi_Host *instance)
|
||||
static int a3000_release(struct Scsi_Host *instance)
|
||||
{
|
||||
wd33c93_release();
|
||||
DMA(instance)->CNTR = 0;
|
||||
|
@ -11,9 +11,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
int a3000_detect(struct scsi_host_template *);
|
||||
int a3000_release(struct Scsi_Host *);
|
||||
|
||||
#ifndef CMD_PER_LUN
|
||||
#define CMD_PER_LUN 2
|
||||
#endif
|
||||
|
@ -143,7 +143,7 @@ static char *aac_get_status_string(u32 status);
|
||||
*/
|
||||
|
||||
static int nondasd = -1;
|
||||
static int aac_cache;
|
||||
static int aac_cache = 2; /* WCE=0 to avoid performance problems */
|
||||
static int dacmode = -1;
|
||||
int aac_msi;
|
||||
int aac_commit = -1;
|
||||
@ -157,7 +157,7 @@ module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n"
|
||||
"\tbit 0 - Disable FUA in WRITE SCSI commands\n"
|
||||
"\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n"
|
||||
"\tbit 2 - Disable only if Battery not protecting Cache");
|
||||
"\tbit 2 - Disable only if Battery is protecting Cache");
|
||||
module_param(dacmode, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC."
|
||||
" 0=off, 1=on");
|
||||
@ -217,6 +217,14 @@ int aac_reset_devices;
|
||||
module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
|
||||
|
||||
int aac_wwn = 1;
|
||||
module_param_named(wwn, aac_wwn, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(wwn, "Select a WWN type for the arrays:\n"
|
||||
"\t0 - Disable\n"
|
||||
"\t1 - Array Meta Data Signature (default)\n"
|
||||
"\t2 - Adapter Serial Number");
|
||||
|
||||
|
||||
static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
|
||||
struct fib *fibptr) {
|
||||
struct scsi_device *device;
|
||||
@ -1206,9 +1214,8 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
|
||||
|
||||
static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
|
||||
{
|
||||
if ((sizeof(dma_addr_t) > 4) &&
|
||||
(num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
|
||||
(fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
|
||||
if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&
|
||||
(fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
|
||||
return FAILED;
|
||||
return aac_scsi_32(fib, cmd);
|
||||
}
|
||||
@ -1371,8 +1378,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
|
||||
if (dev->nondasd_support && !dev->in_reset)
|
||||
printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
|
||||
|
||||
if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK)
|
||||
dev->needs_dac = 1;
|
||||
dev->dac_support = 0;
|
||||
if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
|
||||
if ((sizeof(dma_addr_t) > 4) && dev->needs_dac &&
|
||||
(dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
|
||||
if (!dev->in_reset)
|
||||
printk(KERN_INFO "%s%d: 64bit support enabled.\n",
|
||||
dev->name, dev->id);
|
||||
@ -1382,6 +1392,15 @@ int aac_get_adapter_info(struct aac_dev* dev)
|
||||
if(dacmode != -1) {
|
||||
dev->dac_support = (dacmode!=0);
|
||||
}
|
||||
|
||||
/* avoid problems with AAC_QUIRK_SCSI_32 controllers */
|
||||
if (dev->dac_support && (aac_get_driver_ident(dev->cardtype)->quirks
|
||||
& AAC_QUIRK_SCSI_32)) {
|
||||
dev->nondasd_support = 0;
|
||||
dev->jbod = 0;
|
||||
expose_physicals = 0;
|
||||
}
|
||||
|
||||
if(dev->dac_support != 0) {
|
||||
if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
|
||||
!pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
|
||||
@ -2058,7 +2077,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
|
||||
memset(&inq_data, 0, sizeof (struct inquiry_data));
|
||||
|
||||
if (scsicmd->cmnd[1] & 0x1) {
|
||||
if ((scsicmd->cmnd[1] & 0x1) && aac_wwn) {
|
||||
char *arr = (char *)&inq_data;
|
||||
|
||||
/* EVPD bit set */
|
||||
@ -2081,7 +2100,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
arr[1] = scsicmd->cmnd[2];
|
||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||
sizeof(inq_data));
|
||||
return aac_get_container_serial(scsicmd);
|
||||
if (aac_wwn != 2)
|
||||
return aac_get_container_serial(
|
||||
scsicmd);
|
||||
/* SLES 10 SP1 special */
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
} else {
|
||||
/* vpd page not implemented */
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
|
@ -12,7 +12,7 @@
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef AAC_DRIVER_BUILD
|
||||
# define AAC_DRIVER_BUILD 2456
|
||||
# define AAC_DRIVER_BUILD 2461
|
||||
# define AAC_DRIVER_BRANCH "-ms"
|
||||
#endif
|
||||
#define MAXIMUM_NUM_CONTAINERS 32
|
||||
@ -865,7 +865,11 @@ struct aac_supplement_adapter_info
|
||||
u8 MfgPcbaSerialNo[12];
|
||||
u8 MfgWWNName[8];
|
||||
__le32 SupportedOptions2;
|
||||
__le32 ReservedGrowth[1];
|
||||
__le32 StructExpansion;
|
||||
/* StructExpansion == 1 */
|
||||
__le32 FeatureBits3;
|
||||
__le32 SupportedPerformanceModes;
|
||||
__le32 ReservedForFutureGrowth[80];
|
||||
};
|
||||
#define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
|
||||
#define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
|
||||
@ -1020,6 +1024,7 @@ struct aac_dev
|
||||
u8 jbod;
|
||||
u8 cache_protected;
|
||||
u8 dac_support;
|
||||
u8 needs_dac;
|
||||
u8 raid_scsi_mode;
|
||||
u8 comm_interface;
|
||||
# define AAC_COMM_PRODUCER 0
|
||||
|
@ -54,6 +54,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
const unsigned long printfbufsiz = 256;
|
||||
struct aac_init *init;
|
||||
dma_addr_t phys;
|
||||
unsigned long aac_max_hostphysmempages;
|
||||
|
||||
size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
|
||||
|
||||
@ -90,7 +91,18 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
||||
init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
|
||||
init->AdapterFibsSize = cpu_to_le32(fibsize);
|
||||
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
|
||||
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
|
||||
/*
|
||||
* number of 4k pages of host physical memory. The aacraid fw needs
|
||||
* this number to be less than 4gb worth of pages. New firmware doesn't
|
||||
* have any issues with the mapping system, but older Firmware did, and
|
||||
* had *troubles* dealing with the math overloading past 32 bits, thus
|
||||
* we must limit this field.
|
||||
*/
|
||||
aac_max_hostphysmempages = dma_get_required_mask(&dev->pdev->dev) >> 12;
|
||||
if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
|
||||
init->HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
|
||||
else
|
||||
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
|
||||
|
||||
init->InitFlags = 0;
|
||||
if (dev->comm_interface == AAC_COMM_MESSAGE) {
|
||||
|
@ -86,7 +86,13 @@ char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
|
||||
*
|
||||
* Note: The last field is used to index into aac_drivers below.
|
||||
*/
|
||||
static struct pci_device_id aac_pci_tbl[] = {
|
||||
#ifdef DECLARE_PCI_DEVICE_TABLE
|
||||
static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
|
||||
#elif defined(__devinitconst)
|
||||
static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
|
||||
#else
|
||||
static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
|
||||
#endif
|
||||
{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
|
||||
{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
|
||||
{ 0x1028, 0x0003, 0x1028, 0x0003, 0, 0, 2 }, /* PERC 3/Si (SlimFast/PERC3Si */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1034,7 +1034,7 @@ ahd_intr(struct ahd_softc *ahd)
|
||||
}
|
||||
|
||||
/******************************** Private Inlines *****************************/
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_assert_atn(struct ahd_softc *ahd)
|
||||
{
|
||||
ahd_outb(ahd, SCSISIGO, ATNO);
|
||||
@ -1069,7 +1069,7 @@ ahd_currently_packetized(struct ahd_softc *ahd)
|
||||
return (packetized);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
static inline int
|
||||
ahd_set_active_fifo(struct ahd_softc *ahd)
|
||||
{
|
||||
u_int active_fifo;
|
||||
@ -1086,7 +1086,7 @@ ahd_set_active_fifo(struct ahd_softc *ahd)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
|
||||
{
|
||||
ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
|
||||
@ -1096,7 +1096,7 @@ ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
|
||||
* Determine whether the sequencer reported a residual
|
||||
* for this SCB/transaction.
|
||||
*/
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
|
||||
{
|
||||
uint32_t sgptr;
|
||||
@ -1106,7 +1106,7 @@ ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
|
||||
ahd_calc_residual(ahd, scb);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb)
|
||||
{
|
||||
uint32_t sgptr;
|
||||
@ -7987,7 +7987,7 @@ ahd_resume(struct ahd_softc *ahd)
|
||||
* scbid that should be restored once manipualtion
|
||||
* of the TCL entry is complete.
|
||||
*/
|
||||
static __inline u_int
|
||||
static inline u_int
|
||||
ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
|
||||
{
|
||||
/*
|
||||
|
@ -46,21 +46,20 @@
|
||||
#define _AIC79XX_INLINE_H_
|
||||
|
||||
/******************************** Debugging ***********************************/
|
||||
static __inline char *ahd_name(struct ahd_softc *ahd);
|
||||
static inline char *ahd_name(struct ahd_softc *ahd);
|
||||
|
||||
static __inline char *
|
||||
ahd_name(struct ahd_softc *ahd)
|
||||
static inline char *ahd_name(struct ahd_softc *ahd)
|
||||
{
|
||||
return (ahd->name);
|
||||
}
|
||||
|
||||
/************************ Sequencer Execution Control *************************/
|
||||
static __inline void ahd_known_modes(struct ahd_softc *ahd,
|
||||
static inline void ahd_known_modes(struct ahd_softc *ahd,
|
||||
ahd_mode src, ahd_mode dst);
|
||||
static __inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd,
|
||||
static inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd,
|
||||
ahd_mode src,
|
||||
ahd_mode dst);
|
||||
static __inline void ahd_extract_mode_state(struct ahd_softc *ahd,
|
||||
static inline void ahd_extract_mode_state(struct ahd_softc *ahd,
|
||||
ahd_mode_state state,
|
||||
ahd_mode *src, ahd_mode *dst);
|
||||
|
||||
@ -73,7 +72,7 @@ int ahd_is_paused(struct ahd_softc *ahd);
|
||||
void ahd_pause(struct ahd_softc *ahd);
|
||||
void ahd_unpause(struct ahd_softc *ahd);
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
|
||||
{
|
||||
ahd->src_mode = src;
|
||||
@ -82,13 +81,13 @@ ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
|
||||
ahd->saved_dst_mode = dst;
|
||||
}
|
||||
|
||||
static __inline ahd_mode_state
|
||||
static inline ahd_mode_state
|
||||
ahd_build_mode_state(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
|
||||
{
|
||||
return ((src << SRC_MODE_SHIFT) | (dst << DST_MODE_SHIFT));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_extract_mode_state(struct ahd_softc *ahd, ahd_mode_state state,
|
||||
ahd_mode *src, ahd_mode *dst)
|
||||
{
|
||||
@ -102,13 +101,12 @@ void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb,
|
||||
bus_size_t len, int last);
|
||||
|
||||
/************************** Memory mapping routines ***************************/
|
||||
static __inline size_t ahd_sg_size(struct ahd_softc *ahd);
|
||||
static inline size_t ahd_sg_size(struct ahd_softc *ahd);
|
||||
|
||||
void ahd_sync_sglist(struct ahd_softc *ahd,
|
||||
struct scb *scb, int op);
|
||||
|
||||
static __inline size_t
|
||||
ahd_sg_size(struct ahd_softc *ahd)
|
||||
static inline size_t ahd_sg_size(struct ahd_softc *ahd)
|
||||
{
|
||||
if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
|
||||
return (sizeof(struct ahd_dma64_seg));
|
||||
@ -141,11 +139,9 @@ struct scb *
|
||||
ahd_lookup_scb(struct ahd_softc *ahd, u_int tag);
|
||||
void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb);
|
||||
|
||||
static __inline uint8_t *
|
||||
ahd_get_sense_buf(struct ahd_softc *ahd,
|
||||
static inline uint8_t *ahd_get_sense_buf(struct ahd_softc *ahd,
|
||||
struct scb *scb);
|
||||
static __inline uint32_t
|
||||
ahd_get_sense_bufaddr(struct ahd_softc *ahd,
|
||||
static inline uint32_t ahd_get_sense_bufaddr(struct ahd_softc *ahd,
|
||||
struct scb *scb);
|
||||
|
||||
#if 0 /* unused */
|
||||
@ -158,13 +154,13 @@ do { \
|
||||
|
||||
#endif
|
||||
|
||||
static __inline uint8_t *
|
||||
static inline uint8_t *
|
||||
ahd_get_sense_buf(struct ahd_softc *ahd, struct scb *scb)
|
||||
{
|
||||
return (scb->sense_data);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
static inline uint32_t
|
||||
ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb)
|
||||
{
|
||||
return (scb->sense_busaddr);
|
||||
|
@ -395,19 +395,19 @@ struct info_str {
|
||||
};
|
||||
|
||||
/******************************** Locking *************************************/
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_lockinit(struct ahd_softc *ahd)
|
||||
{
|
||||
spin_lock_init(&ahd->platform_data->spin_lock);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
|
||||
{
|
||||
spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
|
||||
{
|
||||
spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
|
||||
@ -490,29 +490,29 @@ void ahd_pci_write_config(ahd_dev_softc_t pci,
|
||||
int reg, uint32_t value,
|
||||
int width);
|
||||
|
||||
static __inline int ahd_get_pci_function(ahd_dev_softc_t);
|
||||
static __inline int
|
||||
static inline int ahd_get_pci_function(ahd_dev_softc_t);
|
||||
static inline int
|
||||
ahd_get_pci_function(ahd_dev_softc_t pci)
|
||||
{
|
||||
return (PCI_FUNC(pci->devfn));
|
||||
}
|
||||
|
||||
static __inline int ahd_get_pci_slot(ahd_dev_softc_t);
|
||||
static __inline int
|
||||
static inline int ahd_get_pci_slot(ahd_dev_softc_t);
|
||||
static inline int
|
||||
ahd_get_pci_slot(ahd_dev_softc_t pci)
|
||||
{
|
||||
return (PCI_SLOT(pci->devfn));
|
||||
}
|
||||
|
||||
static __inline int ahd_get_pci_bus(ahd_dev_softc_t);
|
||||
static __inline int
|
||||
static inline int ahd_get_pci_bus(ahd_dev_softc_t);
|
||||
static inline int
|
||||
ahd_get_pci_bus(ahd_dev_softc_t pci)
|
||||
{
|
||||
return (pci->bus->number);
|
||||
}
|
||||
|
||||
static __inline void ahd_flush_device_writes(struct ahd_softc *);
|
||||
static __inline void
|
||||
static inline void ahd_flush_device_writes(struct ahd_softc *);
|
||||
static inline void
|
||||
ahd_flush_device_writes(struct ahd_softc *ahd)
|
||||
{
|
||||
/* XXX Is this sufficient for all architectures??? */
|
||||
@ -524,81 +524,81 @@ int ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
|
||||
off_t, int, int);
|
||||
|
||||
/*********************** Transaction Access Wrappers **************************/
|
||||
static __inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
|
||||
static __inline void ahd_set_transaction_status(struct scb *, uint32_t);
|
||||
static __inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
|
||||
static __inline void ahd_set_scsi_status(struct scb *, uint32_t);
|
||||
static __inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
|
||||
static __inline uint32_t ahd_get_transaction_status(struct scb *);
|
||||
static __inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
|
||||
static __inline uint32_t ahd_get_scsi_status(struct scb *);
|
||||
static __inline void ahd_set_transaction_tag(struct scb *, int, u_int);
|
||||
static __inline u_long ahd_get_transfer_length(struct scb *);
|
||||
static __inline int ahd_get_transfer_dir(struct scb *);
|
||||
static __inline void ahd_set_residual(struct scb *, u_long);
|
||||
static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
|
||||
static __inline u_long ahd_get_residual(struct scb *);
|
||||
static __inline u_long ahd_get_sense_residual(struct scb *);
|
||||
static __inline int ahd_perform_autosense(struct scb *);
|
||||
static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
|
||||
static inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
|
||||
static inline void ahd_set_transaction_status(struct scb *, uint32_t);
|
||||
static inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
|
||||
static inline void ahd_set_scsi_status(struct scb *, uint32_t);
|
||||
static inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
|
||||
static inline uint32_t ahd_get_transaction_status(struct scb *);
|
||||
static inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
|
||||
static inline uint32_t ahd_get_scsi_status(struct scb *);
|
||||
static inline void ahd_set_transaction_tag(struct scb *, int, u_int);
|
||||
static inline u_long ahd_get_transfer_length(struct scb *);
|
||||
static inline int ahd_get_transfer_dir(struct scb *);
|
||||
static inline void ahd_set_residual(struct scb *, u_long);
|
||||
static inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
|
||||
static inline u_long ahd_get_residual(struct scb *);
|
||||
static inline u_long ahd_get_sense_residual(struct scb *);
|
||||
static inline int ahd_perform_autosense(struct scb *);
|
||||
static inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
|
||||
struct scb *);
|
||||
static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
|
||||
static inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
|
||||
struct ahd_devinfo *);
|
||||
static __inline void ahd_platform_scb_free(struct ahd_softc *ahd,
|
||||
static inline void ahd_platform_scb_free(struct ahd_softc *ahd,
|
||||
struct scb *scb);
|
||||
static __inline void ahd_freeze_scb(struct scb *scb);
|
||||
static inline void ahd_freeze_scb(struct scb *scb);
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||
{
|
||||
cmd->result &= ~(CAM_STATUS_MASK << 16);
|
||||
cmd->result |= status << 16;
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahd_set_transaction_status(struct scb *scb, uint32_t status)
|
||||
{
|
||||
ahd_cmd_set_transaction_status(scb->io_ctx,status);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahd_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||
{
|
||||
cmd->result &= ~0xFFFF;
|
||||
cmd->result |= status;
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahd_set_scsi_status(struct scb *scb, uint32_t status)
|
||||
{
|
||||
ahd_cmd_set_scsi_status(scb->io_ctx, status);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return ((cmd->result >> 16) & CAM_STATUS_MASK);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
uint32_t ahd_get_transaction_status(struct scb *scb)
|
||||
{
|
||||
return (ahd_cmd_get_transaction_status(scb->io_ctx));
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return (cmd->result & 0xFFFF);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
uint32_t ahd_get_scsi_status(struct scb *scb)
|
||||
{
|
||||
return (ahd_cmd_get_scsi_status(scb->io_ctx));
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
|
||||
{
|
||||
/*
|
||||
@ -607,43 +607,43 @@ void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
|
||||
*/
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
u_long ahd_get_transfer_length(struct scb *scb)
|
||||
{
|
||||
return (scb->platform_data->xfer_len);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
int ahd_get_transfer_dir(struct scb *scb)
|
||||
{
|
||||
return (scb->io_ctx->sc_data_direction);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahd_set_residual(struct scb *scb, u_long resid)
|
||||
{
|
||||
scsi_set_resid(scb->io_ctx, resid);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahd_set_sense_residual(struct scb *scb, u_long resid)
|
||||
{
|
||||
scb->platform_data->sense_resid = resid;
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
u_long ahd_get_residual(struct scb *scb)
|
||||
{
|
||||
return scsi_get_resid(scb->io_ctx);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
u_long ahd_get_sense_residual(struct scb *scb)
|
||||
{
|
||||
return (scb->platform_data->sense_resid);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
int ahd_perform_autosense(struct scb *scb)
|
||||
{
|
||||
/*
|
||||
@ -654,20 +654,20 @@ int ahd_perform_autosense(struct scb *scb)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
static inline uint32_t
|
||||
ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb)
|
||||
{
|
||||
return (sizeof(struct scsi_sense_data));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_notify_xfer_settings_change(struct ahd_softc *ahd,
|
||||
struct ahd_devinfo *devinfo)
|
||||
{
|
||||
/* Nothing to do here for linux */
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb)
|
||||
{
|
||||
ahd->flags &= ~AHD_RESOURCE_SHORTAGE;
|
||||
@ -678,7 +678,7 @@ void ahd_platform_free(struct ahd_softc *ahd);
|
||||
void ahd_platform_init(struct ahd_softc *ahd);
|
||||
void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahd_freeze_scb(struct scb *scb)
|
||||
{
|
||||
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
|
||||
|
@ -51,7 +51,7 @@
|
||||
|
||||
#include "aic79xx_pci.h"
|
||||
|
||||
static __inline uint64_t
|
||||
static inline uint64_t
|
||||
ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
|
||||
{
|
||||
uint64_t id;
|
||||
@ -377,14 +377,12 @@ ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
|
||||
error = ahd_init(ahd);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
ahd->init_level++;
|
||||
|
||||
/*
|
||||
* Allow interrupts now that we are completely setup.
|
||||
*/
|
||||
error = ahd_pci_map_int(ahd);
|
||||
if (!error)
|
||||
ahd->init_level++;
|
||||
return error;
|
||||
return ahd_pci_map_int(ahd);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -55,10 +55,9 @@ void ahc_sync_sglist(struct ahc_softc *ahc,
|
||||
struct scb *scb, int op);
|
||||
|
||||
/******************************** Debugging ***********************************/
|
||||
static __inline char *ahc_name(struct ahc_softc *ahc);
|
||||
static inline char *ahc_name(struct ahc_softc *ahc);
|
||||
|
||||
static __inline char *
|
||||
ahc_name(struct ahc_softc *ahc)
|
||||
static inline char *ahc_name(struct ahc_softc *ahc)
|
||||
{
|
||||
return (ahc->name);
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
|
||||
#include "aic7xxx.h"
|
||||
|
||||
/***************************** Timer Facilities *******************************/
|
||||
static __inline void
|
||||
static inline void
|
||||
ahc_scb_timer_reset(struct scb *scb, u_int usec)
|
||||
{
|
||||
}
|
||||
@ -401,19 +401,19 @@ struct info_str {
|
||||
/******************************** Locking *************************************/
|
||||
/* Lock protecting internal data structures */
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahc_lockinit(struct ahc_softc *ahc)
|
||||
{
|
||||
spin_lock_init(&ahc->platform_data->spin_lock);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
|
||||
{
|
||||
spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
|
||||
{
|
||||
spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
|
||||
@ -493,22 +493,22 @@ void ahc_pci_write_config(ahc_dev_softc_t pci,
|
||||
int reg, uint32_t value,
|
||||
int width);
|
||||
|
||||
static __inline int ahc_get_pci_function(ahc_dev_softc_t);
|
||||
static __inline int
|
||||
static inline int ahc_get_pci_function(ahc_dev_softc_t);
|
||||
static inline int
|
||||
ahc_get_pci_function(ahc_dev_softc_t pci)
|
||||
{
|
||||
return (PCI_FUNC(pci->devfn));
|
||||
}
|
||||
|
||||
static __inline int ahc_get_pci_slot(ahc_dev_softc_t);
|
||||
static __inline int
|
||||
static inline int ahc_get_pci_slot(ahc_dev_softc_t);
|
||||
static inline int
|
||||
ahc_get_pci_slot(ahc_dev_softc_t pci)
|
||||
{
|
||||
return (PCI_SLOT(pci->devfn));
|
||||
}
|
||||
|
||||
static __inline int ahc_get_pci_bus(ahc_dev_softc_t);
|
||||
static __inline int
|
||||
static inline int ahc_get_pci_bus(ahc_dev_softc_t);
|
||||
static inline int
|
||||
ahc_get_pci_bus(ahc_dev_softc_t pci)
|
||||
{
|
||||
return (pci->bus->number);
|
||||
@ -521,8 +521,8 @@ static inline void ahc_linux_pci_exit(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline void ahc_flush_device_writes(struct ahc_softc *);
|
||||
static __inline void
|
||||
static inline void ahc_flush_device_writes(struct ahc_softc *);
|
||||
static inline void
|
||||
ahc_flush_device_writes(struct ahc_softc *ahc)
|
||||
{
|
||||
/* XXX Is this sufficient for all architectures??? */
|
||||
@ -535,81 +535,81 @@ int ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
|
||||
|
||||
/*************************** Domain Validation ********************************/
|
||||
/*********************** Transaction Access Wrappers *************************/
|
||||
static __inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
|
||||
static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
|
||||
static __inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
|
||||
static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
|
||||
static __inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
|
||||
static __inline uint32_t ahc_get_transaction_status(struct scb *);
|
||||
static __inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
|
||||
static __inline uint32_t ahc_get_scsi_status(struct scb *);
|
||||
static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
|
||||
static __inline u_long ahc_get_transfer_length(struct scb *);
|
||||
static __inline int ahc_get_transfer_dir(struct scb *);
|
||||
static __inline void ahc_set_residual(struct scb *, u_long);
|
||||
static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
|
||||
static __inline u_long ahc_get_residual(struct scb *);
|
||||
static __inline u_long ahc_get_sense_residual(struct scb *);
|
||||
static __inline int ahc_perform_autosense(struct scb *);
|
||||
static __inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
|
||||
static inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
|
||||
static inline void ahc_set_transaction_status(struct scb *, uint32_t);
|
||||
static inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
|
||||
static inline void ahc_set_scsi_status(struct scb *, uint32_t);
|
||||
static inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
|
||||
static inline uint32_t ahc_get_transaction_status(struct scb *);
|
||||
static inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
|
||||
static inline uint32_t ahc_get_scsi_status(struct scb *);
|
||||
static inline void ahc_set_transaction_tag(struct scb *, int, u_int);
|
||||
static inline u_long ahc_get_transfer_length(struct scb *);
|
||||
static inline int ahc_get_transfer_dir(struct scb *);
|
||||
static inline void ahc_set_residual(struct scb *, u_long);
|
||||
static inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
|
||||
static inline u_long ahc_get_residual(struct scb *);
|
||||
static inline u_long ahc_get_sense_residual(struct scb *);
|
||||
static inline int ahc_perform_autosense(struct scb *);
|
||||
static inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
|
||||
struct scb *);
|
||||
static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
|
||||
static inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
|
||||
struct ahc_devinfo *);
|
||||
static __inline void ahc_platform_scb_free(struct ahc_softc *ahc,
|
||||
static inline void ahc_platform_scb_free(struct ahc_softc *ahc,
|
||||
struct scb *scb);
|
||||
static __inline void ahc_freeze_scb(struct scb *scb);
|
||||
static inline void ahc_freeze_scb(struct scb *scb);
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||
{
|
||||
cmd->result &= ~(CAM_STATUS_MASK << 16);
|
||||
cmd->result |= status << 16;
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahc_set_transaction_status(struct scb *scb, uint32_t status)
|
||||
{
|
||||
ahc_cmd_set_transaction_status(scb->io_ctx,status);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||
{
|
||||
cmd->result &= ~0xFFFF;
|
||||
cmd->result |= status;
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahc_set_scsi_status(struct scb *scb, uint32_t status)
|
||||
{
|
||||
ahc_cmd_set_scsi_status(scb->io_ctx, status);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return ((cmd->result >> 16) & CAM_STATUS_MASK);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
uint32_t ahc_get_transaction_status(struct scb *scb)
|
||||
{
|
||||
return (ahc_cmd_get_transaction_status(scb->io_ctx));
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return (cmd->result & 0xFFFF);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
uint32_t ahc_get_scsi_status(struct scb *scb)
|
||||
{
|
||||
return (ahc_cmd_get_scsi_status(scb->io_ctx));
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
|
||||
{
|
||||
/*
|
||||
@ -618,43 +618,43 @@ void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
|
||||
*/
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
u_long ahc_get_transfer_length(struct scb *scb)
|
||||
{
|
||||
return (scb->platform_data->xfer_len);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
int ahc_get_transfer_dir(struct scb *scb)
|
||||
{
|
||||
return (scb->io_ctx->sc_data_direction);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahc_set_residual(struct scb *scb, u_long resid)
|
||||
{
|
||||
scsi_set_resid(scb->io_ctx, resid);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
void ahc_set_sense_residual(struct scb *scb, u_long resid)
|
||||
{
|
||||
scb->platform_data->sense_resid = resid;
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
u_long ahc_get_residual(struct scb *scb)
|
||||
{
|
||||
return scsi_get_resid(scb->io_ctx);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
u_long ahc_get_sense_residual(struct scb *scb)
|
||||
{
|
||||
return (scb->platform_data->sense_resid);
|
||||
}
|
||||
|
||||
static __inline
|
||||
static inline
|
||||
int ahc_perform_autosense(struct scb *scb)
|
||||
{
|
||||
/*
|
||||
@ -665,20 +665,20 @@ int ahc_perform_autosense(struct scb *scb)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
static inline uint32_t
|
||||
ahc_get_sense_bufsize(struct ahc_softc *ahc, struct scb *scb)
|
||||
{
|
||||
return (sizeof(struct scsi_sense_data));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahc_notify_xfer_settings_change(struct ahc_softc *ahc,
|
||||
struct ahc_devinfo *devinfo)
|
||||
{
|
||||
/* Nothing to do here for linux */
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
|
||||
{
|
||||
}
|
||||
@ -687,7 +687,7 @@ int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
|
||||
void ahc_platform_free(struct ahc_softc *ahc);
|
||||
void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
ahc_freeze_scb(struct scb *scb)
|
||||
{
|
||||
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
|
||||
|
@ -54,7 +54,7 @@
|
||||
|
||||
#include "aic7xxx_pci.h"
|
||||
|
||||
static __inline uint64_t
|
||||
static inline uint64_t
|
||||
ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
|
||||
{
|
||||
uint64_t id;
|
||||
@ -960,16 +960,12 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
|
||||
error = ahc_init(ahc);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
ahc->init_level++;
|
||||
|
||||
/*
|
||||
* Allow interrupts now that we are completely setup.
|
||||
*/
|
||||
error = ahc_pci_map_int(ahc);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
ahc->init_level++;
|
||||
return (0);
|
||||
return ahc_pci_map_int(ahc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -133,7 +133,7 @@ struct scsi_sense_data
|
||||
#define SCSI_STATUS_TASK_ABORTED 0x40
|
||||
|
||||
/************************* Large Disk Handling ********************************/
|
||||
static __inline int
|
||||
static inline int
|
||||
aic_sector_div(sector_t capacity, int heads, int sectors)
|
||||
{
|
||||
/* ugly, ugly sector_div calling convention.. */
|
||||
@ -141,7 +141,7 @@ aic_sector_div(sector_t capacity, int heads, int sectors)
|
||||
return (int)capacity;
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
static inline uint32_t
|
||||
scsi_4btoul(uint8_t *bytes)
|
||||
{
|
||||
uint32_t rv;
|
||||
|
@ -1,4 +1,4 @@
|
||||
EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/cxgb3
|
||||
|
||||
cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o
|
||||
obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i_ddp.o cxgb3i.o
|
||||
cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o cxgb3i_ddp.o
|
||||
obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i.o
|
||||
|
@ -66,10 +66,12 @@ struct cxgb3i_hba {
|
||||
* @pdev: pointer to pci dev
|
||||
* @hba_cnt: # of hbas (the same as # of ports)
|
||||
* @hba: all the hbas on this adapter
|
||||
* @flags: bit flag for adapter event/status
|
||||
* @tx_max_size: max. tx packet size supported
|
||||
* @rx_max_size: max. rx packet size supported
|
||||
* @tag_format: ddp tag format settings
|
||||
*/
|
||||
#define CXGB3I_ADAPTER_FLAG_RESET 0x1
|
||||
struct cxgb3i_adapter {
|
||||
struct list_head list_head;
|
||||
spinlock_t lock;
|
||||
@ -78,6 +80,7 @@ struct cxgb3i_adapter {
|
||||
unsigned char hba_cnt;
|
||||
struct cxgb3i_hba *hba[MAX_NPORTS];
|
||||
|
||||
unsigned int flags;
|
||||
unsigned int tx_max_size;
|
||||
unsigned int rx_max_size;
|
||||
|
||||
@ -137,10 +140,9 @@ struct cxgb3i_task_data {
|
||||
int cxgb3i_iscsi_init(void);
|
||||
void cxgb3i_iscsi_cleanup(void);
|
||||
|
||||
struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *);
|
||||
void cxgb3i_adapter_remove(struct t3cdev *);
|
||||
int cxgb3i_adapter_ulp_init(struct cxgb3i_adapter *);
|
||||
void cxgb3i_adapter_ulp_cleanup(struct cxgb3i_adapter *);
|
||||
struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *);
|
||||
void cxgb3i_adapter_open(struct t3cdev *);
|
||||
void cxgb3i_adapter_close(struct t3cdev *);
|
||||
|
||||
struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *);
|
||||
struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *,
|
||||
|
@ -23,19 +23,6 @@
|
||||
|
||||
#include "cxgb3i_ddp.h"
|
||||
|
||||
#define DRV_MODULE_NAME "cxgb3i_ddp"
|
||||
#define DRV_MODULE_VERSION "1.0.0"
|
||||
#define DRV_MODULE_RELDATE "Dec. 1, 2008"
|
||||
|
||||
static char version[] =
|
||||
"Chelsio S3xx iSCSI DDP " DRV_MODULE_NAME
|
||||
" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
|
||||
|
||||
MODULE_AUTHOR("Karen Xie <kxie@chelsio.com>");
|
||||
MODULE_DESCRIPTION("cxgb3i ddp pagepod manager");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_MODULE_VERSION);
|
||||
|
||||
#define ddp_log_error(fmt...) printk(KERN_ERR "cxgb3i_ddp: ERR! " fmt)
|
||||
#define ddp_log_warn(fmt...) printk(KERN_WARNING "cxgb3i_ddp: WARN! " fmt)
|
||||
#define ddp_log_info(fmt...) printk(KERN_INFO "cxgb3i_ddp: " fmt)
|
||||
@ -66,9 +53,6 @@ static unsigned char ddp_page_order[DDP_PGIDX_MAX] = {0, 1, 2, 4};
|
||||
static unsigned char ddp_page_shift[DDP_PGIDX_MAX] = {12, 13, 14, 16};
|
||||
static unsigned char page_idx = DDP_PGIDX_MAX;
|
||||
|
||||
static LIST_HEAD(cxgb3i_ddp_list);
|
||||
static DEFINE_RWLOCK(cxgb3i_ddp_rwlock);
|
||||
|
||||
/*
|
||||
* functions to program the pagepod in h/w
|
||||
*/
|
||||
@ -113,8 +97,8 @@ static int set_ddp_map(struct cxgb3i_ddp_info *ddp, struct pagepod_hdr *hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int idx,
|
||||
unsigned int npods)
|
||||
static void clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int tag,
|
||||
unsigned int idx, unsigned int npods)
|
||||
{
|
||||
unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
|
||||
int i;
|
||||
@ -122,13 +106,17 @@ static int clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int idx,
|
||||
for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
|
||||
struct sk_buff *skb = ddp->gl_skb[idx];
|
||||
|
||||
if (!skb) {
|
||||
ddp_log_error("ddp tag 0x%x, 0x%x, %d/%u, skb NULL.\n",
|
||||
tag, idx, i, npods);
|
||||
continue;
|
||||
}
|
||||
ddp->gl_skb[idx] = NULL;
|
||||
memset((skb->head + sizeof(struct ulp_mem_io)), 0, PPOD_SIZE);
|
||||
ulp_mem_io_set_hdr(skb, pm_addr);
|
||||
skb->priority = CPL_PRIORITY_CONTROL;
|
||||
cxgb3_ofld_send(ddp->tdev, skb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ddp_find_unused_entries(struct cxgb3i_ddp_info *ddp,
|
||||
@ -211,7 +199,6 @@ int cxgb3i_ddp_find_page_index(unsigned long pgsz)
|
||||
ddp_log_debug("ddp page size 0x%lx not supported.\n", pgsz);
|
||||
return DDP_PGIDX_MAX;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_ddp_find_page_index);
|
||||
|
||||
static inline void ddp_gl_unmap(struct pci_dev *pdev,
|
||||
struct cxgb3i_gather_list *gl)
|
||||
@ -334,7 +321,6 @@ error_out:
|
||||
kfree(gl);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_ddp_make_gl);
|
||||
|
||||
/**
|
||||
* cxgb3i_ddp_release_gl - release a page buffer list
|
||||
@ -348,7 +334,6 @@ void cxgb3i_ddp_release_gl(struct cxgb3i_gather_list *gl,
|
||||
ddp_gl_unmap(pdev, gl);
|
||||
kfree(gl);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_ddp_release_gl);
|
||||
|
||||
/**
|
||||
* cxgb3i_ddp_tag_reserve - set up ddp for a data transfer
|
||||
@ -430,7 +415,6 @@ unmark_entries:
|
||||
ddp_unmark_entries(ddp, idx, npods);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_ddp_tag_reserve);
|
||||
|
||||
/**
|
||||
* cxgb3i_ddp_tag_release - release a ddp tag
|
||||
@ -453,22 +437,21 @@ void cxgb3i_ddp_tag_release(struct t3cdev *tdev, u32 tag)
|
||||
struct cxgb3i_gather_list *gl = ddp->gl_map[idx];
|
||||
unsigned int npods;
|
||||
|
||||
if (!gl) {
|
||||
ddp_log_error("release ddp 0x%x, idx 0x%x, gl NULL.\n",
|
||||
tag, idx);
|
||||
if (!gl || !gl->nelem) {
|
||||
ddp_log_error("release 0x%x, idx 0x%x, gl 0x%p, %u.\n",
|
||||
tag, idx, gl, gl ? gl->nelem : 0);
|
||||
return;
|
||||
}
|
||||
npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
|
||||
ddp_log_debug("ddp tag 0x%x, release idx 0x%x, npods %u.\n",
|
||||
tag, idx, npods);
|
||||
clear_ddp_map(ddp, idx, npods);
|
||||
clear_ddp_map(ddp, tag, idx, npods);
|
||||
ddp_unmark_entries(ddp, idx, npods);
|
||||
cxgb3i_ddp_release_gl(gl, ddp->pdev);
|
||||
} else
|
||||
ddp_log_error("ddp tag 0x%x, idx 0x%x > max 0x%x.\n",
|
||||
tag, idx, ddp->nppods);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_ddp_tag_release);
|
||||
|
||||
static int setup_conn_pgidx(struct t3cdev *tdev, unsigned int tid, int pg_idx,
|
||||
int reply)
|
||||
@ -509,7 +492,6 @@ int cxgb3i_setup_conn_host_pagesize(struct t3cdev *tdev, unsigned int tid,
|
||||
{
|
||||
return setup_conn_pgidx(tdev, tid, page_idx, reply);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_host_pagesize);
|
||||
|
||||
/**
|
||||
* cxgb3i_setup_conn_pagesize - setup the conn.'s ddp page size
|
||||
@ -526,7 +508,6 @@ int cxgb3i_setup_conn_pagesize(struct t3cdev *tdev, unsigned int tid,
|
||||
|
||||
return setup_conn_pgidx(tdev, tid, pgidx, reply);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_pagesize);
|
||||
|
||||
/**
|
||||
* cxgb3i_setup_conn_digest - setup conn. digest setting
|
||||
@ -562,26 +543,104 @@ int cxgb3i_setup_conn_digest(struct t3cdev *tdev, unsigned int tid,
|
||||
cxgb3_ofld_send(tdev, skb);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_digest);
|
||||
|
||||
static int ddp_init(struct t3cdev *tdev)
|
||||
|
||||
/**
|
||||
* cxgb3i_adapter_ddp_info - read the adapter's ddp information
|
||||
* @tdev: t3cdev adapter
|
||||
* @tformat: tag format
|
||||
* @txsz: max tx pdu payload size, filled in by this func.
|
||||
* @rxsz: max rx pdu payload size, filled in by this func.
|
||||
* setup the tag format for a given iscsi entity
|
||||
*/
|
||||
int cxgb3i_adapter_ddp_info(struct t3cdev *tdev,
|
||||
struct cxgb3i_tag_format *tformat,
|
||||
unsigned int *txsz, unsigned int *rxsz)
|
||||
{
|
||||
struct cxgb3i_ddp_info *ddp;
|
||||
unsigned char idx_bits;
|
||||
|
||||
if (!tformat)
|
||||
return -EINVAL;
|
||||
|
||||
if (!tdev->ulp_iscsi)
|
||||
return -EINVAL;
|
||||
|
||||
ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
|
||||
|
||||
idx_bits = 32 - tformat->sw_bits;
|
||||
tformat->rsvd_bits = ddp->idx_bits;
|
||||
tformat->rsvd_shift = PPOD_IDX_SHIFT;
|
||||
tformat->rsvd_mask = (1 << tformat->rsvd_bits) - 1;
|
||||
|
||||
ddp_log_info("tag format: sw %u, rsvd %u,%u, mask 0x%x.\n",
|
||||
tformat->sw_bits, tformat->rsvd_bits,
|
||||
tformat->rsvd_shift, tformat->rsvd_mask);
|
||||
|
||||
*txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
|
||||
ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
|
||||
*rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
|
||||
ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
|
||||
ddp_log_info("max payload size: %u/%u, %u/%u.\n",
|
||||
*txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb3i_ddp_cleanup - release the cxgb3 adapter's ddp resource
|
||||
* @tdev: t3cdev adapter
|
||||
* release all the resource held by the ddp pagepod manager for a given
|
||||
* adapter if needed
|
||||
*/
|
||||
void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
|
||||
{
|
||||
int i = 0;
|
||||
struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
|
||||
|
||||
ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp);
|
||||
|
||||
if (ddp) {
|
||||
tdev->ulp_iscsi = NULL;
|
||||
while (i < ddp->nppods) {
|
||||
struct cxgb3i_gather_list *gl = ddp->gl_map[i];
|
||||
if (gl) {
|
||||
int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
|
||||
>> PPOD_PAGES_SHIFT;
|
||||
ddp_log_info("t3dev 0x%p, ddp %d + %d.\n",
|
||||
tdev, i, npods);
|
||||
kfree(gl);
|
||||
ddp_free_gl_skb(ddp, i, npods);
|
||||
i += npods;
|
||||
} else
|
||||
i++;
|
||||
}
|
||||
cxgb3i_free_big_mem(ddp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ddp_init - initialize the cxgb3 adapter's ddp resource
|
||||
* @tdev: t3cdev adapter
|
||||
* initialize the ddp pagepod manager for a given adapter
|
||||
*/
|
||||
static void ddp_init(struct t3cdev *tdev)
|
||||
{
|
||||
struct cxgb3i_ddp_info *ddp;
|
||||
struct ulp_iscsi_info uinfo;
|
||||
unsigned int ppmax, bits;
|
||||
int i, err;
|
||||
static int vers_printed;
|
||||
|
||||
if (!vers_printed) {
|
||||
printk(KERN_INFO "%s", version);
|
||||
vers_printed = 1;
|
||||
if (tdev->ulp_iscsi) {
|
||||
ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
|
||||
tdev, tdev->ulp_iscsi);
|
||||
return;
|
||||
}
|
||||
|
||||
err = tdev->ctl(tdev, ULP_ISCSI_GET_PARAMS, &uinfo);
|
||||
if (err < 0) {
|
||||
ddp_log_error("%s, failed to get iscsi param err=%d.\n",
|
||||
tdev->name, err);
|
||||
return err;
|
||||
return;
|
||||
}
|
||||
|
||||
ppmax = (uinfo.ulimit - uinfo.llimit + 1) >> PPOD_SIZE_SHIFT;
|
||||
@ -598,7 +657,7 @@ static int ddp_init(struct t3cdev *tdev)
|
||||
if (!ddp) {
|
||||
ddp_log_warn("%s unable to alloc ddp 0x%d, ddp disabled.\n",
|
||||
tdev->name, ppmax);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
ddp->gl_map = (struct cxgb3i_gather_list **)(ddp + 1);
|
||||
ddp->gl_skb = (struct sk_buff **)(((char *)ddp->gl_map) +
|
||||
@ -632,142 +691,26 @@ static int ddp_init(struct t3cdev *tdev)
|
||||
|
||||
tdev->ulp_iscsi = ddp;
|
||||
|
||||
/* add to the list */
|
||||
write_lock(&cxgb3i_ddp_rwlock);
|
||||
list_add_tail(&ddp->list, &cxgb3i_ddp_list);
|
||||
write_unlock(&cxgb3i_ddp_rwlock);
|
||||
|
||||
ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x "
|
||||
"pkt %u/%u, %u/%u.\n",
|
||||
ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits,
|
||||
ddp->idx_mask, ddp->rsvd_tag_mask,
|
||||
ddp->max_txsz, uinfo.max_txsz,
|
||||
ddp_log_info("tdev 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u,"
|
||||
" %u/%u.\n",
|
||||
tdev, ppmax, ddp->idx_bits, ddp->idx_mask,
|
||||
ddp->rsvd_tag_mask, ddp->max_txsz, uinfo.max_txsz,
|
||||
ddp->max_rxsz, uinfo.max_rxsz);
|
||||
return 0;
|
||||
return;
|
||||
|
||||
free_ddp_map:
|
||||
cxgb3i_free_big_mem(ddp);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource
|
||||
* @tdev: t3cdev adapter
|
||||
* @tformat: tag format
|
||||
* @txsz: max tx pdu payload size, filled in by this func.
|
||||
* @rxsz: max rx pdu payload size, filled in by this func.
|
||||
* initialize the ddp pagepod manager for a given adapter if needed and
|
||||
* setup the tag format for a given iscsi entity
|
||||
* cxgb3i_ddp_init - initialize ddp functions
|
||||
*/
|
||||
int cxgb3i_adapter_ddp_init(struct t3cdev *tdev,
|
||||
struct cxgb3i_tag_format *tformat,
|
||||
unsigned int *txsz, unsigned int *rxsz)
|
||||
void cxgb3i_ddp_init(struct t3cdev *tdev)
|
||||
{
|
||||
struct cxgb3i_ddp_info *ddp;
|
||||
unsigned char idx_bits;
|
||||
|
||||
if (!tformat)
|
||||
return -EINVAL;
|
||||
|
||||
if (!tdev->ulp_iscsi) {
|
||||
int err = ddp_init(tdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (page_idx == DDP_PGIDX_MAX) {
|
||||
page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
|
||||
ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
|
||||
PAGE_SIZE, page_idx);
|
||||
}
|
||||
ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
|
||||
|
||||
idx_bits = 32 - tformat->sw_bits;
|
||||
tformat->rsvd_bits = ddp->idx_bits;
|
||||
tformat->rsvd_shift = PPOD_IDX_SHIFT;
|
||||
tformat->rsvd_mask = (1 << tformat->rsvd_bits) - 1;
|
||||
|
||||
ddp_log_info("tag format: sw %u, rsvd %u,%u, mask 0x%x.\n",
|
||||
tformat->sw_bits, tformat->rsvd_bits,
|
||||
tformat->rsvd_shift, tformat->rsvd_mask);
|
||||
|
||||
*txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
|
||||
ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
|
||||
*rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
|
||||
ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
|
||||
ddp_log_info("max payload size: %u/%u, %u/%u.\n",
|
||||
*txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
|
||||
return 0;
|
||||
ddp_init(tdev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init);
|
||||
|
||||
static void ddp_release(struct cxgb3i_ddp_info *ddp)
|
||||
{
|
||||
int i = 0;
|
||||
struct t3cdev *tdev = ddp->tdev;
|
||||
|
||||
tdev->ulp_iscsi = NULL;
|
||||
while (i < ddp->nppods) {
|
||||
struct cxgb3i_gather_list *gl = ddp->gl_map[i];
|
||||
if (gl) {
|
||||
int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
|
||||
>> PPOD_PAGES_SHIFT;
|
||||
|
||||
kfree(gl);
|
||||
ddp_free_gl_skb(ddp, i, npods);
|
||||
} else
|
||||
i++;
|
||||
}
|
||||
cxgb3i_free_big_mem(ddp);
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb3i_adapter_ddp_cleanup - release the adapter's ddp resource
|
||||
* @tdev: t3cdev adapter
|
||||
* release all the resource held by the ddp pagepod manager for a given
|
||||
* adapter if needed
|
||||
*/
|
||||
void cxgb3i_adapter_ddp_cleanup(struct t3cdev *tdev)
|
||||
{
|
||||
struct cxgb3i_ddp_info *ddp;
|
||||
|
||||
/* remove from the list */
|
||||
write_lock(&cxgb3i_ddp_rwlock);
|
||||
list_for_each_entry(ddp, &cxgb3i_ddp_list, list) {
|
||||
if (ddp->tdev == tdev) {
|
||||
list_del(&ddp->list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
write_unlock(&cxgb3i_ddp_rwlock);
|
||||
|
||||
if (ddp)
|
||||
ddp_release(ddp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_cleanup);
|
||||
|
||||
/**
|
||||
* cxgb3i_ddp_init_module - module init entry point
|
||||
* initialize any driver wide global data structures
|
||||
*/
|
||||
static int __init cxgb3i_ddp_init_module(void)
|
||||
{
|
||||
page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
|
||||
ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
|
||||
PAGE_SIZE, page_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb3i_ddp_exit_module - module cleanup/exit entry point
|
||||
* go through the ddp list and release any resource held.
|
||||
*/
|
||||
static void __exit cxgb3i_ddp_exit_module(void)
|
||||
{
|
||||
struct cxgb3i_ddp_info *ddp;
|
||||
|
||||
/* release all ddp manager if there is any */
|
||||
write_lock(&cxgb3i_ddp_rwlock);
|
||||
list_for_each_entry(ddp, &cxgb3i_ddp_list, list) {
|
||||
list_del(&ddp->list);
|
||||
ddp_release(ddp);
|
||||
}
|
||||
write_unlock(&cxgb3i_ddp_rwlock);
|
||||
}
|
||||
|
||||
module_init(cxgb3i_ddp_init_module);
|
||||
module_exit(cxgb3i_ddp_exit_module);
|
||||
|
@ -301,7 +301,9 @@ int cxgb3i_setup_conn_pagesize(struct t3cdev *, unsigned int tid, int reply,
|
||||
int cxgb3i_setup_conn_digest(struct t3cdev *, unsigned int tid,
|
||||
int hcrc, int dcrc, int reply);
|
||||
int cxgb3i_ddp_find_page_index(unsigned long pgsz);
|
||||
int cxgb3i_adapter_ddp_init(struct t3cdev *, struct cxgb3i_tag_format *,
|
||||
int cxgb3i_adapter_ddp_info(struct t3cdev *, struct cxgb3i_tag_format *,
|
||||
unsigned int *txsz, unsigned int *rxsz);
|
||||
void cxgb3i_adapter_ddp_cleanup(struct t3cdev *);
|
||||
|
||||
void cxgb3i_ddp_init(struct t3cdev *);
|
||||
void cxgb3i_ddp_cleanup(struct t3cdev *);
|
||||
#endif
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "cxgb3i.h"
|
||||
|
||||
#define DRV_MODULE_NAME "cxgb3i"
|
||||
#define DRV_MODULE_VERSION "1.0.1"
|
||||
#define DRV_MODULE_RELDATE "Jan. 2009"
|
||||
#define DRV_MODULE_VERSION "1.0.2"
|
||||
#define DRV_MODULE_RELDATE "Mar. 2009"
|
||||
|
||||
static char version[] =
|
||||
"Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
|
||||
@ -26,6 +26,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
|
||||
|
||||
static void open_s3_dev(struct t3cdev *);
|
||||
static void close_s3_dev(struct t3cdev *);
|
||||
static void s3_err_handler(struct t3cdev *tdev, u32 status, u32 error);
|
||||
|
||||
static cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS];
|
||||
static struct cxgb3_client t3c_client = {
|
||||
@ -33,6 +34,7 @@ static struct cxgb3_client t3c_client = {
|
||||
.handlers = cxgb3i_cpl_handlers,
|
||||
.add = open_s3_dev,
|
||||
.remove = close_s3_dev,
|
||||
.err_handler = s3_err_handler,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -48,8 +50,9 @@ static void open_s3_dev(struct t3cdev *t3dev)
|
||||
vers_printed = 1;
|
||||
}
|
||||
|
||||
cxgb3i_ddp_init(t3dev);
|
||||
cxgb3i_sdev_add(t3dev, &t3c_client);
|
||||
cxgb3i_adapter_add(t3dev);
|
||||
cxgb3i_adapter_open(t3dev);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,8 +61,28 @@ static void open_s3_dev(struct t3cdev *t3dev)
|
||||
*/
|
||||
static void close_s3_dev(struct t3cdev *t3dev)
|
||||
{
|
||||
cxgb3i_adapter_remove(t3dev);
|
||||
cxgb3i_adapter_close(t3dev);
|
||||
cxgb3i_sdev_remove(t3dev);
|
||||
cxgb3i_ddp_cleanup(t3dev);
|
||||
}
|
||||
|
||||
static void s3_err_handler(struct t3cdev *tdev, u32 status, u32 error)
|
||||
{
|
||||
struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(tdev);
|
||||
|
||||
cxgb3i_log_info("snic 0x%p, tdev 0x%p, status 0x%x, err 0x%x.\n",
|
||||
snic, tdev, status, error);
|
||||
if (!snic)
|
||||
return;
|
||||
|
||||
switch (status) {
|
||||
case OFFLOAD_STATUS_DOWN:
|
||||
snic->flags |= CXGB3I_ADAPTER_FLAG_RESET;
|
||||
break;
|
||||
case OFFLOAD_STATUS_UP:
|
||||
snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,36 +53,52 @@ static LIST_HEAD(cxgb3i_snic_list);
|
||||
static DEFINE_RWLOCK(cxgb3i_snic_rwlock);
|
||||
|
||||
/**
|
||||
* cxgb3i_adapter_add - init a s3 adapter structure and any h/w settings
|
||||
* @t3dev: t3cdev adapter
|
||||
* return the resulting cxgb3i_adapter struct
|
||||
* cxgb3i_adpater_find_by_tdev - find the cxgb3i_adapter structure via t3cdev
|
||||
* @tdev: t3cdev pointer
|
||||
*/
|
||||
struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *t3dev)
|
||||
struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *tdev)
|
||||
{
|
||||
struct cxgb3i_adapter *snic;
|
||||
struct adapter *adapter = tdev2adap(t3dev);
|
||||
int i;
|
||||
|
||||
snic = kzalloc(sizeof(*snic), GFP_KERNEL);
|
||||
if (!snic) {
|
||||
cxgb3i_api_debug("cxgb3 %s, OOM.\n", t3dev->name);
|
||||
return NULL;
|
||||
read_lock(&cxgb3i_snic_rwlock);
|
||||
list_for_each_entry(snic, &cxgb3i_snic_list, list_head) {
|
||||
if (snic->tdev == tdev) {
|
||||
read_unlock(&cxgb3i_snic_rwlock);
|
||||
return snic;
|
||||
}
|
||||
}
|
||||
spin_lock_init(&snic->lock);
|
||||
read_unlock(&cxgb3i_snic_rwlock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int adapter_update(struct cxgb3i_adapter *snic)
|
||||
{
|
||||
cxgb3i_log_info("snic 0x%p, t3dev 0x%p, updating.\n",
|
||||
snic, snic->tdev);
|
||||
return cxgb3i_adapter_ddp_info(snic->tdev, &snic->tag_format,
|
||||
&snic->tx_max_size,
|
||||
&snic->rx_max_size);
|
||||
}
|
||||
|
||||
static int adapter_add(struct cxgb3i_adapter *snic)
|
||||
{
|
||||
struct t3cdev *t3dev = snic->tdev;
|
||||
struct adapter *adapter = tdev2adap(t3dev);
|
||||
int i, err;
|
||||
|
||||
snic->tdev = t3dev;
|
||||
snic->pdev = adapter->pdev;
|
||||
snic->tag_format.sw_bits = sw_tag_idx_bits + sw_tag_age_bits;
|
||||
|
||||
if (cxgb3i_adapter_ddp_init(t3dev, &snic->tag_format,
|
||||
err = cxgb3i_adapter_ddp_info(t3dev, &snic->tag_format,
|
||||
&snic->tx_max_size,
|
||||
&snic->rx_max_size) < 0)
|
||||
goto free_snic;
|
||||
&snic->rx_max_size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for_each_port(adapter, i) {
|
||||
snic->hba[i] = cxgb3i_hba_host_add(snic, adapter->port[i]);
|
||||
if (!snic->hba[i])
|
||||
goto ulp_cleanup;
|
||||
return -EINVAL;
|
||||
}
|
||||
snic->hba_cnt = adapter->params.nports;
|
||||
|
||||
@ -91,46 +107,71 @@ struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *t3dev)
|
||||
list_add_tail(&snic->list_head, &cxgb3i_snic_list);
|
||||
write_unlock(&cxgb3i_snic_rwlock);
|
||||
|
||||
return snic;
|
||||
|
||||
ulp_cleanup:
|
||||
cxgb3i_adapter_ddp_cleanup(t3dev);
|
||||
free_snic:
|
||||
kfree(snic);
|
||||
return NULL;
|
||||
cxgb3i_log_info("t3dev 0x%p open, snic 0x%p, %u scsi hosts added.\n",
|
||||
t3dev, snic, snic->hba_cnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb3i_adapter_remove - release the resources held and cleanup h/w settings
|
||||
* cxgb3i_adapter_open - init a s3 adapter structure and any h/w settings
|
||||
* @t3dev: t3cdev adapter
|
||||
*/
|
||||
void cxgb3i_adapter_remove(struct t3cdev *t3dev)
|
||||
void cxgb3i_adapter_open(struct t3cdev *t3dev)
|
||||
{
|
||||
struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
|
||||
int err;
|
||||
|
||||
if (snic)
|
||||
err = adapter_update(snic);
|
||||
else {
|
||||
snic = kzalloc(sizeof(*snic), GFP_KERNEL);
|
||||
if (snic) {
|
||||
spin_lock_init(&snic->lock);
|
||||
snic->tdev = t3dev;
|
||||
err = adapter_add(snic);
|
||||
} else
|
||||
err = -ENOMEM;
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
cxgb3i_log_info("snic 0x%p, f 0x%x, t3dev 0x%p open, err %d.\n",
|
||||
snic, snic ? snic->flags : 0, t3dev, err);
|
||||
if (snic) {
|
||||
snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
|
||||
cxgb3i_adapter_close(t3dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb3i_adapter_close - release the resources held and cleanup h/w settings
|
||||
* @t3dev: t3cdev adapter
|
||||
*/
|
||||
void cxgb3i_adapter_close(struct t3cdev *t3dev)
|
||||
{
|
||||
struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
|
||||
int i;
|
||||
struct cxgb3i_adapter *snic;
|
||||
|
||||
if (!snic || snic->flags & CXGB3I_ADAPTER_FLAG_RESET) {
|
||||
cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, f 0x%x.\n",
|
||||
t3dev, snic, snic ? snic->flags : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* remove from the list */
|
||||
write_lock(&cxgb3i_snic_rwlock);
|
||||
list_for_each_entry(snic, &cxgb3i_snic_list, list_head) {
|
||||
if (snic->tdev == t3dev) {
|
||||
list_del(&snic->list_head);
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_del(&snic->list_head);
|
||||
write_unlock(&cxgb3i_snic_rwlock);
|
||||
|
||||
if (snic) {
|
||||
for (i = 0; i < snic->hba_cnt; i++) {
|
||||
if (snic->hba[i]) {
|
||||
cxgb3i_hba_host_remove(snic->hba[i]);
|
||||
snic->hba[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < snic->hba_cnt; i++) {
|
||||
if (snic->hba[i]) {
|
||||
cxgb3i_hba_host_remove(snic->hba[i]);
|
||||
snic->hba[i] = NULL;
|
||||
}
|
||||
|
||||
/* release ddp resources */
|
||||
cxgb3i_adapter_ddp_cleanup(snic->tdev);
|
||||
kfree(snic);
|
||||
}
|
||||
cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, %u scsi hosts removed.\n",
|
||||
t3dev, snic, snic->hba_cnt);
|
||||
kfree(snic);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,7 +211,8 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
|
||||
shost = iscsi_host_alloc(&cxgb3i_host_template,
|
||||
sizeof(struct cxgb3i_hba), 1);
|
||||
if (!shost) {
|
||||
cxgb3i_log_info("iscsi_host_alloc failed.\n");
|
||||
cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_alloc failed.\n",
|
||||
snic, ndev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -188,7 +230,8 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
|
||||
pci_dev_get(snic->pdev);
|
||||
err = iscsi_host_add(shost, &snic->pdev->dev);
|
||||
if (err) {
|
||||
cxgb3i_log_info("iscsi_host_add failed.\n");
|
||||
cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_add failed.\n",
|
||||
snic, ndev);
|
||||
goto pci_dev_put;
|
||||
}
|
||||
|
||||
|
@ -94,29 +94,30 @@ static int c3cn_get_port(struct s3_conn *c3cn, struct cxgb3i_sdev_data *cdata)
|
||||
if (!cdata)
|
||||
goto error_out;
|
||||
|
||||
if (c3cn->saddr.sin_port != 0) {
|
||||
idx = ntohs(c3cn->saddr.sin_port) - cxgb3_sport_base;
|
||||
if (idx < 0 || idx >= cxgb3_max_connect)
|
||||
return 0;
|
||||
if (!test_and_set_bit(idx, cdata->sport_map))
|
||||
return -EADDRINUSE;
|
||||
if (c3cn->saddr.sin_port) {
|
||||
cxgb3i_log_error("connect, sin_port NON-ZERO %u.\n",
|
||||
c3cn->saddr.sin_port);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
|
||||
/* the sport_map_next may not be accurate but that is okay, sport_map
|
||||
should be */
|
||||
start = idx = cdata->sport_map_next;
|
||||
spin_lock_bh(&cdata->lock);
|
||||
start = idx = cdata->sport_next;
|
||||
do {
|
||||
if (++idx >= cxgb3_max_connect)
|
||||
idx = 0;
|
||||
if (!(test_and_set_bit(idx, cdata->sport_map))) {
|
||||
if (!cdata->sport_conn[idx]) {
|
||||
c3cn->saddr.sin_port = htons(cxgb3_sport_base + idx);
|
||||
cdata->sport_map_next = idx;
|
||||
cdata->sport_next = idx;
|
||||
cdata->sport_conn[idx] = c3cn;
|
||||
spin_unlock_bh(&cdata->lock);
|
||||
|
||||
c3cn_conn_debug("%s reserve port %u.\n",
|
||||
cdata->cdev->name,
|
||||
cxgb3_sport_base + idx);
|
||||
return 0;
|
||||
}
|
||||
} while (idx != start);
|
||||
spin_unlock_bh(&cdata->lock);
|
||||
|
||||
error_out:
|
||||
return -EADDRNOTAVAIL;
|
||||
@ -124,15 +125,19 @@ error_out:
|
||||
|
||||
static void c3cn_put_port(struct s3_conn *c3cn)
|
||||
{
|
||||
struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(c3cn->cdev);
|
||||
if (!c3cn->cdev)
|
||||
return;
|
||||
|
||||
if (c3cn->saddr.sin_port) {
|
||||
struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(c3cn->cdev);
|
||||
int idx = ntohs(c3cn->saddr.sin_port) - cxgb3_sport_base;
|
||||
|
||||
c3cn->saddr.sin_port = 0;
|
||||
if (idx < 0 || idx >= cxgb3_max_connect)
|
||||
return;
|
||||
clear_bit(idx, cdata->sport_map);
|
||||
spin_lock_bh(&cdata->lock);
|
||||
cdata->sport_conn[idx] = NULL;
|
||||
spin_unlock_bh(&cdata->lock);
|
||||
c3cn_conn_debug("%s, release port %u.\n",
|
||||
cdata->cdev->name, cxgb3_sport_base + idx);
|
||||
}
|
||||
@ -1305,11 +1310,7 @@ static void c3cn_release_offload_resources(struct s3_conn *c3cn)
|
||||
struct t3cdev *cdev = c3cn->cdev;
|
||||
unsigned int tid = c3cn->tid;
|
||||
|
||||
if (!cdev)
|
||||
return;
|
||||
|
||||
c3cn->qset = 0;
|
||||
|
||||
c3cn_free_cpl_skbs(c3cn);
|
||||
|
||||
if (c3cn->wr_avail != c3cn->wr_max) {
|
||||
@ -1317,18 +1318,22 @@ static void c3cn_release_offload_resources(struct s3_conn *c3cn)
|
||||
reset_wr_list(c3cn);
|
||||
}
|
||||
|
||||
if (c3cn->l2t) {
|
||||
l2t_release(L2DATA(cdev), c3cn->l2t);
|
||||
c3cn->l2t = NULL;
|
||||
}
|
||||
|
||||
if (c3cn->state == C3CN_STATE_CONNECTING) /* we have ATID */
|
||||
s3_free_atid(cdev, tid);
|
||||
else { /* we have TID */
|
||||
cxgb3_remove_tid(cdev, (void *)c3cn, tid);
|
||||
c3cn_put(c3cn);
|
||||
if (cdev) {
|
||||
if (c3cn->l2t) {
|
||||
l2t_release(L2DATA(cdev), c3cn->l2t);
|
||||
c3cn->l2t = NULL;
|
||||
}
|
||||
if (c3cn->state == C3CN_STATE_CONNECTING)
|
||||
/* we have ATID */
|
||||
s3_free_atid(cdev, tid);
|
||||
else {
|
||||
/* we have TID */
|
||||
cxgb3_remove_tid(cdev, (void *)c3cn, tid);
|
||||
c3cn_put(c3cn);
|
||||
}
|
||||
}
|
||||
|
||||
c3cn->dst_cache = NULL;
|
||||
c3cn->cdev = NULL;
|
||||
}
|
||||
|
||||
@ -1417,17 +1422,18 @@ static void c3cn_active_close(struct s3_conn *c3cn)
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb3i_c3cn_release - close and release an iscsi tcp connection
|
||||
* cxgb3i_c3cn_release - close and release an iscsi tcp connection and any
|
||||
* resource held
|
||||
* @c3cn: the iscsi tcp connection
|
||||
*/
|
||||
void cxgb3i_c3cn_release(struct s3_conn *c3cn)
|
||||
{
|
||||
c3cn_conn_debug("c3cn 0x%p, s %u, f 0x%lx.\n",
|
||||
c3cn, c3cn->state, c3cn->flags);
|
||||
if (likely(c3cn->state != C3CN_STATE_CONNECTING))
|
||||
c3cn_active_close(c3cn);
|
||||
else
|
||||
if (unlikely(c3cn->state == C3CN_STATE_CONNECTING))
|
||||
c3cn_set_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED);
|
||||
else if (likely(c3cn->state != C3CN_STATE_CLOSED))
|
||||
c3cn_active_close(c3cn);
|
||||
c3cn_put(c3cn);
|
||||
}
|
||||
|
||||
@ -1656,7 +1662,6 @@ int cxgb3i_c3cn_connect(struct s3_conn *c3cn, struct sockaddr_in *usin)
|
||||
c3cn_set_state(c3cn, C3CN_STATE_CLOSED);
|
||||
ip_rt_put(rt);
|
||||
c3cn_put_port(c3cn);
|
||||
c3cn->daddr.sin_port = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1776,10 +1781,25 @@ out_err:
|
||||
static void sdev_data_cleanup(struct cxgb3i_sdev_data *cdata)
|
||||
{
|
||||
struct adap_ports *ports = &cdata->ports;
|
||||
struct s3_conn *c3cn;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cxgb3_max_connect; i++) {
|
||||
if (cdata->sport_conn[i]) {
|
||||
c3cn = cdata->sport_conn[i];
|
||||
cdata->sport_conn[i] = NULL;
|
||||
|
||||
spin_lock_bh(&c3cn->lock);
|
||||
c3cn->cdev = NULL;
|
||||
c3cn_set_flag(c3cn, C3CN_OFFLOAD_DOWN);
|
||||
c3cn_closed(c3cn);
|
||||
spin_unlock_bh(&c3cn->lock);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ports->nports; i++)
|
||||
NDEV2CDATA(ports->lldevs[i]) = NULL;
|
||||
|
||||
cxgb3i_free_big_mem(cdata);
|
||||
}
|
||||
|
||||
@ -1821,21 +1841,27 @@ void cxgb3i_sdev_add(struct t3cdev *cdev, struct cxgb3_client *client)
|
||||
struct cxgb3i_sdev_data *cdata;
|
||||
struct ofld_page_info rx_page_info;
|
||||
unsigned int wr_len;
|
||||
int mapsize = DIV_ROUND_UP(cxgb3_max_connect,
|
||||
8 * sizeof(unsigned long));
|
||||
int mapsize = cxgb3_max_connect * sizeof(struct s3_conn *);
|
||||
int i;
|
||||
|
||||
cdata = cxgb3i_alloc_big_mem(sizeof(*cdata) + mapsize, GFP_KERNEL);
|
||||
if (!cdata)
|
||||
if (!cdata) {
|
||||
cxgb3i_log_warn("t3dev 0x%p, offload up, OOM %d.\n",
|
||||
cdev, mapsize);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cdev->ctl(cdev, GET_WR_LEN, &wr_len) < 0 ||
|
||||
cdev->ctl(cdev, GET_PORTS, &cdata->ports) < 0 ||
|
||||
cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info) < 0)
|
||||
cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info) < 0) {
|
||||
cxgb3i_log_warn("t3dev 0x%p, offload up, ioctl failed.\n",
|
||||
cdev);
|
||||
goto free_cdata;
|
||||
}
|
||||
|
||||
s3_init_wr_tab(wr_len);
|
||||
|
||||
spin_lock_init(&cdata->lock);
|
||||
INIT_LIST_HEAD(&cdata->list);
|
||||
cdata->cdev = cdev;
|
||||
cdata->client = client;
|
||||
@ -1847,6 +1873,7 @@ void cxgb3i_sdev_add(struct t3cdev *cdev, struct cxgb3_client *client)
|
||||
list_add_tail(&cdata->list, &cdata_list);
|
||||
write_unlock(&cdata_rwlock);
|
||||
|
||||
cxgb3i_log_info("t3dev 0x%p, offload up, added.\n", cdev);
|
||||
return;
|
||||
|
||||
free_cdata:
|
||||
@ -1861,6 +1888,8 @@ void cxgb3i_sdev_remove(struct t3cdev *cdev)
|
||||
{
|
||||
struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(cdev);
|
||||
|
||||
cxgb3i_log_info("t3dev 0x%p, offload down, remove.\n", cdev);
|
||||
|
||||
write_lock(&cdata_rwlock);
|
||||
list_del(&cdata->list);
|
||||
write_unlock(&cdata_rwlock);
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define _CXGB3I_OFFLOAD_H
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/tcp.h>
|
||||
#include <linux/in.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "adapter.h"
|
||||
@ -135,11 +135,11 @@ enum c3cn_flags {
|
||||
C3CN_ABORT_RPL_PENDING, /* expecting an abort reply */
|
||||
C3CN_TX_DATA_SENT, /* already sent a TX_DATA WR */
|
||||
C3CN_ACTIVE_CLOSE_NEEDED, /* need to be closed */
|
||||
C3CN_OFFLOAD_DOWN /* offload function off */
|
||||
};
|
||||
|
||||
/**
|
||||
* cxgb3i_sdev_data - Per adapter data.
|
||||
*
|
||||
* Linked off of each Ethernet device port on the adapter.
|
||||
* Also available via the t3cdev structure since we have pointers to our port
|
||||
* net_device's there ...
|
||||
@ -148,16 +148,17 @@ enum c3cn_flags {
|
||||
* @cdev: t3cdev adapter
|
||||
* @client: CPL client pointer
|
||||
* @ports: array of adapter ports
|
||||
* @sport_map_next: next index into the port map
|
||||
* @sport_map: source port map
|
||||
* @sport_next: next port
|
||||
* @sport_conn: source port connection
|
||||
*/
|
||||
struct cxgb3i_sdev_data {
|
||||
struct list_head list;
|
||||
struct t3cdev *cdev;
|
||||
struct cxgb3_client *client;
|
||||
struct adap_ports ports;
|
||||
unsigned int sport_map_next;
|
||||
unsigned long sport_map[0];
|
||||
spinlock_t lock;
|
||||
unsigned int sport_next;
|
||||
struct s3_conn *sport_conn[0];
|
||||
};
|
||||
#define NDEV2CDATA(ndev) (*(struct cxgb3i_sdev_data **)&(ndev)->ec_ptr)
|
||||
#define CXGB3_SDEV_DATA(cdev) NDEV2CDATA((cdev)->lldev)
|
||||
|
@ -1,8 +1,2 @@
|
||||
# $Id: Makefile
|
||||
|
||||
obj-$(CONFIG_FCOE) += fcoe.o
|
||||
|
||||
fcoe-y := \
|
||||
libfcoe.o \
|
||||
fcoe_sw.o \
|
||||
fc_transport_fcoe.o
|
||||
obj-$(CONFIG_LIBFCOE) += libfcoe.o
|
||||
|
@ -1,443 +0,0 @@
|
||||
/*
|
||||
* Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Maintained at www.Open-FCoE.org
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <scsi/libfcoe.h>
|
||||
#include <scsi/fc_transport_fcoe.h>
|
||||
|
||||
/* internal fcoe transport */
|
||||
struct fcoe_transport_internal {
|
||||
struct fcoe_transport *t;
|
||||
struct net_device *netdev;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* fcoe transports list and its lock */
|
||||
static LIST_HEAD(fcoe_transports);
|
||||
static DEFINE_MUTEX(fcoe_transports_lock);
|
||||
|
||||
/**
|
||||
* fcoe_transport_default() - Returns ptr to the default transport fcoe_sw
|
||||
*/
|
||||
struct fcoe_transport *fcoe_transport_default(void)
|
||||
{
|
||||
return &fcoe_sw_transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_transport_to_pcidev() - get the pci dev from a netdev
|
||||
* @netdev: the netdev that pci dev will be retrived from
|
||||
*
|
||||
* Returns: NULL or the corrsponding pci_dev
|
||||
*/
|
||||
struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev)
|
||||
{
|
||||
if (!netdev->dev.parent)
|
||||
return NULL;
|
||||
return to_pci_dev(netdev->dev.parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_transport_device_lookup() - Lookup a transport
|
||||
* @netdev: the netdev the transport to be attached to
|
||||
*
|
||||
* This will look for existing offload driver, if not found, it falls back to
|
||||
* the default sw hba (fcoe_sw) as its fcoe transport.
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
static struct fcoe_transport_internal *
|
||||
fcoe_transport_device_lookup(struct fcoe_transport *t,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fcoe_transport_internal *ti;
|
||||
|
||||
/* assign the transpor to this device */
|
||||
mutex_lock(&t->devlock);
|
||||
list_for_each_entry(ti, &t->devlist, list) {
|
||||
if (ti->netdev == netdev) {
|
||||
mutex_unlock(&t->devlock);
|
||||
return ti;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&t->devlock);
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
* fcoe_transport_device_add() - Assign a transport to a device
|
||||
* @netdev: the netdev the transport to be attached to
|
||||
*
|
||||
* This will look for existing offload driver, if not found, it falls back to
|
||||
* the default sw hba (fcoe_sw) as its fcoe transport.
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
static int fcoe_transport_device_add(struct fcoe_transport *t,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fcoe_transport_internal *ti;
|
||||
|
||||
ti = fcoe_transport_device_lookup(t, netdev);
|
||||
if (ti) {
|
||||
printk(KERN_DEBUG "fcoe_transport_device_add:"
|
||||
"device %s is already added to transport %s\n",
|
||||
netdev->name, t->name);
|
||||
return -EEXIST;
|
||||
}
|
||||
/* allocate an internal struct to host the netdev and the list */
|
||||
ti = kzalloc(sizeof(*ti), GFP_KERNEL);
|
||||
if (!ti)
|
||||
return -ENOMEM;
|
||||
|
||||
ti->t = t;
|
||||
ti->netdev = netdev;
|
||||
INIT_LIST_HEAD(&ti->list);
|
||||
dev_hold(ti->netdev);
|
||||
|
||||
mutex_lock(&t->devlock);
|
||||
list_add(&ti->list, &t->devlist);
|
||||
mutex_unlock(&t->devlock);
|
||||
|
||||
printk(KERN_DEBUG "fcoe_transport_device_add:"
|
||||
"device %s added to transport %s\n",
|
||||
netdev->name, t->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_transport_device_remove() - Remove a device from its transport
|
||||
* @netdev: the netdev the transport to be attached to
|
||||
*
|
||||
* This removes the device from the transport so the given transport will
|
||||
* not manage this device any more
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
static int fcoe_transport_device_remove(struct fcoe_transport *t,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fcoe_transport_internal *ti;
|
||||
|
||||
ti = fcoe_transport_device_lookup(t, netdev);
|
||||
if (!ti) {
|
||||
printk(KERN_DEBUG "fcoe_transport_device_remove:"
|
||||
"device %s is not managed by transport %s\n",
|
||||
netdev->name, t->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
mutex_lock(&t->devlock);
|
||||
list_del(&ti->list);
|
||||
mutex_unlock(&t->devlock);
|
||||
printk(KERN_DEBUG "fcoe_transport_device_remove:"
|
||||
"device %s removed from transport %s\n",
|
||||
netdev->name, t->name);
|
||||
dev_put(ti->netdev);
|
||||
kfree(ti);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_transport_device_remove_all() - Remove all from transport devlist
|
||||
*
|
||||
* This removes the device from the transport so the given transport will
|
||||
* not manage this device any more
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
static void fcoe_transport_device_remove_all(struct fcoe_transport *t)
|
||||
{
|
||||
struct fcoe_transport_internal *ti, *tmp;
|
||||
|
||||
mutex_lock(&t->devlock);
|
||||
list_for_each_entry_safe(ti, tmp, &t->devlist, list) {
|
||||
list_del(&ti->list);
|
||||
kfree(ti);
|
||||
}
|
||||
mutex_unlock(&t->devlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_transport_match() - Use the bus device match function to match the hw
|
||||
* @t: The fcoe transport to check
|
||||
* @netdev: The netdev to match against
|
||||
*
|
||||
* This function is used to check if the given transport wants to manage the
|
||||
* input netdev. if the transports implements the match function, it will be
|
||||
* called, o.w. we just compare the pci vendor and device id.
|
||||
*
|
||||
* Returns: true for match up
|
||||
*/
|
||||
static bool fcoe_transport_match(struct fcoe_transport *t,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
/* match transport by vendor and device id */
|
||||
struct pci_dev *pci;
|
||||
|
||||
pci = fcoe_transport_pcidev(netdev);
|
||||
|
||||
if (pci) {
|
||||
printk(KERN_DEBUG "fcoe_transport_match:"
|
||||
"%s:%x:%x -- %s:%x:%x\n",
|
||||
t->name, t->vendor, t->device,
|
||||
netdev->name, pci->vendor, pci->device);
|
||||
|
||||
/* if transport supports match */
|
||||
if (t->match)
|
||||
return t->match(netdev);
|
||||
|
||||
/* else just compare the vendor and device id: pci only */
|
||||
return (t->vendor == pci->vendor) && (t->device == pci->device);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_transport_lookup() - Check if the transport is already registered
|
||||
* @t: the transport to be looked up
|
||||
*
|
||||
* This compares the parent device (pci) vendor and device id
|
||||
*
|
||||
* Returns: NULL if not found
|
||||
*
|
||||
* TODO: return default sw transport if no other transport is found
|
||||
*/
|
||||
static struct fcoe_transport *
|
||||
fcoe_transport_lookup(struct net_device *netdev)
|
||||
{
|
||||
struct fcoe_transport *t;
|
||||
|
||||
mutex_lock(&fcoe_transports_lock);
|
||||
list_for_each_entry(t, &fcoe_transports, list) {
|
||||
if (fcoe_transport_match(t, netdev)) {
|
||||
mutex_unlock(&fcoe_transports_lock);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&fcoe_transports_lock);
|
||||
|
||||
printk(KERN_DEBUG "fcoe_transport_lookup:"
|
||||
"use default transport for %s\n", netdev->name);
|
||||
return fcoe_transport_default();
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_transport_register() - Adds a fcoe transport to the fcoe transports list
|
||||
* @t: ptr to the fcoe transport to be added
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
int fcoe_transport_register(struct fcoe_transport *t)
|
||||
{
|
||||
struct fcoe_transport *tt;
|
||||
|
||||
/* TODO - add fcoe_transport specific initialization here */
|
||||
mutex_lock(&fcoe_transports_lock);
|
||||
list_for_each_entry(tt, &fcoe_transports, list) {
|
||||
if (tt == t) {
|
||||
mutex_unlock(&fcoe_transports_lock);
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
list_add_tail(&t->list, &fcoe_transports);
|
||||
mutex_unlock(&fcoe_transports_lock);
|
||||
|
||||
printk(KERN_DEBUG "fcoe_transport_register:%s\n", t->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fcoe_transport_register);
|
||||
|
||||
/**
|
||||
* fcoe_transport_unregister() - Remove the tranport fro the fcoe transports list
|
||||
* @t: ptr to the fcoe transport to be removed
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
int fcoe_transport_unregister(struct fcoe_transport *t)
|
||||
{
|
||||
struct fcoe_transport *tt, *tmp;
|
||||
|
||||
mutex_lock(&fcoe_transports_lock);
|
||||
list_for_each_entry_safe(tt, tmp, &fcoe_transports, list) {
|
||||
if (tt == t) {
|
||||
list_del(&t->list);
|
||||
mutex_unlock(&fcoe_transports_lock);
|
||||
fcoe_transport_device_remove_all(t);
|
||||
printk(KERN_DEBUG "fcoe_transport_unregister:%s\n",
|
||||
t->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&fcoe_transports_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fcoe_transport_unregister);
|
||||
|
||||
/**
|
||||
* fcoe_load_transport_driver() - Load an offload driver by alias name
|
||||
* @netdev: the target net device
|
||||
*
|
||||
* Requests for an offload driver module as the fcoe transport, if fails, it
|
||||
* falls back to use the SW HBA (fcoe_sw) as its transport
|
||||
*
|
||||
* TODO -
|
||||
* 1. supports only PCI device
|
||||
* 2. needs fix for VLAn and bonding
|
||||
* 3. pure hw fcoe hba may not have netdev
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
int fcoe_load_transport_driver(struct net_device *netdev)
|
||||
{
|
||||
struct pci_dev *pci;
|
||||
struct device *dev = netdev->dev.parent;
|
||||
|
||||
if (fcoe_transport_lookup(netdev)) {
|
||||
/* load default transport */
|
||||
printk(KERN_DEBUG "fcoe: already loaded transport for %s\n",
|
||||
netdev->name);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
pci = to_pci_dev(dev);
|
||||
if (dev->bus != &pci_bus_type) {
|
||||
printk(KERN_DEBUG "fcoe: support noly PCI device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
printk(KERN_DEBUG "fcoe: loading driver fcoe-pci-0x%04x-0x%04x\n",
|
||||
pci->vendor, pci->device);
|
||||
|
||||
return request_module("fcoe-pci-0x%04x-0x%04x",
|
||||
pci->vendor, pci->device);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fcoe_load_transport_driver);
|
||||
|
||||
/**
|
||||
* fcoe_transport_attach() - Load transport to fcoe
|
||||
* @netdev: the netdev the transport to be attached to
|
||||
*
|
||||
* This will look for existing offload driver, if not found, it falls back to
|
||||
* the default sw hba (fcoe_sw) as its fcoe transport.
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
int fcoe_transport_attach(struct net_device *netdev)
|
||||
{
|
||||
struct fcoe_transport *t;
|
||||
|
||||
/* find the corresponding transport */
|
||||
t = fcoe_transport_lookup(netdev);
|
||||
if (!t) {
|
||||
printk(KERN_DEBUG "fcoe_transport_attach"
|
||||
":no transport for %s:use %s\n",
|
||||
netdev->name, t->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
/* add to the transport */
|
||||
if (fcoe_transport_device_add(t, netdev)) {
|
||||
printk(KERN_DEBUG "fcoe_transport_attach"
|
||||
":failed to add %s to tramsport %s\n",
|
||||
netdev->name, t->name);
|
||||
return -EIO;
|
||||
}
|
||||
/* transport create function */
|
||||
if (t->create)
|
||||
t->create(netdev);
|
||||
|
||||
printk(KERN_DEBUG "fcoe_transport_attach:transport %s for %s\n",
|
||||
t->name, netdev->name);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fcoe_transport_attach);
|
||||
|
||||
/**
|
||||
* fcoe_transport_release() - Unload transport from fcoe
|
||||
* @netdev: the net device on which fcoe is to be released
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
int fcoe_transport_release(struct net_device *netdev)
|
||||
{
|
||||
struct fcoe_transport *t;
|
||||
|
||||
/* find the corresponding transport */
|
||||
t = fcoe_transport_lookup(netdev);
|
||||
if (!t) {
|
||||
printk(KERN_DEBUG "fcoe_transport_release:"
|
||||
"no transport for %s:use %s\n",
|
||||
netdev->name, t->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
/* remove the device from the transport */
|
||||
if (fcoe_transport_device_remove(t, netdev)) {
|
||||
printk(KERN_DEBUG "fcoe_transport_release:"
|
||||
"failed to add %s to tramsport %s\n",
|
||||
netdev->name, t->name);
|
||||
return -EIO;
|
||||
}
|
||||
/* transport destroy function */
|
||||
if (t->destroy)
|
||||
t->destroy(netdev);
|
||||
|
||||
printk(KERN_DEBUG "fcoe_transport_release:"
|
||||
"device %s dettached from transport %s\n",
|
||||
netdev->name, t->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fcoe_transport_release);
|
||||
|
||||
/**
|
||||
* fcoe_transport_init() - Initializes fcoe transport layer
|
||||
*
|
||||
* This prepares for the fcoe transport layer
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
int __init fcoe_transport_init(void)
|
||||
{
|
||||
INIT_LIST_HEAD(&fcoe_transports);
|
||||
mutex_init(&fcoe_transports_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_transport_exit() - Cleans up the fcoe transport layer
|
||||
*
|
||||
* This cleans up the fcoe transport layer. removing any transport on the list,
|
||||
* note that the transport destroy func is not called here.
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
int __exit fcoe_transport_exit(void)
|
||||
{
|
||||
struct fcoe_transport *t, *tmp;
|
||||
|
||||
mutex_lock(&fcoe_transports_lock);
|
||||
list_for_each_entry_safe(t, tmp, &fcoe_transports, list) {
|
||||
list_del(&t->list);
|
||||
mutex_unlock(&fcoe_transports_lock);
|
||||
fcoe_transport_device_remove_all(t);
|
||||
mutex_lock(&fcoe_transports_lock);
|
||||
}
|
||||
mutex_unlock(&fcoe_transports_lock);
|
||||
return 0;
|
||||
}
|
1878
drivers/scsi/fcoe/fcoe.c
Normal file
1878
drivers/scsi/fcoe/fcoe.c
Normal file
File diff suppressed because it is too large
Load Diff
75
drivers/scsi/fcoe/fcoe.h
Normal file
75
drivers/scsi/fcoe/fcoe.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright(c) 2009 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Maintained at www.Open-FCoE.org
|
||||
*/
|
||||
|
||||
#ifndef _FCOE_H_
|
||||
#define _FCOE_H_
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
#define FCOE_MAX_QUEUE_DEPTH 256
|
||||
#define FCOE_LOW_QUEUE_DEPTH 32
|
||||
|
||||
#define FCOE_WORD_TO_BYTE 4
|
||||
|
||||
#define FCOE_VERSION "0.1"
|
||||
#define FCOE_NAME "fcoe"
|
||||
#define FCOE_VENDOR "Open-FCoE.org"
|
||||
|
||||
#define FCOE_MAX_LUN 255
|
||||
#define FCOE_MAX_FCP_TARGET 256
|
||||
|
||||
#define FCOE_MAX_OUTSTANDING_COMMANDS 1024
|
||||
|
||||
#define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */
|
||||
#define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */
|
||||
|
||||
/*
|
||||
* this percpu struct for fcoe
|
||||
*/
|
||||
struct fcoe_percpu_s {
|
||||
struct task_struct *thread;
|
||||
struct sk_buff_head fcoe_rx_list;
|
||||
struct page *crc_eof_page;
|
||||
int crc_eof_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* the fcoe sw transport private data
|
||||
*/
|
||||
struct fcoe_softc {
|
||||
struct list_head list;
|
||||
struct net_device *real_dev;
|
||||
struct net_device *phys_dev; /* device with ethtool_ops */
|
||||
struct packet_type fcoe_packet_type;
|
||||
struct packet_type fip_packet_type;
|
||||
struct sk_buff_head fcoe_pending_queue;
|
||||
u8 fcoe_pending_queue_active;
|
||||
struct fcoe_ctlr ctlr;
|
||||
};
|
||||
|
||||
#define fcoe_from_ctlr(fc) container_of(fc, struct fcoe_softc, ctlr)
|
||||
|
||||
static inline struct net_device *fcoe_netdev(
|
||||
const struct fc_lport *lp)
|
||||
{
|
||||
return ((struct fcoe_softc *)lport_priv(lp))->real_dev;
|
||||
}
|
||||
|
||||
#endif /* _FCOE_H_ */
|
@ -1,561 +0,0 @@
|
||||
/*
|
||||
* Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Maintained at www.Open-FCoE.org
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <net/rtnetlink.h>
|
||||
|
||||
#include <scsi/fc/fc_els.h>
|
||||
#include <scsi/fc/fc_encaps.h>
|
||||
#include <scsi/fc/fc_fs.h>
|
||||
#include <scsi/scsi_transport.h>
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
|
||||
#include <scsi/libfc.h>
|
||||
#include <scsi/libfcoe.h>
|
||||
#include <scsi/fc_transport_fcoe.h>
|
||||
|
||||
#define FCOE_SW_VERSION "0.1"
|
||||
#define FCOE_SW_NAME "fcoesw"
|
||||
#define FCOE_SW_VENDOR "Open-FCoE.org"
|
||||
|
||||
#define FCOE_MAX_LUN 255
|
||||
#define FCOE_MAX_FCP_TARGET 256
|
||||
|
||||
#define FCOE_MAX_OUTSTANDING_COMMANDS 1024
|
||||
|
||||
#define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */
|
||||
#define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */
|
||||
|
||||
static struct scsi_transport_template *scsi_transport_fcoe_sw;
|
||||
|
||||
struct fc_function_template fcoe_sw_transport_function = {
|
||||
.show_host_node_name = 1,
|
||||
.show_host_port_name = 1,
|
||||
.show_host_supported_classes = 1,
|
||||
.show_host_supported_fc4s = 1,
|
||||
.show_host_active_fc4s = 1,
|
||||
.show_host_maxframe_size = 1,
|
||||
|
||||
.show_host_port_id = 1,
|
||||
.show_host_supported_speeds = 1,
|
||||
.get_host_speed = fc_get_host_speed,
|
||||
.show_host_speed = 1,
|
||||
.show_host_port_type = 1,
|
||||
.get_host_port_state = fc_get_host_port_state,
|
||||
.show_host_port_state = 1,
|
||||
.show_host_symbolic_name = 1,
|
||||
|
||||
.dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
|
||||
.show_rport_maxframe_size = 1,
|
||||
.show_rport_supported_classes = 1,
|
||||
|
||||
.show_host_fabric_name = 1,
|
||||
.show_starget_node_name = 1,
|
||||
.show_starget_port_name = 1,
|
||||
.show_starget_port_id = 1,
|
||||
.set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
|
||||
.show_rport_dev_loss_tmo = 1,
|
||||
.get_fc_host_stats = fc_get_host_stats,
|
||||
.issue_fc_host_lip = fcoe_reset,
|
||||
|
||||
.terminate_rport_io = fc_rport_terminate_io,
|
||||
};
|
||||
|
||||
static struct scsi_host_template fcoe_sw_shost_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = "FCoE Driver",
|
||||
.proc_name = FCOE_SW_NAME,
|
||||
.queuecommand = fc_queuecommand,
|
||||
.eh_abort_handler = fc_eh_abort,
|
||||
.eh_device_reset_handler = fc_eh_device_reset,
|
||||
.eh_host_reset_handler = fc_eh_host_reset,
|
||||
.slave_alloc = fc_slave_alloc,
|
||||
.change_queue_depth = fc_change_queue_depth,
|
||||
.change_queue_type = fc_change_queue_type,
|
||||
.this_id = -1,
|
||||
.cmd_per_lun = 32,
|
||||
.can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.sg_tablesize = SG_ALL,
|
||||
.max_sectors = 0xffff,
|
||||
};
|
||||
|
||||
/**
|
||||
* fcoe_sw_lport_config() - sets up the fc_lport
|
||||
* @lp: ptr to the fc_lport
|
||||
* @shost: ptr to the parent scsi host
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
static int fcoe_sw_lport_config(struct fc_lport *lp)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
lp->link_up = 0;
|
||||
lp->qfull = 0;
|
||||
lp->max_retry_count = 3;
|
||||
lp->e_d_tov = 2 * 1000; /* FC-FS default */
|
||||
lp->r_a_tov = 2 * 2 * 1000;
|
||||
lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
|
||||
FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
|
||||
|
||||
/*
|
||||
* allocate per cpu stats block
|
||||
*/
|
||||
for_each_online_cpu(i)
|
||||
lp->dev_stats[i] = kzalloc(sizeof(struct fcoe_dev_stats),
|
||||
GFP_KERNEL);
|
||||
|
||||
/* lport fc_lport related configuration */
|
||||
fc_lport_config(lp);
|
||||
|
||||
/* offload related configuration */
|
||||
lp->crc_offload = 0;
|
||||
lp->seq_offload = 0;
|
||||
lp->lro_enabled = 0;
|
||||
lp->lro_xid = 0;
|
||||
lp->lso_max = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_sw_netdev_config() - Set up netdev for SW FCoE
|
||||
* @lp : ptr to the fc_lport
|
||||
* @netdev : ptr to the associated netdevice struct
|
||||
*
|
||||
* Must be called after fcoe_sw_lport_config() as it will use lport mutex
|
||||
*
|
||||
* Returns : 0 for success
|
||||
*/
|
||||
static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
|
||||
{
|
||||
u32 mfs;
|
||||
u64 wwnn, wwpn;
|
||||
struct fcoe_softc *fc;
|
||||
u8 flogi_maddr[ETH_ALEN];
|
||||
|
||||
/* Setup lport private data to point to fcoe softc */
|
||||
fc = lport_priv(lp);
|
||||
fc->lp = lp;
|
||||
fc->real_dev = netdev;
|
||||
fc->phys_dev = netdev;
|
||||
|
||||
/* Require support for get_pauseparam ethtool op. */
|
||||
if (netdev->priv_flags & IFF_802_1Q_VLAN)
|
||||
fc->phys_dev = vlan_dev_real_dev(netdev);
|
||||
|
||||
/* Do not support for bonding device */
|
||||
if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
|
||||
(fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
|
||||
(fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine max frame size based on underlying device and optional
|
||||
* user-configured limit. If the MFS is too low, fcoe_link_ok()
|
||||
* will return 0, so do this first.
|
||||
*/
|
||||
mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
|
||||
sizeof(struct fcoe_crc_eof));
|
||||
if (fc_set_mfs(lp, mfs))
|
||||
return -EINVAL;
|
||||
|
||||
if (!fcoe_link_ok(lp))
|
||||
lp->link_up = 1;
|
||||
|
||||
/* offload features support */
|
||||
if (fc->real_dev->features & NETIF_F_SG)
|
||||
lp->sg_supp = 1;
|
||||
|
||||
#ifdef NETIF_F_FCOE_CRC
|
||||
if (netdev->features & NETIF_F_FCOE_CRC) {
|
||||
lp->crc_offload = 1;
|
||||
printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n",
|
||||
netdev->name);
|
||||
}
|
||||
#endif
|
||||
#ifdef NETIF_F_FSO
|
||||
if (netdev->features & NETIF_F_FSO) {
|
||||
lp->seq_offload = 1;
|
||||
lp->lso_max = netdev->gso_max_size;
|
||||
printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n",
|
||||
netdev->name, lp->lso_max);
|
||||
}
|
||||
#endif
|
||||
if (netdev->fcoe_ddp_xid) {
|
||||
lp->lro_enabled = 1;
|
||||
lp->lro_xid = netdev->fcoe_ddp_xid;
|
||||
printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n",
|
||||
netdev->name, lp->lro_xid);
|
||||
}
|
||||
skb_queue_head_init(&fc->fcoe_pending_queue);
|
||||
fc->fcoe_pending_queue_active = 0;
|
||||
|
||||
/* setup Source Mac Address */
|
||||
memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr,
|
||||
fc->real_dev->addr_len);
|
||||
|
||||
wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
|
||||
fc_set_wwnn(lp, wwnn);
|
||||
/* XXX - 3rd arg needs to be vlan id */
|
||||
wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
|
||||
fc_set_wwpn(lp, wwpn);
|
||||
|
||||
/*
|
||||
* Add FCoE MAC address as second unicast MAC address
|
||||
* or enter promiscuous mode if not capable of listening
|
||||
* for multiple unicast MACs.
|
||||
*/
|
||||
rtnl_lock();
|
||||
memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
|
||||
dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
|
||||
rtnl_unlock();
|
||||
|
||||
/*
|
||||
* setup the receive function from ethernet driver
|
||||
* on the ethertype for the given device
|
||||
*/
|
||||
fc->fcoe_packet_type.func = fcoe_rcv;
|
||||
fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
|
||||
fc->fcoe_packet_type.dev = fc->real_dev;
|
||||
dev_add_pack(&fc->fcoe_packet_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_sw_shost_config() - Sets up fc_lport->host
|
||||
* @lp : ptr to the fc_lport
|
||||
* @shost : ptr to the associated scsi host
|
||||
* @dev : device associated to scsi host
|
||||
*
|
||||
* Must be called after fcoe_sw_lport_config() and fcoe_sw_netdev_config()
|
||||
*
|
||||
* Returns : 0 for success
|
||||
*/
|
||||
static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
|
||||
struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* lport scsi host config */
|
||||
lp->host = shost;
|
||||
|
||||
lp->host->max_lun = FCOE_MAX_LUN;
|
||||
lp->host->max_id = FCOE_MAX_FCP_TARGET;
|
||||
lp->host->max_channel = 0;
|
||||
lp->host->transportt = scsi_transport_fcoe_sw;
|
||||
|
||||
/* add the new host to the SCSI-ml */
|
||||
rc = scsi_add_host(lp->host, dev);
|
||||
if (rc) {
|
||||
FC_DBG("fcoe_sw_shost_config:error on scsi_add_host\n");
|
||||
return rc;
|
||||
}
|
||||
sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
|
||||
FCOE_SW_NAME, FCOE_SW_VERSION,
|
||||
fcoe_netdev(lp)->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_sw_em_config() - allocates em for this lport
|
||||
* @lp: the port that em is to allocated for
|
||||
*
|
||||
* Returns : 0 on success
|
||||
*/
|
||||
static inline int fcoe_sw_em_config(struct fc_lport *lp)
|
||||
{
|
||||
BUG_ON(lp->emp);
|
||||
|
||||
lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
|
||||
FCOE_MIN_XID, FCOE_MAX_XID);
|
||||
if (!lp->emp)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_sw_destroy() - FCoE software HBA tear-down function
|
||||
* @netdev: ptr to the associated net_device
|
||||
*
|
||||
* Returns: 0 if link is OK for use by FCoE.
|
||||
*/
|
||||
static int fcoe_sw_destroy(struct net_device *netdev)
|
||||
{
|
||||
int cpu;
|
||||
struct fc_lport *lp = NULL;
|
||||
struct fcoe_softc *fc;
|
||||
u8 flogi_maddr[ETH_ALEN];
|
||||
|
||||
BUG_ON(!netdev);
|
||||
|
||||
printk(KERN_DEBUG "fcoe_sw_destroy:interface on %s\n",
|
||||
netdev->name);
|
||||
|
||||
lp = fcoe_hostlist_lookup(netdev);
|
||||
if (!lp)
|
||||
return -ENODEV;
|
||||
|
||||
fc = lport_priv(lp);
|
||||
|
||||
/* Logout of the fabric */
|
||||
fc_fabric_logoff(lp);
|
||||
|
||||
/* Remove the instance from fcoe's list */
|
||||
fcoe_hostlist_remove(lp);
|
||||
|
||||
/* Don't listen for Ethernet packets anymore */
|
||||
dev_remove_pack(&fc->fcoe_packet_type);
|
||||
|
||||
/* Cleanup the fc_lport */
|
||||
fc_lport_destroy(lp);
|
||||
fc_fcp_destroy(lp);
|
||||
|
||||
/* Detach from the scsi-ml */
|
||||
fc_remove_host(lp->host);
|
||||
scsi_remove_host(lp->host);
|
||||
|
||||
/* There are no more rports or I/O, free the EM */
|
||||
if (lp->emp)
|
||||
fc_exch_mgr_free(lp->emp);
|
||||
|
||||
/* Delete secondary MAC addresses */
|
||||
rtnl_lock();
|
||||
memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
|
||||
dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
|
||||
if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
|
||||
dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN);
|
||||
rtnl_unlock();
|
||||
|
||||
/* Free the per-CPU revieve threads */
|
||||
fcoe_percpu_clean(lp);
|
||||
|
||||
/* Free existing skbs */
|
||||
fcoe_clean_pending_queue(lp);
|
||||
|
||||
/* Free memory used by statistical counters */
|
||||
for_each_online_cpu(cpu)
|
||||
kfree(lp->dev_stats[cpu]);
|
||||
|
||||
/* Release the net_device and Scsi_Host */
|
||||
dev_put(fc->real_dev);
|
||||
scsi_host_put(lp->host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* fcoe_sw_ddp_setup - calls LLD's ddp_setup through net_device
|
||||
* @lp: the corresponding fc_lport
|
||||
* @xid: the exchange id for this ddp transfer
|
||||
* @sgl: the scatterlist describing this transfer
|
||||
* @sgc: number of sg items
|
||||
*
|
||||
* Returns : 0 no ddp
|
||||
*/
|
||||
static int fcoe_sw_ddp_setup(struct fc_lport *lp, u16 xid,
|
||||
struct scatterlist *sgl, unsigned int sgc)
|
||||
{
|
||||
struct net_device *n = fcoe_netdev(lp);
|
||||
|
||||
if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
|
||||
return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* fcoe_sw_ddp_done - calls LLD's ddp_done through net_device
|
||||
* @lp: the corresponding fc_lport
|
||||
* @xid: the exchange id for this ddp transfer
|
||||
*
|
||||
* Returns : the length of data that have been completed by ddp
|
||||
*/
|
||||
static int fcoe_sw_ddp_done(struct fc_lport *lp, u16 xid)
|
||||
{
|
||||
struct net_device *n = fcoe_netdev(lp);
|
||||
|
||||
if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
|
||||
return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct libfc_function_template fcoe_sw_libfc_fcn_templ = {
|
||||
.frame_send = fcoe_xmit,
|
||||
.ddp_setup = fcoe_sw_ddp_setup,
|
||||
.ddp_done = fcoe_sw_ddp_done,
|
||||
};
|
||||
|
||||
/**
|
||||
* fcoe_sw_create() - this function creates the fcoe interface
|
||||
* @netdev: pointer the associated netdevice
|
||||
*
|
||||
* Creates fc_lport struct and scsi_host for lport, configures lport
|
||||
* and starts fabric login.
|
||||
*
|
||||
* Returns : 0 on success
|
||||
*/
|
||||
static int fcoe_sw_create(struct net_device *netdev)
|
||||
{
|
||||
int rc;
|
||||
struct fc_lport *lp = NULL;
|
||||
struct fcoe_softc *fc;
|
||||
struct Scsi_Host *shost;
|
||||
|
||||
BUG_ON(!netdev);
|
||||
|
||||
printk(KERN_DEBUG "fcoe_sw_create:interface on %s\n",
|
||||
netdev->name);
|
||||
|
||||
lp = fcoe_hostlist_lookup(netdev);
|
||||
if (lp)
|
||||
return -EEXIST;
|
||||
|
||||
shost = fcoe_host_alloc(&fcoe_sw_shost_template,
|
||||
sizeof(struct fcoe_softc));
|
||||
if (!shost) {
|
||||
FC_DBG("Could not allocate host structure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
lp = shost_priv(shost);
|
||||
fc = lport_priv(lp);
|
||||
|
||||
/* configure fc_lport, e.g., em */
|
||||
rc = fcoe_sw_lport_config(lp);
|
||||
if (rc) {
|
||||
FC_DBG("Could not configure lport\n");
|
||||
goto out_host_put;
|
||||
}
|
||||
|
||||
/* configure lport network properties */
|
||||
rc = fcoe_sw_netdev_config(lp, netdev);
|
||||
if (rc) {
|
||||
FC_DBG("Could not configure netdev for lport\n");
|
||||
goto out_host_put;
|
||||
}
|
||||
|
||||
/* configure lport scsi host properties */
|
||||
rc = fcoe_sw_shost_config(lp, shost, &netdev->dev);
|
||||
if (rc) {
|
||||
FC_DBG("Could not configure shost for lport\n");
|
||||
goto out_host_put;
|
||||
}
|
||||
|
||||
/* lport exch manager allocation */
|
||||
rc = fcoe_sw_em_config(lp);
|
||||
if (rc) {
|
||||
FC_DBG("Could not configure em for lport\n");
|
||||
goto out_host_put;
|
||||
}
|
||||
|
||||
/* Initialize the library */
|
||||
rc = fcoe_libfc_config(lp, &fcoe_sw_libfc_fcn_templ);
|
||||
if (rc) {
|
||||
FC_DBG("Could not configure libfc for lport!\n");
|
||||
goto out_lp_destroy;
|
||||
}
|
||||
|
||||
/* add to lports list */
|
||||
fcoe_hostlist_add(lp);
|
||||
|
||||
lp->boot_time = jiffies;
|
||||
|
||||
fc_fabric_login(lp);
|
||||
|
||||
dev_hold(netdev);
|
||||
|
||||
return rc;
|
||||
|
||||
out_lp_destroy:
|
||||
fc_exch_mgr_free(lp->emp); /* Free the EM */
|
||||
out_host_put:
|
||||
scsi_host_put(lp->host);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_sw_match() - The FCoE SW transport match function
|
||||
*
|
||||
* Returns : false always
|
||||
*/
|
||||
static bool fcoe_sw_match(struct net_device *netdev)
|
||||
{
|
||||
/* FIXME - for sw transport, always return false */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* the sw hba fcoe transport */
|
||||
struct fcoe_transport fcoe_sw_transport = {
|
||||
.name = "fcoesw",
|
||||
.create = fcoe_sw_create,
|
||||
.destroy = fcoe_sw_destroy,
|
||||
.match = fcoe_sw_match,
|
||||
.vendor = 0x0,
|
||||
.device = 0xffff,
|
||||
};
|
||||
|
||||
/**
|
||||
* fcoe_sw_init() - Registers fcoe_sw_transport
|
||||
*
|
||||
* Returns : 0 on success
|
||||
*/
|
||||
int __init fcoe_sw_init(void)
|
||||
{
|
||||
/* attach to scsi transport */
|
||||
scsi_transport_fcoe_sw =
|
||||
fc_attach_transport(&fcoe_sw_transport_function);
|
||||
|
||||
if (!scsi_transport_fcoe_sw) {
|
||||
printk(KERN_ERR "fcoe_sw_init:fc_attach_transport() failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_init(&fcoe_sw_transport.devlock);
|
||||
INIT_LIST_HEAD(&fcoe_sw_transport.devlist);
|
||||
|
||||
/* register sw transport */
|
||||
fcoe_transport_register(&fcoe_sw_transport);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fcoe_sw_exit() - Unregisters fcoe_sw_transport
|
||||
*
|
||||
* Returns : 0 on success
|
||||
*/
|
||||
int __exit fcoe_sw_exit(void)
|
||||
{
|
||||
/* dettach the transport */
|
||||
fc_release_transport(scsi_transport_fcoe_sw);
|
||||
fcoe_transport_unregister(&fcoe_sw_transport);
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -75,7 +75,7 @@ MODULE_PARM_DESC(max_lun, "Maximum allowed LUN. "
|
||||
module_param_named(max_targets, max_targets, uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(max_targets, "Maximum allowed targets. "
|
||||
"[Default=" __stringify(IBMVFC_MAX_TARGETS) "]");
|
||||
module_param_named(disc_threads, disc_threads, uint, S_IRUGO | S_IWUSR);
|
||||
module_param_named(disc_threads, disc_threads, uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(disc_threads, "Number of device discovery threads to use. "
|
||||
"[Default=" __stringify(IBMVFC_MAX_DISC_THREADS) "]");
|
||||
module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR);
|
||||
@ -640,6 +640,7 @@ static void ibmvfc_release_crq_queue(struct ibmvfc_host *vhost)
|
||||
|
||||
ibmvfc_dbg(vhost, "Releasing CRQ\n");
|
||||
free_irq(vdev->irq, vhost);
|
||||
tasklet_kill(&vhost->tasklet);
|
||||
do {
|
||||
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
|
||||
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
|
||||
@ -2699,6 +2700,25 @@ static struct ibmvfc_crq *ibmvfc_next_crq(struct ibmvfc_host *vhost)
|
||||
static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
|
||||
{
|
||||
struct ibmvfc_host *vhost = (struct ibmvfc_host *)dev_instance;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(vhost->host->host_lock, flags);
|
||||
vio_disable_interrupts(to_vio_dev(vhost->dev));
|
||||
tasklet_schedule(&vhost->tasklet);
|
||||
spin_unlock_irqrestore(vhost->host->host_lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* ibmvfc_tasklet - Interrupt handler tasklet
|
||||
* @data: ibmvfc host struct
|
||||
*
|
||||
* Returns:
|
||||
* Nothing
|
||||
**/
|
||||
static void ibmvfc_tasklet(void *data)
|
||||
{
|
||||
struct ibmvfc_host *vhost = data;
|
||||
struct vio_dev *vdev = to_vio_dev(vhost->dev);
|
||||
struct ibmvfc_crq *crq;
|
||||
struct ibmvfc_async_crq *async;
|
||||
@ -2706,7 +2726,6 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
|
||||
int done = 0;
|
||||
|
||||
spin_lock_irqsave(vhost->host->host_lock, flags);
|
||||
vio_disable_interrupts(to_vio_dev(vhost->dev));
|
||||
while (!done) {
|
||||
/* Pull all the valid messages off the CRQ */
|
||||
while ((crq = ibmvfc_next_crq(vhost)) != NULL) {
|
||||
@ -2734,7 +2753,6 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(vhost->host->host_lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3105,6 +3123,7 @@ static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt)
|
||||
|
||||
vhost->discovery_threads--;
|
||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
|
||||
del_timer(&tgt->timer);
|
||||
|
||||
switch (status) {
|
||||
case IBMVFC_MAD_SUCCESS:
|
||||
@ -3160,10 +3179,90 @@ static void ibmvfc_init_passthru(struct ibmvfc_event *evt)
|
||||
mad->iu.rsp.len = sizeof(mad->fc_iu.response);
|
||||
}
|
||||
|
||||
/**
|
||||
* ibmvfc_tgt_adisc_cancel_done - Completion handler when cancelling an ADISC
|
||||
* @evt: ibmvfc event struct
|
||||
*
|
||||
* Just cleanup this event struct. Everything else is handled by
|
||||
* the ADISC completion handler. If the ADISC never actually comes
|
||||
* back, we still have the timer running on the ADISC event struct
|
||||
* which will fire and cause the CRQ to get reset.
|
||||
*
|
||||
**/
|
||||
static void ibmvfc_tgt_adisc_cancel_done(struct ibmvfc_event *evt)
|
||||
{
|
||||
struct ibmvfc_host *vhost = evt->vhost;
|
||||
struct ibmvfc_target *tgt = evt->tgt;
|
||||
|
||||
tgt_dbg(tgt, "ADISC cancel complete\n");
|
||||
vhost->abort_threads--;
|
||||
ibmvfc_free_event(evt);
|
||||
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||
wake_up(&vhost->work_wait_q);
|
||||
}
|
||||
|
||||
/**
|
||||
* ibmvfc_adisc_timeout - Handle an ADISC timeout
|
||||
* @tgt: ibmvfc target struct
|
||||
*
|
||||
* If an ADISC times out, send a cancel. If the cancel times
|
||||
* out, reset the CRQ. When the ADISC comes back as cancelled,
|
||||
* log back into the target.
|
||||
**/
|
||||
static void ibmvfc_adisc_timeout(struct ibmvfc_target *tgt)
|
||||
{
|
||||
struct ibmvfc_host *vhost = tgt->vhost;
|
||||
struct ibmvfc_event *evt;
|
||||
struct ibmvfc_tmf *tmf;
|
||||
unsigned long flags;
|
||||
int rc;
|
||||
|
||||
tgt_dbg(tgt, "ADISC timeout\n");
|
||||
spin_lock_irqsave(vhost->host->host_lock, flags);
|
||||
if (vhost->abort_threads >= disc_threads ||
|
||||
tgt->action != IBMVFC_TGT_ACTION_INIT_WAIT ||
|
||||
vhost->state != IBMVFC_INITIALIZING ||
|
||||
vhost->action != IBMVFC_HOST_ACTION_QUERY_TGTS) {
|
||||
spin_unlock_irqrestore(vhost->host->host_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
vhost->abort_threads++;
|
||||
kref_get(&tgt->kref);
|
||||
evt = ibmvfc_get_event(vhost);
|
||||
ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT);
|
||||
|
||||
evt->tgt = tgt;
|
||||
tmf = &evt->iu.tmf;
|
||||
memset(tmf, 0, sizeof(*tmf));
|
||||
tmf->common.version = 1;
|
||||
tmf->common.opcode = IBMVFC_TMF_MAD;
|
||||
tmf->common.length = sizeof(*tmf);
|
||||
tmf->scsi_id = tgt->scsi_id;
|
||||
tmf->cancel_key = tgt->cancel_key;
|
||||
|
||||
rc = ibmvfc_send_event(evt, vhost, default_timeout);
|
||||
|
||||
if (rc) {
|
||||
tgt_err(tgt, "Failed to send cancel event for ADISC. rc=%d\n", rc);
|
||||
vhost->abort_threads--;
|
||||
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||
__ibmvfc_reset_host(vhost);
|
||||
} else
|
||||
tgt_dbg(tgt, "Attempting to cancel ADISC\n");
|
||||
spin_unlock_irqrestore(vhost->host->host_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* ibmvfc_tgt_adisc - Initiate an ADISC for specified target
|
||||
* @tgt: ibmvfc target struct
|
||||
*
|
||||
* When sending an ADISC we end up with two timers running. The
|
||||
* first timer is the timer in the ibmvfc target struct. If this
|
||||
* fires, we send a cancel to the target. The second timer is the
|
||||
* timer on the ibmvfc event for the ADISC, which is longer. If that
|
||||
* fires, it means the ADISC timed out and our attempt to cancel it
|
||||
* also failed, so we need to reset the CRQ.
|
||||
**/
|
||||
static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
|
||||
{
|
||||
@ -3184,6 +3283,7 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
|
||||
mad = &evt->iu.passthru;
|
||||
mad->iu.flags = IBMVFC_FC_ELS;
|
||||
mad->iu.scsi_id = tgt->scsi_id;
|
||||
mad->iu.cancel_key = tgt->cancel_key;
|
||||
|
||||
mad->fc_iu.payload[0] = IBMVFC_ADISC;
|
||||
memcpy(&mad->fc_iu.payload[2], &vhost->login_buf->resp.port_name,
|
||||
@ -3192,9 +3292,19 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
|
||||
sizeof(vhost->login_buf->resp.node_name));
|
||||
mad->fc_iu.payload[6] = vhost->login_buf->resp.scsi_id & 0x00ffffff;
|
||||
|
||||
if (timer_pending(&tgt->timer))
|
||||
mod_timer(&tgt->timer, jiffies + (IBMVFC_ADISC_TIMEOUT * HZ));
|
||||
else {
|
||||
tgt->timer.data = (unsigned long) tgt;
|
||||
tgt->timer.expires = jiffies + (IBMVFC_ADISC_TIMEOUT * HZ);
|
||||
tgt->timer.function = (void (*)(unsigned long))ibmvfc_adisc_timeout;
|
||||
add_timer(&tgt->timer);
|
||||
}
|
||||
|
||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
|
||||
if (ibmvfc_send_event(evt, vhost, default_timeout)) {
|
||||
if (ibmvfc_send_event(evt, vhost, IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT)) {
|
||||
vhost->discovery_threads--;
|
||||
del_timer(&tgt->timer);
|
||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
|
||||
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||
} else
|
||||
@ -3322,6 +3432,8 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id)
|
||||
tgt->new_scsi_id = scsi_id;
|
||||
tgt->vhost = vhost;
|
||||
tgt->need_login = 1;
|
||||
tgt->cancel_key = vhost->task_set++;
|
||||
init_timer(&tgt->timer);
|
||||
kref_init(&tgt->kref);
|
||||
ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
|
||||
spin_lock_irqsave(vhost->host->host_lock, flags);
|
||||
@ -3716,6 +3828,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
|
||||
spin_unlock_irqrestore(vhost->host->host_lock, flags);
|
||||
if (rport)
|
||||
fc_remote_port_delete(rport);
|
||||
del_timer_sync(&tgt->timer);
|
||||
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||
return;
|
||||
}
|
||||
@ -3859,6 +3972,8 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
|
||||
|
||||
retrc = 0;
|
||||
|
||||
tasklet_init(&vhost->tasklet, (void *)ibmvfc_tasklet, (unsigned long)vhost);
|
||||
|
||||
if ((rc = request_irq(vdev->irq, ibmvfc_interrupt, 0, IBMVFC_NAME, vhost))) {
|
||||
dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n", vdev->irq, rc);
|
||||
goto req_irq_failed;
|
||||
@ -3874,6 +3989,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
|
||||
return retrc;
|
||||
|
||||
req_irq_failed:
|
||||
tasklet_kill(&vhost->tasklet);
|
||||
do {
|
||||
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
|
||||
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
|
||||
@ -4040,6 +4156,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
|
||||
vhost->dev = dev;
|
||||
vhost->partition_number = -1;
|
||||
vhost->log_level = log_level;
|
||||
vhost->task_set = 1;
|
||||
strcpy(vhost->partition_name, "UNKNOWN");
|
||||
init_waitqueue_head(&vhost->work_wait_q);
|
||||
init_waitqueue_head(&vhost->init_wait_q);
|
||||
@ -4174,6 +4291,7 @@ static struct fc_function_template ibmvfc_transport_functions = {
|
||||
.show_host_supported_classes = 1,
|
||||
.show_host_port_type = 1,
|
||||
.show_host_port_id = 1,
|
||||
.show_host_maxframe_size = 1,
|
||||
|
||||
.get_host_port_state = ibmvfc_get_host_port_state,
|
||||
.show_host_port_state = 1,
|
||||
|
@ -29,10 +29,14 @@
|
||||
#include "viosrp.h"
|
||||
|
||||
#define IBMVFC_NAME "ibmvfc"
|
||||
#define IBMVFC_DRIVER_VERSION "1.0.4"
|
||||
#define IBMVFC_DRIVER_DATE "(November 14, 2008)"
|
||||
#define IBMVFC_DRIVER_VERSION "1.0.5"
|
||||
#define IBMVFC_DRIVER_DATE "(March 19, 2009)"
|
||||
|
||||
#define IBMVFC_DEFAULT_TIMEOUT 60
|
||||
#define IBMVFC_ADISC_CANCEL_TIMEOUT 45
|
||||
#define IBMVFC_ADISC_TIMEOUT 15
|
||||
#define IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT \
|
||||
(IBMVFC_ADISC_TIMEOUT + IBMVFC_ADISC_CANCEL_TIMEOUT)
|
||||
#define IBMVFC_INIT_TIMEOUT 120
|
||||
#define IBMVFC_MAX_REQUESTS_DEFAULT 100
|
||||
|
||||
@ -53,9 +57,9 @@
|
||||
* Ensure we have resources for ERP and initialization:
|
||||
* 1 for ERP
|
||||
* 1 for initialization
|
||||
* 1 for each discovery thread
|
||||
* 2 for each discovery thread
|
||||
*/
|
||||
#define IBMVFC_NUM_INTERNAL_REQ (1 + 1 + disc_threads)
|
||||
#define IBMVFC_NUM_INTERNAL_REQ (1 + 1 + (disc_threads * 2))
|
||||
|
||||
#define IBMVFC_MAD_SUCCESS 0x00
|
||||
#define IBMVFC_MAD_NOT_SUPPORTED 0xF1
|
||||
@ -585,10 +589,12 @@ struct ibmvfc_target {
|
||||
enum ibmvfc_target_action action;
|
||||
int need_login;
|
||||
int init_retries;
|
||||
u32 cancel_key;
|
||||
struct ibmvfc_service_parms service_parms;
|
||||
struct ibmvfc_service_parms service_parms_change;
|
||||
struct fc_rport_identifiers ids;
|
||||
void (*job_step) (struct ibmvfc_target *);
|
||||
struct timer_list timer;
|
||||
struct kref kref;
|
||||
};
|
||||
|
||||
@ -672,6 +678,7 @@ struct ibmvfc_host {
|
||||
int task_set;
|
||||
int init_retries;
|
||||
int discovery_threads;
|
||||
int abort_threads;
|
||||
int client_migrated;
|
||||
int reinit;
|
||||
int delay_init;
|
||||
@ -684,6 +691,7 @@ struct ibmvfc_host {
|
||||
char partition_name[97];
|
||||
void (*job_step) (struct ibmvfc_host *);
|
||||
struct task_struct *work_thread;
|
||||
struct tasklet_struct tasklet;
|
||||
wait_queue_head_t init_wait_q;
|
||||
wait_queue_head_t work_wait_q;
|
||||
};
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
MODULE_AUTHOR("Open-FCoE.org");
|
||||
MODULE_DESCRIPTION("libfc");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
static int fc_fcp_debug;
|
||||
|
||||
@ -407,10 +407,12 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
|
||||
|
||||
if (~crc != le32_to_cpu(fr_crc(fp))) {
|
||||
crc_err:
|
||||
stats = lp->dev_stats[smp_processor_id()];
|
||||
stats = fc_lport_get_stats(lp);
|
||||
stats->ErrorFrames++;
|
||||
/* FIXME - per cpu count, not total count! */
|
||||
if (stats->InvalidCRCCount++ < 5)
|
||||
FC_DBG("CRC error on data frame\n");
|
||||
printk(KERN_WARNING "CRC error on data frame for port (%6x)\n",
|
||||
fc_host_port_id(lp->host));
|
||||
/*
|
||||
* Assume the frame is total garbage.
|
||||
* We may have copied it over the good part
|
||||
@ -1752,7 +1754,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
|
||||
/*
|
||||
* setup the data direction
|
||||
*/
|
||||
stats = lp->dev_stats[smp_processor_id()];
|
||||
stats = fc_lport_get_stats(lp);
|
||||
if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
|
||||
fsp->req_flags = FC_SRB_READ;
|
||||
stats->InputRequests++;
|
||||
|
@ -267,10 +267,10 @@ EXPORT_SYMBOL(fc_get_host_speed);
|
||||
|
||||
struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
|
||||
{
|
||||
int i;
|
||||
struct fc_host_statistics *fcoe_stats;
|
||||
struct fc_lport *lp = shost_priv(shost);
|
||||
struct timespec v0, v1;
|
||||
unsigned int cpu;
|
||||
|
||||
fcoe_stats = &lp->host_stats;
|
||||
memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
|
||||
@ -279,10 +279,11 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
|
||||
jiffies_to_timespec(lp->boot_time, &v1);
|
||||
fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec);
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
struct fcoe_dev_stats *stats = lp->dev_stats[i];
|
||||
if (stats == NULL)
|
||||
continue;
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct fcoe_dev_stats *stats;
|
||||
|
||||
stats = per_cpu_ptr(lp->dev_stats, cpu);
|
||||
|
||||
fcoe_stats->tx_frames += stats->TxFrames;
|
||||
fcoe_stats->tx_words += stats->TxWords;
|
||||
fcoe_stats->rx_frames += stats->RxFrames;
|
||||
|
@ -1999,8 +1999,10 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size)
|
||||
|
||||
q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
|
||||
GFP_KERNEL, NULL);
|
||||
if (q->queue == ERR_PTR(-ENOMEM))
|
||||
if (IS_ERR(q->queue)) {
|
||||
q->queue = NULL;
|
||||
goto enomem;
|
||||
}
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
q->pool[i] = kzalloc(item_size, GFP_KERNEL);
|
||||
|
@ -338,20 +338,6 @@ struct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp)
|
||||
}
|
||||
EXPORT_SYMBOL(osd_start_request);
|
||||
|
||||
/*
|
||||
* If osd_finalize_request() was called but the request was not executed through
|
||||
* the block layer, then we must release BIOs.
|
||||
*/
|
||||
static void _abort_unexecuted_bios(struct request *rq)
|
||||
{
|
||||
struct bio *bio;
|
||||
|
||||
while ((bio = rq->bio) != NULL) {
|
||||
rq->bio = bio->bi_next;
|
||||
bio_endio(bio, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void _osd_free_seg(struct osd_request *or __unused,
|
||||
struct _osd_req_data_segment *seg)
|
||||
{
|
||||
@ -363,9 +349,30 @@ static void _osd_free_seg(struct osd_request *or __unused,
|
||||
seg->alloc_size = 0;
|
||||
}
|
||||
|
||||
static void _put_request(struct request *rq , bool is_async)
|
||||
{
|
||||
if (is_async) {
|
||||
WARN_ON(rq->bio);
|
||||
__blk_put_request(rq->q, rq);
|
||||
} else {
|
||||
/*
|
||||
* If osd_finalize_request() was called but the request was not
|
||||
* executed through the block layer, then we must release BIOs.
|
||||
* TODO: Keep error code in or->async_error. Need to audit all
|
||||
* code paths.
|
||||
*/
|
||||
if (unlikely(rq->bio))
|
||||
blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
|
||||
else
|
||||
blk_put_request(rq);
|
||||
}
|
||||
}
|
||||
|
||||
void osd_end_request(struct osd_request *or)
|
||||
{
|
||||
struct request *rq = or->request;
|
||||
/* IMPORTANT: make sure this agrees with osd_execute_request_async */
|
||||
bool is_async = (or->request->end_io_data == or);
|
||||
|
||||
_osd_free_seg(or, &or->set_attr);
|
||||
_osd_free_seg(or, &or->enc_get_attr);
|
||||
@ -373,12 +380,11 @@ void osd_end_request(struct osd_request *or)
|
||||
|
||||
if (rq) {
|
||||
if (rq->next_rq) {
|
||||
_abort_unexecuted_bios(rq->next_rq);
|
||||
blk_put_request(rq->next_rq);
|
||||
_put_request(rq->next_rq, is_async);
|
||||
rq->next_rq = NULL;
|
||||
}
|
||||
|
||||
_abort_unexecuted_bios(rq);
|
||||
blk_put_request(rq);
|
||||
_put_request(rq, is_async);
|
||||
}
|
||||
_osd_request_free(or);
|
||||
}
|
||||
|
@ -345,10 +345,6 @@ static int osd_probe(struct device *dev)
|
||||
}
|
||||
|
||||
dev_set_drvdata(oud->class_member, oud);
|
||||
error = sysfs_create_link(&scsi_device->sdev_gendev.kobj,
|
||||
&oud->class_member->kobj, osd_symlink);
|
||||
if (error)
|
||||
OSD_ERR("warning: unable to make symlink\n");
|
||||
|
||||
OSD_INFO("osd_probe %s\n", disk->disk_name);
|
||||
return 0;
|
||||
@ -377,8 +373,6 @@ static int osd_remove(struct device *dev)
|
||||
scsi_device);
|
||||
}
|
||||
|
||||
sysfs_remove_link(&oud->od.scsi_device->sdev_gendev.kobj, osd_symlink);
|
||||
|
||||
if (oud->class_member)
|
||||
device_destroy(osd_sysfs_class,
|
||||
MKDEV(SCSI_OSD_MAJOR, oud->minor));
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -348,6 +348,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
@ -384,11 +385,7 @@
|
||||
#define MEMORY_MAPPED_IO 1
|
||||
#endif
|
||||
|
||||
#define UNIQUE_FW_NAME
|
||||
#include "qla1280.h"
|
||||
#include "ql12160_fw.h" /* ISP RISC codes */
|
||||
#include "ql1280_fw.h"
|
||||
#include "ql1040_fw.h"
|
||||
|
||||
#ifndef BITS_PER_LONG
|
||||
#error "BITS_PER_LONG not defined!"
|
||||
@ -541,10 +538,7 @@ __setup("qla1280=", qla1280_setup);
|
||||
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 */
|
||||
char *fwname; /* firmware name */
|
||||
};
|
||||
|
||||
/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
|
||||
@ -567,19 +561,13 @@ 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]},
|
||||
{"QLA1040", 1, &risc_code01[0], &risc_code_length01,
|
||||
&risc_code_addr01, &firmware_version[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}
|
||||
{"QLA12160", 2, "qlogic/12160.bin"},
|
||||
{"QLA1040", 1, "qlogic/1040.bin"},
|
||||
{"QLA1080", 1, "qlogic/1280.bin"},
|
||||
{"QLA1240", 2, "qlogic/1280.bin"},
|
||||
{"QLA1280", 2, "qlogic/1280.bin"},
|
||||
{"QLA10160", 1, "qlogic/12160.bin"},
|
||||
{" ", 0, " "},
|
||||
};
|
||||
|
||||
static int qla1280_verbose = 1;
|
||||
@ -704,7 +692,7 @@ qla1280_info(struct Scsi_Host *host)
|
||||
sprintf (bp,
|
||||
"QLogic %s PCI to SCSI Host Adapter\n"
|
||||
" Firmware version: %2d.%02d.%02d, Driver version %s",
|
||||
&bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
|
||||
&bdp->name[0], ha->fwver1, ha->fwver2, ha->fwver3,
|
||||
QLA1280_VERSION);
|
||||
return bp;
|
||||
}
|
||||
@ -1648,36 +1636,60 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
|
||||
static int
|
||||
qla1280_load_firmware_pio(struct scsi_qla_host *ha)
|
||||
{
|
||||
uint16_t risc_address, *risc_code_address, risc_code_size;
|
||||
const struct firmware *fw;
|
||||
const __le16 *fw_data;
|
||||
uint16_t risc_address, risc_code_size;
|
||||
uint16_t mb[MAILBOX_REGISTER_COUNT], i;
|
||||
int err;
|
||||
|
||||
err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
|
||||
&ha->pdev->dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
|
||||
ql1280_board_tbl[ha->devnum].fwname, err);
|
||||
return err;
|
||||
}
|
||||
if ((fw->size % 2) || (fw->size < 6)) {
|
||||
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
|
||||
fw->size, ql1280_board_tbl[ha->devnum].fwname);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ha->fwver1 = fw->data[0];
|
||||
ha->fwver2 = fw->data[1];
|
||||
ha->fwver3 = fw->data[2];
|
||||
fw_data = (const __le16 *)&fw->data[0];
|
||||
ha->fwstart = __le16_to_cpu(fw_data[2]);
|
||||
|
||||
/* Load RISC code. */
|
||||
risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
|
||||
risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
|
||||
risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
|
||||
risc_address = ha->fwstart;
|
||||
fw_data = (const __le16 *)&fw->data[4];
|
||||
risc_code_size = (fw->size - 6) / 2;
|
||||
|
||||
for (i = 0; i < risc_code_size; i++) {
|
||||
mb[0] = MBC_WRITE_RAM_WORD;
|
||||
mb[1] = risc_address + i;
|
||||
mb[2] = risc_code_address[i];
|
||||
mb[2] = __le16_to_cpu(fw_data[i]);
|
||||
|
||||
err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb);
|
||||
if (err) {
|
||||
printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
|
||||
ha->host_no);
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
#define DUMP_IT_BACK 0 /* for debug of RISC loading */
|
||||
static int
|
||||
qla1280_load_firmware_dma(struct scsi_qla_host *ha)
|
||||
{
|
||||
uint16_t risc_address, *risc_code_address, risc_code_size;
|
||||
const struct firmware *fw;
|
||||
const __le16 *fw_data;
|
||||
uint16_t risc_address, risc_code_size;
|
||||
uint16_t mb[MAILBOX_REGISTER_COUNT], cnt;
|
||||
int err = 0, num, i;
|
||||
#if DUMP_IT_BACK
|
||||
@ -1689,10 +1701,29 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
|
||||
err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
|
||||
&ha->pdev->dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
|
||||
ql1280_board_tbl[ha->devnum].fwname, err);
|
||||
return err;
|
||||
}
|
||||
if ((fw->size % 2) || (fw->size < 6)) {
|
||||
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
|
||||
fw->size, ql1280_board_tbl[ha->devnum].fwname);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ha->fwver1 = fw->data[0];
|
||||
ha->fwver2 = fw->data[1];
|
||||
ha->fwver3 = fw->data[2];
|
||||
fw_data = (const __le16 *)&fw->data[0];
|
||||
ha->fwstart = __le16_to_cpu(fw_data[2]);
|
||||
|
||||
/* Load RISC code. */
|
||||
risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
|
||||
risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
|
||||
risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
|
||||
risc_address = ha->fwstart;
|
||||
fw_data = (const __le16 *)&fw->data[4];
|
||||
risc_code_size = (fw->size - 6) / 2;
|
||||
|
||||
dprintk(1, "%s: DMA RISC code (%i) words\n",
|
||||
__func__, risc_code_size);
|
||||
@ -1708,10 +1739,9 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
|
||||
|
||||
dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p),"
|
||||
"%d,%d(0x%x)\n",
|
||||
risc_code_address, cnt, num, risc_address);
|
||||
fw_data, cnt, num, risc_address);
|
||||
for(i = 0; i < cnt; i++)
|
||||
((__le16 *)ha->request_ring)[i] =
|
||||
cpu_to_le16(risc_code_address[i]);
|
||||
((__le16 *)ha->request_ring)[i] = fw_data[i];
|
||||
|
||||
mb[0] = MBC_LOAD_RAM;
|
||||
mb[1] = risc_address;
|
||||
@ -1763,7 +1793,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
|
||||
#endif
|
||||
risc_address += cnt;
|
||||
risc_code_size = risc_code_size - cnt;
|
||||
risc_code_address = risc_code_address + cnt;
|
||||
fw_data = fw_data + cnt;
|
||||
num++;
|
||||
}
|
||||
|
||||
@ -1771,6 +1801,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
|
||||
#if DUMP_IT_BACK
|
||||
pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
|
||||
#endif
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1786,7 +1817,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
|
||||
/* 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;
|
||||
mb[1] = ha->fwstart;
|
||||
err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
|
||||
if (err) {
|
||||
printk(KERN_ERR "scsi(%li): RISC checksum failed.\n", ha->host_no);
|
||||
@ -1796,7 +1827,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
|
||||
/* Start firmware execution. */
|
||||
dprintk(1, "%s: start firmware running.\n", __func__);
|
||||
mb[0] = MBC_EXECUTE_FIRMWARE;
|
||||
mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
|
||||
mb[1] = ha->fwstart;
|
||||
err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
|
||||
if (err) {
|
||||
printk(KERN_ERR "scsi(%li): Failed to start firmware\n",
|
||||
@ -4450,6 +4481,9 @@ module_exit(qla1280_exit);
|
||||
MODULE_AUTHOR("Qlogic & Jes Sorensen");
|
||||
MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_FIRMWARE("qlogic/1040.bin");
|
||||
MODULE_FIRMWARE("qlogic/1280.bin");
|
||||
MODULE_FIRMWARE("qlogic/12160.bin");
|
||||
MODULE_VERSION(QLA1280_VERSION);
|
||||
|
||||
/*
|
||||
|
@ -1069,6 +1069,12 @@ struct scsi_qla_host {
|
||||
|
||||
struct nvram nvram;
|
||||
int nvram_valid;
|
||||
|
||||
/* Firmware Info */
|
||||
unsigned short fwstart; /* start address for F/W */
|
||||
unsigned char fwver1; /* F/W version first char */
|
||||
unsigned char fwver2; /* F/W version second char */
|
||||
unsigned char fwver3; /* F/W version third char */
|
||||
};
|
||||
|
||||
#endif /* _QLA1280_H */
|
||||
|
@ -96,7 +96,9 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return 0;
|
||||
|
||||
/* Read NVRAM data from cache. */
|
||||
if (IS_NOCACHE_VPD_TYPE(ha))
|
||||
ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_nvram << 2,
|
||||
ha->nvram_size);
|
||||
return memory_read_from_buffer(buf, count, &off, ha->nvram,
|
||||
ha->nvram_size);
|
||||
}
|
||||
@ -111,7 +113,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
uint16_t cnt;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size ||
|
||||
!ha->isp_ops->write_nvram)
|
||||
return 0;
|
||||
|
||||
/* Checksum NVRAM. */
|
||||
@ -137,12 +140,21 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
|
||||
*iter = chksum;
|
||||
}
|
||||
|
||||
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"HBA not online, failing NVRAM update.\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Write NVRAM. */
|
||||
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
|
||||
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
|
||||
count);
|
||||
|
||||
/* NVRAM settings take effect immediately. */
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
qla2x00_wait_for_chip_reset(vha);
|
||||
|
||||
return (count);
|
||||
}
|
||||
@ -330,6 +342,12 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
|
||||
if (ha->optrom_state != QLA_SWRITING)
|
||||
break;
|
||||
|
||||
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"HBA not online, failing flash update.\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Writing flash region -- 0x%x/0x%x.\n",
|
||||
ha->optrom_region_start, ha->optrom_region_size));
|
||||
@ -364,7 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return 0;
|
||||
|
||||
/* Read NVRAM data from cache. */
|
||||
if (IS_NOCACHE_VPD_TYPE(ha))
|
||||
ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
|
||||
ha->vpd_size);
|
||||
return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
|
||||
}
|
||||
|
||||
@ -376,14 +396,35 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
|
||||
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
uint8_t *tmp_data;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size ||
|
||||
!ha->isp_ops->write_nvram)
|
||||
return 0;
|
||||
|
||||
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"HBA not online, failing VPD update.\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Write NVRAM. */
|
||||
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
|
||||
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
|
||||
|
||||
/* Update flash version information for 4Gb & above. */
|
||||
if (!IS_FWI2_CAPABLE(ha))
|
||||
goto done;
|
||||
|
||||
tmp_data = vmalloc(256);
|
||||
if (!tmp_data) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Unable to allocate memory for VPD information update.\n");
|
||||
goto done;
|
||||
}
|
||||
ha->isp_ops->get_flash_version(vha, tmp_data);
|
||||
vfree(tmp_data);
|
||||
done:
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -458,6 +499,199 @@ static struct bin_attribute sysfs_sfp_attr = {
|
||||
.read = qla2x00_sysfs_read_sfp,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
qla2x00_sysfs_write_reset(struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int type;
|
||||
|
||||
if (off != 0)
|
||||
return 0;
|
||||
|
||||
type = simple_strtol(buf, NULL, 10);
|
||||
switch (type) {
|
||||
case 0x2025c:
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"Issuing ISP reset on (%ld).\n", vha->host_no);
|
||||
|
||||
scsi_block_requests(vha->host);
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
qla2x00_wait_for_chip_reset(vha);
|
||||
scsi_unblock_requests(vha->host);
|
||||
break;
|
||||
case 0x2025d:
|
||||
if (!IS_QLA81XX(ha))
|
||||
break;
|
||||
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"Issuing MPI reset on (%ld).\n", vha->host_no);
|
||||
|
||||
/* Make sure FC side is not in reset */
|
||||
qla2x00_wait_for_hba_online(vha);
|
||||
|
||||
/* Issue MPI reset */
|
||||
scsi_block_requests(vha->host);
|
||||
if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"MPI reset failed on (%ld).\n", vha->host_no);
|
||||
scsi_unblock_requests(vha->host);
|
||||
break;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct bin_attribute sysfs_reset_attr = {
|
||||
.attr = {
|
||||
.name = "reset",
|
||||
.mode = S_IWUSR,
|
||||
},
|
||||
.size = 0,
|
||||
.write = qla2x00_sysfs_write_reset,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
qla2x00_sysfs_write_edc(struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
uint16_t dev, adr, opt, len;
|
||||
int rval;
|
||||
|
||||
ha->edc_data_len = 0;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
|
||||
return 0;
|
||||
|
||||
if (!ha->edc_data) {
|
||||
ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
|
||||
&ha->edc_data_dma);
|
||||
if (!ha->edc_data) {
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Unable to allocate memory for EDC write.\n"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
dev = le16_to_cpup((void *)&buf[0]);
|
||||
adr = le16_to_cpup((void *)&buf[2]);
|
||||
opt = le16_to_cpup((void *)&buf[4]);
|
||||
len = le16_to_cpup((void *)&buf[6]);
|
||||
|
||||
if (!(opt & BIT_0))
|
||||
if (len == 0 || len > DMA_POOL_SIZE || len > count - 8)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(ha->edc_data, &buf[8], len);
|
||||
|
||||
rval = qla2x00_write_edc(vha, dev, adr, ha->edc_data_dma,
|
||||
ha->edc_data, len, opt);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Unable to write EDC (%x) %02x:%02x:%04x:%02x:%02x.\n",
|
||||
rval, dev, adr, opt, len, *buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct bin_attribute sysfs_edc_attr = {
|
||||
.attr = {
|
||||
.name = "edc",
|
||||
.mode = S_IWUSR,
|
||||
},
|
||||
.size = 0,
|
||||
.write = qla2x00_sysfs_write_edc,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
qla2x00_sysfs_write_edc_status(struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
uint16_t dev, adr, opt, len;
|
||||
int rval;
|
||||
|
||||
ha->edc_data_len = 0;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
|
||||
return 0;
|
||||
|
||||
if (!ha->edc_data) {
|
||||
ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
|
||||
&ha->edc_data_dma);
|
||||
if (!ha->edc_data) {
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Unable to allocate memory for EDC status.\n"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
dev = le16_to_cpup((void *)&buf[0]);
|
||||
adr = le16_to_cpup((void *)&buf[2]);
|
||||
opt = le16_to_cpup((void *)&buf[4]);
|
||||
len = le16_to_cpup((void *)&buf[6]);
|
||||
|
||||
if (!(opt & BIT_0))
|
||||
if (len == 0 || len > DMA_POOL_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
memset(ha->edc_data, 0, len);
|
||||
rval = qla2x00_read_edc(vha, dev, adr, ha->edc_data_dma,
|
||||
ha->edc_data, len, opt);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Unable to write EDC status (%x) %02x:%02x:%04x:%02x.\n",
|
||||
rval, dev, adr, opt, len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ha->edc_data_len = len;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_sysfs_read_edc_status(struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count == 0)
|
||||
return 0;
|
||||
|
||||
if (!ha->edc_data || ha->edc_data_len == 0 || ha->edc_data_len > count)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buf, ha->edc_data, ha->edc_data_len);
|
||||
|
||||
return ha->edc_data_len;
|
||||
}
|
||||
|
||||
static struct bin_attribute sysfs_edc_status_attr = {
|
||||
.attr = {
|
||||
.name = "edc_status",
|
||||
.mode = S_IRUSR | S_IWUSR,
|
||||
},
|
||||
.size = 0,
|
||||
.write = qla2x00_sysfs_write_edc_status,
|
||||
.read = qla2x00_sysfs_read_edc_status,
|
||||
};
|
||||
|
||||
static struct sysfs_entry {
|
||||
char *name;
|
||||
struct bin_attribute *attr;
|
||||
@ -469,6 +703,9 @@ static struct sysfs_entry {
|
||||
{ "optrom_ctl", &sysfs_optrom_ctl_attr, },
|
||||
{ "vpd", &sysfs_vpd_attr, 1 },
|
||||
{ "sfp", &sysfs_sfp_attr, 1 },
|
||||
{ "reset", &sysfs_reset_attr, },
|
||||
{ "edc", &sysfs_edc_attr, 2 },
|
||||
{ "edc_status", &sysfs_edc_status_attr, 2 },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
@ -482,6 +719,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
|
||||
for (iter = bin_file_entries; iter->name; iter++) {
|
||||
if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw))
|
||||
continue;
|
||||
if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
|
||||
continue;
|
||||
|
||||
ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
|
||||
iter->attr);
|
||||
@ -502,6 +741,8 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
|
||||
for (iter = bin_file_entries; iter->name; iter++) {
|
||||
if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
|
||||
continue;
|
||||
if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
|
||||
continue;
|
||||
|
||||
sysfs_remove_bin_file(&host->shost_gendev.kobj,
|
||||
iter->attr);
|
||||
@ -818,9 +1059,33 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
|
||||
if (!IS_QLA81XX(ha))
|
||||
return snprintf(buf, PAGE_SIZE, "\n");
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x (%x)\n",
|
||||
return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
|
||||
ha->mpi_version[0], ha->mpi_version[1], ha->mpi_version[2],
|
||||
ha->mpi_version[3], ha->mpi_capabilities);
|
||||
ha->mpi_capabilities);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (!IS_QLA81XX(ha))
|
||||
return snprintf(buf, PAGE_SIZE, "\n");
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
|
||||
ha->phy_version[0], ha->phy_version[1], ha->phy_version[2]);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_flash_block_size_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "0x%x\n", ha->fdt_block_size);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
|
||||
@ -848,6 +1113,9 @@ static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show,
|
||||
static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
|
||||
NULL);
|
||||
static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
|
||||
static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
|
||||
static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
|
||||
NULL);
|
||||
|
||||
struct device_attribute *qla2x00_host_attrs[] = {
|
||||
&dev_attr_driver_version,
|
||||
@ -868,6 +1136,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
|
||||
&dev_attr_optrom_fw_version,
|
||||
&dev_attr_total_isp_aborts,
|
||||
&dev_attr_mpi_version,
|
||||
&dev_attr_phy_version,
|
||||
&dev_attr_flash_block_size,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -1012,7 +1282,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
|
||||
if (!fcport)
|
||||
return;
|
||||
|
||||
qla2x00_abort_fcport_cmds(fcport);
|
||||
if (unlikely(pci_channel_offline(fcport->vha->hw->pdev)))
|
||||
qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
|
||||
else
|
||||
qla2x00_abort_fcport_cmds(fcport);
|
||||
|
||||
/*
|
||||
* Transport has effectively 'deleted' the rport, clear
|
||||
@ -1032,16 +1305,18 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
|
||||
if (!fcport)
|
||||
return;
|
||||
|
||||
if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
|
||||
qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* At this point all fcport's software-states are cleared. Perform any
|
||||
* final cleanup of firmware resources (PCBs and XCBs).
|
||||
*/
|
||||
if (fcport->loop_id != FC_NO_LOOP_ID) {
|
||||
if (fcport->loop_id != FC_NO_LOOP_ID)
|
||||
fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
|
||||
fcport->loop_id, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa);
|
||||
fcport->loop_id = FC_NO_LOOP_ID;
|
||||
}
|
||||
|
||||
qla2x00_abort_fcport_cmds(fcport);
|
||||
}
|
||||
|
@ -176,8 +176,7 @@
|
||||
/* ISP request and response entry counts (37-65535) */
|
||||
#define REQUEST_ENTRY_CNT_2100 128 /* Number of request entries. */
|
||||
#define REQUEST_ENTRY_CNT_2200 2048 /* Number of request entries. */
|
||||
#define REQUEST_ENTRY_CNT_2XXX_EXT_MEM 4096 /* Number of request entries. */
|
||||
#define REQUEST_ENTRY_CNT_24XX 4096 /* Number of request entries. */
|
||||
#define REQUEST_ENTRY_CNT_24XX 2048 /* Number of request entries. */
|
||||
#define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/
|
||||
#define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/
|
||||
|
||||
@ -201,20 +200,7 @@ typedef struct srb {
|
||||
/*
|
||||
* SRB flag definitions
|
||||
*/
|
||||
#define SRB_TIMEOUT BIT_0 /* Command timed out */
|
||||
#define SRB_DMA_VALID BIT_1 /* Command sent to ISP */
|
||||
#define SRB_WATCHDOG BIT_2 /* Command on watchdog list */
|
||||
#define SRB_ABORT_PENDING BIT_3 /* Command abort sent to device */
|
||||
|
||||
#define SRB_ABORTED BIT_4 /* Command aborted command already */
|
||||
#define SRB_RETRY BIT_5 /* Command needs retrying */
|
||||
#define SRB_GOT_SENSE BIT_6 /* Command has sense data */
|
||||
#define SRB_FAILOVER BIT_7 /* Command in failover state */
|
||||
|
||||
#define SRB_BUSY BIT_8 /* Command is in busy retry state */
|
||||
#define SRB_FO_CANCEL BIT_9 /* Command don't need to do failover */
|
||||
#define SRB_IOCTL BIT_10 /* IOCTL command. */
|
||||
#define SRB_TAPE BIT_11 /* FCP2 (Tape) command. */
|
||||
#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */
|
||||
|
||||
/*
|
||||
* ISP I/O Register Set structure definitions.
|
||||
@ -372,10 +358,10 @@ struct device_reg_2xxx {
|
||||
};
|
||||
|
||||
struct device_reg_25xxmq {
|
||||
volatile uint32_t req_q_in;
|
||||
volatile uint32_t req_q_out;
|
||||
volatile uint32_t rsp_q_in;
|
||||
volatile uint32_t rsp_q_out;
|
||||
uint32_t req_q_in;
|
||||
uint32_t req_q_out;
|
||||
uint32_t rsp_q_in;
|
||||
uint32_t rsp_q_out;
|
||||
};
|
||||
|
||||
typedef union {
|
||||
@ -620,6 +606,7 @@ typedef struct {
|
||||
#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */
|
||||
#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */
|
||||
#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */
|
||||
#define MBC_WRITE_SFP 0x30 /* Write SFP Data. */
|
||||
#define MBC_READ_SFP 0x31 /* Read SFP Data. */
|
||||
#define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */
|
||||
#define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */
|
||||
@ -1570,39 +1557,13 @@ typedef struct fc_port {
|
||||
#define FCS_DEVICE_DEAD 2
|
||||
#define FCS_DEVICE_LOST 3
|
||||
#define FCS_ONLINE 4
|
||||
#define FCS_NOT_SUPPORTED 5
|
||||
#define FCS_FAILOVER 6
|
||||
#define FCS_FAILOVER_FAILED 7
|
||||
|
||||
/*
|
||||
* FC port flags.
|
||||
*/
|
||||
#define FCF_FABRIC_DEVICE BIT_0
|
||||
#define FCF_LOGIN_NEEDED BIT_1
|
||||
#define FCF_FO_MASKED BIT_2
|
||||
#define FCF_FAILOVER_NEEDED BIT_3
|
||||
#define FCF_RESET_NEEDED BIT_4
|
||||
#define FCF_PERSISTENT_BOUND BIT_5
|
||||
#define FCF_TAPE_PRESENT BIT_6
|
||||
#define FCF_FARP_DONE BIT_7
|
||||
#define FCF_FARP_FAILED BIT_8
|
||||
#define FCF_FARP_REPLY_NEEDED BIT_9
|
||||
#define FCF_AUTH_REQ BIT_10
|
||||
#define FCF_SEND_AUTH_REQ BIT_11
|
||||
#define FCF_RECEIVE_AUTH_REQ BIT_12
|
||||
#define FCF_AUTH_SUCCESS BIT_13
|
||||
#define FCF_RLC_SUPPORT BIT_14
|
||||
#define FCF_CONFIG BIT_15 /* Needed? */
|
||||
#define FCF_RESCAN_NEEDED BIT_16
|
||||
#define FCF_XP_DEVICE BIT_17
|
||||
#define FCF_MSA_DEVICE BIT_18
|
||||
#define FCF_EVA_DEVICE BIT_19
|
||||
#define FCF_MSA_PORT_ACTIVE BIT_20
|
||||
#define FCF_FAILBACK_DISABLE BIT_21
|
||||
#define FCF_FAILOVER_DISABLE BIT_22
|
||||
#define FCF_DSXXX_DEVICE BIT_23
|
||||
#define FCF_AA_EVA_DEVICE BIT_24
|
||||
#define FCF_AA_MSA_DEVICE BIT_25
|
||||
#define FCF_TAPE_PRESENT BIT_2
|
||||
|
||||
/* No loop ID flag. */
|
||||
#define FC_NO_LOOP_ID 0x1000
|
||||
@ -2102,9 +2063,6 @@ struct isp_operations {
|
||||
|
||||
int (*get_flash_version) (struct scsi_qla_host *, void *);
|
||||
int (*start_scsi) (srb_t *);
|
||||
void (*wrt_req_reg) (struct qla_hw_data *, uint16_t, uint16_t);
|
||||
void (*wrt_rsp_reg) (struct qla_hw_data *, uint16_t, uint16_t);
|
||||
uint16_t (*rd_req_reg) (struct qla_hw_data *, uint16_t);
|
||||
};
|
||||
|
||||
/* MSI-X Support *************************************************************/
|
||||
@ -2200,6 +2158,8 @@ struct rsp_que {
|
||||
dma_addr_t dma;
|
||||
response_t *ring;
|
||||
response_t *ring_ptr;
|
||||
uint32_t __iomem *rsp_q_in; /* FWI2-capable only. */
|
||||
uint32_t __iomem *rsp_q_out;
|
||||
uint16_t ring_index;
|
||||
uint16_t out_ptr;
|
||||
uint16_t length;
|
||||
@ -2217,6 +2177,8 @@ struct req_que {
|
||||
dma_addr_t dma;
|
||||
request_t *ring;
|
||||
request_t *ring_ptr;
|
||||
uint32_t __iomem *req_q_in; /* FWI2-capable only. */
|
||||
uint32_t __iomem *req_q_out;
|
||||
uint16_t ring_index;
|
||||
uint16_t in_ptr;
|
||||
uint16_t cnt;
|
||||
@ -2256,10 +2218,10 @@ struct qla_hw_data {
|
||||
uint32_t msix_enabled :1;
|
||||
uint32_t disable_serdes :1;
|
||||
uint32_t gpsc_supported :1;
|
||||
uint32_t vsan_enabled :1;
|
||||
uint32_t npiv_supported :1;
|
||||
uint32_t fce_enabled :1;
|
||||
uint32_t hw_event_marker_found:1;
|
||||
uint32_t fac_supported :1;
|
||||
uint32_t chip_reset_done :1;
|
||||
} flags;
|
||||
|
||||
/* This spinlock is used to protect "io transactions", you must
|
||||
@ -2277,7 +2239,7 @@ struct qla_hw_data {
|
||||
|
||||
#define MIN_IOBASE_LEN 0x100
|
||||
/* Multi queue data structs */
|
||||
device_reg_t *mqiobase;
|
||||
device_reg_t __iomem *mqiobase;
|
||||
uint16_t msix_count;
|
||||
uint8_t mqenable;
|
||||
struct req_que **req_q_map;
|
||||
@ -2300,7 +2262,6 @@ struct qla_hw_data {
|
||||
uint16_t max_loop_id;
|
||||
|
||||
uint16_t fb_rev;
|
||||
uint16_t max_public_loop_ids;
|
||||
uint16_t min_external_loopid; /* First external loop Id */
|
||||
|
||||
#define PORT_SPEED_UNKNOWN 0xFFFF
|
||||
@ -2381,6 +2342,8 @@ struct qla_hw_data {
|
||||
IS_QLA25XX(ha) || IS_QLA81XX(ha))
|
||||
#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \
|
||||
(ha)->flags.msix_enabled)
|
||||
#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha))
|
||||
#define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha))
|
||||
|
||||
#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
|
||||
#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
|
||||
@ -2425,6 +2388,10 @@ struct qla_hw_data {
|
||||
void *sfp_data;
|
||||
dma_addr_t sfp_data_dma;
|
||||
|
||||
uint8_t *edc_data;
|
||||
dma_addr_t edc_data_dma;
|
||||
uint16_t edc_data_len;
|
||||
|
||||
struct task_struct *dpc_thread;
|
||||
uint8_t dpc_active; /* DPC routine is active */
|
||||
|
||||
@ -2439,6 +2406,8 @@ struct qla_hw_data {
|
||||
dma_addr_t init_cb_dma;
|
||||
init_cb_t *init_cb;
|
||||
int init_cb_size;
|
||||
dma_addr_t ex_init_cb_dma;
|
||||
struct ex_init_cb_81xx *ex_init_cb;
|
||||
|
||||
/* These are used by mailbox operations. */
|
||||
volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
|
||||
@ -2453,15 +2422,6 @@ struct qla_hw_data {
|
||||
struct completion mbx_cmd_comp; /* Serialize mbx access */
|
||||
struct completion mbx_intr_comp; /* Used for completion notification */
|
||||
|
||||
uint32_t mbx_flags;
|
||||
#define MBX_IN_PROGRESS BIT_0
|
||||
#define MBX_BUSY BIT_1 /* Got the Access */
|
||||
#define MBX_SLEEPING_ON_SEM BIT_2
|
||||
#define MBX_POLLING_FOR_COMP BIT_3
|
||||
#define MBX_COMPLETED BIT_4
|
||||
#define MBX_TIMEDOUT BIT_5
|
||||
#define MBX_ACCESS_TIMEDOUT BIT_6
|
||||
|
||||
/* Basic firmware related information. */
|
||||
uint16_t fw_major_version;
|
||||
uint16_t fw_minor_version;
|
||||
@ -2473,13 +2433,15 @@ struct qla_hw_data {
|
||||
#define RISC_START_ADDRESS_2100 0x1000
|
||||
#define RISC_START_ADDRESS_2300 0x800
|
||||
#define RISC_START_ADDRESS_2400 0x100000
|
||||
uint16_t fw_xcb_count;
|
||||
|
||||
uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */
|
||||
uint8_t fw_seriallink_options[4];
|
||||
uint16_t fw_seriallink_options24[4];
|
||||
|
||||
uint8_t mpi_version[4];
|
||||
uint8_t mpi_version[3];
|
||||
uint32_t mpi_capabilities;
|
||||
uint8_t phy_version[3];
|
||||
|
||||
/* Firmware dump information. */
|
||||
struct qla2xxx_fw_dump *fw_dump;
|
||||
@ -2545,6 +2507,8 @@ struct qla_hw_data {
|
||||
uint32_t flt_region_boot;
|
||||
uint32_t flt_region_fw;
|
||||
uint32_t flt_region_vpd_nvram;
|
||||
uint32_t flt_region_vpd;
|
||||
uint32_t flt_region_nvram;
|
||||
uint32_t flt_region_npiv_conf;
|
||||
|
||||
/* Needed for BEACON */
|
||||
@ -2613,36 +2577,19 @@ typedef struct scsi_qla_host {
|
||||
#define LOOP_RESYNC_ACTIVE 5
|
||||
#define LOCAL_LOOP_UPDATE 6 /* Perform a local loop update. */
|
||||
#define RSCN_UPDATE 7 /* Perform an RSCN update. */
|
||||
#define MAILBOX_RETRY 8
|
||||
#define ISP_RESET_NEEDED 9 /* Initiate a ISP reset. */
|
||||
#define FAILOVER_EVENT_NEEDED 10
|
||||
#define FAILOVER_EVENT 11
|
||||
#define FAILOVER_NEEDED 12
|
||||
#define SCSI_RESTART_NEEDED 13 /* Processes SCSI retry queue. */
|
||||
#define PORT_RESTART_NEEDED 14 /* Processes Retry queue. */
|
||||
#define RESTART_QUEUES_NEEDED 15 /* Restarts the Lun queue. */
|
||||
#define ABORT_QUEUES_NEEDED 16
|
||||
#define RELOGIN_NEEDED 17
|
||||
#define LOGIN_RETRY_NEEDED 18 /* Initiate required fabric logins. */
|
||||
#define REGISTER_FC4_NEEDED 19 /* SNS FC4 registration required. */
|
||||
#define ISP_ABORT_RETRY 20 /* ISP aborted. */
|
||||
#define FCPORT_RESCAN_NEEDED 21 /* IO descriptor processing needed */
|
||||
#define IODESC_PROCESS_NEEDED 22 /* IO descriptor processing needed */
|
||||
#define IOCTL_ERROR_RECOVERY 23
|
||||
#define LOOP_RESET_NEEDED 24
|
||||
#define BEACON_BLINK_NEEDED 25
|
||||
#define REGISTER_FDMI_NEEDED 26
|
||||
#define FCPORT_UPDATE_NEEDED 27
|
||||
#define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
|
||||
#define UNLOADING 29
|
||||
#define NPIV_CONFIG_NEEDED 30
|
||||
#define RELOGIN_NEEDED 8
|
||||
#define REGISTER_FC4_NEEDED 9 /* SNS FC4 registration required. */
|
||||
#define ISP_ABORT_RETRY 10 /* ISP aborted. */
|
||||
#define BEACON_BLINK_NEEDED 11
|
||||
#define REGISTER_FDMI_NEEDED 12
|
||||
#define FCPORT_UPDATE_NEEDED 13
|
||||
#define VP_DPC_NEEDED 14 /* wake up for VP dpc handling */
|
||||
#define UNLOADING 15
|
||||
#define NPIV_CONFIG_NEEDED 16
|
||||
|
||||
uint32_t device_flags;
|
||||
#define DFLG_LOCAL_DEVICES BIT_0
|
||||
#define DFLG_RETRY_LOCAL_DEVICES BIT_1
|
||||
#define DFLG_FABRIC_DEVICES BIT_2
|
||||
#define SWITCH_FOUND BIT_3
|
||||
#define DFLG_NO_CABLE BIT_4
|
||||
#define SWITCH_FOUND BIT_0
|
||||
#define DFLG_NO_CABLE BIT_1
|
||||
|
||||
srb_t *status_srb; /* Status continuation entry. */
|
||||
|
||||
@ -2755,10 +2702,5 @@ typedef struct scsi_qla_host {
|
||||
#include "qla_inline.h"
|
||||
|
||||
#define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr)
|
||||
#define CMD_COMPL_STATUS(Cmnd) ((Cmnd)->SCp.this_residual)
|
||||
#define CMD_RESID_LEN(Cmnd) ((Cmnd)->SCp.buffers_residual)
|
||||
#define CMD_SCSI_STATUS(Cmnd) ((Cmnd)->SCp.Status)
|
||||
#define CMD_ACTUAL_SNSLEN(Cmnd) ((Cmnd)->SCp.Message)
|
||||
#define CMD_ENTRY_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in)
|
||||
|
||||
#endif
|
||||
|
@ -71,7 +71,7 @@ qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
|
||||
|
||||
mutex_unlock(&ha->fce_mutex);
|
||||
out:
|
||||
return single_open(file, qla2x00_dfs_fce_show, ha);
|
||||
return single_open(file, qla2x00_dfs_fce_show, vha);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -145,7 +145,7 @@ create_dir:
|
||||
atomic_inc(&qla2x00_dfs_root_count);
|
||||
|
||||
create_nodes:
|
||||
ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, ha,
|
||||
ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
|
||||
&dfs_fce_ops);
|
||||
if (!ha->dfs_fce) {
|
||||
qla_printk(KERN_NOTICE, ha,
|
||||
|
@ -1403,6 +1403,21 @@ struct access_chip_rsp_84xx {
|
||||
#define MBA_IDC_TIME_EXT 0x8102
|
||||
|
||||
#define MBC_IDC_ACK 0x101
|
||||
#define MBC_RESTART_MPI_FW 0x3d
|
||||
#define MBC_FLASH_ACCESS_CTRL 0x3e /* Control flash access. */
|
||||
|
||||
/* Flash access control option field bit definitions */
|
||||
#define FAC_OPT_FORCE_SEMAPHORE BIT_15
|
||||
#define FAC_OPT_REQUESTOR_ID BIT_14
|
||||
#define FAC_OPT_CMD_SUBCODE 0xff
|
||||
|
||||
/* Flash access control command subcodes */
|
||||
#define FAC_OPT_CMD_WRITE_PROTECT 0x00
|
||||
#define FAC_OPT_CMD_WRITE_ENABLE 0x01
|
||||
#define FAC_OPT_CMD_ERASE_SECTOR 0x02
|
||||
#define FAC_OPT_CMD_LOCK_SEMAPHORE 0x03
|
||||
#define FAC_OPT_CMD_UNLOCK_SEMAPHORE 0x04
|
||||
#define FAC_OPT_CMD_GET_SECTOR_SIZE 0x05
|
||||
|
||||
struct nvram_81xx {
|
||||
/* NVRAM header. */
|
||||
@ -1440,7 +1455,17 @@ struct nvram_81xx {
|
||||
uint16_t reserved_6[24];
|
||||
|
||||
/* Offset 128. */
|
||||
uint16_t reserved_7[64];
|
||||
uint16_t ex_version;
|
||||
uint8_t prio_fcf_matching_flags;
|
||||
uint8_t reserved_6_1[3];
|
||||
uint16_t pri_fcf_vlan_id;
|
||||
uint8_t pri_fcf_fabric_name[8];
|
||||
uint16_t reserved_6_2[7];
|
||||
uint8_t spma_mac_addr[6];
|
||||
uint16_t reserved_6_3[14];
|
||||
|
||||
/* Offset 192. */
|
||||
uint16_t reserved_7[32];
|
||||
|
||||
/*
|
||||
* BIT 0 = Enable spinup delay
|
||||
@ -1664,6 +1689,17 @@ struct mid_init_cb_81xx {
|
||||
struct mid_conf_entry_24xx entries[MAX_MULTI_ID_FABRIC];
|
||||
};
|
||||
|
||||
struct ex_init_cb_81xx {
|
||||
uint16_t ex_version;
|
||||
uint8_t prio_fcf_matching_flags;
|
||||
uint8_t reserved_1[3];
|
||||
uint16_t pri_fcf_vlan_id;
|
||||
uint8_t pri_fcf_fabric_name[8];
|
||||
uint16_t reserved_2[7];
|
||||
uint8_t spma_mac_addr[6];
|
||||
uint16_t reserved_3[14];
|
||||
};
|
||||
|
||||
#define FARX_ACCESS_FLASH_CONF_81XX 0x7FFD0000
|
||||
#define FARX_ACCESS_FLASH_DATA_81XX 0x7F800000
|
||||
|
||||
@ -1672,6 +1708,10 @@ struct mid_init_cb_81xx {
|
||||
#define FA_RISC_CODE_ADDR_81 0xA0000
|
||||
#define FA_FW_AREA_ADDR_81 0xC0000
|
||||
#define FA_VPD_NVRAM_ADDR_81 0xD0000
|
||||
#define FA_VPD0_ADDR_81 0xD0000
|
||||
#define FA_VPD1_ADDR_81 0xD0400
|
||||
#define FA_NVRAM0_ADDR_81 0xD0080
|
||||
#define FA_NVRAM1_ADDR_81 0xD0480
|
||||
#define FA_FEATURE_ADDR_81 0xD4000
|
||||
#define FA_FLASH_DESCR_ADDR_81 0xD8000
|
||||
#define FA_FLASH_LAYOUT_ADDR_81 0xD8400
|
||||
|
@ -73,6 +73,7 @@ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
|
||||
extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
|
||||
fc_host_event_code, u32);
|
||||
extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
|
||||
extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
|
||||
|
||||
extern void qla2x00_abort_fcport_cmds(fc_port_t *);
|
||||
extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
|
||||
@ -82,7 +83,7 @@ extern void qla2x00_relogin(struct scsi_qla_host *);
|
||||
/*
|
||||
* Global Functions in qla_mid.c source file.
|
||||
*/
|
||||
extern struct scsi_host_template qla24xx_driver_template;
|
||||
extern struct scsi_host_template qla2xxx_driver_template;
|
||||
extern struct scsi_transport_template *qla2xxx_transport_vport_template;
|
||||
extern void qla2x00_timer(scsi_qla_host_t *);
|
||||
extern void qla2x00_start_timer(scsi_qla_host_t *, void *, unsigned long);
|
||||
@ -110,6 +111,7 @@ extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
|
||||
extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
|
||||
|
||||
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
|
||||
extern int qla2x00_wait_for_chip_reset(scsi_qla_host_t *);
|
||||
|
||||
extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
|
||||
extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
|
||||
@ -144,8 +146,8 @@ extern int
|
||||
qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
|
||||
|
||||
extern void
|
||||
qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *,
|
||||
uint16_t *, uint16_t *, uint16_t *, uint32_t *, uint8_t *, uint32_t *);
|
||||
qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *,
|
||||
uint16_t *, uint32_t *, uint8_t *, uint32_t *, uint8_t *);
|
||||
|
||||
extern int
|
||||
qla2x00_get_fw_options(scsi_qla_host_t *, uint16_t *);
|
||||
@ -262,6 +264,14 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *);
|
||||
extern int
|
||||
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
|
||||
|
||||
extern int
|
||||
qla2x00_read_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t,
|
||||
uint8_t *, uint16_t, uint16_t);
|
||||
|
||||
extern int
|
||||
qla2x00_write_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t,
|
||||
uint8_t *, uint16_t, uint16_t);
|
||||
|
||||
extern int
|
||||
qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
|
||||
|
||||
@ -269,6 +279,15 @@ extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
|
||||
|
||||
extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *);
|
||||
|
||||
extern int
|
||||
qla81xx_fac_get_sector_size(scsi_qla_host_t *, uint32_t *);
|
||||
|
||||
extern int
|
||||
qla81xx_fac_do_write_enable(scsi_qla_host_t *, int);
|
||||
|
||||
extern int
|
||||
qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_isr.c source file.
|
||||
*/
|
||||
|
@ -20,7 +20,6 @@
|
||||
* QLogic ISP2x00 Hardware Support Function Prototypes.
|
||||
*/
|
||||
static int qla2x00_isp_firmware(scsi_qla_host_t *);
|
||||
static void qla2x00_resize_request_q(scsi_qla_host_t *);
|
||||
static int qla2x00_setup_chip(scsi_qla_host_t *);
|
||||
static int qla2x00_init_rings(scsi_qla_host_t *);
|
||||
static int qla2x00_fw_ready(scsi_qla_host_t *);
|
||||
@ -61,8 +60,10 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
|
||||
int rval;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct req_que *req = ha->req_q_map[0];
|
||||
|
||||
/* Clear adapter flags. */
|
||||
vha->flags.online = 0;
|
||||
ha->flags.chip_reset_done = 0;
|
||||
vha->flags.reset_active = 0;
|
||||
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
|
||||
atomic_set(&vha->loop_state, LOOP_DOWN);
|
||||
@ -70,7 +71,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
|
||||
vha->dpc_flags = 0;
|
||||
vha->flags.management_server_logged_in = 0;
|
||||
vha->marker_needed = 0;
|
||||
ha->mbx_flags = 0;
|
||||
ha->isp_abort_cnt = 0;
|
||||
ha->beacon_blink_led = 0;
|
||||
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
|
||||
@ -131,6 +131,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
|
||||
}
|
||||
}
|
||||
rval = qla2x00_init_rings(vha);
|
||||
ha->flags.chip_reset_done = 1;
|
||||
|
||||
return (rval);
|
||||
}
|
||||
@ -512,7 +513,6 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
|
||||
static inline void
|
||||
qla24xx_reset_risc(scsi_qla_host_t *vha)
|
||||
{
|
||||
int hw_evt = 0;
|
||||
unsigned long flags = 0;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||
@ -542,8 +542,6 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
|
||||
d2 = (uint32_t) RD_REG_WORD(®->mailbox0);
|
||||
barrier();
|
||||
}
|
||||
if (cnt == 0)
|
||||
hw_evt = 1;
|
||||
|
||||
/* Wait for soft-reset to complete. */
|
||||
d2 = RD_REG_DWORD(®->ctrl_status);
|
||||
@ -816,7 +814,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
|
||||
qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n",
|
||||
FCE_SIZE / 1024);
|
||||
|
||||
fce_size = sizeof(struct qla2xxx_fce_chain) + EFT_SIZE;
|
||||
fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
|
||||
ha->flags.fce_enabled = 1;
|
||||
ha->fce_dma = tc_dma;
|
||||
ha->fce = tc;
|
||||
@ -893,62 +891,6 @@ cont_alloc:
|
||||
htonl(offsetof(struct qla2xxx_fw_dump, isp));
|
||||
}
|
||||
|
||||
/**
|
||||
* qla2x00_resize_request_q() - Resize request queue given available ISP memory.
|
||||
* @ha: HA context
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
static void
|
||||
qla2x00_resize_request_q(scsi_qla_host_t *vha)
|
||||
{
|
||||
int rval;
|
||||
uint16_t fw_iocb_cnt = 0;
|
||||
uint16_t request_q_length = REQUEST_ENTRY_CNT_2XXX_EXT_MEM;
|
||||
dma_addr_t request_dma;
|
||||
request_t *request_ring;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct req_que *req = ha->req_q_map[0];
|
||||
|
||||
/* Valid only on recent ISPs. */
|
||||
if (IS_QLA2100(ha) || IS_QLA2200(ha))
|
||||
return;
|
||||
|
||||
/* Retrieve IOCB counts available to the firmware. */
|
||||
rval = qla2x00_get_resource_cnts(vha, NULL, NULL, NULL, &fw_iocb_cnt,
|
||||
&ha->max_npiv_vports);
|
||||
if (rval)
|
||||
return;
|
||||
/* No point in continuing if current settings are sufficient. */
|
||||
if (fw_iocb_cnt < 1024)
|
||||
return;
|
||||
if (req->length >= request_q_length)
|
||||
return;
|
||||
|
||||
/* Attempt to claim larger area for request queue. */
|
||||
request_ring = dma_alloc_coherent(&ha->pdev->dev,
|
||||
(request_q_length + 1) * sizeof(request_t), &request_dma,
|
||||
GFP_KERNEL);
|
||||
if (request_ring == NULL)
|
||||
return;
|
||||
|
||||
/* Resize successful, report extensions. */
|
||||
qla_printk(KERN_INFO, ha, "Extended memory detected (%d KB)...\n",
|
||||
(ha->fw_memory_size + 1) / 1024);
|
||||
qla_printk(KERN_INFO, ha, "Resizing request queue depth "
|
||||
"(%d -> %d)...\n", req->length, request_q_length);
|
||||
|
||||
/* Clear old allocations. */
|
||||
dma_free_coherent(&ha->pdev->dev,
|
||||
(req->length + 1) * sizeof(request_t), req->ring,
|
||||
req->dma);
|
||||
|
||||
/* Begin using larger queue. */
|
||||
req->length = request_q_length;
|
||||
req->ring = request_ring;
|
||||
req->dma = request_dma;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla2x00_setup_chip() - Load and start RISC firmware.
|
||||
* @ha: HA context
|
||||
@ -963,6 +905,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
|
||||
unsigned long flags;
|
||||
uint16_t fw_major_version;
|
||||
|
||||
if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
|
||||
/* Disable SRAM, Instruction RAM and GP RAM parity. */
|
||||
@ -986,13 +929,15 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
|
||||
|
||||
rval = qla2x00_execute_fw(vha, srisc_address);
|
||||
/* Retrieve firmware information. */
|
||||
if (rval == QLA_SUCCESS && ha->fw_major_version == 0) {
|
||||
if (rval == QLA_SUCCESS) {
|
||||
fw_major_version = ha->fw_major_version;
|
||||
qla2x00_get_fw_version(vha,
|
||||
&ha->fw_major_version,
|
||||
&ha->fw_minor_version,
|
||||
&ha->fw_subminor_version,
|
||||
&ha->fw_attributes, &ha->fw_memory_size,
|
||||
ha->mpi_version, &ha->mpi_capabilities);
|
||||
ha->mpi_version, &ha->mpi_capabilities,
|
||||
ha->phy_version);
|
||||
ha->flags.npiv_supported = 0;
|
||||
if (IS_QLA2XXX_MIDTYPE(ha) &&
|
||||
(ha->fw_attributes & BIT_2)) {
|
||||
@ -1003,9 +948,11 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
|
||||
ha->max_npiv_vports =
|
||||
MIN_MULTI_ID_FABRIC - 1;
|
||||
}
|
||||
qla2x00_resize_request_q(vha);
|
||||
qla2x00_get_resource_cnts(vha, NULL,
|
||||
&ha->fw_xcb_count, NULL, NULL,
|
||||
&ha->max_npiv_vports);
|
||||
|
||||
if (ql2xallocfwdump)
|
||||
if (!fw_major_version && ql2xallocfwdump)
|
||||
qla2x00_alloc_fw_dump(vha);
|
||||
}
|
||||
} else {
|
||||
@ -1028,6 +975,21 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
}
|
||||
|
||||
if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) {
|
||||
uint32_t size;
|
||||
|
||||
rval = qla81xx_fac_get_sector_size(vha, &size);
|
||||
if (rval == QLA_SUCCESS) {
|
||||
ha->flags.fac_supported = 1;
|
||||
ha->fdt_block_size = size << 2;
|
||||
} else {
|
||||
qla_printk(KERN_ERR, ha,
|
||||
"Unsupported FAC firmware (%d.%02d.%02d).\n",
|
||||
ha->fw_major_version, ha->fw_minor_version,
|
||||
ha->fw_subminor_version);
|
||||
}
|
||||
}
|
||||
|
||||
if (rval) {
|
||||
DEBUG2_3(printk("scsi(%ld): Setup chip **** FAILED ****.\n",
|
||||
vha->host_no));
|
||||
@ -1314,8 +1276,11 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
|
||||
mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports);
|
||||
}
|
||||
|
||||
|
||||
mid_init_cb->options = __constant_cpu_to_le16(BIT_1);
|
||||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
mid_init_cb->options = __constant_cpu_to_le16(BIT_1);
|
||||
mid_init_cb->init_cb.execution_throttle =
|
||||
cpu_to_le16(ha->fw_xcb_count);
|
||||
}
|
||||
|
||||
rval = qla2x00_init_firmware(vha, ha->init_cb_size);
|
||||
if (rval) {
|
||||
@ -1989,7 +1954,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
|
||||
fcport->port_type = FCT_UNKNOWN;
|
||||
fcport->loop_id = FC_NO_LOOP_ID;
|
||||
atomic_set(&fcport->state, FCS_UNCONFIGURED);
|
||||
fcport->flags = FCF_RLC_SUPPORT;
|
||||
fcport->supported_classes = FC_COS_UNSPECIFIED;
|
||||
|
||||
return fcport;
|
||||
@ -2171,7 +2135,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
|
||||
vha->host_no, fcport->loop_id));
|
||||
|
||||
atomic_set(&fcport->state, FCS_DEVICE_LOST);
|
||||
fcport->flags &= ~FCF_FARP_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2228,8 +2191,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
|
||||
WWN_SIZE))
|
||||
continue;
|
||||
|
||||
fcport->flags &= ~(FCF_FABRIC_DEVICE |
|
||||
FCF_PERSISTENT_BOUND);
|
||||
fcport->flags &= ~FCF_FABRIC_DEVICE;
|
||||
fcport->loop_id = new_fcport->loop_id;
|
||||
fcport->port_type = new_fcport->port_type;
|
||||
fcport->d_id.b24 = new_fcport->d_id.b24;
|
||||
@ -2242,7 +2204,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
|
||||
|
||||
if (!found) {
|
||||
/* New device, add to fcports list. */
|
||||
new_fcport->flags &= ~FCF_PERSISTENT_BOUND;
|
||||
if (vha->vp_idx) {
|
||||
new_fcport->vha = vha;
|
||||
new_fcport->vp_idx = vha->vp_idx;
|
||||
@ -2275,11 +2236,6 @@ cleanup_allocation:
|
||||
"rval=%x\n", vha->host_no, rval));
|
||||
}
|
||||
|
||||
if (found_devs) {
|
||||
vha->device_flags |= DFLG_LOCAL_DEVICES;
|
||||
vha->device_flags &= ~DFLG_RETRY_LOCAL_DEVICES;
|
||||
}
|
||||
|
||||
return (rval);
|
||||
}
|
||||
|
||||
@ -2765,7 +2721,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
|
||||
fcport->loop_id = FC_NO_LOOP_ID;
|
||||
fcport->flags |= (FCF_FABRIC_DEVICE |
|
||||
FCF_LOGIN_NEEDED);
|
||||
fcport->flags &= ~FCF_PERSISTENT_BOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2808,9 +2763,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
|
||||
kfree(swl);
|
||||
kfree(new_fcport);
|
||||
|
||||
if (!list_empty(new_fcports))
|
||||
vha->device_flags |= DFLG_FABRIC_DEVICES;
|
||||
|
||||
return (rval);
|
||||
}
|
||||
|
||||
@ -2993,7 +2945,6 @@ qla2x00_device_resync(scsi_qla_host_t *vha)
|
||||
0, 0);
|
||||
}
|
||||
}
|
||||
fcport->flags &= ~FCF_FARP_DONE;
|
||||
}
|
||||
}
|
||||
return (rval);
|
||||
@ -3302,6 +3253,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
|
||||
|
||||
if (vha->flags.online) {
|
||||
vha->flags.online = 0;
|
||||
ha->flags.chip_reset_done = 0;
|
||||
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
ha->qla_stats.total_isp_aborts++;
|
||||
|
||||
@ -3451,6 +3403,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
|
||||
|
||||
if (!status && !(status = qla2x00_init_rings(vha))) {
|
||||
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
|
||||
ha->flags.chip_reset_done = 1;
|
||||
/* Initialize the queues in use */
|
||||
qla25xx_init_queues(ha);
|
||||
|
||||
@ -4338,23 +4291,17 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
|
||||
|
||||
/* Determine NVRAM starting address. */
|
||||
ha->nvram_size = sizeof(struct nvram_81xx);
|
||||
ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
|
||||
ha->vpd_size = FA_NVRAM_VPD_SIZE;
|
||||
ha->vpd_base = FA_NVRAM_VPD0_ADDR;
|
||||
if (PCI_FUNC(ha->pdev->devfn) & 1) {
|
||||
ha->nvram_base = FA_NVRAM_FUNC1_ADDR;
|
||||
ha->vpd_base = FA_NVRAM_VPD1_ADDR;
|
||||
}
|
||||
|
||||
/* Get VPD data into cache */
|
||||
ha->vpd = ha->nvram + VPD_OFFSET;
|
||||
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd,
|
||||
ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4);
|
||||
ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
|
||||
ha->vpd_size);
|
||||
|
||||
/* Get NVRAM data into cache and calculate checksum. */
|
||||
dptr = (uint32_t *)nv;
|
||||
ha->isp_ops->read_nvram(vha, (uint8_t *)dptr, ha->nvram_base,
|
||||
ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2,
|
||||
ha->nvram_size);
|
||||
dptr = (uint32_t *)nv;
|
||||
for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
|
||||
chksum += le32_to_cpu(*dptr++);
|
||||
|
||||
@ -4452,6 +4399,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
|
||||
icb->enode_mac[5] = 0x06 + PCI_FUNC(ha->pdev->devfn);
|
||||
}
|
||||
|
||||
/* Use extended-initialization control block. */
|
||||
memcpy(ha->ex_init_cb, &nv->ex_version, sizeof(*ha->ex_init_cb));
|
||||
|
||||
/*
|
||||
* Setup driver NVRAM options.
|
||||
*/
|
||||
|
@ -776,7 +776,7 @@ qla24xx_start_scsi(srb_t *sp)
|
||||
|
||||
req_cnt = qla24xx_calc_iocbs(tot_dsds);
|
||||
if (req->cnt < (req_cnt + 2)) {
|
||||
cnt = ha->isp_ops->rd_req_reg(ha, req->id);
|
||||
cnt = RD_REG_DWORD_RELAXED(req->req_q_out);
|
||||
|
||||
if (req->ring_index < cnt)
|
||||
req->cnt = cnt - req->ring_index;
|
||||
@ -836,7 +836,8 @@ qla24xx_start_scsi(srb_t *sp)
|
||||
sp->flags |= SRB_DMA_VALID;
|
||||
|
||||
/* Set chip new ring index. */
|
||||
ha->isp_ops->wrt_req_reg(ha, req->id, req->ring_index);
|
||||
WRT_REG_DWORD(req->req_q_in, req->ring_index);
|
||||
RD_REG_DWORD_RELAXED(&ha->iobase->isp24.hccr);
|
||||
|
||||
/* Manage unprocessed RIO/ZIO commands in response queue. */
|
||||
if (vha->flags.process_response_queue &&
|
||||
@ -854,35 +855,3 @@ queuing_error:
|
||||
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
qla24xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id)
|
||||
{
|
||||
device_reg_t __iomem *reg = (void *) ha->iobase;
|
||||
return RD_REG_DWORD_RELAXED(®->isp24.req_q_out);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
qla25xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id)
|
||||
{
|
||||
device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
|
||||
return RD_REG_DWORD_RELAXED(®->isp25mq.req_q_out);
|
||||
}
|
||||
|
||||
void
|
||||
qla24xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
|
||||
{
|
||||
device_reg_t __iomem *reg = (void *) ha->iobase;
|
||||
WRT_REG_DWORD(®->isp24.req_q_in, index);
|
||||
RD_REG_DWORD_RELAXED(®->isp24.req_q_in);
|
||||
}
|
||||
|
||||
void
|
||||
qla25xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
|
||||
{
|
||||
device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
|
||||
struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
|
||||
WRT_REG_DWORD(®->isp25mq.req_q_in, index);
|
||||
RD_REG_DWORD(&ioreg->hccr); /* PCI posting */
|
||||
}
|
||||
|
||||
|
@ -852,9 +852,6 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
|
||||
/* Free outstanding command slot. */
|
||||
req->outstanding_cmds[index] = NULL;
|
||||
|
||||
CMD_COMPL_STATUS(sp->cmd) = 0L;
|
||||
CMD_SCSI_STATUS(sp->cmd) = 0L;
|
||||
|
||||
/* Save ISP completion status */
|
||||
sp->cmd->result = DID_OK << 16;
|
||||
|
||||
@ -955,7 +952,6 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
|
||||
if (sense_len >= SCSI_SENSE_BUFFERSIZE)
|
||||
sense_len = SCSI_SENSE_BUFFERSIZE;
|
||||
|
||||
CMD_ACTUAL_SNSLEN(cp) = sense_len;
|
||||
sp->request_sense_length = sense_len;
|
||||
sp->request_sense_ptr = cp->sense_buffer;
|
||||
if (sp->request_sense_length > 32)
|
||||
@ -973,8 +969,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
|
||||
cp->device->channel, cp->device->id, cp->device->lun, cp,
|
||||
cp->serial_number));
|
||||
if (sense_len)
|
||||
DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
|
||||
CMD_ACTUAL_SNSLEN(cp)));
|
||||
DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, sense_len));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1043,9 +1038,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
||||
}
|
||||
|
||||
lscsi_status = scsi_status & STATUS_MASK;
|
||||
CMD_ENTRY_STATUS(cp) = sts->entry_status;
|
||||
CMD_COMPL_STATUS(cp) = comp_status;
|
||||
CMD_SCSI_STATUS(cp) = scsi_status;
|
||||
|
||||
fcport = sp->fcport;
|
||||
|
||||
@ -1104,7 +1096,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
||||
if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
|
||||
resid = resid_len;
|
||||
scsi_set_resid(cp, resid);
|
||||
CMD_RESID_LEN(cp) = resid;
|
||||
|
||||
if (!lscsi_status &&
|
||||
((unsigned)(scsi_bufflen(cp) - resid) <
|
||||
@ -1160,7 +1151,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
||||
|
||||
if (scsi_status & SS_RESIDUAL_UNDER) {
|
||||
scsi_set_resid(cp, resid);
|
||||
CMD_RESID_LEN(cp) = resid;
|
||||
} else {
|
||||
DEBUG2(printk(KERN_INFO
|
||||
"scsi(%ld:%d:%d) UNDERRUN status detected "
|
||||
@ -1499,7 +1489,6 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
|
||||
void
|
||||
qla24xx_process_response_queue(struct rsp_que *rsp)
|
||||
{
|
||||
struct qla_hw_data *ha = rsp->hw;
|
||||
struct sts_entry_24xx *pkt;
|
||||
struct scsi_qla_host *vha;
|
||||
|
||||
@ -1553,7 +1542,7 @@ qla24xx_process_response_queue(struct rsp_que *rsp)
|
||||
}
|
||||
|
||||
/* Adjust ring index */
|
||||
ha->isp_ops->wrt_rsp_reg(ha, rsp->id, rsp->ring_index);
|
||||
WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2029,7 +2018,7 @@ skip_msix:
|
||||
skip_msi:
|
||||
|
||||
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
|
||||
IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
|
||||
IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
|
||||
if (ret) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Failed to reserve interrupt %d already in use.\n",
|
||||
@ -2117,18 +2106,3 @@ int qla25xx_request_irq(struct rsp_que *rsp)
|
||||
msix->rsp = rsp;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
qla25xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
|
||||
{
|
||||
device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
|
||||
WRT_REG_DWORD(®->isp25mq.rsp_q_out, index);
|
||||
}
|
||||
|
||||
void
|
||||
qla24xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
|
||||
{
|
||||
device_reg_t __iomem *reg = (void *) ha->iobase;
|
||||
WRT_REG_DWORD(®->isp24.rsp_q_out, index);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
||||
|
||||
if (ha->pdev->error_state > pci_channel_io_frozen)
|
||||
return QLA_FUNCTION_TIMEOUT;
|
||||
|
||||
reg = ha->iobase;
|
||||
io_lock_on = base_vha->flags.init_done;
|
||||
|
||||
@ -408,7 +411,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
|
||||
void
|
||||
qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
|
||||
uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi,
|
||||
uint32_t *mpi_caps)
|
||||
uint32_t *mpi_caps, uint8_t *phy)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
@ -420,7 +423,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
|
||||
mcp->out_mb = MBX_0;
|
||||
mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
if (IS_QLA81XX(vha->hw))
|
||||
mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
|
||||
mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
|
||||
mcp->flags = 0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
@ -435,11 +438,13 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
|
||||
else
|
||||
*memory = (mcp->mb[5] << 16) | mcp->mb[4];
|
||||
if (IS_QLA81XX(vha->hw)) {
|
||||
mpi[0] = mcp->mb[10] >> 8;
|
||||
mpi[1] = mcp->mb[10] & 0xff;
|
||||
mpi[2] = mcp->mb[11] >> 8;
|
||||
mpi[3] = mcp->mb[11] & 0xff;
|
||||
mpi[0] = mcp->mb[10] & 0xff;
|
||||
mpi[1] = mcp->mb[11] >> 8;
|
||||
mpi[2] = mcp->mb[11] & 0xff;
|
||||
*mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13];
|
||||
phy[0] = mcp->mb[8] & 0xff;
|
||||
phy[1] = mcp->mb[9] >> 8;
|
||||
phy[2] = mcp->mb[9] & 0xff;
|
||||
}
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
@ -1043,14 +1048,22 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
|
||||
else
|
||||
mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
|
||||
|
||||
mcp->mb[1] = 0;
|
||||
mcp->mb[2] = MSW(ha->init_cb_dma);
|
||||
mcp->mb[3] = LSW(ha->init_cb_dma);
|
||||
mcp->mb[4] = 0;
|
||||
mcp->mb[5] = 0;
|
||||
mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
|
||||
mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
|
||||
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
|
||||
mcp->in_mb = MBX_5|MBX_4|MBX_0;
|
||||
mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
if (IS_QLA81XX(ha) && ha->ex_init_cb->ex_version) {
|
||||
mcp->mb[1] = BIT_0;
|
||||
mcp->mb[10] = MSW(ha->ex_init_cb_dma);
|
||||
mcp->mb[11] = LSW(ha->ex_init_cb_dma);
|
||||
mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
|
||||
mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
|
||||
mcp->mb[14] = sizeof(*ha->ex_init_cb);
|
||||
mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
|
||||
}
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->buf_size = size;
|
||||
mcp->flags = MBX_DMA_OUT;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
@ -1187,10 +1200,6 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
|
||||
fcport->d_id.b.al_pa = pd->port_id[2];
|
||||
fcport->d_id.b.rsvd_1 = 0;
|
||||
|
||||
/* Check for device require authentication. */
|
||||
pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
|
||||
(fcport->flags &= ~FCF_AUTH_REQ);
|
||||
|
||||
/* If not target must be initiator or unknown type. */
|
||||
if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
|
||||
fcport->port_type = FCT_INITIATOR;
|
||||
@ -3218,3 +3227,204 @@ qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
if (!IS_QLA81XX(vha->hw))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
|
||||
mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_1|MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
|
||||
__func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
|
||||
*sector_size = mcp->mb[1];
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
if (!IS_QLA81XX(vha->hw))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
|
||||
mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
|
||||
FAC_OPT_CMD_WRITE_PROTECT;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_1|MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
|
||||
__func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
if (!IS_QLA81XX(vha->hw))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
|
||||
mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
|
||||
mcp->mb[2] = LSW(start);
|
||||
mcp->mb[3] = MSW(start);
|
||||
mcp->mb[4] = LSW(finish);
|
||||
mcp->mb[5] = MSW(finish);
|
||||
mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_2|MBX_1|MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
|
||||
"mb[2]=%x.\n", __func__, vha->host_no, rval, mcp->mb[0],
|
||||
mcp->mb[1], mcp->mb[2]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
|
||||
{
|
||||
int rval = 0;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_RESTART_MPI_FW;
|
||||
mcp->out_mb = MBX_0;
|
||||
mcp->in_mb = MBX_0|MBX_1;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=0x%x mb[1]=0x%x.\n",
|
||||
__func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
|
||||
dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
|
||||
|
||||
mcp->mb[0] = MBC_READ_SFP;
|
||||
mcp->mb[1] = dev;
|
||||
mcp->mb[2] = MSW(sfp_dma);
|
||||
mcp->mb[3] = LSW(sfp_dma);
|
||||
mcp->mb[6] = MSW(MSD(sfp_dma));
|
||||
mcp->mb[7] = LSW(MSD(sfp_dma));
|
||||
mcp->mb[8] = len;
|
||||
mcp->mb[9] = adr;
|
||||
mcp->mb[10] = opt;
|
||||
mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
|
||||
if (opt & BIT_0)
|
||||
if (sfp)
|
||||
*sfp = mcp->mb[8];
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
|
||||
vha->host_no, rval, mcp->mb[0]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
|
||||
dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
|
||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
|
||||
|
||||
if (opt & BIT_0)
|
||||
if (sfp)
|
||||
len = *sfp;
|
||||
|
||||
mcp->mb[0] = MBC_WRITE_SFP;
|
||||
mcp->mb[1] = dev;
|
||||
mcp->mb[2] = MSW(sfp_dma);
|
||||
mcp->mb[3] = LSW(sfp_dma);
|
||||
mcp->mb[6] = MSW(MSD(sfp_dma));
|
||||
mcp->mb[7] = LSW(MSD(sfp_dma));
|
||||
mcp->mb[8] = len;
|
||||
mcp->mb[9] = adr;
|
||||
mcp->mb[10] = opt;
|
||||
mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
|
||||
vha->host_no, rval, mcp->mb[0]));
|
||||
} else {
|
||||
DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
|
||||
scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
|
||||
struct qla_hw_data *ha = base_vha->hw;
|
||||
scsi_qla_host_t *vha;
|
||||
struct scsi_host_template *sht = &qla24xx_driver_template;
|
||||
struct scsi_host_template *sht = &qla2xxx_driver_template;
|
||||
struct Scsi_Host *host;
|
||||
|
||||
vha = qla2x00_create_host(sht, ha);
|
||||
@ -584,6 +584,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
|
||||
struct req_que *req = NULL;
|
||||
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
|
||||
uint16_t que_id = 0;
|
||||
device_reg_t __iomem *reg;
|
||||
|
||||
req = kzalloc(sizeof(struct req_que), GFP_KERNEL);
|
||||
if (req == NULL) {
|
||||
@ -631,6 +632,9 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
|
||||
req->ring_index = 0;
|
||||
req->cnt = req->length;
|
||||
req->id = que_id;
|
||||
reg = ISP_QUE_REG(ha, que_id);
|
||||
req->req_q_in = ®->isp25mq.req_q_in;
|
||||
req->req_q_out = ®->isp25mq.req_q_out;
|
||||
req->max_q_depth = ha->req_q_map[0]->max_q_depth;
|
||||
mutex_unlock(&ha->vport_lock);
|
||||
|
||||
@ -658,7 +662,8 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
|
||||
int ret = 0;
|
||||
struct rsp_que *rsp = NULL;
|
||||
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
|
||||
uint16_t que_id = 0;;
|
||||
uint16_t que_id = 0;
|
||||
device_reg_t __iomem *reg;
|
||||
|
||||
rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL);
|
||||
if (rsp == NULL) {
|
||||
@ -706,6 +711,9 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
|
||||
rsp->ring_ptr = rsp->ring;
|
||||
rsp->ring_index = 0;
|
||||
rsp->id = que_id;
|
||||
reg = ISP_QUE_REG(ha, que_id);
|
||||
rsp->rsp_q_in = ®->isp25mq.rsp_q_in;
|
||||
rsp->rsp_q_out = ®->isp25mq.rsp_q_out;
|
||||
mutex_unlock(&ha->vport_lock);
|
||||
|
||||
ret = qla25xx_request_irq(rsp);
|
||||
|
@ -104,9 +104,7 @@ static int qla2xxx_slave_alloc(struct scsi_device *);
|
||||
static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
|
||||
static void qla2xxx_scan_start(struct Scsi_Host *);
|
||||
static void qla2xxx_slave_destroy(struct scsi_device *);
|
||||
static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
|
||||
void (*fn)(struct scsi_cmnd *));
|
||||
static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
|
||||
static int qla2xxx_queuecommand(struct scsi_cmnd *cmd,
|
||||
void (*fn)(struct scsi_cmnd *));
|
||||
static int qla2xxx_eh_abort(struct scsi_cmnd *);
|
||||
static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
|
||||
@ -117,42 +115,10 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
|
||||
static int qla2x00_change_queue_depth(struct scsi_device *, int);
|
||||
static int qla2x00_change_queue_type(struct scsi_device *, int);
|
||||
|
||||
static struct scsi_host_template qla2x00_driver_template = {
|
||||
struct scsi_host_template qla2xxx_driver_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = QLA2XXX_DRIVER_NAME,
|
||||
.queuecommand = qla2x00_queuecommand,
|
||||
|
||||
.eh_abort_handler = qla2xxx_eh_abort,
|
||||
.eh_device_reset_handler = qla2xxx_eh_device_reset,
|
||||
.eh_target_reset_handler = qla2xxx_eh_target_reset,
|
||||
.eh_bus_reset_handler = qla2xxx_eh_bus_reset,
|
||||
.eh_host_reset_handler = qla2xxx_eh_host_reset,
|
||||
|
||||
.slave_configure = qla2xxx_slave_configure,
|
||||
|
||||
.slave_alloc = qla2xxx_slave_alloc,
|
||||
.slave_destroy = qla2xxx_slave_destroy,
|
||||
.scan_finished = qla2xxx_scan_finished,
|
||||
.scan_start = qla2xxx_scan_start,
|
||||
.change_queue_depth = qla2x00_change_queue_depth,
|
||||
.change_queue_type = qla2x00_change_queue_type,
|
||||
.this_id = -1,
|
||||
.cmd_per_lun = 3,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.sg_tablesize = SG_ALL,
|
||||
|
||||
/*
|
||||
* The RISC allows for each command to transfer (2^32-1) bytes of data,
|
||||
* which equates to 0x800000 sectors.
|
||||
*/
|
||||
.max_sectors = 0xFFFF,
|
||||
.shost_attrs = qla2x00_host_attrs,
|
||||
};
|
||||
|
||||
struct scsi_host_template qla24xx_driver_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = QLA2XXX_DRIVER_NAME,
|
||||
.queuecommand = qla24xx_queuecommand,
|
||||
.queuecommand = qla2xxx_queuecommand,
|
||||
|
||||
.eh_abort_handler = qla2xxx_eh_abort,
|
||||
.eh_device_reset_handler = qla2xxx_eh_device_reset,
|
||||
@ -430,73 +396,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
|
||||
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
srb_t *sp;
|
||||
int rval;
|
||||
|
||||
if (unlikely(pci_channel_offline(ha->pdev))) {
|
||||
cmd->result = DID_REQUEUE << 16;
|
||||
goto qc_fail_command;
|
||||
}
|
||||
|
||||
rval = fc_remote_port_chkready(rport);
|
||||
if (rval) {
|
||||
cmd->result = rval;
|
||||
goto qc_fail_command;
|
||||
}
|
||||
|
||||
/* Close window on fcport/rport state-transitioning. */
|
||||
if (fcport->drport)
|
||||
goto qc_target_busy;
|
||||
|
||||
if (atomic_read(&fcport->state) != FCS_ONLINE) {
|
||||
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
|
||||
atomic_read(&vha->loop_state) == LOOP_DEAD) {
|
||||
cmd->result = DID_NO_CONNECT << 16;
|
||||
goto qc_fail_command;
|
||||
}
|
||||
goto qc_target_busy;
|
||||
}
|
||||
|
||||
spin_unlock_irq(vha->host->host_lock);
|
||||
|
||||
sp = qla2x00_get_new_sp(vha, fcport, cmd, done);
|
||||
if (!sp)
|
||||
goto qc_host_busy_lock;
|
||||
|
||||
rval = ha->isp_ops->start_scsi(sp);
|
||||
if (rval != QLA_SUCCESS)
|
||||
goto qc_host_busy_free_sp;
|
||||
|
||||
spin_lock_irq(vha->host->host_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
qc_host_busy_free_sp:
|
||||
qla2x00_sp_free_dma(sp);
|
||||
mempool_free(sp, ha->srb_mempool);
|
||||
|
||||
qc_host_busy_lock:
|
||||
spin_lock_irq(vha->host->host_lock);
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
|
||||
qc_target_busy:
|
||||
return SCSI_MLQUEUE_TARGET_BUSY;
|
||||
|
||||
qc_fail_command:
|
||||
done(cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
|
||||
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
|
||||
@ -507,7 +407,10 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
int rval;
|
||||
|
||||
if (unlikely(pci_channel_offline(ha->pdev))) {
|
||||
cmd->result = DID_REQUEUE << 16;
|
||||
if (ha->pdev->error_state == pci_channel_io_frozen)
|
||||
cmd->result = DID_REQUEUE << 16;
|
||||
else
|
||||
cmd->result = DID_NO_CONNECT << 16;
|
||||
goto qc24_fail_command;
|
||||
}
|
||||
|
||||
@ -635,6 +538,34 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
|
||||
return (return_status);
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
|
||||
{
|
||||
int return_status;
|
||||
unsigned long wait_reset;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
||||
|
||||
wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ);
|
||||
while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
|
||||
test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
|
||||
test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
|
||||
ha->dpc_active) && time_before(jiffies, wait_reset)) {
|
||||
|
||||
msleep(1000);
|
||||
|
||||
if (!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
|
||||
ha->flags.chip_reset_done)
|
||||
break;
|
||||
}
|
||||
if (ha->flags.chip_reset_done)
|
||||
return_status = QLA_SUCCESS;
|
||||
else
|
||||
return_status = QLA_FUNCTION_FAILED;
|
||||
|
||||
return return_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* qla2x00_wait_for_loop_ready
|
||||
* Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
|
||||
@ -1163,7 +1094,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
|
||||
continue;
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp && sp->fcport->vha == vha) {
|
||||
if (sp) {
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
sp->cmd->result = res;
|
||||
qla2x00_sp_compl(ha, sp);
|
||||
@ -1351,9 +1282,6 @@ static struct isp_operations qla2100_isp_ops = {
|
||||
.write_optrom = qla2x00_write_optrom_data,
|
||||
.get_flash_version = qla2x00_get_flash_version,
|
||||
.start_scsi = qla2x00_start_scsi,
|
||||
.wrt_req_reg = NULL,
|
||||
.wrt_rsp_reg = NULL,
|
||||
.rd_req_reg = NULL,
|
||||
};
|
||||
|
||||
static struct isp_operations qla2300_isp_ops = {
|
||||
@ -1389,9 +1317,6 @@ static struct isp_operations qla2300_isp_ops = {
|
||||
.write_optrom = qla2x00_write_optrom_data,
|
||||
.get_flash_version = qla2x00_get_flash_version,
|
||||
.start_scsi = qla2x00_start_scsi,
|
||||
.wrt_req_reg = NULL,
|
||||
.wrt_rsp_reg = NULL,
|
||||
.rd_req_reg = NULL,
|
||||
};
|
||||
|
||||
static struct isp_operations qla24xx_isp_ops = {
|
||||
@ -1427,9 +1352,6 @@ static struct isp_operations qla24xx_isp_ops = {
|
||||
.write_optrom = qla24xx_write_optrom_data,
|
||||
.get_flash_version = qla24xx_get_flash_version,
|
||||
.start_scsi = qla24xx_start_scsi,
|
||||
.wrt_req_reg = qla24xx_wrt_req_reg,
|
||||
.wrt_rsp_reg = qla24xx_wrt_rsp_reg,
|
||||
.rd_req_reg = qla24xx_rd_req_reg,
|
||||
};
|
||||
|
||||
static struct isp_operations qla25xx_isp_ops = {
|
||||
@ -1465,9 +1387,6 @@ static struct isp_operations qla25xx_isp_ops = {
|
||||
.write_optrom = qla24xx_write_optrom_data,
|
||||
.get_flash_version = qla24xx_get_flash_version,
|
||||
.start_scsi = qla24xx_start_scsi,
|
||||
.wrt_req_reg = qla24xx_wrt_req_reg,
|
||||
.wrt_rsp_reg = qla24xx_wrt_rsp_reg,
|
||||
.rd_req_reg = qla24xx_rd_req_reg,
|
||||
};
|
||||
|
||||
static struct isp_operations qla81xx_isp_ops = {
|
||||
@ -1493,8 +1412,8 @@ static struct isp_operations qla81xx_isp_ops = {
|
||||
.build_iocbs = NULL,
|
||||
.prep_ms_iocb = qla24xx_prep_ms_iocb,
|
||||
.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb,
|
||||
.read_nvram = qla25xx_read_nvram_data,
|
||||
.write_nvram = qla25xx_write_nvram_data,
|
||||
.read_nvram = NULL,
|
||||
.write_nvram = NULL,
|
||||
.fw_dump = qla81xx_fw_dump,
|
||||
.beacon_on = qla24xx_beacon_on,
|
||||
.beacon_off = qla24xx_beacon_off,
|
||||
@ -1503,9 +1422,6 @@ static struct isp_operations qla81xx_isp_ops = {
|
||||
.write_optrom = qla24xx_write_optrom_data,
|
||||
.get_flash_version = qla24xx_get_flash_version,
|
||||
.start_scsi = qla24xx_start_scsi,
|
||||
.wrt_req_reg = qla24xx_wrt_req_reg,
|
||||
.wrt_rsp_reg = qla24xx_wrt_rsp_reg,
|
||||
.rd_req_reg = qla24xx_rd_req_reg,
|
||||
};
|
||||
|
||||
static inline void
|
||||
@ -1727,7 +1643,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
struct rsp_que *rsp = NULL;
|
||||
|
||||
bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
|
||||
sht = &qla2x00_driver_template;
|
||||
sht = &qla2xxx_driver_template;
|
||||
if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
|
||||
@ -1736,7 +1652,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532 ||
|
||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8001) {
|
||||
bars = pci_select_bars(pdev, IORESOURCE_MEM);
|
||||
sht = &qla24xx_driver_template;
|
||||
mem_only = 1;
|
||||
}
|
||||
|
||||
@ -1927,10 +1842,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
ha->rsp_q_map[0] = rsp;
|
||||
ha->req_q_map[0] = req;
|
||||
|
||||
/* FWI2-capable only. */
|
||||
req->req_q_in = &ha->iobase->isp24.req_q_in;
|
||||
req->req_q_out = &ha->iobase->isp24.req_q_out;
|
||||
rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in;
|
||||
rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out;
|
||||
if (ha->mqenable) {
|
||||
ha->isp_ops->wrt_req_reg = qla25xx_wrt_req_reg;
|
||||
ha->isp_ops->wrt_rsp_reg = qla25xx_wrt_rsp_reg;
|
||||
ha->isp_ops->rd_req_reg = qla25xx_rd_req_reg;
|
||||
req->req_q_in = &ha->mqiobase->isp25mq.req_q_in;
|
||||
req->req_q_out = &ha->mqiobase->isp25mq.req_q_out;
|
||||
rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in;
|
||||
rsp->rsp_q_out = &ha->mqiobase->isp25mq.rsp_q_out;
|
||||
}
|
||||
|
||||
if (qla2x00_initialize_adapter(base_vha)) {
|
||||
@ -2000,6 +1921,16 @@ probe_init_failed:
|
||||
ha->max_queues = 0;
|
||||
|
||||
probe_failed:
|
||||
if (base_vha->timer_active)
|
||||
qla2x00_stop_timer(base_vha);
|
||||
base_vha->flags.online = 0;
|
||||
if (ha->dpc_thread) {
|
||||
struct task_struct *t = ha->dpc_thread;
|
||||
|
||||
ha->dpc_thread = NULL;
|
||||
kthread_stop(t);
|
||||
}
|
||||
|
||||
qla2x00_free_device(base_vha);
|
||||
|
||||
scsi_host_put(base_vha->host);
|
||||
@ -2033,10 +1964,30 @@ qla2x00_remove_one(struct pci_dev *pdev)
|
||||
|
||||
set_bit(UNLOADING, &base_vha->dpc_flags);
|
||||
|
||||
qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
|
||||
|
||||
qla2x00_dfs_remove(base_vha);
|
||||
|
||||
qla84xx_put_chip(base_vha);
|
||||
|
||||
/* Disable timer */
|
||||
if (base_vha->timer_active)
|
||||
qla2x00_stop_timer(base_vha);
|
||||
|
||||
base_vha->flags.online = 0;
|
||||
|
||||
/* Kill the kernel thread for this host */
|
||||
if (ha->dpc_thread) {
|
||||
struct task_struct *t = ha->dpc_thread;
|
||||
|
||||
/*
|
||||
* qla2xxx_wake_dpc checks for ->dpc_thread
|
||||
* so we need to zero it out.
|
||||
*/
|
||||
ha->dpc_thread = NULL;
|
||||
kthread_stop(t);
|
||||
}
|
||||
|
||||
qla2x00_free_sysfs_attr(base_vha);
|
||||
|
||||
fc_remove_host(base_vha->host);
|
||||
@ -2065,25 +2016,6 @@ static void
|
||||
qla2x00_free_device(scsi_qla_host_t *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
|
||||
|
||||
/* Disable timer */
|
||||
if (vha->timer_active)
|
||||
qla2x00_stop_timer(vha);
|
||||
|
||||
vha->flags.online = 0;
|
||||
|
||||
/* Kill the kernel thread for this host */
|
||||
if (ha->dpc_thread) {
|
||||
struct task_struct *t = ha->dpc_thread;
|
||||
|
||||
/*
|
||||
* qla2xxx_wake_dpc checks for ->dpc_thread
|
||||
* so we need to zero it out.
|
||||
*/
|
||||
ha->dpc_thread = NULL;
|
||||
kthread_stop(t);
|
||||
}
|
||||
|
||||
if (ha->flags.fce_enabled)
|
||||
qla2x00_disable_fce_trace(vha, NULL, NULL);
|
||||
@ -2313,9 +2245,19 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
|
||||
} else
|
||||
ha->npiv_info = NULL;
|
||||
|
||||
/* Get consistent memory allocated for EX-INIT-CB. */
|
||||
if (IS_QLA81XX(ha)) {
|
||||
ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
|
||||
&ha->ex_init_cb_dma);
|
||||
if (!ha->ex_init_cb)
|
||||
goto fail_ex_init_cb;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&ha->vp_list);
|
||||
return 1;
|
||||
|
||||
fail_ex_init_cb:
|
||||
kfree(ha->npiv_info);
|
||||
fail_npiv_info:
|
||||
dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) *
|
||||
sizeof(response_t), (*rsp)->ring, (*rsp)->dma);
|
||||
@ -2398,18 +2340,22 @@ qla2x00_mem_free(struct qla_hw_data *ha)
|
||||
if (ha->sfp_data)
|
||||
dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);
|
||||
|
||||
if (ha->edc_data)
|
||||
dma_pool_free(ha->s_dma_pool, ha->edc_data, ha->edc_data_dma);
|
||||
|
||||
if (ha->ms_iocb)
|
||||
dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
|
||||
|
||||
if (ha->ex_init_cb)
|
||||
dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
|
||||
|
||||
if (ha->s_dma_pool)
|
||||
dma_pool_destroy(ha->s_dma_pool);
|
||||
|
||||
|
||||
if (ha->gid_list)
|
||||
dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
|
||||
ha->gid_list_dma);
|
||||
|
||||
|
||||
if (ha->init_cb)
|
||||
dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
|
||||
ha->init_cb, ha->init_cb_dma);
|
||||
@ -2428,6 +2374,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
|
||||
ha->ms_iocb_dma = 0;
|
||||
ha->init_cb = NULL;
|
||||
ha->init_cb_dma = 0;
|
||||
ha->ex_init_cb = NULL;
|
||||
ha->ex_init_cb_dma = 0;
|
||||
|
||||
ha->s_dma_pool = NULL;
|
||||
|
||||
@ -2914,19 +2862,11 @@ qla2x00_timer(scsi_qla_host_t *vha)
|
||||
spin_unlock_irqrestore(&ha->hardware_lock,
|
||||
cpu_flags);
|
||||
}
|
||||
set_bit(ABORT_QUEUES_NEEDED, &vha->dpc_flags);
|
||||
start_dpc++;
|
||||
}
|
||||
|
||||
/* if the loop has been down for 4 minutes, reinit adapter */
|
||||
if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
|
||||
DEBUG(printk("scsi(%ld): Loop down exceed 4 mins - "
|
||||
"restarting queues.\n",
|
||||
vha->host_no));
|
||||
|
||||
set_bit(RESTART_QUEUES_NEEDED, &vha->dpc_flags);
|
||||
start_dpc++;
|
||||
|
||||
if (!(vha->device_flags & DFLG_NO_CABLE) &&
|
||||
!vha->vp_idx) {
|
||||
DEBUG(printk("scsi(%ld): Loop down - "
|
||||
@ -3053,6 +2993,8 @@ qla2x00_release_firmware(void)
|
||||
static pci_ers_result_t
|
||||
qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
|
||||
{
|
||||
scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
|
||||
|
||||
switch (state) {
|
||||
case pci_channel_io_normal:
|
||||
return PCI_ERS_RESULT_CAN_RECOVER;
|
||||
@ -3060,7 +3002,7 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
|
||||
pci_disable_device(pdev);
|
||||
return PCI_ERS_RESULT_NEED_RESET;
|
||||
case pci_channel_io_perm_failure:
|
||||
qla2x00_remove_one(pdev);
|
||||
qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
}
|
||||
return PCI_ERS_RESULT_NEED_RESET;
|
||||
|
@ -612,8 +612,8 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
|
||||
|
||||
/* Good data. Use specified location. */
|
||||
loc = locations[1];
|
||||
*start = le16_to_cpu(fltl->start_hi) << 16 |
|
||||
le16_to_cpu(fltl->start_lo);
|
||||
*start = (le16_to_cpu(fltl->start_hi) << 16 |
|
||||
le16_to_cpu(fltl->start_lo)) >> 2;
|
||||
end:
|
||||
DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start));
|
||||
return QLA_SUCCESS;
|
||||
@ -629,6 +629,14 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
|
||||
{ FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR_81 };
|
||||
const uint32_t def_vpd_nvram[] =
|
||||
{ FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR_81 };
|
||||
const uint32_t def_vpd0[] =
|
||||
{ 0, 0, FA_VPD0_ADDR_81 };
|
||||
const uint32_t def_vpd1[] =
|
||||
{ 0, 0, FA_VPD1_ADDR_81 };
|
||||
const uint32_t def_nvram0[] =
|
||||
{ 0, 0, FA_NVRAM0_ADDR_81 };
|
||||
const uint32_t def_nvram1[] =
|
||||
{ 0, 0, FA_NVRAM1_ADDR_81 };
|
||||
const uint32_t def_fdt[] =
|
||||
{ FA_FLASH_DESCR_ADDR_24, FA_FLASH_DESCR_ADDR,
|
||||
FA_FLASH_DESCR_ADDR_81 };
|
||||
@ -693,6 +701,20 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
|
||||
break;
|
||||
case FLT_REG_VPD_0:
|
||||
ha->flt_region_vpd_nvram = start;
|
||||
if (!(PCI_FUNC(ha->pdev->devfn) & 1))
|
||||
ha->flt_region_vpd = start;
|
||||
break;
|
||||
case FLT_REG_VPD_1:
|
||||
if (PCI_FUNC(ha->pdev->devfn) & 1)
|
||||
ha->flt_region_vpd = start;
|
||||
break;
|
||||
case FLT_REG_NVRAM_0:
|
||||
if (!(PCI_FUNC(ha->pdev->devfn) & 1))
|
||||
ha->flt_region_nvram = start;
|
||||
break;
|
||||
case FLT_REG_NVRAM_1:
|
||||
if (PCI_FUNC(ha->pdev->devfn) & 1)
|
||||
ha->flt_region_nvram = start;
|
||||
break;
|
||||
case FLT_REG_FDT:
|
||||
ha->flt_region_fdt = start;
|
||||
@ -722,13 +744,18 @@ no_flash_data:
|
||||
ha->flt_region_fw = def_fw[def];
|
||||
ha->flt_region_boot = def_boot[def];
|
||||
ha->flt_region_vpd_nvram = def_vpd_nvram[def];
|
||||
ha->flt_region_vpd = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
|
||||
def_vpd0[def]: def_vpd1[def];
|
||||
ha->flt_region_nvram = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
|
||||
def_nvram0[def]: def_nvram1[def];
|
||||
ha->flt_region_fdt = def_fdt[def];
|
||||
ha->flt_region_npiv_conf = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
|
||||
def_npiv_conf0[def]: def_npiv_conf1[def];
|
||||
done:
|
||||
DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
|
||||
"vpd_nvram=0x%x fdt=0x%x flt=0x%x npiv=0x%x.\n", loc,
|
||||
ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram,
|
||||
"vpd_nvram=0x%x vpd=0x%x nvram=0x%x fdt=0x%x flt=0x%x "
|
||||
"npiv=0x%x.\n", loc, ha->flt_region_boot, ha->flt_region_fw,
|
||||
ha->flt_region_vpd_nvram, ha->flt_region_vpd, ha->flt_region_nvram,
|
||||
ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_npiv_conf));
|
||||
}
|
||||
|
||||
@ -931,31 +958,41 @@ done:
|
||||
ha->npiv_info = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
qla24xx_unprotect_flash(struct qla_hw_data *ha)
|
||||
static int
|
||||
qla24xx_unprotect_flash(scsi_qla_host_t *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||
|
||||
if (ha->flags.fac_supported)
|
||||
return qla81xx_fac_do_write_enable(vha, 1);
|
||||
|
||||
/* Enable flash write. */
|
||||
WRT_REG_DWORD(®->ctrl_status,
|
||||
RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE);
|
||||
RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */
|
||||
|
||||
if (!ha->fdt_wrt_disable)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
/* Disable flash write-protection, first clear SR protection bit */
|
||||
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
|
||||
/* Then write zero again to clear remaining SR bits.*/
|
||||
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
|
||||
done:
|
||||
return QLA_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
qla24xx_protect_flash(struct qla_hw_data *ha)
|
||||
static int
|
||||
qla24xx_protect_flash(scsi_qla_host_t *vha)
|
||||
{
|
||||
uint32_t cnt;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||
|
||||
if (ha->flags.fac_supported)
|
||||
return qla81xx_fac_do_write_enable(vha, 0);
|
||||
|
||||
if (!ha->fdt_wrt_disable)
|
||||
goto skip_wrt_protect;
|
||||
|
||||
@ -973,6 +1010,26 @@ skip_wrt_protect:
|
||||
WRT_REG_DWORD(®->ctrl_status,
|
||||
RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE);
|
||||
RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */
|
||||
|
||||
return QLA_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
qla24xx_erase_sector(scsi_qla_host_t *vha, uint32_t fdata)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
uint32_t start, finish;
|
||||
|
||||
if (ha->flags.fac_supported) {
|
||||
start = fdata >> 2;
|
||||
finish = start + (ha->fdt_block_size >> 2) - 1;
|
||||
return qla81xx_fac_erase_sector(vha, flash_data_addr(ha,
|
||||
start), flash_data_addr(ha, finish));
|
||||
}
|
||||
|
||||
return qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd,
|
||||
(fdata & 0xff00) | ((fdata << 16) & 0xff0000) |
|
||||
((fdata >> 16) & 0xff));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -987,8 +1044,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
|
||||
void *optrom = NULL;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
ret = QLA_SUCCESS;
|
||||
|
||||
/* Prepare burst-capable write on supported ISPs. */
|
||||
if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) &&
|
||||
dwords > OPTROM_BURST_DWORDS) {
|
||||
@ -1004,7 +1059,12 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
|
||||
rest_addr = (ha->fdt_block_size >> 2) - 1;
|
||||
sec_mask = ~rest_addr;
|
||||
|
||||
qla24xx_unprotect_flash(ha);
|
||||
ret = qla24xx_unprotect_flash(vha);
|
||||
if (ret != QLA_SUCCESS) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Unable to unprotect flash for update.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
|
||||
fdata = (faddr & sec_mask) << 2;
|
||||
@ -1017,9 +1077,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
|
||||
ha->fdt_unprotect_sec_cmd,
|
||||
(fdata & 0xff00) | ((fdata << 16) &
|
||||
0xff0000) | ((fdata >> 16) & 0xff));
|
||||
ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd,
|
||||
(fdata & 0xff00) |((fdata << 16) &
|
||||
0xff0000) | ((fdata >> 16) & 0xff));
|
||||
ret = qla24xx_erase_sector(vha, fdata);
|
||||
if (ret != QLA_SUCCESS) {
|
||||
DEBUG9(qla_printk("Unable to erase sector: "
|
||||
"address=%x.\n", faddr));
|
||||
@ -1073,8 +1131,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
|
||||
0xff0000) | ((fdata >> 16) & 0xff));
|
||||
}
|
||||
|
||||
qla24xx_protect_flash(ha);
|
||||
|
||||
ret = qla24xx_protect_flash(vha);
|
||||
if (ret != QLA_SUCCESS)
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Unable to protect flash after update.\n");
|
||||
done:
|
||||
if (optrom)
|
||||
dma_free_coherent(&ha->pdev->dev,
|
||||
OPTROM_BURST_SIZE, optrom, optrom_dma);
|
||||
@ -1915,7 +1976,7 @@ qla2x00_resume_hba(struct scsi_qla_host *vha)
|
||||
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
qla2x00_wait_for_hba_online(vha);
|
||||
qla2x00_wait_for_chip_reset(vha);
|
||||
scsi_unblock_requests(vha->host);
|
||||
}
|
||||
|
||||
@ -2206,11 +2267,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
|
||||
rval = qla24xx_write_flash_data(vha, (uint32_t *)buf, offset >> 2,
|
||||
length >> 2);
|
||||
|
||||
/* Resume HBA -- RISC reset needed. */
|
||||
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
qla2x00_wait_for_hba_online(vha);
|
||||
scsi_unblock_requests(vha->host);
|
||||
|
||||
return rval;
|
||||
@ -2518,7 +2575,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
dcode = mbuf;
|
||||
|
||||
/* Begin with first PCI expansion ROM header. */
|
||||
pcihdr = ha->flt_region_boot;
|
||||
pcihdr = ha->flt_region_boot << 2;
|
||||
last_image = 1;
|
||||
do {
|
||||
/* Verify PCI expansion ROM header. */
|
||||
|
@ -7,9 +7,9 @@
|
||||
/*
|
||||
* Driver version
|
||||
*/
|
||||
#define QLA2XXX_VERSION "8.03.00-k4"
|
||||
#define QLA2XXX_VERSION "8.03.01-k1"
|
||||
|
||||
#define QLA_DRIVER_MAJOR_VER 8
|
||||
#define QLA_DRIVER_MINOR_VER 3
|
||||
#define QLA_DRIVER_PATCH_VER 0
|
||||
#define QLA_DRIVER_PATCH_VER 1
|
||||
#define QLA_DRIVER_BETA_VER 0
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
@ -53,8 +54,6 @@
|
||||
|
||||
#define DEFAULT_LOOP_COUNT 10000
|
||||
|
||||
#include "qlogicpti_asm.c"
|
||||
|
||||
static struct qlogicpti *qptichain = NULL;
|
||||
static DEFINE_SPINLOCK(qptichain_lock);
|
||||
|
||||
@ -465,16 +464,32 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
|
||||
|
||||
static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
const char fwname[] = "qlogic/isp1000.bin";
|
||||
const __le16 *fw_data;
|
||||
struct Scsi_Host *host = qpti->qhost;
|
||||
unsigned short csum = 0;
|
||||
unsigned short param[6];
|
||||
unsigned short *risc_code, risc_code_addr, risc_code_length;
|
||||
unsigned short risc_code_addr, risc_code_length;
|
||||
int err;
|
||||
unsigned long flags;
|
||||
int i, timeout;
|
||||
|
||||
risc_code = &sbus_risc_code01[0];
|
||||
err = request_firmware(&fw, fwname, &qpti->op->dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
|
||||
fwname, err);
|
||||
return err;
|
||||
}
|
||||
if (fw->size % 2) {
|
||||
printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
|
||||
fw->size, fwname);
|
||||
err = -EINVAL;
|
||||
goto outfirm;
|
||||
}
|
||||
fw_data = (const __le16 *)&fw->data[0];
|
||||
risc_code_addr = 0x1000; /* all f/w modules load at 0x1000 */
|
||||
risc_code_length = sbus_risc_code_length01;
|
||||
risc_code_length = fw->size / 2;
|
||||
|
||||
spin_lock_irqsave(host->host_lock, flags);
|
||||
|
||||
@ -482,12 +497,12 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
|
||||
* afterwards via the mailbox commands.
|
||||
*/
|
||||
for (i = 0; i < risc_code_length; i++)
|
||||
csum += risc_code[i];
|
||||
csum += __le16_to_cpu(fw_data[i]);
|
||||
if (csum) {
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!",
|
||||
qpti->qpti_id);
|
||||
return 1;
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
sbus_writew(SBUS_CTRL_RESET, qpti->qregs + SBUS_CTRL);
|
||||
sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + CMD_DMA_CTRL);
|
||||
@ -496,9 +511,9 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
|
||||
while (--timeout && (sbus_readw(qpti->qregs + SBUS_CTRL) & SBUS_CTRL_RESET))
|
||||
udelay(20);
|
||||
if (!timeout) {
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
printk(KERN_EMERG "qlogicpti%d: Cannot reset the ISP.", qpti->qpti_id);
|
||||
return 1;
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sbus_writew(HCCTRL_RESET, qpti->qregs + HCCTRL);
|
||||
@ -536,21 +551,21 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
|
||||
if (qlogicpti_mbox_command(qpti, param, 1)) {
|
||||
printk(KERN_EMERG "qlogicpti%d: Cannot stop firmware for reload.\n",
|
||||
qpti->qpti_id);
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
return 1;
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Load it up.. */
|
||||
for (i = 0; i < risc_code_length; i++) {
|
||||
param[0] = MBOX_WRITE_RAM_WORD;
|
||||
param[1] = risc_code_addr + i;
|
||||
param[2] = risc_code[i];
|
||||
param[2] = __le16_to_cpu(fw_data[i]);
|
||||
if (qlogicpti_mbox_command(qpti, param, 1) ||
|
||||
param[0] != MBOX_COMMAND_COMPLETE) {
|
||||
printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
|
||||
qpti->qpti_id);
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
return 1;
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -569,8 +584,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
|
||||
(param[0] != MBOX_COMMAND_COMPLETE)) {
|
||||
printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n",
|
||||
qpti->qpti_id);
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
return 1;
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Start using newly downloaded firmware. */
|
||||
@ -583,8 +598,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
|
||||
(param[0] != MBOX_COMMAND_COMPLETE)) {
|
||||
printk(KERN_EMERG "qlogicpti%d: AboutFirmware cmd fails.\n",
|
||||
qpti->qpti_id);
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
return 1;
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Snag the major and minor revisions from the result. */
|
||||
@ -599,8 +614,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
|
||||
(param[0] != MBOX_COMMAND_COMPLETE)) {
|
||||
printk(KERN_EMERG "qlogicpti%d: could not set clock rate.\n",
|
||||
qpti->qpti_id);
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
return 1;
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (qpti->is_pti != 0) {
|
||||
@ -616,8 +631,11 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
|
||||
qlogicpti_mbox_command(qpti, param, 1);
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(host->host_lock, flags);
|
||||
return 0;
|
||||
outfirm:
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
|
||||
@ -1458,6 +1476,7 @@ MODULE_DESCRIPTION("QlogicISP SBUS driver");
|
||||
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("2.1");
|
||||
MODULE_FIRMWARE("qlogic/isp1000.bin");
|
||||
|
||||
module_init(qpti_init);
|
||||
module_exit(qpti_exit);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -169,12 +169,10 @@ scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask)
|
||||
{
|
||||
struct scsi_cmnd *cmd;
|
||||
|
||||
cmd = kmem_cache_alloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
|
||||
cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
|
||||
if (!cmd)
|
||||
return NULL;
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
||||
cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
|
||||
gfp_mask | pool->gfp_mask);
|
||||
if (!cmd->sense_buffer) {
|
||||
|
@ -791,7 +791,22 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
|
||||
"%d bytes done.\n",
|
||||
req->nr_sectors, good_bytes));
|
||||
|
||||
/* A number of bytes were successfully read. If there
|
||||
/*
|
||||
* Recovered errors need reporting, but they're always treated
|
||||
* as success, so fiddle the result code here. For BLOCK_PC
|
||||
* we already took a copy of the original into rq->errors which
|
||||
* is what gets returned to the user
|
||||
*/
|
||||
if (sense_valid && sshdr.sense_key == RECOVERED_ERROR) {
|
||||
if (!(req->cmd_flags & REQ_QUIET))
|
||||
scsi_print_sense("", cmd);
|
||||
result = 0;
|
||||
/* BLOCK_PC may have set error */
|
||||
error = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A number of bytes were successfully read. If there
|
||||
* are leftovers and there is some kind of error
|
||||
* (result != 0), retry the rest.
|
||||
*/
|
||||
|
@ -1051,12 +1051,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
|
||||
good_bytes = sd_completed_bytes(SCpnt);
|
||||
break;
|
||||
case RECOVERED_ERROR:
|
||||
/* Inform the user, but make sure that it's not treated
|
||||
* as a hard error.
|
||||
*/
|
||||
scsi_print_sense("sd", SCpnt);
|
||||
SCpnt->result = 0;
|
||||
memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
|
||||
good_bytes = scsi_bufflen(SCpnt);
|
||||
break;
|
||||
case NO_SENSE:
|
||||
|
@ -264,6 +264,7 @@ struct ses_host_edev {
|
||||
struct enclosure_device *edev;
|
||||
};
|
||||
|
||||
#if 0
|
||||
int ses_match_host(struct enclosure_device *edev, void *data)
|
||||
{
|
||||
struct ses_host_edev *sed = data;
|
||||
@ -280,6 +281,7 @@ int ses_match_host(struct enclosure_device *edev, void *data)
|
||||
sed->edev = edev;
|
||||
return 1;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
static void ses_process_descriptor(struct enclosure_component *ecomp,
|
||||
unsigned char *desc)
|
||||
|
@ -1312,8 +1312,10 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
|
||||
wake_up_interruptible(&sfp->read_wait);
|
||||
kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
|
||||
kref_put(&sfp->f_ref, sg_remove_sfp);
|
||||
} else
|
||||
execute_in_process_context(sg_rq_end_io_usercontext, &srp->ew);
|
||||
} else {
|
||||
INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext);
|
||||
schedule_work(&srp->ew.work);
|
||||
}
|
||||
}
|
||||
|
||||
static struct file_operations sg_fops = {
|
||||
@ -1656,10 +1658,30 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd)
|
||||
md->null_mapped = hp->dxferp ? 0 : 1;
|
||||
}
|
||||
|
||||
if (iov_count)
|
||||
res = blk_rq_map_user_iov(q, rq, md, hp->dxferp, iov_count,
|
||||
hp->dxfer_len, GFP_ATOMIC);
|
||||
else
|
||||
if (iov_count) {
|
||||
int len, size = sizeof(struct sg_iovec) * iov_count;
|
||||
struct iovec *iov;
|
||||
|
||||
iov = kmalloc(size, GFP_ATOMIC);
|
||||
if (!iov)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(iov, hp->dxferp, size)) {
|
||||
kfree(iov);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
len = iov_length(iov, iov_count);
|
||||
if (hp->dxfer_len < len) {
|
||||
iov_count = iov_shorten(iov, iov_count, hp->dxfer_len);
|
||||
len = hp->dxfer_len;
|
||||
}
|
||||
|
||||
res = blk_rq_map_user_iov(q, rq, md, (struct sg_iovec *)iov,
|
||||
iov_count,
|
||||
len, GFP_ATOMIC);
|
||||
kfree(iov);
|
||||
} else
|
||||
res = blk_rq_map_user(q, rq, md, hp->dxferp,
|
||||
hp->dxfer_len, GFP_ATOMIC);
|
||||
|
||||
@ -2079,7 +2101,8 @@ static void sg_remove_sfp(struct kref *kref)
|
||||
write_unlock_irqrestore(&sg_index_lock, iflags);
|
||||
wake_up_interruptible(&sdp->o_excl_wait);
|
||||
|
||||
execute_in_process_context(sg_remove_sfp_usercontext, &sfp->ew);
|
||||
INIT_WORK(&sfp->ew.work, sg_remove_sfp_usercontext);
|
||||
schedule_work(&sfp->ew.work);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -309,15 +309,6 @@ static int sr_done(struct scsi_cmnd *SCpnt)
|
||||
break;
|
||||
|
||||
case RECOVERED_ERROR:
|
||||
|
||||
/*
|
||||
* An error occured, but it recovered. Inform the
|
||||
* user, but make sure that it's not treated as a
|
||||
* hard error.
|
||||
*/
|
||||
scsi_print_sense("sr", SCpnt);
|
||||
SCpnt->result = 0;
|
||||
SCpnt->sense_buffer[0] = 0x0;
|
||||
good_bytes = this_count;
|
||||
break;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -234,7 +234,7 @@ static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host)
|
||||
/*
|
||||
* Set the status field of a CAM CCB.
|
||||
*/
|
||||
static __inline void
|
||||
static inline void
|
||||
sym_set_cam_status(struct scsi_cmnd *cmd, int status)
|
||||
{
|
||||
cmd->result &= ~(0xff << 16);
|
||||
@ -244,7 +244,7 @@ sym_set_cam_status(struct scsi_cmnd *cmd, int status)
|
||||
/*
|
||||
* Get the status field of a CAM CCB.
|
||||
*/
|
||||
static __inline int
|
||||
static inline int
|
||||
sym_get_cam_status(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return host_byte(cmd->result);
|
||||
@ -253,7 +253,7 @@ sym_get_cam_status(struct scsi_cmnd *cmd)
|
||||
/*
|
||||
* Build CAM result for a successful IO and for a failed IO.
|
||||
*/
|
||||
static __inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid)
|
||||
static inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid)
|
||||
{
|
||||
scsi_set_resid(cmd, resid);
|
||||
cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f));
|
||||
|
@ -602,7 +602,7 @@ sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fa
|
||||
/*
|
||||
* Set initial io register bits from burst code.
|
||||
*/
|
||||
static __inline void sym_init_burst(struct sym_hcb *np, u_char bc)
|
||||
static inline void sym_init_burst(struct sym_hcb *np, u_char bc)
|
||||
{
|
||||
np->rv_ctest4 &= ~0x80;
|
||||
np->rv_dmode &= ~(0x3 << 6);
|
||||
|
@ -1096,7 +1096,7 @@ do { \
|
||||
#elif SYM_CONF_DMA_ADDRESSING_MODE == 2
|
||||
#define DMA_DAC_MASK DMA_64BIT_MASK
|
||||
int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s);
|
||||
static __inline void
|
||||
static inline void
|
||||
sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len)
|
||||
{
|
||||
u32 h = (badd>>32);
|
||||
@ -1201,7 +1201,7 @@ dma_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m);
|
||||
|
||||
#define sym_m_pool_match(mp_id1, mp_id2) (mp_id1 == mp_id2)
|
||||
|
||||
static __inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
|
||||
static inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
|
||||
{
|
||||
void *vaddr = NULL;
|
||||
dma_addr_t baddr = 0;
|
||||
@ -1215,7 +1215,7 @@ static __inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
static __inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
|
||||
static inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
|
||||
{
|
||||
dma_free_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, vbp->vaddr,
|
||||
vbp->baddr);
|
||||
|
@ -262,7 +262,7 @@ static void ___free_dma_mem_cluster(m_pool_p mp, void *m)
|
||||
#endif
|
||||
|
||||
/* Fetch the memory pool for a given pool id (i.e. DMA constraints) */
|
||||
static __inline m_pool_p ___get_dma_pool(m_pool_ident_t dev_dmat)
|
||||
static inline m_pool_p ___get_dma_pool(m_pool_ident_t dev_dmat)
|
||||
{
|
||||
m_pool_p mp;
|
||||
for (mp = mp0.next;
|
||||
|
@ -52,17 +52,17 @@ typedef struct sym_quehead {
|
||||
(ptr)->flink = (ptr); (ptr)->blink = (ptr); \
|
||||
} while (0)
|
||||
|
||||
static __inline struct sym_quehead *sym_que_first(struct sym_quehead *head)
|
||||
static inline struct sym_quehead *sym_que_first(struct sym_quehead *head)
|
||||
{
|
||||
return (head->flink == head) ? 0 : head->flink;
|
||||
}
|
||||
|
||||
static __inline struct sym_quehead *sym_que_last(struct sym_quehead *head)
|
||||
static inline struct sym_quehead *sym_que_last(struct sym_quehead *head)
|
||||
{
|
||||
return (head->blink == head) ? 0 : head->blink;
|
||||
}
|
||||
|
||||
static __inline void __sym_que_add(struct sym_quehead * new,
|
||||
static inline void __sym_que_add(struct sym_quehead * new,
|
||||
struct sym_quehead * blink,
|
||||
struct sym_quehead * flink)
|
||||
{
|
||||
@ -72,19 +72,19 @@ static __inline void __sym_que_add(struct sym_quehead * new,
|
||||
blink->flink = new;
|
||||
}
|
||||
|
||||
static __inline void __sym_que_del(struct sym_quehead * blink,
|
||||
static inline void __sym_que_del(struct sym_quehead * blink,
|
||||
struct sym_quehead * flink)
|
||||
{
|
||||
flink->blink = blink;
|
||||
blink->flink = flink;
|
||||
}
|
||||
|
||||
static __inline int sym_que_empty(struct sym_quehead *head)
|
||||
static inline int sym_que_empty(struct sym_quehead *head)
|
||||
{
|
||||
return head->flink == head;
|
||||
}
|
||||
|
||||
static __inline void sym_que_splice(struct sym_quehead *list,
|
||||
static inline void sym_que_splice(struct sym_quehead *list,
|
||||
struct sym_quehead *head)
|
||||
{
|
||||
struct sym_quehead *first = list->flink;
|
||||
@ -101,7 +101,7 @@ static __inline void sym_que_splice(struct sym_quehead *list,
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void sym_que_move(struct sym_quehead *orig,
|
||||
static inline void sym_que_move(struct sym_quehead *orig,
|
||||
struct sym_quehead *dest)
|
||||
{
|
||||
struct sym_quehead *first, *last;
|
||||
@ -129,7 +129,7 @@ static __inline void sym_que_move(struct sym_quehead *orig,
|
||||
|
||||
#define sym_insque_head(new, head) __sym_que_add(new, head, (head)->flink)
|
||||
|
||||
static __inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
|
||||
static inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
|
||||
{
|
||||
struct sym_quehead *elem = head->flink;
|
||||
|
||||
@ -142,7 +142,7 @@ static __inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
|
||||
|
||||
#define sym_insque_tail(new, head) __sym_que_add(new, (head)->blink, head)
|
||||
|
||||
static __inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head)
|
||||
static inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head)
|
||||
{
|
||||
struct sym_quehead *elem = head->blink;
|
||||
|
||||
|
@ -41,6 +41,11 @@ fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
|
||||
fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
|
||||
e100/d102e_ucode.bin
|
||||
fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
|
||||
fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
|
||||
advansys/3550.bin advansys/38C0800.bin
|
||||
fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \
|
||||
qlogic/12160.bin
|
||||
fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin
|
||||
fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin
|
||||
fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp
|
||||
fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \
|
||||
|
@ -45,6 +45,32 @@ Found alsa-firmware package in hex form, with the following comment:
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Driver: SCSI_ADVANSYS - AdvanSys SCSI
|
||||
|
||||
File: advansys/mcode.bin
|
||||
File: advansys/3550.bin
|
||||
File: advansys/38C0800.bin
|
||||
File: advansys/38C1600.bin
|
||||
|
||||
Licence: BSD, no source available.
|
||||
|
||||
Found in hex form in kernel source.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Driver: SCSI_QLOGIC_1280 - Qlogic QLA 1240/1x80/1x160 SCSI support
|
||||
|
||||
File: qlogic/1040.bin
|
||||
File: qlogic/1280.bin
|
||||
File: qlogic/12160.bin
|
||||
|
||||
Licence: Allegedly GPLv2+, but no source visible. Marked:
|
||||
|
||||
QLOGIC LINUX SOFTWARE
|
||||
QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x
|
||||
Copyright (C) 2001 Qlogic Corporation (www.qlogic.com)
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Driver: smctr -- SMC ISA/MCA Token Ring adapter
|
||||
|
||||
File: tr_smctr.bin
|
||||
@ -596,3 +622,13 @@ Licence: Allegedly GPL, but no source visible. Marked:
|
||||
Found in hex form in kernel source.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Driver: SCSI_QLOGICPTI - PTI Qlogic, ISP Driver
|
||||
|
||||
File: qlogic/isp1000.bin
|
||||
|
||||
Licence: Unknown
|
||||
|
||||
Found in hex form in kernel source.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
317
firmware/advansys/3550.bin.ihex
Normal file
317
firmware/advansys/3550.bin.ihex
Normal file
@ -0,0 +1,317 @@
|
||||
:10000000DD2DD504000000F200F0001618E400FC1D
|
||||
:10001000010048E4BE18188003F6020000FAFFFF52
|
||||
:10002000280E9EE7FF0082E700EA00F601E609E7F6
|
||||
:1000300055F001F601FA08000300040018F410005E
|
||||
:1000400000EC85F0BC00D5F08E0C385400E61EF0B4
|
||||
:1000500086F0B4009857D0010C1C3E1C0C00BB006D
|
||||
:10006000AA18028032F001FC880CC6120213184054
|
||||
:10007000005701EA3C006C016E0104123E570080FB
|
||||
:1000800003E6B600C00001013E01DA0F221008129B
|
||||
:10009000024AB95403581B8030E44BE4200032007C
|
||||
:1000A0003E00800024013C0168016A017001720178
|
||||
:1000B000740176017801620A920C2C102E1006133E
|
||||
:1000C0004C1CBB553C5604804AE402EE5BF0B1F098
|
||||
:1000D00003F706F703FC0F004000BE000001B00864
|
||||
:1000E00030136415321C381C4E1C10440248004C5E
|
||||
:1000F00004EA5DF004F602FC0500340036009800C6
|
||||
:10010000CC0020014E014E0B1E0E0C100A120413DF
|
||||
:100110004013301C004EBD56068300DC05F009F08C
|
||||
:1001200059F0A7F0B8F00EF70600190033009B0055
|
||||
:10013000A400B500BA00D000E100E700DE03560AD3
|
||||
:10014000140E021004100A1036100A131213521360
|
||||
:1001500010151415AC16201C341C361C08443844E9
|
||||
:1001600091440A454846014868548355B0570158A0
|
||||
:10017000835905E60BF00CF05CF04BF404F805F83D
|
||||
:1001800002FA03FA04FC05FC07000A000D001C003B
|
||||
:100190009E00A800AA00B900E00022012601790112
|
||||
:1001A0007A01C001C2017C025A03EA04E807680828
|
||||
:1001B0006908BA08E909060B3A0E00101A10ED108A
|
||||
:1001C000F11006120C1316131E1382134214D614C8
|
||||
:1001D0008A15C617D2176B18121C461C9C32004099
|
||||
:1001E0000E47484741488948804C00544455E555DE
|
||||
:1001F00014567757BF57405C0680089003A1FE9CB9
|
||||
:10020000F02902FEB80CFF100000D0FECC1800CF81
|
||||
:10021000FE8001FF030000FE9315FE0F05FF38006E
|
||||
:1002200000FE572400FE48004FFF04000010FF09A5
|
||||
:100230000000FF080101FF08FFFFFF270000FF107B
|
||||
:10024000FFFFFF0F0000FE7856FE3412FF21000072
|
||||
:10025000FE04F7CF2A670B01FECE0EFE04F7CF6730
|
||||
:100260000B3C2AFE3DF0FE0202FE20F09CFE91F0C7
|
||||
:10027000FEF001FE90F0FEF001FE8FF09C05513B78
|
||||
:1002800002FED40C01FE440DFEDD12FEFC10FE2821
|
||||
:100290001C05FEA600FED3124718FEA600B5FE48B8
|
||||
:1002A000F0FE8602FE49F0FEA002FE4AF0FEBE020B
|
||||
:1002B000FE46F0FE5002FE47F0FE5602FE43F0FE00
|
||||
:1002C0004402FE44F0FE4802FE45F0FE4C02170BCD
|
||||
:1002D000A0170618960229FE001CDEFE021CDDFE99
|
||||
:1002E0001E1CFEE91001FE2017FEE710FE06FCC7EB
|
||||
:1002F0000A6B019E0229144D379701FE640F0A6BA9
|
||||
:100300000182FEBD100A6B0182FEAD10FE161CFEBE
|
||||
:10031000581C170618962A2529FE3DF0FE020221D8
|
||||
:10032000FE9402FE5A1CEAFE141C14FE300037979D
|
||||
:1003300001FE540F1706189602D01E20071034FE37
|
||||
:10034000691017061896FE04EC20463D1220FE05A3
|
||||
:10035000F6C701FE5216094A4C35112D3C8A01E6BA
|
||||
:1003600002290A40010E07005D016FFE1810FE41D0
|
||||
:10037000580A99010EFEC85464FE0C0301E60229D6
|
||||
:100380002A46FE02E827F8FE9E43F7FE27F0FEDC31
|
||||
:1003900001FE074BFE20F09CFE401C25D2FE26F0FD
|
||||
:1003A000FE5603FEA0F0FE4403FE11F09CFEEF108B
|
||||
:1003B000FE9FF0FE6403EB0FFE1100025A2AFE4876
|
||||
:1003C0001CEB09041DFE1813231E98AC12980A405A
|
||||
:1003D000010EAC7501FEBC1511CA25D2FE01F0D28A
|
||||
:1003E000FE82F0FE9203EC11FEE40065FEA40325FC
|
||||
:1003F000321FFEB4030143FE06F0FEC4038D81FEEE
|
||||
:100400000AF0FE7A060222056B2816FEF604142C6A
|
||||
:1004100001338FFE660202D1EB2A671AFE671BF8D2
|
||||
:10042000F7FE481C70016E870A40010E070016D3C4
|
||||
:100430000ACA010E7460597627056B28FE10121443
|
||||
:100440002C01338FFE660202D1BC7DBD7F25226563
|
||||
:10045000FE3C041FFE380468FEA000FE9B57FE4EC3
|
||||
:10046000122BFF02001001081FFEE0042B01081FE1
|
||||
:1004700022302ED5FE4C44FE4C1260FE4448132C14
|
||||
:10048000FE4C5464D3467627FAEFFE621309041D2E
|
||||
:10049000FE2A132F077EA5FE2010132CFE4C546459
|
||||
:1004A000D3FAEF8609041DFE08132F077E6E090498
|
||||
:1004B0001DFE1C1214920904063B14C401338FFE66
|
||||
:1004C000700C02222B11FEE600FE1C90F903149220
|
||||
:1004D00001330229FE425B671AFE4659F8F7FE8790
|
||||
:1004E00080FE31E44F09040BFE7813FE2080071ACA
|
||||
:1004F000FE7012490406FE601305FEA2002816FED7
|
||||
:100500008005FE31E46A49040BFE4A1305FEA00093
|
||||
:1005100028FE42125E01082532F1010826FE9805E8
|
||||
:1005200011FEE3002349FE4AF0FE6A05FE49F0FE93
|
||||
:1005300064058324FE2100A124FE2200A0244CFE99
|
||||
:100540000948010826FE9805FEE2084904C53B015A
|
||||
:1005500086240612CC37FE270109041DFE2212470D
|
||||
:1005600001A714920904063B14C401338FFE700CDA
|
||||
:10057000022205FE9C0028FE3E12055028FE36137E
|
||||
:100580004701A726FE08060A06490419FE02125F63
|
||||
:1005900001FEAA141FFEFE05119A014311FEE5009B
|
||||
:1005A0000550B40C5005C628FE6212053F28FE5ABD
|
||||
:1005B0001301FE141801FE6618FE4348B719136CA8
|
||||
:1005C000FF020057488B1C3D85B7694701A726FEEF
|
||||
:1005D000720649041BDF890A4D01FED8141FFE680C
|
||||
:1005E00006119A014311FEE500053FB40C3F1706C2
|
||||
:1005F00001A7EC7270016E8711FEE200010825323E
|
||||
:10060000FE0AF0FEA6068CFE5C07FE06F0FE6407FE
|
||||
:100610008D81022209040BFE2E12151A0108150005
|
||||
:1006200001081500010815000108FE99A40108152C
|
||||
:100630000002FE320861041BFE381209041B6E150D
|
||||
:10064000FE1B000108150001081500010815000136
|
||||
:100650000815060108150002D9664CFE3A555FFEE2
|
||||
:100660009A814B1DBAFE32070A1DFE096FAFFECA02
|
||||
:1006700045FE3212622C85667B01082532FE0AF0A7
|
||||
:10068000FE32078D818CFE5C070222014302FE8A46
|
||||
:1006900006151902FE8A06FE9CF7D4FE2C90FEAECB
|
||||
:1006A0009077FECA070C541855094A6A351E200770
|
||||
:1006B00010FE0E1274FE808037206327FE0610FEA7
|
||||
:1006C00083E7C4A1FE0340094A4F3501A8ADFE1FD0
|
||||
:1006D00040125801A5FE0850FE8A50FE4451FEC645
|
||||
:1006E0005183FBFE8A900C521853FE0C90FE8E90A4
|
||||
:1006F000FE4050FEC2500C39183AFE4A1009046AF6
|
||||
:10070000FE2A12FE2C90FEAE900C54185509044F90
|
||||
:100710008501A8FE1F801258FE4490FEC6900C561C
|
||||
:100720001857FBFE8A900C521853FE4090FEC29060
|
||||
:100730000C39183A0C38184E094A19352A13FE4E4E
|
||||
:100740001165FE4808FE9EF0FE5C08B116322A7361
|
||||
:10075000DDB8FE8008B9FE9E088CFE7408FE06F027
|
||||
:10076000FE7A088D8102220143FEC9101519FEC9C7
|
||||
:1007700010610406FE101261040B4509040BFE68AB
|
||||
:1007800012FE2E1C02FE240A6104064561040BFEC3
|
||||
:100790005212FE2C1CFEAAF0FE1E09FEACF0FEBE9C
|
||||
:1007A00008FE8A10AAFEF310FEADF0FECA0802FE93
|
||||
:1007B000240AABFEE710FE2BF09DE91CFE00FEFEB6
|
||||
:1007C0001C12B5FED2F09DFE76181C1A169D05CBA4
|
||||
:1007D0001C06169DB86DB96DAAABFEB110705E2BEC
|
||||
:1007E000149201330FFE3500FE01F05A0F7C025ABD
|
||||
:1007F000FE74181CFE00F8166D671B01FE440D3BCD
|
||||
:1008000001E61E2774671A026D09040B21FE060A11
|
||||
:1008100009046AFE8212090419FE66131E58ACFC14
|
||||
:10082000FE8380FEC844FE2E13FE0491FE86916373
|
||||
:1008300027FE4059FEC15977D7055431550C7B1816
|
||||
:100840007CBE54BF5501A8AD63271258C038C14EB5
|
||||
:1008500079566857F4F5FE04FA38FE05FA4E01A5FC
|
||||
:10086000A2230C7B0C7C79566857FE1210090419E0
|
||||
:1008700016D77939683A0904FEF700350552315325
|
||||
:10088000FE1058FE9158FE1459FE9559026D090448
|
||||
:100890001916D70904FEF70035FE3A55FE19815F97
|
||||
:1008A000FE1090FE9290FED7102F079B16FEC608F2
|
||||
:1008B000119B09040BFE14130539313A77FEC60863
|
||||
:1008C000FE0C58FE8D58026D2347FE1980DE090488
|
||||
:1008D0000BFE1A12FE6C19FE1941E9B5FED1F0D9D2
|
||||
:1008E000147A01330FFE4400FE8E10FE6C19BE39DF
|
||||
:1008F000FEED19BF3AFE0C51FE8E51E91CFE00FFC1
|
||||
:1009000034FE7410B5FED2F0FEB20AFE76181C1A40
|
||||
:100910008405CB1C06FE08130FFE1600025AFED1FA
|
||||
:10092000F0FEC40A147A01330FFE1700FE4210FED7
|
||||
:10093000CEF0FECA0AFE3C10FECDF0FED60A0FFE37
|
||||
:100940002200025AFECBF0FEE20A0FFE2400025AF9
|
||||
:10095000FED0F0FEEC0A0F93DCFECFF0FEF60A0F9D
|
||||
:100960004CFE1010FECCF0D96104193B0FFE1200B2
|
||||
:100970002A13FE4E1165FE0C0BFE9EF0FE200BB1FD
|
||||
:1009800016322A73DDB822B9222AEC65FE2C0B251B
|
||||
:10099000328CFE480B8D81B8D4B9D402220143FEBB
|
||||
:1009A000DB1011FEE800AAAB70BC7DBD7FFE89F0B4
|
||||
:1009B00022302ED8BC7DBD7F01081F22302ED6B13B
|
||||
:1009C000450FFE4200025A7806FE814916FE380C99
|
||||
:1009D00009040BFE44130F004B0BFE54124BFE2870
|
||||
:1009E0000021FEA60C0A40010E07005D3EFE280015
|
||||
:1009F000FEE21001E701E80A9901FE320E59112DBD
|
||||
:100A0000016F02290FFE44004B0BDF3E0BFEB410BA
|
||||
:100A100001863E0BFEAA100186FE1982FE3446A313
|
||||
:100A20003E0B0FFE4300FE9610094A0B3501E7010D
|
||||
:100A3000E859112D016F670B593C8A02FE2A030900
|
||||
:100A4000040B843E0B0F00FE5C1061041BFE581269
|
||||
:100A500009041BFE5013FE1C1CFE9DF0FE5C0CFEE8
|
||||
:100A60001C1CFE9DF0FE620C094A1B35FEA9100FEE
|
||||
:100A7000FE1500FE04E60B5F5C0FFE1300FE101077
|
||||
:100A80000FFE4700A10FFE4100A00FFE240087AA21
|
||||
:100A9000AB70056B2821D15FFE04E61BFE9D41FE75
|
||||
:100AA0001C425901DA0229EA140B3795A914FE31C8
|
||||
:100AB00000379701FE540F02D03CFE06ECC9EE3E13
|
||||
:100AC0001DFECE45343CFE06EAC9FE474B89FE7545
|
||||
:100AD000570551FE9856FE38120A42010EFE444850
|
||||
:100AE0004609041DFE1A130A40010E47FE41580A2A
|
||||
:100AF00099010EFE49548EFE2A0D02FE2A030A5168
|
||||
:100B0000FEEE14EE3E1DFECE45343CFECE47FEAD5D
|
||||
:100B10001302291E200710FE9E1223124D1294125A
|
||||
:100B2000CE1E2D47372DB1E0FEBCF0FEEC0D1306B6
|
||||
:100B3000124D01FEE21505FE380131FE3A0177FE45
|
||||
:100B4000F00DFE02ECCE62005DFE04EC2046FE05D8
|
||||
:100B5000F6FE340101FE5216FBFE48F40DFE18139A
|
||||
:100B6000AFFE02EACE627AFEC513141B3795A95C6C
|
||||
:100B700005FE38011CFEF0FF0CFE600105FE3A0187
|
||||
:100B80000CFE62013D12202406122D112D8A13063F
|
||||
:100B90000323031E4DFEF7121E94AC1294077AFE37
|
||||
:100BA0007113FE241C141A3795A9FED910B6FE0342
|
||||
:100BB000DCFE7357FE805D03B6FE03DCFE5B57FE72
|
||||
:100BC000805D03FE0357B623FE00CC03FE0357B639
|
||||
:100BD000750309044CFE2213FE1C800706FE1A133F
|
||||
:100BE000FE1E80E1FE1D80A4FE0C90FE0E13FE0E84
|
||||
:100BF00090A3FE3C90FE30F40BFE3C50A001FE8220
|
||||
:100C0000162F072DE001FEBC1509041D4501E70163
|
||||
:100C1000E811FEE90009044CFE2C1301FE1416FE37
|
||||
:100C20001E1CFE1490FE96900CFE640118FE6601D8
|
||||
:100C300009044FFE1212FE038074FE01EC20FE80B8
|
||||
:100C4000401220632711C8591E20ED762003FE08AC
|
||||
:100C50001C05FEAC00FE065805FEAE00FE0758055A
|
||||
:100C6000FEB000FE085805FEB200FE0958FE0A1C40
|
||||
:100C7000246912C9230C500C3F1340485F171DFE16
|
||||
:100C8000904DFE915421FE080F3E10134248174C20
|
||||
:100C9000FE904DFE915421FE1E0F24101220782C40
|
||||
:100CA000461E20ED762011C8F6FED6F0FE320FEA81
|
||||
:100CB00070FE141CFE101CFE181C033CFE0C14EEEF
|
||||
:100CC000FE07E61DFECE47FEF513030186782C468F
|
||||
:100CD000FAEFFE42132F072DFE34130A42010EB025
|
||||
:100CE000FE3612F0FE454801E3FE00CCB0FEF313E1
|
||||
:100CF0003D750710A30A80010EFE805C016FFE0E99
|
||||
:100D000010077E45F6FED6F0FE6C0F03FE445874C5
|
||||
:100D1000FE01EC97FE9E40FE9DE700FE9CE71B76E1
|
||||
:100D20002701DAFEDD102ABC7DBD7F302ED5071BE2
|
||||
:100D3000FE4812070BFE5612071AFE301207C216A3
|
||||
:100D4000FE3E1107FE230016FE4A11070616FEA8F6
|
||||
:100D5000110719FE12120700162214C201339F2B2D
|
||||
:100D600001088C43032BFE62080ACA01FE320E11F1
|
||||
:100D70007E02292B2F079BFED9137939683A77FE1B
|
||||
:100D8000FC1009046AFE7212C038C14EF4F58EFEE2
|
||||
:100D9000C6101E58FE2613057B317C77FE820C0C94
|
||||
:100DA000541855230C7B0C7C01A82469731258013C
|
||||
:100DB000A5C038C14EFE0455FEA555FE04FA38FE06
|
||||
:100DC00005FA4EFE911005563157FE4056FEE1568B
|
||||
:100DD0000C56185783C038C14EF4F505523153FEF6
|
||||
:100DE0000056FEA1560C52185309046AFE1E121E2C
|
||||
:100DF00058FE1F4005543155FE2C50FEAE5005568E
|
||||
:100E00003157FE4450FEC65005523153FE0850FE85
|
||||
:100E10008A500539313AFE4050FEC250025C240629
|
||||
:100E200012CD025B2B01081F44302ED5070621444A
|
||||
:100E30002F079B215B016E1C3D164409040BE279D0
|
||||
:100E400039683AFE0A5534FE8B55BE39BF3AFE0C5E
|
||||
:100E500051FE8E51025BFE1981AFFE1941025B2BE0
|
||||
:100E6000010825321FA2302ED84B1AFEA6124B0BBA
|
||||
:100E70003B0244010825321FA2302ED6071A214416
|
||||
:100E800001081FA2302EFEE809FEC2496005FE9C43
|
||||
:100E9000002884490419349FFEBB454B00453E069B
|
||||
:100EA000783DFEDA14016E87FE4B45E22F079AE18A
|
||||
:100EB00005C62884053F28345E025BFEC05DFEF84F
|
||||
:100EC00014FE03170550B40C505E2B0108265C017C
|
||||
:100ED000FEAA14025C010825321F44302ED60706F4
|
||||
:100EE000214401FE8E13FE4258FE8214FEA4148794
|
||||
:100EF000FE4AF40B1644FE4AF406FE0C122F079A23
|
||||
:100F000085025B053FB40C3F5E2B0108265C01FEA9
|
||||
:100F1000D814025C130665FECA1226FEE01272F1B6
|
||||
:100F200001082372038FFEDC1225FEDC121FFECAAD
|
||||
:100F3000125E2B0108FED510136CFF020057488B80
|
||||
:100F40001CFEFF7FFE3056FE005C03136CFF0200A8
|
||||
:100F500057488B1C3DFE3056FE005C03136CFF02AD
|
||||
:100F60000057488B03136CFF020057488BFE0B5849
|
||||
:100F7000030A5001820A3F018203FC1C10FF030098
|
||||
:100F800054FE00F41948FE007DFE017DFE027DFE48
|
||||
:100F9000037C63270C521853BE56BF5703FE6208EA
|
||||
:100FA000FE824AFEE11AFE835A740301FE1418FE03
|
||||
:100FB00042485F608901081FFEA214302ED8010844
|
||||
:100FC0001FFEA214302EFEE80AFEC15905C628FEF7
|
||||
:100FD000CC1249041BFEC41323621BE24BC364FE04
|
||||
:100FE000E8133B130617C378DBFE7810FF02835526
|
||||
:100FF000A1FF028355621AA4BBFE30008EE4172CB9
|
||||
:101000001306FE5610620BE1BBFE64008EE40AFE7E
|
||||
:10101000640017931306FE28106206FE6013BBFEE1
|
||||
:10102000C8008EE40AFEC800174D130683BBFE906D
|
||||
:1010300001BAFE4E1489FE1210FE43F494FE56F0DF
|
||||
:10104000FE6014FE04F46CFE43F493FEF310F90109
|
||||
:10105000FE22131C3DFE1013FE0017FE4DE469BA7C
|
||||
:10106000FE9C14B769FE1C10FE0017FE4DE419BA71
|
||||
:10107000FE9C14B719836023FE4DF400DF8913062C
|
||||
:10108000FEB456FEC3580360130B03150601082671
|
||||
:10109000E5150B010826E5151A010826E572FE89FB
|
||||
:1010A000490108031506010826A6151A010826A6F7
|
||||
:1010B0001506010826A6FE8949010826A672FE89A2
|
||||
:1010C0004A01080360031ECC0706FE4413AD12CC90
|
||||
:1010D000FE49F4003B729F5EFE01ECFE2701F10128
|
||||
:1010E000082F07FEE300FE20131FFE5A152312CD22
|
||||
:1010F00001431ECD070645094A0635030A42010E83
|
||||
:10110000ED880710A40A80010E880A51019E030A87
|
||||
:1011100080010E88FE80E710071084FE455801E329
|
||||
:1011200088030A42010E880A51019E030A42010EF9
|
||||
:10113000FE8080F2FE49E410A40A80010EF20A51FA
|
||||
:1011400001820317107166FE6001FE18DFFE19DED2
|
||||
:10115000FE241CFE1DF71D90FEF61501FEFC16E098
|
||||
:10116000911D66FE2C01FE2F1903AE21FEE615FE31
|
||||
:10117000DA1017107105FE6401FE00F419FE18580C
|
||||
:1011800005FE6601FE19589119FE3C90FE30F406EA
|
||||
:10119000FE3C5066FE3800FE0F79FE1CF71990FEEB
|
||||
:1011A0004016FEB6143403AE21FE1816FE9C10172E
|
||||
:1011B0001071FE835AFE18DFFE19DEFE1DF738900F
|
||||
:1011C000FE6216FE9414FE10139138661BFEAF19D2
|
||||
:1011D000FE98E70003AE21FE5616FE6C1017107144
|
||||
:1011E000FE30BCFEB2BC91C5661BFE0F79FE1CF73B
|
||||
:1011F000C590FE9A16FE5C143403AE21FE8616FEE0
|
||||
:101200004210FE02F61071FE18FE54FE19FE55FC47
|
||||
:10121000FE1DF74F90FEC016FE3614FE1C13914FB4
|
||||
:1012200047FE8358FEAF19FE80E710FE81E71011DC
|
||||
:10123000FEDD006327036327FE124521FEB016146E
|
||||
:10124000063795A90229FE39F0FE04172303FE7E16
|
||||
:10125000181C1A5D130D037105CB1C06FEEF12FE60
|
||||
:10126000E110782C462F072DFE3C13FE8214FE421F
|
||||
:10127000133C8A0A42010EB0FE3E12F0FE454801C0
|
||||
:10128000E3FE00CCB0FEF3133D750710A30A800106
|
||||
:101290000EF2016FFE1610077E85FE4014FE24122A
|
||||
:1012A000F6FED6F0FE2417170B03FE9CE70B0FFE8D
|
||||
:1012B000150059762701DA1706033C8A094A1D35BD
|
||||
:1012C000112D016F170603FE3890FEBA9079C7689A
|
||||
:1012D000C8FE485534FEC955031E98731298030A78
|
||||
:1012E00099010EF00A40010EFE494416FEF01773F4
|
||||
:1012F00075030A42010E0710450A51019E0A40017A
|
||||
:101300000E737503FE4EE41A64FE241805FE900069
|
||||
:10131000FE3A455BFE4EE4C264FE361805FE9200BE
|
||||
:10132000FE02E61BDCFE4EE4FE0B0064FE481805E0
|
||||
:10133000FE9400FE02E619FE081005FE9600FE026D
|
||||
:10134000E62CFE4E45FE0C12AFFF046854DE1C690D
|
||||
:1013500003077AFE5AF0FE741824FE0900FE3410CA
|
||||
:10136000071BFE5AF0FE821824C3FE2610071A5DE2
|
||||
:10137000242CDC070B5D2493FE0E1007065D244D24
|
||||
:101380009FAD0314FE09000133FE04FE7D057FF9C5
|
||||
:101390000325FECA18FE14F00865FEC61803FF1ADE
|
||||
:0213A00000004B
|
||||
:00000001FF
|
||||
/* Microcode buffer is kept after initialization for error recovery. */
|
336
firmware/advansys/38C0800.bin.ihex
Normal file
336
firmware/advansys/38C0800.bin.ihex
Normal file
@ -0,0 +1,336 @@
|
||||
:10000000D83F0D05000000F200F000FC001618E4D7
|
||||
:10001000010048E4188003F60200CE1900FAFFFF41
|
||||
:100020001C0F00F69EE7FF0082E700EA01FA01E6F6
|
||||
:1000300009E755F001F60300040010001EF085F0FA
|
||||
:1000400018F40800BC00385400ECD5F0820D00E62E
|
||||
:1000500086F0B1F0985701FCB400D4010C1C3E1C92
|
||||
:100060003C00BB000010BA19028032F07C0D021374
|
||||
:10007000BA131840005701EA02FC03FC3E006C0171
|
||||
:100080006E0174017601B9543E57008003E6B60054
|
||||
:10009000C00001013E017A01CA08CE1016110412F7
|
||||
:1000A0000812024ABB553C5603581B8030E44BE40F
|
||||
:1000B0005DF002FA200032004000800024013C0183
|
||||
:1000C00068016A017001720178017C01620A860D83
|
||||
:1000D00006134C1C04804AE402EE5BF003F70C00AC
|
||||
:1000E0000F004700BE00000120115C16321C381CB6
|
||||
:1000F0004E1C1044004C04EA5CF0A7F004F603FA2E
|
||||
:100100000500340036009800CC0020014E014A0B57
|
||||
:10011000420C120F0C1022110A120413301C024858
|
||||
:10012000004E42544455BD56068300DC05F009F0EC
|
||||
:1001300059F0B8F04BF406F70EF704FC05FC060086
|
||||
:10014000190033009B00A400B500BA00D000E10004
|
||||
:10015000E700E203080F021004100A100A130C1340
|
||||
:1001600012132414341404160816A417201C341C6B
|
||||
:10017000361C0844384491440A45484601486854AE
|
||||
:100180003A558355E555B0570158835905E60BF0AC
|
||||
:100190000CF004F805F807000A001C001E009E0081
|
||||
:1001A000A800AA00B900E0002201260179017E0121
|
||||
:1001B000C401C60180025E03EE049A06F8076208D5
|
||||
:1001C00068086908D608E909FA0B2E0F12101A10F0
|
||||
:1001D000ED10F1102A1106120C123E121013161314
|
||||
:1001E0001E134614761482143615CA156B18BE18E1
|
||||
:1001F000CA18E619121C461C9C3200400E47FE9C91
|
||||
:10020000F02B02FEAC0DFF100000D7FEE81900D65F
|
||||
:10021000FE8401FF030000FE9315FE0F05FF38006A
|
||||
:1002200000FE572400FE4C005BFF04000011FF0994
|
||||
:100230000000FF080101FF08FFFFFF270000FF107B
|
||||
:10024000FFFFFF110000FE7856FE3412FF21000070
|
||||
:10025000FE04F7D62C990A01FEC20FFE04F7D699C8
|
||||
:100260000A422CFE3DF0FE0602FE20F0A7FE91F0B1
|
||||
:10027000FEF401FE90F0FEF401FE8FF0A7035D4D49
|
||||
:1002800002FEC80D01FE380EFEDD12FEFC10FE2837
|
||||
:100290001C03FEA600FED3124114FEA600C2FE48B7
|
||||
:1002A000F0FE8A02FE49F0FEA402FE4AF0FEC202FF
|
||||
:1002B000FE46F0FE5402FE47F0FE5A02FE43F0FEF8
|
||||
:1002C0004802FE44F0FE4C02FE45F0FE5002180AC1
|
||||
:1002D000AA180614A1022BFE001CE7FE021CE6FE73
|
||||
:1002E0001E1CFEE91001FE1818FEE710FE06FCCEEB
|
||||
:1002F000097001A8022B155939A201FE5810097086
|
||||
:100300000187FEBD1009700187FEAD10FE161CFEB0
|
||||
:10031000581C180614A12C1C2BFE3DF0FE060223CF
|
||||
:10032000FE9802FE5A1CF8FE141C15FE300039A27D
|
||||
:1003300001FE4810180614A102D72220071135FE2D
|
||||
:100340006910180614A1FE04EC204F431320FE058B
|
||||
:10035000F6CE01FE4A1708545837122F429201FE7A
|
||||
:100360008216022B0946010E0700660173FE181063
|
||||
:10037000FE415809A4010EFEC8546BFE100301FE95
|
||||
:100380008216022B2C4FFE02E82AFEBF57FE9E4328
|
||||
:10039000FE7757FE27F0FEE001FE074BFE20F0A798
|
||||
:1003A000FE401C1CD9FE26F0FE5A03FEA0F0FE48BB
|
||||
:1003B00003FE11F0A7FEEF10FE9FF0FE6803F91098
|
||||
:1003C000FE110002652CFE481CF908051BFE1813DF
|
||||
:1003D0002122A3B713A30946010EB77801FEB41674
|
||||
:1003E00012D11CD9FE01F0D9FE82F0FE9603FA125A
|
||||
:1003F000FEE40027FEA8031C341DFEB803014BFEDB
|
||||
:1004000006F0FEC8039586FE0AF0FE8A0602240363
|
||||
:10041000702817FEFA04156D01367BFE6A0202D8B9
|
||||
:10042000F92C9919FE671BFEBF57FE7757FE481C33
|
||||
:100430007401AF8C0946010E070017DA09D1010ECD
|
||||
:100440008D5164792A037028FE1012156D01367BD8
|
||||
:10045000FE6A0202D8C781C8831C2427FE40041DFF
|
||||
:10046000FE3C043BFEA000FE9B57FE4E122DFF02F9
|
||||
:100470000010010B1DFEE4042D010B1D243331DEA1
|
||||
:10048000FE4C44FE4C1251FE44480F6FFE4C546B20
|
||||
:10049000DA4F792AFE0680FE4847FE621308051BE4
|
||||
:1004A000FE2A13320782FE5213FE20100F6FFE4CFD
|
||||
:1004B000546BDAFE0680FE4847FE401308051BFE1B
|
||||
:1004C0000813320782FE301308051BFE1C12159D0F
|
||||
:1004D0000805064D15FE0D0001367BFE640D022455
|
||||
:1004E0002D12FEE600FE1C90FE405C04159D0136B8
|
||||
:1004F000022BFE425B9919FE4659FEBF57FE775705
|
||||
:10050000FE8780FE31E45B08050AFE8413FE20802E
|
||||
:100510000719FE7C12530506FE6C1303FEA2002889
|
||||
:1005200017FE9005FE31E45A53050AFE561303FEEA
|
||||
:10053000A00028FE4E1267FF02001027FE48051C8F
|
||||
:1005400034FE8948FF02001027FE560526FEA80546
|
||||
:1005500012FEE3002153FE4AF0FE7605FE49F0FE4E
|
||||
:1005600070058825FE2100AB25FE2200AA2558FE35
|
||||
:100570000948FF02001027FE860526FEA805FEE2B8
|
||||
:10058000085305CB4D01B0250613D339FE270108CA
|
||||
:10059000051BFE22124101B2159D0805064D15FEF0
|
||||
:1005A0000D0001367BFE640D022403FE9C0028EB47
|
||||
:1005B000035C28FE36134101B226FE1806090653D5
|
||||
:1005C000051FFE02125001FE9E151DFE0E0612A50D
|
||||
:1005D000014B12FEE500035CC10C5C03CD28FE62FA
|
||||
:1005E00012034528FE5A1301FE0C1901FE7619FE6E
|
||||
:1005F0004348C4CC0F71FF02005752931E438BC473
|
||||
:100600006E4101B226FE820653051AE9910959018D
|
||||
:10061000FECC151DFE780612A5014B12FEE5000367
|
||||
:1006200045C10C45180601B2FA767401AF8C12FE72
|
||||
:10063000E20027DB1C34FE0AF0FEB60694FE6C07CF
|
||||
:10064000FE06F0FE74079586022408050AFE2E12A7
|
||||
:100650001619010B1600010B1600010B1600010BF9
|
||||
:10066000FE99A4010B160002FE420868051AFE3826
|
||||
:100670001208051AFE301316FE1B00010B160001AE
|
||||
:100680000B1600010B1600010B1606010B160002DB
|
||||
:10069000E26C58BE50FE9A81551B7AFE4207091B38
|
||||
:1006A000FE096FBAFECA45FE3212696D8B6C7F2758
|
||||
:1006B000FE54071C34FE0AF0FE4207958694FE6C39
|
||||
:1006C000070224014B02DB161F02DBFE9CF7DCFE57
|
||||
:1006D0002C90FEAE9056FEDA070C60146108545A56
|
||||
:1006E0003722200711FE0E128DFE808039206A2AE3
|
||||
:1006F000FE0610FE83E7FE4800ABFE034008545B95
|
||||
:100700003701B3B8FE1F40136201EFFE0850FE8AA6
|
||||
:1007100050FE4451FEC65188FE0890FE8A900C5E41
|
||||
:10072000145FFE0C90FE8E90FE4050FEC2500C3DB9
|
||||
:10073000143EFE4A1008055AFE2A12FE2C90FEAE08
|
||||
:10074000900C60146108055B8B01B3FE1F8013627F
|
||||
:10075000FE4490FEC6900C3F1440FE0890FE8A9026
|
||||
:100760000C5E145FFE4090FEC2900C3D143E0C2EB9
|
||||
:10077000143C210C490C6308541F372C0FFE4E11FA
|
||||
:1007800027DDFE9EF0FE7608BC17342C77E6C5FE0A
|
||||
:100790009A08C6FEB80894FE8E08FE06F0FE94087D
|
||||
:1007A00095860224014BFEC910161FFEC91068056C
|
||||
:1007B00006FE101268050A4E08050AFE9012FE2E6B
|
||||
:1007C0001C02FE180B6805064E68050AFE7A12FE2A
|
||||
:1007D0002C1CFEAAF0FED209FEACF0FE000902FEBF
|
||||
:1007E000DE09FEB7F0FEFC08FE02F61A50FE701895
|
||||
:1007F000FEF118FE4055FEE155FE1058FE9158FEE0
|
||||
:100800001459FE95591C85FE8CF0FEFC08FEACF0D8
|
||||
:10081000FEF008B5FECB10FEADF0FE0C0902FE188E
|
||||
:100820000BB6FEBF10FE2BF085F41EFE00FEFE1C74
|
||||
:1008300012C2FED2F085FE76181E19178503D21E4D
|
||||
:10084000061785C54AC64AB5B6FE891074672D15C8
|
||||
:100850009D013610FE3500FE01F06510800265FE38
|
||||
:100860009880FE19E40AFE1A1251FE1982FE6C18D5
|
||||
:10087000FE4454BEFE1981FE74188F9017FECE08F8
|
||||
:10088000024A08055AEC032E293C0C3F14409B2ECB
|
||||
:100890009C3CFE6C18FEED18FE4454FEE5543A3FB5
|
||||
:1008A0003B40034929638FFEE354FE7418FEF5189C
|
||||
:1008B0008FFEE35490C056FECE08024AFE37F0FE8B
|
||||
:1008C000DA09FE8BF0FE6009024A08050A23FEFAE7
|
||||
:1008D0000A3A493B6356FE3E0A0FFEC007419800A4
|
||||
:1008E000ADFE0159FE52F0FE0C0A8F7AFE240A3A40
|
||||
:1008F000498FFEE35457497D63FE1458FE95580214
|
||||
:100900004A3A493B63FE1459FE9559BE574957630D
|
||||
:10091000024A08055AFE821208051FFE661322626B
|
||||
:10092000B7FE03A1FE8380FEC844FE2E13FE049191
|
||||
:10093000FE86916A2AFE4059FEC15956E00360299D
|
||||
:10094000610C7F148057607D6101B3B86A2A13621D
|
||||
:100950009B2E9C3C3A3F3B4090C0FE04FA2EFE0585
|
||||
:10096000FA3C01EFFE3610210C7F0C803A3F3B40F1
|
||||
:10097000E408051F17E03A3D3B3E0805FEF7003747
|
||||
:10098000035E295FFE1058FE915857497D6302FEB1
|
||||
:10099000F40908051F17E00805FEF70037BEFE1929
|
||||
:1009A0008150FE1090FE9290FED3103207A617FEE3
|
||||
:1009B000080912A608050AFE1413033D293E56FE37
|
||||
:1009C0000809FE0C58FE8D58024A2141FE1980E7A5
|
||||
:1009D00008050AFE1A12FE6C19FE1941F4C2FED176
|
||||
:1009E000F0E2157E013610FE4400FE8E10FE6C19FA
|
||||
:1009F000573DFEED197D3EFE0C51FE8E51F41EFE5C
|
||||
:100A000000FF35FE7410C2FED2F0FEA60BFE761873
|
||||
:100A10001E198A03D21E06FE081310FE1600026578
|
||||
:100A2000FED1F0FEB80B157E013610FE1700FE4217
|
||||
:100A300010FECEF0FEBE0BFE3C10FECDF0FECA0B4B
|
||||
:100A400010FE22000265FECBF0FED60B10FE240045
|
||||
:100A50000265FED0F0FEE00B109EE5FECFF0FEEA50
|
||||
:100A60000B1058FE1010FECCF0E268051F4D10FE72
|
||||
:100A700012002C0FFE4E1127FE000CFE9EF0FE14FD
|
||||
:100A80000CBC17342C77E6C524C6242CFA27FE208C
|
||||
:100A90000C1C3494FE3C0C9586C5DCC6DC0224019B
|
||||
:100AA0004BFEDB1012FEE800B5B674C781C883FEAA
|
||||
:100AB00089F0243331E1C781C88327FE660C1D24E9
|
||||
:100AC0003331DFBC4E10FE420002657C06FE8149D8
|
||||
:100AD00017FE2C0D08050AFE44131000550AFE549B
|
||||
:100AE0001255FE280023FE9A0D0946010E070066E6
|
||||
:100AF00044FE2800FEE21001F501F609A401FE26DD
|
||||
:100B00000F64122F0173022B10FE4400550AE944B2
|
||||
:100B10000AFEB41001B0440AFEAA1001B0FE198208
|
||||
:100B2000FE3446AC440A10FE4300FE961008540AF8
|
||||
:100B30003701F501F664122F0173990A644292029B
|
||||
:100B4000FE2E0308050A8A440A1000FE5C106805A0
|
||||
:100B50001AFE581208051AFE5013FE1C1CFE9DF0CA
|
||||
:100B6000FE500DFE1C1CFE9DF0FE560D08541A375B
|
||||
:100B7000FEA91010FE1500FE04E60A50FE2E10100D
|
||||
:100B8000FE1300FE1010106FAB10FE4100AA10FE05
|
||||
:100B900024008CB5B67403702823D850FE04E61ADE
|
||||
:100BA000FE9D41FE1C426401E3022BF8150A39A0A8
|
||||
:100BB000B415FE310039A201FE481002D742FE06EC
|
||||
:100BC000ECD0FC441BFECE453542FE06EAD0FE4783
|
||||
:100BD0004B91FE7557035DFE9856FE381209480189
|
||||
:100BE0000EFE44484F08051BFE1A130946010E412C
|
||||
:100BF000FE415809A4010EFE495496FE1E0E02FE47
|
||||
:100C00002E03095DFEEE14FC441BFECE453542FE6C
|
||||
:100C1000CE47FEAD13022B22200711FE9E12211398
|
||||
:100C200059139F13D5222F41392FBCADFEBCF0FEC6
|
||||
:100C3000E00E0F06135901FEDA1603FE380129FEF5
|
||||
:100C40003A0156FEE40EFE02ECD5690066FE04ECA5
|
||||
:100C5000204FFE05F6FE340101FE4A17FE0890FE05
|
||||
:100C600048F40DFE1813BAFE02EAD5697EFEC513DC
|
||||
:100C7000151A39A0B4FE2E1003FE38011EFEF0FF37
|
||||
:100C80000CFE600103FE3A010CFE620143132025B5
|
||||
:100C900006132F122F920F060421042259FEF71279
|
||||
:100CA000229FB7139F077EFE7113FE241C1519396E
|
||||
:100CB000A0B4FED910C3FE03DCFE7357FE805D04B2
|
||||
:100CC000C3FE03DCFE5B57FE805D04FE0357C321B9
|
||||
:100CD000FE00CC04FE0357C37804080558FE221317
|
||||
:100CE000FE1C800706FE1A13FE1E80EDFE1D80AE60
|
||||
:100CF000FE0C90FE0E13FE0E90ACFE3C90FE30F407
|
||||
:100D00000AFE3C50AA01FE7A1732072FAD01FEB44D
|
||||
:100D10001608051B4E01F501F612FEE900080558FC
|
||||
:100D2000FE2C1301FE0C17FE1E1CFE1490FE969066
|
||||
:100D30000CFE640114FE660108055BFE1212FE0340
|
||||
:100D4000808DFE01EC20FE804013206A2A12CF64C1
|
||||
:100D50002220FB792004FE081C03FEAC00FE06588E
|
||||
:100D600003FEAE00FE075803FEB000FE085803FE67
|
||||
:100D7000B200FE0958FE0A1C256E13D0210C5C0C33
|
||||
:100D8000450F465250181BFE904DFE915423FEFC19
|
||||
:100D90000F44110F48521858FE904DFE915423E411
|
||||
:100DA000251113207C6F4F2220FB792012CFFE14D7
|
||||
:100DB00056FED6F0FE2610F874FE141CFE101CFE23
|
||||
:100DC000181C0442FE0C14FCFE07E61BFECE47FE78
|
||||
:100DD000F5130401B07C6F4FFE0680FE4847FE42CB
|
||||
:100DE0001332072FFE34130948010EBBFE3612FEE4
|
||||
:100DF0004148FE454801F0FE00CCBBFEF3134378AA
|
||||
:100E00000711AC0984010EFE805C0173FE0E100711
|
||||
:100E1000824EFE1456FED6F0FE601004FE44588D3D
|
||||
:100E2000FE01ECA2FE9E40FE9DE700FE9CE71A79C3
|
||||
:100E30002A01E3FEDD102CC781C8833331DE071A97
|
||||
:100E4000FE4812070AFE56120719FE301207C9178C
|
||||
:100E5000FE321207FE230017EB070617FE9C12074F
|
||||
:100E60001FFE12120700172415C90136A92D010B08
|
||||
:100E7000944B042DDD09D101FE260F1282022B2D89
|
||||
:100E80003207A6FED9133A3D3B3E56FEF011080547
|
||||
:100E90005AFE72129B2E9C3C90C096FEBA112262A2
|
||||
:100EA000FE2613037F298056FE760D0C6014612107
|
||||
:100EB0000C7F0C8001B3256E77136201EF9B2E9C93
|
||||
:100EC0003CFE0455FEA555FE04FA2EFE05FA3CFE36
|
||||
:100ED0009110033F2940FE4056FEE1560C3F14405E
|
||||
:100EE000889B2E9C3C90C0035E295FFE0056FEA1AD
|
||||
:100EF000560C5E145F08055AFE1E122262FE1F4049
|
||||
:100F000003602961FE2C50FEAE50033F2940FE4491
|
||||
:100F100050FEC650035E295FFE0850FE8A50033D16
|
||||
:100F2000293EFE4050FEC2500289250613D40272AB
|
||||
:100F30002D010B1D4C3331DE0706234C3207A6234F
|
||||
:100F40007201AF1E43174C08050AEE3A3D3B3EFEC8
|
||||
:100F50000A5535FE8B55573D7D3EFE0C51FE8E5198
|
||||
:100F60000272FE1981BAFE194102722D010B1C3466
|
||||
:100F70001DE83331E15519FEA612550A4D024C0108
|
||||
:100F80000B1C341DE83331DF0719234C010B1DE81E
|
||||
:100F90003331FEE809FEC2495103FE9C00288A5302
|
||||
:100FA000051F35A9FEBB4555004E44067C43FEDABD
|
||||
:100FB0001401AF8CFE4B45EE3207A5ED03CD288A18
|
||||
:100FC00003452835670272FEC05DFEF814FE031764
|
||||
:100FD000035CC10C5C672D010B268901FE9E150286
|
||||
:100FE00089010B1C341D4C3331DF0706234C01F102
|
||||
:100FF000FE4258F1FEA4148CFE4AF40A174CFE4A35
|
||||
:10100000F406EA3207A58B02720345C10C45672D31
|
||||
:10101000010B268901FECC1502890F0627FEBE139F
|
||||
:1010200026FED41376FE8948010B2176047BFED080
|
||||
:10103000131CFED0131DFEBE13672D010BFED51031
|
||||
:101040000F71FF02005752931EFEFF7FFE3056FEC7
|
||||
:10105000005C040F71FF02005752931E43FE30568E
|
||||
:10106000FE005C040F71FF0200575293040F71FFE2
|
||||
:101070000200575293FE0B5804095C018709450191
|
||||
:101080008704FE03A11E11FF030054FE00F41F524B
|
||||
:10109000FE007DFE017DFE027DFE037C6A2A0C5E61
|
||||
:1010A000145F573F7D4004DDFE824AFEE11AFE8355
|
||||
:1010B0005A8D0401FE0C19FE4248505191010B1D3E
|
||||
:1010C000FE96153331E1010B1DFE96153331FEE816
|
||||
:1010D0000AFEC15903CD28FECC1253051AFEC413D3
|
||||
:1010E00021691AEE55CA6BFEDC144D0F0618CA7C36
|
||||
:1010F00030FE7810FF028355ABFF0283556919AEAD
|
||||
:1011000098FE300096F2186D0F06FE5610690AED33
|
||||
:1011100098FE640096F209FE6400189E0F06FE28F1
|
||||
:10112000106906FE601398FEC80096F209FEC8001A
|
||||
:1011300018590F068898FE90017AFE421591E4FE38
|
||||
:1011400043F49FFE56F0FE5415FE04F471FE43F482
|
||||
:101150009EFEF310FE405C01FE16141E43ECFE00E2
|
||||
:1011600017FE4DE46E7AFE9015C46EFE1C10FE0054
|
||||
:1011700017FE4DE4CC7AFE9015C4CC885121FE4D6B
|
||||
:10118000F400E9910F06FEB456FEC35804510F0A4D
|
||||
:10119000041606010B26F3160A010B26F316190195
|
||||
:1011A0000B26F376FE8949010B041606010B26B1C6
|
||||
:1011B0001619010B26B11606010B26B1FE8949014D
|
||||
:1011C0000B26B176FE894A010B04510422D307068F
|
||||
:1011D000FE4813B813D3FE49F4004D76A967FE010B
|
||||
:1011E000ECFE2701FE8948FF02001027FE2E163272
|
||||
:1011F00007FEE300FE20131DFE52162113D4014BFF
|
||||
:1012000022D407064E08540637040948010EFB8E07
|
||||
:101210000711AE0984010E8E095D01A8040984013D
|
||||
:101220000E8EFE80E71107118AFE455801F08E04EC
|
||||
:101230000948010E8E095D01A8040948010EFE80CF
|
||||
:1012400080FE804CFE49E411AE0984010EFE804C04
|
||||
:10125000095D0187041811756CFE6001FE18DFFE40
|
||||
:1012600019DEFE241CFE1DF71B97FEEE1601FEF490
|
||||
:1012700017AD9A1B6CFE2C01FE2F1904B923FEDE5C
|
||||
:1012800016FEDA1018117503FE6401FE00F41FFE4D
|
||||
:10129000185803FE6601FE19589A1FFE3C90FE3056
|
||||
:1012A000F406FE3C506CFE3800FE0F79FE1CF71F62
|
||||
:1012B00097FE3817FEB6143504B923FE1017FE9CAE
|
||||
:1012C00010181175FE835AFE18DFFE19DEFE1DF799
|
||||
:1012D0002E97FE5A17FE9414EC9A2E6C1AFEAF1934
|
||||
:1012E000FE98E70004B923FE4E17FE6C1018117526
|
||||
:1012F000FE30BCFEB2BC9ACB6C1AFE0F79FE1CF716
|
||||
:10130000CB97FE9217FE5C143504B923FE7E17FEC0
|
||||
:101310004210FE02F61175FE18FE60FE19FE61FE17
|
||||
:1013200003A1FE1DF75B97FEB817FE3614FE1C13D3
|
||||
:101330009A5B41FE8358FEAF19FE80E711FE81E7FC
|
||||
:101340001112FEDD006A2A046A2AFE124523FEA855
|
||||
:1013500017150639A0B4022BFE39F0FEFC17210444
|
||||
:10136000FE7E181E19660F0D047503D21E06FEEFD1
|
||||
:1013700012FEE1107C6F4F32072FFE3C13F1FE424C
|
||||
:101380001342920948010EBBEBFE4148FE4548015D
|
||||
:10139000F0FE00CCBBFEF31343780711AC098401C7
|
||||
:1013A0000EFE804C0173FE161007828BFE4014FE69
|
||||
:1013B0002412FE1456FED6F0FE1C18180A04FE9CD9
|
||||
:1013C000E70A10FE150064792A01E3180604429228
|
||||
:1013D00008541B37122F0173180604FE3890FEBA0A
|
||||
:1013E000903ACE3BCFFE485535FEC9550422A3772F
|
||||
:1013F00013A30409A4010EFE41480946010EFE494B
|
||||
:101400004417FEE8187778040948010E07114E09C1
|
||||
:101410005D01A80946010E777804FE4EE4196BFEC3
|
||||
:101420001C1903FE9000FE3A45FE2C10FE4EE4C946
|
||||
:101430006BFE2E1903FE9200FE02E61AE5FE4EE454
|
||||
:10144000FE0B006BFE401903FE9400FE02E61FFE39
|
||||
:10145000081003FE9600FE02E66DFE4E45EABAFF56
|
||||
:10146000046854E71E6EFE081CFE6719FE0A1CFE87
|
||||
:101470001AF4FE0004EAFE48F4197AFE74190F19F2
|
||||
:1014800004077EFE5AF0FE841925FE0900FE341082
|
||||
:10149000071AFE5AF0FE921925CAFE261007196691
|
||||
:1014A000256DE5070A66259EFE0E1007066625597E
|
||||
:1014B000A9B80415FE09000136FE04FE810383FE6F
|
||||
:1014C000405C041CF7FE14F00B27FED6191CF77BBA
|
||||
:0C14D000F7FE82F0FEDA1904FFCC0000E9
|
||||
:00000001FF
|
||||
/* Microcode buffer is kept after initialization for error recovery. */
|
398
firmware/advansys/38C1600.bin.ihex
Normal file
398
firmware/advansys/38C1600.bin.ihex
Normal file
@ -0,0 +1,398 @@
|
||||
:1000000077EF0406000000F2001600FC001000F07C
|
||||
:1000100018E40100041E48E403F6F7132E1E020044
|
||||
:100020000717C05F00FAFFFF040000F609E782E748
|
||||
:1000300085F086F04E109EE7FF0055F001F60300B4
|
||||
:10004000985701E600EA00EC01FA18F40800F01DE8
|
||||
:10005000385432F01000C20E1EF0D5F0BC004BE454
|
||||
:1000600000E6B1F0B40002133E1CC8473E00D801C0
|
||||
:1000700006130C1C5E1E0057C85701FCBC0EA212D2
|
||||
:10008000B9540080620A5A12C8153E1E1840BD5667
|
||||
:1000900003E601EA5CF00F0020006C016E0104121F
|
||||
:1000A0000413BB553C563E5703584AE44000B60083
|
||||
:1000B000BB00C000000101013E01580A44100A12B1
|
||||
:1000C0004C1C4E1C024A30E405E60C003C0080004B
|
||||
:1000D00024013C0168016A0170017201740176011A
|
||||
:1000E00078017C01C60E0C10AC12AE12161A321C2E
|
||||
:1000F0006E1E02483A55C95702EE5BF003F706F749
|
||||
:1001000003FC06001E00BE00E1000C12181A701A53
|
||||
:10011000301C381C1044004CB057405C4DE404EADD
|
||||
:100120005DF0A7F004F602FC05000900190032009A
|
||||
:1001300033003400360098009E00CC0020014E01B0
|
||||
:1001400079013C09680D021004103A1008120A13D4
|
||||
:100150004016501600174A19004E0054015800DC92
|
||||
:1001600005F009F059F0B8F048F40EF70A009B00CA
|
||||
:100170009C00A400B500BA00D000E700F0036908B5
|
||||
:10018000E9095C0CB612BC19D81B201C341C361CA7
|
||||
:10019000421D0844384491440A45484689486854F9
|
||||
:1001A0008355835931E402E607F008F00BF00CF0B8
|
||||
:1001B0004BF404F805F802FA03FA04FC05FC070006
|
||||
:1001C000A800AA00B900E000E500220126016001B4
|
||||
:1001D0007A018201C801CA0186026A031805B207C2
|
||||
:1001E0006808100D06100A100E1012106010ED10A5
|
||||
:1001F000F310061210121E120C130E131013FE9C95
|
||||
:10020000F03505FEEC0EFF100000E9FE341F00E89B
|
||||
:10021000FE8801FF030000FE9315FE0F05FF380066
|
||||
:1002200000FE572400FE4C0065FF0400001AFF0981
|
||||
:100230000000FF080101FF08FFFFFF270000FF107B
|
||||
:10024000FFFFFF130000FE7856FE3412FF2100006E
|
||||
:10025000FE04F7E8377D0D01FE4A11FE04F7E87D44
|
||||
:100260000D5137FE3DF0FE0C02FE20F0BCFE91F079
|
||||
:10027000FEF801FE90F0FEF801FE8FF0BC03674D22
|
||||
:1002800005FE080F01FE780FFEDD1205FE0E03FECF
|
||||
:10029000281C03FEA600FED1123E22FEA600ACFEE4
|
||||
:1002A00048F0FE9002FE49F0FEAA02FE4AF0FEC8A7
|
||||
:1002B00002FE46F0FE5A02FE47F0FE6002FE43F0E8
|
||||
:1002C000FE4E02FE44F0FE5202FE45F0FE56021CB7
|
||||
:1002D0000DA21C0722B70535FE001CFEF110FE0220
|
||||
:1002E0001CF5FE1E1CFEE910015FFEE710FE06FC79
|
||||
:1002F000DE0A8101A305351F9547B801FEE4110A06
|
||||
:1003000081015CFEBD100A81015CFEAD10FE161C71
|
||||
:10031000FE581C1C0722B7372A35FE3DF0FE0C02A2
|
||||
:100320002BFE9E02FE5A1CFE121CFE141C1FFE30E9
|
||||
:100330000047B801FED4111C0722B705E9212C099A
|
||||
:100340001A31FE69101C0722B7FE04EC2C6001FE76
|
||||
:100350001E1E202CFE05F6DE01FE621B010C614A0A
|
||||
:100360004415565101FE9E1E01FE961A05350A5788
|
||||
:1003700001180900360185FE1810FE41580ABA011D
|
||||
:1003800018FEC8547BFE1C0301FE961A0535376023
|
||||
:10039000FE02E830FEBF57FE9E43FE7757FE27F071
|
||||
:1003A000FEE401FE074BFE20F0BCFE401C2AEBFEE3
|
||||
:1003B00026F0FE6603FEA0F0FE5403FE11F0BCFE24
|
||||
:1003C000EF10FE9FF0FE7403FE461C19FE1100059F
|
||||
:1003D0007037FE481CFE461C010C0628FE1813262A
|
||||
:1003E00021B9C720B90A570118C78901FEC81A15D3
|
||||
:1003F000E12AEBFE01F0EBFE82F0FEA403FE9C324C
|
||||
:1004000015FEE4002FFEB6032A3C16FEC60301418A
|
||||
:10041000FE06F0FED603AFA0FE0AF0FEA2070529F5
|
||||
:1004200003811E1BFE24051F6301428FFE7002051F
|
||||
:10043000EAFE461C377D1DFE671BFEBF57FE775741
|
||||
:10044000FE481C7501A6860A57011809001BEC0A14
|
||||
:10045000E101187750408D3003811EF81F6301427F
|
||||
:100460008FFE700205EAD799D89C2A292FFE4E04E8
|
||||
:1004700016FE4A047EFEA000FE9B57FE541232FF79
|
||||
:10048000020010010816FE02053201081629272570
|
||||
:10049000EEFE4C44FE581250FE44481334FE4C54B9
|
||||
:1004A0007BEC608D3001FE4E1EFE4847FE7C130142
|
||||
:1004B0000C0628FE32130143099BFE6813FE26102A
|
||||
:1004C0001334FE4C547BEC01FE4E1EFE4847FE5496
|
||||
:1004D00013010C0628A50143099BFE4013010C06DD
|
||||
:1004E00028F91F7F010C06074D1FFE0D0001428FEA
|
||||
:1004F000FEA40E05293215FEE6000FFE1C9004FE38
|
||||
:100500009C933A0B0E8B021F7F01420535FE425B26
|
||||
:100510007D1DFE4659FEBF57FE77570FFE878004AC
|
||||
:10052000FE8783FEC9470B0ED065010C060DFE98B1
|
||||
:10053000130FFE208004FEA083330B0E091DFE84E2
|
||||
:100540001201380607FE701303FEA2001E1BFEDA1E
|
||||
:1005500005D0540138060DFE581303FEA0001EFE00
|
||||
:1005600050125EFF0200102FFE90052A3CCCFF02C5
|
||||
:1005700000102FFE9E0517FEF40515FEE300260170
|
||||
:1005800038FE4AF0FEC005FE49F0FEBA05712EFEA7
|
||||
:100590002100F12EFE2200A22E4AFE0948FF020091
|
||||
:1005A000102FFED00517FEF405FEE208013806FE06
|
||||
:1005B0001C004D01A72E0720E447FE2701010C0671
|
||||
:1005C00028FE24123E01841F7F010C06074D1FFEEA
|
||||
:1005D0000D0001428FFEA40E052903E61EFECA137C
|
||||
:1005E00003B61EFE401203661EFE38133E0184173A
|
||||
:1005F000FE72060A0701380624FE02124F01FE565B
|
||||
:100600001916FE68061582014115E203668A106616
|
||||
:10061000039A1EFE701203551EFE681301C60912CE
|
||||
:1006200048FE92062E1201FEAC1DFE434862801366
|
||||
:1006300058FF02005752AD233F4E62493E018417D6
|
||||
:10064000FEEA0601380612F7450A9501FE841916DE
|
||||
:10065000FEE0061582014115E203558A10551C077C
|
||||
:100660000184FEAE10036F1EFE9E133E0184039AAA
|
||||
:100670001EFE1A1201380612FC01C601FEAC1DFE58
|
||||
:1006800043486280F0450A9503B61EF801380624F7
|
||||
:1006900036FE02F60771788C004D62493E2D934E6E
|
||||
:1006A000D00D17FE9A0701FEC01916FE90072620EE
|
||||
:1006B0009E1582014115E2219E0907FB03E6FE58C3
|
||||
:1006C0005710E605FE2A06036F8A106F1C07018487
|
||||
:1006D000FE9C325F7501A68615FEE2002FED2A3CD6
|
||||
:1006E000FE0AF0FECE07AEFE9608FE06F0FE9E085D
|
||||
:1006F000AFA00529010C060DFE2E12141D010814D1
|
||||
:100700000001081400010814000108FE99A4010862
|
||||
:10071000140005FEC60901760612FE3A12010C0607
|
||||
:1007200012FE301314FE1B0001081400010814000F
|
||||
:1007300001081400010814070108140005EF7C4AA1
|
||||
:10074000784F0FFE9A8104FE9A83FECB470B0E2D45
|
||||
:100750002848FE6C080A28FE096FCAFECA45FE3208
|
||||
:100760001253634E7C972FFE7E082A3CFE0AF0FE51
|
||||
:100770006C08AFA0AEFE96080529014105ED1424D2
|
||||
:1007800005EDFE9CF79F01FEAE1EFE185801FEBE51
|
||||
:100790001EFE9958FE7818FEF9188EFE1609106A8A
|
||||
:1007A000226B010C615444212C091AF87701FE7E5A
|
||||
:1007B0001E472C7A30F0FE83E7FE3F0071FE0340B7
|
||||
:1007C000010C61654401C2C8FE1F40206E01FE6A33
|
||||
:1007D00016FE0850FE8A50FE4451FEC651FE10100F
|
||||
:1007E00001FECE1E01FEDE1E1068226901FEEE1E15
|
||||
:1007F00001FEFE1EFE4050FEC250104B224CFE8AEF
|
||||
:1008000010010C0654FE501201FEAE1E01FEBE1E6B
|
||||
:10081000106A226B010C06654E01C20FFE1F800498
|
||||
:10082000FE9F83330B0E206E0FFE449004FEC49394
|
||||
:100830003A0BFEC69004FEC693790B0E106C226D27
|
||||
:1008400001FECE1E01FEDE1E106822690FFE4090E2
|
||||
:1008500004FEC0933A0BFEC29004FEC293790B0EC5
|
||||
:10086000104B224C10642234010C6124443713FED7
|
||||
:100870004E112FFEDE09FE9EF0FEF209FE01481B1E
|
||||
:100880003C3788F5D4FE1E0AD5FE420AD2FE1E0A67
|
||||
:10089000D3FE420AAEFE120AFE06F0FE180AAFA010
|
||||
:1008A00005290141FEC1101424FEC110017606077E
|
||||
:1008B000FE14120176060D5D010C060DFE7412FE8B
|
||||
:1008C0002E1C05FE1A0C017606075D0176060D4109
|
||||
:1008D000FE2C1CFEAAF0FECE0AFEACF0FE660AFE5E
|
||||
:1008E0009210C4F6FEADF0FE720A05FE1A0CC5FEAB
|
||||
:1008F000E710FE2BF0BFFE6B1823FE00FEFE1C125D
|
||||
:10090000ACFED2F0BFFE7618231D1BBF03E3230706
|
||||
:100910001BBFD45BD55BD25BD35BC4C5FEA910758E
|
||||
:100920005E321F7F014219FE3500FE01F0701998FA
|
||||
:100930000570FE741823FE00F81B5B7D1201FE7823
|
||||
:100940000F4D01FE961A2130777D1D055B010C06C7
|
||||
:100950000D2BFEE20B010C0654FEA612010C062420
|
||||
:10096000FE8813216EC701FE1E1F0FFE838004FE4A
|
||||
:100970008383FEC9470B0EFEC844FE42130FFE04DC
|
||||
:100980009104FE8493FECA570BFE869104FE869363
|
||||
:10099000FECB570B0E7A30FE4059FEC1598E4003F4
|
||||
:1009A0006A3B6B10972298D96ADA6B01C2C87A3019
|
||||
:1009B000206EDB64DC34916C7E6DFE4455FEE555A3
|
||||
:1009C000FE04FA64FE05FA3401FE6A16A3261097A7
|
||||
:1009D0001098916C7E6DFE1410010C06241B409142
|
||||
:1009E0004B7E4C010C06FEF7004403683B69FE1089
|
||||
:1009F00058FE9158FE1459FE9559055B010C0624CA
|
||||
:100A00001B40010C06FEF700447801FE8E1E4F0FBE
|
||||
:100A1000FE109004FE90933A0BFE929004FE929387
|
||||
:100A2000790B0EFEBD10014309BB1BFE6E0A15BB00
|
||||
:100A3000010C060DFE1413034B3B4C8EFE6E0AFE9A
|
||||
:100A40000C58FE8D58055B263E0FFE198004FE995A
|
||||
:100A500083330B0EFEE510010C060DFE1A12FE6C20
|
||||
:100A600019FE1941FE6B18ACFED1F0EF1F92014246
|
||||
:100A700019FE4400FE9010FE6C19D94BFEED19DAF8
|
||||
:100A80004CFE0C51FE8E51FE6B1823FE00FF31FE12
|
||||
:100A90007610ACFED2F0FEBA0CFE7618231D5D0374
|
||||
:100AA000E32307FE081319FE16000570FED1F0FEC1
|
||||
:100AB000CC0C1F92014219FE17005CFECEF0FED254
|
||||
:100AC0000CFE3E10FECDF0FEDE0C19FE220005707D
|
||||
:100AD000FECBF0FEEA0C19FE24000570FED0F0FEFD
|
||||
:100AE000F40C1994FE1C10FECFF0FEFE0C194AF314
|
||||
:100AF000FECCF0EF017606244D19FE12003713FEEE
|
||||
:100B00004E112FFE160DFE9EF0FE2A0DFE01481B13
|
||||
:100B10003C3788F5D429D529D229D32937FE9C32F0
|
||||
:100B20002FFE3E0D2A3CAEFE620DAFA0D49FD59F96
|
||||
:100B3000D29FD39F05290141FED31015FEE800C4C2
|
||||
:100B4000C575D799D89CFE89F0292725BED799D895
|
||||
:100B50009C2FFE8C0D16292725BDFE0148A419FEE9
|
||||
:100B6000420005709007FE81491BFE640E010C06D1
|
||||
:100B70000DFE441319002D0DFE54122DFE28002BDE
|
||||
:100B8000FEDA0E0A57011809003646FE2800FEFA62
|
||||
:100B90001001FEF41C01FE001D0ABA01FE581040AF
|
||||
:100BA00015560185053519FE44002D0DF7460DFE3D
|
||||
:100BB000CC1001A7460DFEC21001A70FFE1982043A
|
||||
:100BC000FE9983FECC470B0EFE3446A5460D19FE5A
|
||||
:100BD0004300FEA210010C610D4401FEF41C01FE55
|
||||
:100BE000001D40155601857D0D405101FE9E1E05DC
|
||||
:100BF000FE3A03010C060D5D460D1900FE62100160
|
||||
:100C0000760612FE5C12010C0612FE5213FE1C1C2C
|
||||
:100C1000FE9DF0FE8E0EFE1C1CFE9DF0FE940E014D
|
||||
:100C20000C611244FE9F1019FE1500FE04E60D4FE4
|
||||
:100C3000FE2E1019FE1300FE101019FE4700F119C8
|
||||
:100C4000FE4100A219FE240086C4C57503811E2B37
|
||||
:100C5000EA4FFE04E612FE9D41FE1C424001F405EF
|
||||
:100C600035FE121C1F0D47B5C31FFE310047B801EA
|
||||
:100C7000FED41105E951FE06ECE0FE0E474628FEC3
|
||||
:100C8000CE453151FE06EAE0FE474B45FE7557035F
|
||||
:100C900067FE9856FE38120A5A0118FE4448600151
|
||||
:100CA0000C0628FE18130A5701183EFE41580ABACE
|
||||
:100CB000FEFA14FE4954B0FE5E0F05FE3A030A67C1
|
||||
:100CC000FEE014FE0E474628FECE453151FECE47CB
|
||||
:100CD000FEAD130535212C091AFE98122620962008
|
||||
:100CE000E7FE081CFE7C19FEFD19FE0A1C03E5FE4A
|
||||
:100CF0004855A53BFE6201FEC95531FE741001FE48
|
||||
:100D0000F01A03FE38013BFE3A018EFE1E10FE0271
|
||||
:100D1000ECE7530036FE04EC2C60FE05F6FE3401D1
|
||||
:100D200001FE621B01FECE1EB211FE1813CAFE02A6
|
||||
:100D3000EAE75392FEC3131F1247B5C3FE2A1003FE
|
||||
:100D4000FE380123FEF0FF10E503FE3A0110FE62BB
|
||||
:100D50000101FE1E1E202C155601FE9E1E130702C9
|
||||
:100D600026022196C720960992FE79131F1D47B5CA
|
||||
:100D7000C3FEE110CFFE03DCFE7357FE805D02CFA1
|
||||
:100D8000FE03DCFE5B57FE805D02FE0357CF26FEAE
|
||||
:100D900000CC02FE0357CF8902010C064AFE4E1317
|
||||
:100DA0000FFE1C8004FE9C83330B0E0907FE3A13D2
|
||||
:100DB0000FFE1E8004FE9E83330B0EFE2A130FFED1
|
||||
:100DC0001D8004FE9D83FEF9130EFE1C1301FEEE32
|
||||
:100DD0001EACFE141301FEFE1EFE8158FA01FE0E2B
|
||||
:100DE0001FFE30F40DFE3C50A201FE921B01430990
|
||||
:100DF00056FB01FEC81A010C0628A401FEF41C01D2
|
||||
:100E0000FE001D15FEE900010C064AFE4E1301FE10
|
||||
:100E1000221BFE1E1C0FFE149004FE94933A0BFE40
|
||||
:100E2000969004FE9693790B0E10FE640122FE66E6
|
||||
:100E300001010C0665F90FFE038004FE8383330B6A
|
||||
:100E40000E77FE01EC2CFE8040202C7A3015DF401E
|
||||
:100E5000212CFE00408D2C02FE081C03FEAC00FE7F
|
||||
:100E6000065803FEAE00FE075803FEB000FE085809
|
||||
:100E700003FEB200FE0958FE0A1C2E4920E026108F
|
||||
:100E8000661055106F1357524F1C28FE904DFE915F
|
||||
:100E9000542BFE8811461A135A521C4AFE904DFEDE
|
||||
:100EA00091542BFE9E112E1A202C903460212CFE82
|
||||
:100EB00000408D2C15DFFE1456FED6F0FEB211FE5A
|
||||
:100EC000121C75FE141CFE101CFE181C0251FE0C98
|
||||
:100ED00014FE0E47FE07E628FECE47FEF51302017C
|
||||
:100EE000A7903460FE0680FE4847FE4213FE028053
|
||||
:100EF0000956FE34130A5A0118CBFE3612FE414839
|
||||
:100F0000FE454801FEB216FE00CCCBFEF3133F892E
|
||||
:100F1000091AA50A9D0118FE805C0185F2099BA4AF
|
||||
:100F2000FE1456FED6F0FEEC1102FE445877FE0188
|
||||
:100F3000ECB8FE9E40FE9DE700FE9CE7128D30015E
|
||||
:100F4000F4FEDD1037D799D89C2725EE0912FE480C
|
||||
:100F500012090DFE5612091DFE301209DD1BFEC4DA
|
||||
:100F60001309FE23001BFED01309071BFE341409CE
|
||||
:100F700024FE121209001B291FDD0142A1320108C3
|
||||
:100F8000AE410232FE62080AE101FE5810159B05CF
|
||||
:100F90003532014309BBFED713914B7E4C8EFE8048
|
||||
:100FA00013010C0654FE7212DB64DC34FE4455FE61
|
||||
:100FB000E555B0FE4A13216EFE261303973B988E2B
|
||||
:100FC000FEB60E106A226B261097109801C22E49A9
|
||||
:100FD00088206E01FE6A16DB64DC34FE0455FEA533
|
||||
:100FE00055FE04FA64FE05FA34FE8F10036C3B6D67
|
||||
:100FF000FE4056FEE156106C226D71DB64DC34FE5F
|
||||
:101000004455FEE55503683B69FE0056FEA15610A7
|
||||
:10101000682269010C0654F9216EFE1F40036A3BE9
|
||||
:101020006BFE2C50FEAE50036C3B6DFE4450FEC672
|
||||
:101030005003683B69FE0850FE8A50034B3B4CFE50
|
||||
:101040004050FEC25005732E07209E0572320108E3
|
||||
:10105000163D2725EE09072B3D014309BB2B7201E5
|
||||
:10106000A6233F1B3D010C060DFE1E13914B7E4C2B
|
||||
:10107000FE0A5531FE8B55D94BDA4CFE0C51FE8ED3
|
||||
:1010800051057201FE8E1ECAFE1941057232010819
|
||||
:101090002A3C16C02725BE2D1DC02D0D832D7F1B7C
|
||||
:1010A000FE6615053D01082A3C16C02725BD091D11
|
||||
:1010B0002B3D010816C02725FEE809FEC249500352
|
||||
:1010C000B61E830138062431A1FEBB452D00A4467F
|
||||
:1010D00007903F01FEF81501A686FE4B45FE201342
|
||||
:1010E00001430982FE1613039A1E5D03551E315EED
|
||||
:1010F0000572FEC05D01A7FE031703668A10665ED7
|
||||
:10110000320108177301FE5619057301082A3C16AF
|
||||
:101110003D2725BD09072B3D01FEBE16FE4258FEA8
|
||||
:10112000E81401A686FE4AF40D1B3DFE4AF407FEB4
|
||||
:101130000E12014309824E057203558A10555E3224
|
||||
:101140000108177301FE8419057301082A3C163D36
|
||||
:101150002725BD09122B3D01FEE8178BFEAA14FEC0
|
||||
:10116000B61486A8B20D1B3DB207FE0E120143094C
|
||||
:10117000824E0572036F8A106F5E32010817730189
|
||||
:10118000FEC019057313072FFECC1517FEE2155F7D
|
||||
:10119000CC0108265F028FFEDE152AFEDE1516FE44
|
||||
:1011A000CC155E320108FED5101358FF02005752CD
|
||||
:1011B000AD23FEFF7FFE3056FE005C021358FF0297
|
||||
:1011C000005752AD233FFE3056FE005C021358FF1D
|
||||
:1011D00002005752AD021358FF02005752FE005E44
|
||||
:1011E000021358FF02005752ADFE0B58020A660167
|
||||
:1011F0005C0A55015C0A6F015C0201FE1E1F231A86
|
||||
:10120000FF030054FE00F424520FFE007C04FE078E
|
||||
:101210007C3A0B0EFE0071FEF918FE7A19FEFB19DE
|
||||
:10122000FE1AF700FE1BF7007A3010682269D96CAD
|
||||
:10123000DA6D02FE6208FE824AFEE11AFE835A77E8
|
||||
:101240000201C6FE42484F5045010816FEE017272E
|
||||
:1012500025BE010816FEE0172725FEE80AFEC15943
|
||||
:10126000039A1EFEDA1201380612FED0132653121C
|
||||
:1012700048FE0817D1125312FE1E132DB47BFE2612
|
||||
:10128000174D13071CB49004FE7810FF028355F12C
|
||||
:10129000FF028355531DFE1213D6FE3000B0FE80B0
|
||||
:1012A000171C631307FE5610530DFE1613D6FE646B
|
||||
:1012B00000B0FE80170AFE64001C941307FE28107D
|
||||
:1012C0005307FE6013D6FEC800B0FE80170AFEC8A2
|
||||
:1012D000001C95130771D6FE900148FE8C1745F34C
|
||||
:1012E000FE43F496FE56F0FE9E17FE04F458FE43AD
|
||||
:1012F000F494F68B01FE2416233FFCA88C4948FE8B
|
||||
:10130000DA176249FE1C10A88C8048FEDA1762804A
|
||||
:10131000715026FE4DF400F7451307FEB456FEC388
|
||||
:10132000580250130D02503E784F45010816A92768
|
||||
:1013300025BEFE03EAFE7E01010816A92725FEE967
|
||||
:101340000A010816A92725FEE90AFE05EAFE7F0123
|
||||
:10135000010816A92725FE6909FE02EAFE8001019F
|
||||
:101360000816A92725FEE80847FE810103B61E835B
|
||||
:101370000138062431A278F2530736FE34F43FA137
|
||||
:1013800078039A1E830138061231F04F45FE901003
|
||||
:10139000FE405A233FFB8C4948FEAA186249718CD3
|
||||
:1013A0008048FEAA186280FEB456FE405D01C60168
|
||||
:1013B000FEAC1DFE0217FEC845FE5AF0FEC018FE28
|
||||
:1013C00043482D9336FE34F4FE0011FE40102DB438
|
||||
:1013D00036FE34F404FE34102DFE0B00364663FE58
|
||||
:1013E0002810FEC049FF020054B2FE900148FEFAE8
|
||||
:1013F0001845FE1CF43FF3FE40F496FE56F0FE0C3A
|
||||
:1014000019FE04F458FE40F494F63E2D934ED00D90
|
||||
:1014100021FE7F01FEC846FE24138C005D2621FEBE
|
||||
:101420007E01FEC845FE141321FE8001FE4845FAE8
|
||||
:1014300021FE8101FEC8444E260213070278455062
|
||||
:10144000130D021407010817FE8219140D01081765
|
||||
:10145000FE8219141D010817FE82195FFE894901D9
|
||||
:1014600008021407010817C1141D010817C1140749
|
||||
:10147000010817C1FE8949010817C15FFE894A01A9
|
||||
:1014800008025002140701081774147F010817742A
|
||||
:10149000141201081774FE89490108177414000119
|
||||
:1014A000081774FE894A01081774FE0949010817D4
|
||||
:1014B000745FCC01080221E40907FE4C13C820E444
|
||||
:1014C000FE49F4004D5FA15EFE01ECFE2701CCFF5A
|
||||
:1014D0000200102FFE3E1A014309FEE300FE221314
|
||||
:1014E00016FE641A26209E0141219E09075D010C0B
|
||||
:1014F000610744020A5A0118FE0040AA091AFE12A6
|
||||
:10150000130A9D0118AA0A6701A3020A9D0118AADD
|
||||
:10151000FE80E71A091A5DFE455801FEB216AA02BE
|
||||
:101520000A5A0118AA0A6701A3020A5A011801FE01
|
||||
:101530007E1EFE804CFE49E41AFE12130A9D01181D
|
||||
:10154000FE804C0A67015C021C1A877CE5FE18DFEE
|
||||
:10155000FE19DEFE241CFE1DF728B1FE041B01FE51
|
||||
:101560002A1CFAB3287CFE2C01FE2F1902C92BFE7F
|
||||
:10157000F41AFEFA101C1A8703FE6401FE00F4241C
|
||||
:10158000FE185803FE6601FE1958B32401FE0E1F13
|
||||
:10159000FE30F407FE3C507CFE3800FE0F79FE1C46
|
||||
:1015A000F724B1FE501BFED4143102C92BFE261BBA
|
||||
:1015B000FEBA101C1A87FE835AFE18DFFE19DEFEE3
|
||||
:1015C0001DF754B1FE721BFEB214FCB3547C12FE24
|
||||
:1015D000AF19FE98E70002C92BFE661BFE8A101C9D
|
||||
:1015E0001A878B0FFE309004FEB0933A0BFE18580A
|
||||
:1015F000FE329004FEB2933A0BFE19580EA8B34A7D
|
||||
:101600007C12FE0F79FE1CF74AB1FEC61BFE5E146B
|
||||
:101610003102C92BFE961B5CFE02F61A87FE18FEED
|
||||
:101620006AFE19FE6B01FE1E1FFE1DF765B1FEEE80
|
||||
:101630001BFE3614FE1C13B3653EFE8358FEAF1925
|
||||
:10164000FE80E71AFE81E71A15FEDD007A30027A85
|
||||
:1016500030FE12452BFEDC1B1F0747B5C30535FEC8
|
||||
:1016600039F0752602FE7E18231D361311028703FA
|
||||
:10167000E32307FEEF12FEE110903460FE028009C2
|
||||
:1016800056FE3C13FE8214FE421351FE06830A5A94
|
||||
:101690000118CBFE3E12FE4148FE454801FEB2163F
|
||||
:1016A000FE00CCCBFEF3133F89091AA50A9D011851
|
||||
:1016B000FE804C0185FE1610099B4EFE4014FE2450
|
||||
:1016C00012FE1456FED6F0FE521C1C0D02FE9CE7C4
|
||||
:1016D0000D19FE1500408D3001F41C070251FE0665
|
||||
:1016E00083FE1880612844155601851C0702FE38C8
|
||||
:1016F00090FEBA9091DE7EDFFE485531FEC955025C
|
||||
:1017000021B98820B9020ABA0118FE41480A5701D6
|
||||
:1017100018FE49441BFE1E1D8889020A5A01180939
|
||||
:101720001AA40A6701A30A570118888902FE4EE429
|
||||
:101730001D7BFE521D03FE9000FE3A45FE2C10FE5E
|
||||
:101740004EE4DD7BFE641D03FE9200D112FE1A10F2
|
||||
:10175000FE4EE4FE0B007BFE761D03FE9400D124BA
|
||||
:10176000FE081003FE9600D163FE4E4583CAFF04B7
|
||||
:101770006854FEF1102349FE081CFE6719FE0A1C7E
|
||||
:10178000FE1AF4FE000483B21D48FEAA1D131D02BA
|
||||
:101790000992FE5AF0FEBA1D2E93FE34100912FE75
|
||||
:1017A0005AF0FEC81D2EB4FE2610091D362E63FE0B
|
||||
:1017B0001A10090D362E94F20907362E95A1C8028B
|
||||
:1017C0001F930142FE04FE99039C8B022AFE1C1EFD
|
||||
:1017D000FE14F0082FFE0C1E2AFE1C1E8FFE1C1E7F
|
||||
:1017E000FE82F0FE101E020F3F04FE8083330B0EBC
|
||||
:1017F000020FFE188004FE9883330B0E020FFE02C8
|
||||
:101800008004FE8283330B0E020FFE068004FE86E8
|
||||
:1018100083330B0E020FFE1B8004FE9B83330B0EE3
|
||||
:10182000020FFE048004FE8483330B0E020FFE8041
|
||||
:101830008004FE8083FEC9470B0E020FFE1981044F
|
||||
:10184000FE9983FECA470B0E020FFE068304FE8636
|
||||
:1018500083FECE470B0E020FFE2C9004FEAC933A93
|
||||
:101860000B0E020FFEAE9004FEAE93790B0E020F2C
|
||||
:10187000FE089004FE88933A0B0E020FFE8A900435
|
||||
:10188000FE8A93790B0E020FFE0C9004FE8C933AA5
|
||||
:101890000B0E020FFE8E9004FE8E93790B0E020F3C
|
||||
:1018A000FE3C9004FEBC933A0B0E028B0FFE0380AD
|
||||
:0E18B00004FE8383330B770EA802FF66000050
|
||||
:00000001FF
|
||||
/* Microcode buffer is kept after initialization for error recovery. */
|
147
firmware/advansys/mcode.bin.ihex
Normal file
147
firmware/advansys/mcode.bin.ihex
Normal file
@ -0,0 +1,147 @@
|
||||
:100000003F452C01010301190F0000000000000012
|
||||
:10001000000000000F0F0F0F0F0F0F0F0000000068
|
||||
:1000200000000000000000000000000000000000D0
|
||||
:1000300000000000000000000000000000000000C0
|
||||
:100040000000000000000000C3120D0501000000C8
|
||||
:1000500000FF000000000000FF80FFFF0100000023
|
||||
:10006000000000000000002300000000000700FF67
|
||||
:1000700000000000FFFFFF00000000000000E48817
|
||||
:100080000000000080734804360000A2C2008073A4
|
||||
:1000900003233640B600360005D60CD212DA00A291
|
||||
:1000A000C20092801E985000F5004898DF23366009
|
||||
:1000B000B60092804F00F5004898EF233660B600F6
|
||||
:1000C000928080629280004615EE13EA020109D800
|
||||
:1000D000CD044D0000A3D600A6977F2304618401C0
|
||||
:1000E000E684D2C18073CD044D0000A3DA01A69747
|
||||
:1000F000C681C28880738077000101A1FE004F0095
|
||||
:10010000849707A6080100330300C288030301DEB9
|
||||
:10011000C288CE006960CE0002034A6000A2780166
|
||||
:10012000806307A62401788103038063E20007A6A9
|
||||
:10013000340100330400C2880307020104CA0D23FE
|
||||
:1001400068984D04048505D80D236898CD041523BF
|
||||
:10015000F888FB23026182018063020306A3620127
|
||||
:1001600000330A00C2884E0007A36E0100330B0063
|
||||
:10017000C288CD04362D00331A00C288500488810D
|
||||
:1001800006AB820188814E0007A39201500000A3B4
|
||||
:100190003C0100057C814697020105C60423A001AD
|
||||
:1001A0001523A101BE81FD23026182010ADA4A0002
|
||||
:1001B000066100A0B4018063CD04362D00331B001E
|
||||
:1001C000C28806236898CD04E684060100A2D40103
|
||||
:1001D000576000A0DA01E6848023A001E6848073E2
|
||||
:1001E0004B00066100A2000204010CDE020103CCF8
|
||||
:1001F0004F008497FC810823024182014F006297DF
|
||||
:1002000048048480F0970046560003C00123E800AC
|
||||
:1002100081730629034206E203EE6BEB1123F88893
|
||||
:100220000498F0808073807707A42A027C9506A644
|
||||
:10023000340203A64C044682040103D8B4986A969B
|
||||
:100240004682FE95806783038063B62D02A66C020A
|
||||
:1002500007A65A0206A65E0203A66202C2887C9521
|
||||
:100260004882609648820423A0011423A1013C84A3
|
||||
:1002700004010CDCE0232561EF0014014F04A80108
|
||||
:100280006F00A5010323A40106239C01242B1C015C
|
||||
:1002900002A6AA0207A65A0206A65E0203A6200428
|
||||
:1002A00001A6B40200A6B40200331200C288000EF8
|
||||
:1002B0008063004300A08C024D0404010BDCE723A3
|
||||
:1002C00004618401103112351401EC006C38003FD8
|
||||
:1002D0000000EA821823046118A0E2020401A2C807
|
||||
:1002E00000331F00C28808310A350C390E3D7E9854
|
||||
:1002F000B62D01A6140300A6140307A60C0306A638
|
||||
:10030000100303A6200402A66C0200333300C28847
|
||||
:100310007C95EE826096EE82829880427E9864E4BC
|
||||
:1003200004012DC83105070100A2540300438701D1
|
||||
:10033000050586987E9800A6160307A64C0303A61B
|
||||
:100340003C0406A6500301A6160300332500C2880C
|
||||
:100350007C95328360963283040110CE07C8050570
|
||||
:10036000EB0400330020C020816272830001050588
|
||||
:10037000FFA27A03B1010823B2012E8305051501FE
|
||||
:1003800000A29A03EC006E0095016C38003F00005B
|
||||
:1003900001A6960300A69603108480427E9801A6CB
|
||||
:1003A000A40300A6BC031084A898804201A6A4035D
|
||||
:1003B00007A6B203D4837C95A88300332F00C2889C
|
||||
:1003C000A898804200A6BC0307A6CA03D4837C95E4
|
||||
:1003D000C08300332600C288382B80328036042345
|
||||
:1003E000A0011223A101108407F006A4F403806B7E
|
||||
:1003F000806705238303806303A60E0407A6060413
|
||||
:1004000006A60A0400331700C2887C95F483609620
|
||||
:10041000F483208407F006A42004806B8067052302
|
||||
:1004200083038063B62D03A63C0407A6340406A606
|
||||
:10043000380400333000C2887C9520846096208484
|
||||
:100440001D0106CC00330084C0200023EA00816235
|
||||
:10045000A20D806307A65A0400331800C288030364
|
||||
:100460008063A30107A46404230100A286040AA0F8
|
||||
:100470007604E00000331D00C2880BA08204E00077
|
||||
:1004800000331E00C2884223F888002322A3E6041A
|
||||
:10049000082322A3A204282322A3AE04022322A31A
|
||||
:1004A000C4044223F8884A00066100A0AE04452334
|
||||
:1004B000F888049800A2C004B49800330082C020D9
|
||||
:1004C0008162E8814723F88804010BDE0498B49820
|
||||
:1004D00000330081C0208162140100A00002432388
|
||||
:1004E000F8880423A0014423A10180734D0003A3D5
|
||||
:1004F000F40400332700C288040104DC0223A201B3
|
||||
:100500000423A001049826954B00F6004F044F00E9
|
||||
:1005100000A3220500057600066100A21C050A85DD
|
||||
:100520004697CD04248548048480020103DA8023A1
|
||||
:10053000820134850223A0014A00066100A2400521
|
||||
:100540001D0104D6FF2386414B60CB00FF238001B1
|
||||
:1005500049008101040102C830018001F704030150
|
||||
:1005600049048001C90000050001FFA0600577046F
|
||||
:100570000123EA005D00FEC700620023EA00006379
|
||||
:1005800007A4F805030302A08E05F48500332D00AF
|
||||
:10059000C28804A0B80580630023DF004A0006611A
|
||||
:1005A00000A2A4051D0106D60223024182015000CB
|
||||
:1005B00062970485042302418201048508A0BE05D8
|
||||
:1005C000F48503A0C405F48501A0CE0588008063EE
|
||||
:1005D000CC8607A0EE055F00002BDF0800A2E60531
|
||||
:1005E0008067806301A27A067C8506236898482389
|
||||
:1005F000F88807238000068780637C850023DF005E
|
||||
:1006000000634A00066100A236061D0116D4C0230D
|
||||
:1006100007418303806306A61C0600333700C288A7
|
||||
:100620001D0101D620236360830380630223DF0062
|
||||
:1006300007A67C05EF046F0000634B000641CB006A
|
||||
:100640005200066100A24E061D0103CAC0230741E5
|
||||
:1006500000631D0104CC00330083C020816280232D
|
||||
:1006600007410063806708238303806300630123DD
|
||||
:10067000DF0006A6840607A67C058067806300333A
|
||||
:100680000040C020816200630000FE958303806308
|
||||
:1006900006A6940607A67C05000001A01407002BFF
|
||||
:1006A000400E8063010006A6AA0607A67C05400E40
|
||||
:1006B0008063004300A0A20606A6BC0607A67C0530
|
||||
:1006C0008067400E806307A67C050023DF0000637F
|
||||
:1006D00007A6D60600332A00C28803038063890078
|
||||
:1006E0000A2B07A6E80600332900C288004300A2AF
|
||||
:1006F000F406C00E8063DE86C00E00330080C0208A
|
||||
:100700008162040102DA80637C85807B806306A6B7
|
||||
:100710008C0600332C00C2880CA22E07FE958303A2
|
||||
:10072000806306A62C0707A67C0500333D00C2881F
|
||||
:1007300000008067830380630CA0440707A67C0544
|
||||
:10074000BF2304618401E6840063F0040101F10029
|
||||
:100750000001F20001058001720471008101700442
|
||||
:10076000800581050063F004F20072040101F100CC
|
||||
:1007700070008101700471008101720080017104B8
|
||||
:100780007000800170040063F004F2007204000144
|
||||
:10079000F10070008001700471008001720081011D
|
||||
:1007A000710470008101700400630023B3018305AC
|
||||
:1007B000A301A201A1010123A0010001C80003A11E
|
||||
:1007C000C40700330700C28880058105040111C8F1
|
||||
:1007D0004800B001B1010823B201050148040043FB
|
||||
:1007E00000A2E4070005DA870001C800FF238001AA
|
||||
:1007F00005050063F7041A09F6086E040002804339
|
||||
:100800007608800277040063F7041A09F6086E047C
|
||||
:10081000000200A0140816880043760880027704BE
|
||||
:100820000063F3040023F40074008043F400CF401D
|
||||
:1008300000A2440874040201F7C9F6D9000101A11D
|
||||
:10084000240804982695248873040063F30475042F
|
||||
:100850005A88020104D84697049826954A8875005C
|
||||
:1008600000A3640800054E8873040063807B8063E6
|
||||
:1008700006A6760800333E00C28880678303806343
|
||||
:100880000063382B9C88382B928832093105929866
|
||||
:100890000505B209006300320036003A003E0063ED
|
||||
:1008A00080328036803A803EB43D0063382B40323F
|
||||
:1008B0004036403A403E00635A20C94000A0B40888
|
||||
:1008C0005D00FEC300638073E6200223E8008273AC
|
||||
:1008D000FFFD80731323F8886620C0200423A00145
|
||||
:1008E000A123A1018162E28880738077680000A261
|
||||
:1008F000800003C2F1C74123F8881123A10104231A
|
||||
:04090000A001E684E8
|
||||
:00000001FF
|
||||
/* Microcode buffer is kept after initialization for error recovery. */
|
2111
firmware/qlogic/1040.bin.ihex
Normal file
2111
firmware/qlogic/1040.bin.ihex
Normal file
File diff suppressed because it is too large
Load Diff
1771
firmware/qlogic/12160.bin.ihex
Normal file
1771
firmware/qlogic/12160.bin.ihex
Normal file
File diff suppressed because it is too large
Load Diff
2008
firmware/qlogic/1280.bin.ihex
Normal file
2008
firmware/qlogic/1280.bin.ihex
Normal file
File diff suppressed because it is too large
Load Diff
1158
firmware/qlogic/isp1000.bin.ihex
Normal file
1158
firmware/qlogic/isp1000.bin.ihex
Normal file
File diff suppressed because it is too large
Load Diff
237
include/scsi/fc/fc_fip.h
Normal file
237
include/scsi/fc/fc_fip.h
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright 2008 Cisco Systems, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you may redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef _FC_FIP_H_
|
||||
#define _FC_FIP_H_
|
||||
|
||||
/*
|
||||
* This version is based on:
|
||||
* http://www.t11.org/ftp/t11/pub/fc/bb-5/08-543v1.pdf
|
||||
*/
|
||||
|
||||
/*
|
||||
* The FIP ethertype eventually goes in net/if_ether.h.
|
||||
*/
|
||||
#ifndef ETH_P_FIP
|
||||
#define ETH_P_FIP 0x8914 /* FIP Ethertype */
|
||||
#endif
|
||||
|
||||
#define FIP_DEF_PRI 128 /* default selection priority */
|
||||
#define FIP_DEF_FC_MAP 0x0efc00 /* default FCoE MAP (MAC OUI) value */
|
||||
#define FIP_DEF_FKA 8000 /* default FCF keep-alive/advert period (mS) */
|
||||
#define FIP_VN_KA_PERIOD 90000 /* required VN_port keep-alive period (mS) */
|
||||
#define FIP_FCF_FUZZ 100 /* random time added by FCF (mS) */
|
||||
|
||||
/*
|
||||
* Multicast MAC addresses. T11-adopted.
|
||||
*/
|
||||
#define FIP_ALL_FCOE_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 0 })
|
||||
#define FIP_ALL_ENODE_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 1 })
|
||||
#define FIP_ALL_FCF_MACS ((u8[6]) { 1, 0x10, 0x18, 1, 0, 2 })
|
||||
|
||||
#define FIP_VER 1 /* version for fip_header */
|
||||
|
||||
struct fip_header {
|
||||
__u8 fip_ver; /* upper 4 bits are the version */
|
||||
__u8 fip_resv1; /* reserved */
|
||||
__be16 fip_op; /* operation code */
|
||||
__u8 fip_resv2; /* reserved */
|
||||
__u8 fip_subcode; /* lower 4 bits are sub-code */
|
||||
__be16 fip_dl_len; /* length of descriptors in words */
|
||||
__be16 fip_flags; /* header flags */
|
||||
} __attribute__((packed));
|
||||
|
||||
#define FIP_VER_SHIFT 4
|
||||
#define FIP_VER_ENCAPS(v) ((v) << FIP_VER_SHIFT)
|
||||
#define FIP_VER_DECAPS(v) ((v) >> FIP_VER_SHIFT)
|
||||
#define FIP_BPW 4 /* bytes per word for lengths */
|
||||
|
||||
/*
|
||||
* fip_op.
|
||||
*/
|
||||
enum fip_opcode {
|
||||
FIP_OP_DISC = 1, /* discovery, advertisement, etc. */
|
||||
FIP_OP_LS = 2, /* Link Service request or reply */
|
||||
FIP_OP_CTRL = 3, /* Keep Alive / Link Reset */
|
||||
FIP_OP_VLAN = 4, /* VLAN discovery */
|
||||
FIP_OP_VENDOR_MIN = 0xfff8, /* min vendor-specific opcode */
|
||||
FIP_OP_VENDOR_MAX = 0xfffe, /* max vendor-specific opcode */
|
||||
};
|
||||
|
||||
/*
|
||||
* Subcodes for FIP_OP_DISC.
|
||||
*/
|
||||
enum fip_disc_subcode {
|
||||
FIP_SC_SOL = 1, /* solicitation */
|
||||
FIP_SC_ADV = 2, /* advertisement */
|
||||
};
|
||||
|
||||
/*
|
||||
* Subcodes for FIP_OP_LS.
|
||||
*/
|
||||
enum fip_trans_subcode {
|
||||
FIP_SC_REQ = 1, /* request */
|
||||
FIP_SC_REP = 2, /* reply */
|
||||
};
|
||||
|
||||
/*
|
||||
* Subcodes for FIP_OP_RESET.
|
||||
*/
|
||||
enum fip_reset_subcode {
|
||||
FIP_SC_KEEP_ALIVE = 1, /* keep-alive from VN_Port */
|
||||
FIP_SC_CLR_VLINK = 2, /* clear virtual link from VF_Port */
|
||||
};
|
||||
|
||||
/*
|
||||
* Subcodes for FIP_OP_VLAN.
|
||||
*/
|
||||
enum fip_vlan_subcode {
|
||||
FIP_SC_VL_REQ = 1, /* request */
|
||||
FIP_SC_VL_REP = 2, /* reply */
|
||||
};
|
||||
|
||||
/*
|
||||
* flags in header fip_flags.
|
||||
*/
|
||||
enum fip_flag {
|
||||
FIP_FL_FPMA = 0x8000, /* supports FPMA fabric-provided MACs */
|
||||
FIP_FL_SPMA = 0x4000, /* supports SPMA server-provided MACs */
|
||||
FIP_FL_AVAIL = 0x0004, /* available for FLOGI/ELP */
|
||||
FIP_FL_SOL = 0x0002, /* this is a solicited message */
|
||||
FIP_FL_FPORT = 0x0001, /* sent from an F port */
|
||||
};
|
||||
|
||||
/*
|
||||
* Common descriptor header format.
|
||||
*/
|
||||
struct fip_desc {
|
||||
__u8 fip_dtype; /* type - see below */
|
||||
__u8 fip_dlen; /* length - in 32-bit words */
|
||||
};
|
||||
|
||||
enum fip_desc_type {
|
||||
FIP_DT_PRI = 1, /* priority for forwarder selection */
|
||||
FIP_DT_MAC = 2, /* MAC address */
|
||||
FIP_DT_MAP_OUI = 3, /* FC-MAP OUI */
|
||||
FIP_DT_NAME = 4, /* switch name or node name */
|
||||
FIP_DT_FAB = 5, /* fabric descriptor */
|
||||
FIP_DT_FCOE_SIZE = 6, /* max FCoE frame size */
|
||||
FIP_DT_FLOGI = 7, /* FLOGI request or response */
|
||||
FIP_DT_FDISC = 8, /* FDISC request or response */
|
||||
FIP_DT_LOGO = 9, /* LOGO request or response */
|
||||
FIP_DT_ELP = 10, /* ELP request or response */
|
||||
FIP_DT_VN_ID = 11, /* VN_Node Identifier */
|
||||
FIP_DT_FKA = 12, /* advertisement keep-alive period */
|
||||
FIP_DT_VENDOR = 13, /* vendor ID */
|
||||
FIP_DT_VLAN = 14, /* vlan number */
|
||||
FIP_DT_LIMIT, /* max defined desc_type + 1 */
|
||||
FIP_DT_VENDOR_BASE = 128, /* first vendor-specific desc_type */
|
||||
};
|
||||
|
||||
/*
|
||||
* FIP_DT_PRI - priority descriptor.
|
||||
*/
|
||||
struct fip_pri_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__u8 fd_resvd;
|
||||
__u8 fd_pri; /* FCF priority: higher is better */
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FIP_DT_MAC - MAC address descriptor.
|
||||
*/
|
||||
struct fip_mac_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__u8 fd_mac[ETH_ALEN];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FIP_DT_MAP - descriptor.
|
||||
*/
|
||||
struct fip_map_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__u8 fd_resvd[3];
|
||||
__u8 fd_map[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FIP_DT_NAME descriptor.
|
||||
*/
|
||||
struct fip_wwn_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__u8 fd_resvd[2];
|
||||
__be64 fd_wwn; /* 64-bit WWN, unaligned */
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FIP_DT_FAB descriptor.
|
||||
*/
|
||||
struct fip_fab_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__be16 fd_vfid; /* virtual fabric ID */
|
||||
__u8 fd_resvd;
|
||||
__u8 fd_map[3]; /* FC-MAP value */
|
||||
__be64 fd_wwn; /* fabric name, unaligned */
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FIP_DT_FCOE_SIZE descriptor.
|
||||
*/
|
||||
struct fip_size_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__be16 fd_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Descriptor that encapsulates an ELS or ILS frame.
|
||||
* The encapsulated frame immediately follows this header, without
|
||||
* SOF, EOF, or CRC.
|
||||
*/
|
||||
struct fip_encaps {
|
||||
struct fip_desc fd_desc;
|
||||
__u8 fd_resvd[2];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FIP_DT_VN_ID - VN_Node Identifier descriptor.
|
||||
*/
|
||||
struct fip_vn_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__u8 fd_mac[ETH_ALEN];
|
||||
__u8 fd_resvd;
|
||||
__u8 fd_fc_id[3];
|
||||
__be64 fd_wwpn; /* port name, unaligned */
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FIP_DT_FKA - Advertisement keep-alive period.
|
||||
*/
|
||||
struct fip_fka_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__u8 fd_resvd[2];
|
||||
__be32 fd_fka_period; /* adv./keep-alive period in mS */
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FIP_DT_VENDOR descriptor.
|
||||
*/
|
||||
struct fip_vendor_desc {
|
||||
struct fip_desc fd_desc;
|
||||
__u8 fd_resvd[2];
|
||||
__u8 fd_vendor_id[8];
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* _FC_FIP_H_ */
|
@ -1,54 +0,0 @@
|
||||
#ifndef FC_TRANSPORT_FCOE_H
|
||||
#define FC_TRANSPORT_FCOE_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/libfc.h>
|
||||
|
||||
/**
|
||||
* struct fcoe_transport - FCoE transport struct for generic transport
|
||||
* for Ethernet devices as well as pure HBAs
|
||||
*
|
||||
* @name: name for thsi transport
|
||||
* @bus: physical bus type (pci_bus_type)
|
||||
* @driver: physical bus driver for network device
|
||||
* @create: entry create function
|
||||
* @destroy: exit destroy function
|
||||
* @list: list of transports
|
||||
*/
|
||||
struct fcoe_transport {
|
||||
char *name;
|
||||
unsigned short vendor;
|
||||
unsigned short device;
|
||||
struct bus_type *bus;
|
||||
struct device_driver *driver;
|
||||
int (*create)(struct net_device *device);
|
||||
int (*destroy)(struct net_device *device);
|
||||
bool (*match)(struct net_device *device);
|
||||
struct list_head list;
|
||||
struct list_head devlist;
|
||||
struct mutex devlock;
|
||||
};
|
||||
|
||||
/**
|
||||
* MODULE_ALIAS_FCOE_PCI
|
||||
*
|
||||
* some care must be taken with this, vendor and device MUST be a hex value
|
||||
* preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB)
|
||||
*/
|
||||
#define MODULE_ALIAS_FCOE_PCI(vendor, device) \
|
||||
MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device))
|
||||
|
||||
/* exported funcs */
|
||||
int fcoe_transport_attach(struct net_device *netdev);
|
||||
int fcoe_transport_release(struct net_device *netdev);
|
||||
int fcoe_transport_register(struct fcoe_transport *t);
|
||||
int fcoe_transport_unregister(struct fcoe_transport *t);
|
||||
int fcoe_load_transport_driver(struct net_device *netdev);
|
||||
int __init fcoe_transport_init(void);
|
||||
int __exit fcoe_transport_exit(void);
|
||||
|
||||
/* fcow_sw is the default transport */
|
||||
extern struct fcoe_transport fcoe_sw_transport;
|
||||
#endif /* FC_TRANSPORT_FCOE_H */
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <linux/timer.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#include <scsi/scsi_transport.h>
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
@ -661,7 +662,8 @@ struct fc_lport {
|
||||
unsigned long boot_time;
|
||||
|
||||
struct fc_host_statistics host_stats;
|
||||
struct fcoe_dev_stats *dev_stats[NR_CPUS];
|
||||
struct fcoe_dev_stats *dev_stats;
|
||||
|
||||
u64 wwpn;
|
||||
u64 wwnn;
|
||||
u8 retry_count;
|
||||
@ -694,11 +696,6 @@ struct fc_lport {
|
||||
/*
|
||||
* FC_LPORT HELPER FUNCTIONS
|
||||
*****************************/
|
||||
static inline void *lport_priv(const struct fc_lport *lp)
|
||||
{
|
||||
return (void *)(lp + 1);
|
||||
}
|
||||
|
||||
static inline int fc_lport_test_ready(struct fc_lport *lp)
|
||||
{
|
||||
return lp->state == LPORT_ST_READY;
|
||||
@ -722,6 +719,42 @@ static inline void fc_lport_state_enter(struct fc_lport *lp,
|
||||
lp->state = state;
|
||||
}
|
||||
|
||||
static inline int fc_lport_init_stats(struct fc_lport *lp)
|
||||
{
|
||||
/* allocate per cpu stats block */
|
||||
lp->dev_stats = alloc_percpu(struct fcoe_dev_stats);
|
||||
if (!lp->dev_stats)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fc_lport_free_stats(struct fc_lport *lp)
|
||||
{
|
||||
free_percpu(lp->dev_stats);
|
||||
}
|
||||
|
||||
static inline struct fcoe_dev_stats *fc_lport_get_stats(struct fc_lport *lp)
|
||||
{
|
||||
return per_cpu_ptr(lp->dev_stats, smp_processor_id());
|
||||
}
|
||||
|
||||
static inline void *lport_priv(const struct fc_lport *lp)
|
||||
{
|
||||
return (void *)(lp + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport
|
||||
* @sht: ptr to the scsi host templ
|
||||
* @priv_size: size of private data after fc_lport
|
||||
*
|
||||
* Returns: ptr to Scsi_Host
|
||||
*/
|
||||
static inline struct Scsi_Host *
|
||||
libfc_host_alloc(struct scsi_host_template *sht, int priv_size)
|
||||
{
|
||||
return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* LOCAL PORT LAYER
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2007-2008 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@ -20,134 +21,144 @@
|
||||
#ifndef _LIBFCOE_H
|
||||
#define _LIBFCOE_H
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <scsi/fc/fc_fcoe.h>
|
||||
#include <scsi/libfc.h>
|
||||
|
||||
/*
|
||||
* this percpu struct for fcoe
|
||||
* FIP tunable parameters.
|
||||
*/
|
||||
struct fcoe_percpu_s {
|
||||
int cpu;
|
||||
struct task_struct *thread;
|
||||
struct sk_buff_head fcoe_rx_list;
|
||||
struct page *crc_eof_page;
|
||||
int crc_eof_offset;
|
||||
#define FCOE_CTLR_START_DELAY 2000 /* mS after first adv. to choose FCF */
|
||||
#define FCOE_CTRL_SOL_TOV 2000 /* min. solicitation interval (mS) */
|
||||
#define FCOE_CTLR_FCF_LIMIT 20 /* max. number of FCF entries */
|
||||
|
||||
/**
|
||||
* enum fip_state - internal state of FCoE controller.
|
||||
* @FIP_ST_DISABLED: controller has been disabled or not yet enabled.
|
||||
* @FIP_ST_LINK_WAIT: the physical link is down or unusable.
|
||||
* @FIP_ST_AUTO: determining whether to use FIP or non-FIP mode.
|
||||
* @FIP_ST_NON_FIP: non-FIP mode selected.
|
||||
* @FIP_ST_ENABLED: FIP mode selected.
|
||||
*/
|
||||
enum fip_state {
|
||||
FIP_ST_DISABLED,
|
||||
FIP_ST_LINK_WAIT,
|
||||
FIP_ST_AUTO,
|
||||
FIP_ST_NON_FIP,
|
||||
FIP_ST_ENABLED,
|
||||
};
|
||||
|
||||
/*
|
||||
* the fcoe sw transport private data
|
||||
/**
|
||||
* struct fcoe_ctlr - FCoE Controller and FIP state.
|
||||
* @state: internal FIP state for network link and FIP or non-FIP mode.
|
||||
* @lp: &fc_lport: libfc local port.
|
||||
* @sel_fcf: currently selected FCF, or NULL.
|
||||
* @fcfs: list of discovered FCFs.
|
||||
* @fcf_count: number of discovered FCF entries.
|
||||
* @sol_time: time when a multicast solicitation was last sent.
|
||||
* @sel_time: time after which to select an FCF.
|
||||
* @port_ka_time: time of next port keep-alive.
|
||||
* @ctlr_ka_time: time of next controller keep-alive.
|
||||
* @timer: timer struct used for all delayed events.
|
||||
* @link_work: &work_struct for doing FCF selection.
|
||||
* @recv_work: &work_struct for receiving FIP frames.
|
||||
* @fip_recv_list: list of received FIP frames.
|
||||
* @user_mfs: configured maximum FC frame size, including FC header.
|
||||
* @flogi_oxid: exchange ID of most recent fabric login.
|
||||
* @flogi_count: number of FLOGI attempts in AUTO mode.
|
||||
* @link: current link status for libfc.
|
||||
* @last_link: last link state reported to libfc.
|
||||
* @map_dest: use the FC_MAP mode for destination MAC addresses.
|
||||
* @dest_addr: MAC address of the selected FC forwarder.
|
||||
* @ctl_src_addr: the native MAC address of our local port.
|
||||
* @data_src_addr: the assigned MAC address for the local port after FLOGI.
|
||||
* @send: LLD-supplied function to handle sending of FIP Ethernet frames.
|
||||
* @update_mac: LLD-supplied function to handle changes to MAC addresses.
|
||||
* @lock: lock protecting this structure.
|
||||
*
|
||||
* This structure is used by all FCoE drivers. It contains information
|
||||
* needed by all FCoE low-level drivers (LLDs) as well as internal state
|
||||
* for FIP, and fields shared with the LLDS.
|
||||
*/
|
||||
struct fcoe_softc {
|
||||
struct list_head list;
|
||||
struct fcoe_ctlr {
|
||||
enum fip_state state;
|
||||
struct fc_lport *lp;
|
||||
struct net_device *real_dev;
|
||||
struct net_device *phys_dev; /* device with ethtool_ops */
|
||||
struct packet_type fcoe_packet_type;
|
||||
struct sk_buff_head fcoe_pending_queue;
|
||||
u8 fcoe_pending_queue_active;
|
||||
|
||||
struct fcoe_fcf *sel_fcf;
|
||||
struct list_head fcfs;
|
||||
u16 fcf_count;
|
||||
unsigned long sol_time;
|
||||
unsigned long sel_time;
|
||||
unsigned long port_ka_time;
|
||||
unsigned long ctlr_ka_time;
|
||||
struct timer_list timer;
|
||||
struct work_struct link_work;
|
||||
struct work_struct recv_work;
|
||||
struct sk_buff_head fip_recv_list;
|
||||
u16 user_mfs;
|
||||
u16 flogi_oxid;
|
||||
u8 flogi_count;
|
||||
u8 link;
|
||||
u8 last_link;
|
||||
u8 map_dest;
|
||||
u8 dest_addr[ETH_ALEN];
|
||||
u8 ctl_src_addr[ETH_ALEN];
|
||||
u8 data_src_addr[ETH_ALEN];
|
||||
/*
|
||||
* fcoe protocol address learning related stuff
|
||||
*/
|
||||
u16 flogi_oxid;
|
||||
u8 flogi_progress;
|
||||
u8 address_mode;
|
||||
|
||||
void (*send)(struct fcoe_ctlr *, struct sk_buff *);
|
||||
void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new);
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static inline struct net_device *fcoe_netdev(
|
||||
const struct fc_lport *lp)
|
||||
{
|
||||
return ((struct fcoe_softc *)lport_priv(lp))->real_dev;
|
||||
}
|
||||
/*
|
||||
* struct fcoe_fcf - Fibre-Channel Forwarder.
|
||||
* @list: list linkage.
|
||||
* @time: system time (jiffies) when an advertisement was last received.
|
||||
* @switch_name: WWN of switch from advertisement.
|
||||
* @fabric_name: WWN of fabric from advertisement.
|
||||
* @fc_map: FC_MAP value from advertisement.
|
||||
* @fcf_mac: Ethernet address of the FCF.
|
||||
* @vfid: virtual fabric ID.
|
||||
* @pri: seletion priority, smaller values are better.
|
||||
* @flags: flags received from advertisement.
|
||||
* @fka_period: keep-alive period, in jiffies.
|
||||
*
|
||||
* A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that
|
||||
* passes FCoE frames on to an FC fabric. This structure represents
|
||||
* one FCF from which advertisements have been received.
|
||||
*
|
||||
* When looking up an FCF, @switch_name, @fabric_name, @fc_map, @vfid, and
|
||||
* @fcf_mac together form the lookup key.
|
||||
*/
|
||||
struct fcoe_fcf {
|
||||
struct list_head list;
|
||||
unsigned long time;
|
||||
|
||||
static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct fcoe_hdr *)skb_network_header(skb);
|
||||
}
|
||||
u64 switch_name;
|
||||
u64 fabric_name;
|
||||
u32 fc_map;
|
||||
u16 vfid;
|
||||
u8 fcf_mac[ETH_ALEN];
|
||||
|
||||
static inline int skb_fcoe_offset(const struct sk_buff *skb)
|
||||
{
|
||||
return skb_network_offset(skb);
|
||||
}
|
||||
u8 pri;
|
||||
u16 flags;
|
||||
u32 fka_period;
|
||||
};
|
||||
|
||||
static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct fc_frame_header *)skb_transport_header(skb);
|
||||
}
|
||||
|
||||
static inline int skb_fc_offset(const struct sk_buff *skb)
|
||||
{
|
||||
return skb_transport_offset(skb);
|
||||
}
|
||||
|
||||
static inline void skb_reset_fc_header(struct sk_buff *skb)
|
||||
{
|
||||
skb_reset_network_header(skb);
|
||||
skb_set_transport_header(skb, skb_network_offset(skb) +
|
||||
sizeof(struct fcoe_hdr));
|
||||
}
|
||||
|
||||
static inline bool skb_fc_is_data(const struct sk_buff *skb)
|
||||
{
|
||||
return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA;
|
||||
}
|
||||
|
||||
static inline bool skb_fc_is_cmd(const struct sk_buff *skb)
|
||||
{
|
||||
return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD;
|
||||
}
|
||||
|
||||
static inline bool skb_fc_has_exthdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) ||
|
||||
(skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) ||
|
||||
(skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH);
|
||||
}
|
||||
|
||||
static inline bool skb_fc_is_roff(const struct sk_buff *skb)
|
||||
{
|
||||
return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF;
|
||||
}
|
||||
|
||||
static inline u16 skb_fc_oxid(const struct sk_buff *skb)
|
||||
{
|
||||
return be16_to_cpu(skb_fc_header(skb)->fh_ox_id);
|
||||
}
|
||||
|
||||
static inline u16 skb_fc_rxid(const struct sk_buff *skb)
|
||||
{
|
||||
return be16_to_cpu(skb_fc_header(skb)->fh_rx_id);
|
||||
}
|
||||
/* FIP API functions */
|
||||
void fcoe_ctlr_init(struct fcoe_ctlr *);
|
||||
void fcoe_ctlr_destroy(struct fcoe_ctlr *);
|
||||
void fcoe_ctlr_link_up(struct fcoe_ctlr *);
|
||||
int fcoe_ctlr_link_down(struct fcoe_ctlr *);
|
||||
int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *);
|
||||
void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *);
|
||||
int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa);
|
||||
|
||||
/* libfcoe funcs */
|
||||
int fcoe_reset(struct Scsi_Host *shost);
|
||||
u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
|
||||
unsigned int scheme, unsigned int port);
|
||||
|
||||
u32 fcoe_fc_crc(struct fc_frame *fp);
|
||||
int fcoe_xmit(struct fc_lport *, struct fc_frame *);
|
||||
int fcoe_rcv(struct sk_buff *, struct net_device *,
|
||||
struct packet_type *, struct net_device *);
|
||||
|
||||
int fcoe_percpu_receive_thread(void *arg);
|
||||
void fcoe_clean_pending_queue(struct fc_lport *lp);
|
||||
void fcoe_percpu_clean(struct fc_lport *lp);
|
||||
void fcoe_watchdog(ulong vp);
|
||||
int fcoe_link_ok(struct fc_lport *lp);
|
||||
|
||||
struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
|
||||
int fcoe_hostlist_add(const struct fc_lport *);
|
||||
int fcoe_hostlist_remove(const struct fc_lport *);
|
||||
|
||||
struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int);
|
||||
u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);
|
||||
int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *);
|
||||
|
||||
/* fcoe sw hba */
|
||||
int __init fcoe_sw_init(void);
|
||||
int __exit fcoe_sw_exit(void);
|
||||
#endif /* _LIBFCOE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user