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:
Linus Torvalds 2009-04-06 13:24:49 -07:00
Родитель d7ca6f8cdf 015640edb1
Коммит 22eb5aa6c7
88 изменённых файлов: 14192 добавлений и 12471 удалений

Просмотреть файл

@ -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 */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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));

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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(&reg->mailbox0);
barrier();
}
if (cnt == 0)
hw_evt = 1;
/* Wait for soft-reset to complete. */
d2 = RD_REG_DWORD(&reg->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(&reg->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(&reg->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(&reg->isp24.req_q_in, index);
RD_REG_DWORD_RELAXED(&reg->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(&reg->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(&reg->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(&reg->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 = &reg->isp25mq.req_q_in;
req->req_q_out = &reg->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 = &reg->isp25mq.rsp_q_in;
rsp->rsp_q_out = &reg->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(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
RD_REG_DWORD(&reg->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(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
RD_REG_DWORD(&reg->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);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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.
--------------------------------------------------------------------------

Просмотреть файл

@ -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. */

Просмотреть файл

@ -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. */

Просмотреть файл

@ -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. */

Просмотреть файл

@ -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. */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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 */