diff options
| author | Matt Jacob <mjacob@FreeBSD.org> | 2006-11-02 03:21:32 +0000 |
|---|---|---|
| committer | Matt Jacob <mjacob@FreeBSD.org> | 2006-11-02 03:21:32 +0000 |
| commit | 10365e5a68725142a2a7effaec46ca1d8f5b273a (patch) | |
| tree | 51750d8ca50a883d32c721be30cbb55cbe2c28c8 /sys/dev/isp/ispvar.h | |
| parent | 657669576694b95bd1ea4df0d3b94b9245f5e1c4 (diff) | |
Notes
Diffstat (limited to 'sys/dev/isp/ispvar.h')
| -rw-r--r-- | sys/dev/isp/ispvar.h | 239 |
1 files changed, 162 insertions, 77 deletions
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index 5ea8e8a7c415..fec8423a2625 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -31,20 +31,24 @@ #define _ISPVAR_H #if defined(__NetBSD__) || defined(__OpenBSD__) +#include <dev/ic/isp_stds.h> #include <dev/ic/ispmbox.h> #endif #ifdef __FreeBSD__ +#include <dev/isp/isp_stds.h> #include <dev/isp/ispmbox.h> #endif #ifdef __linux__ +#include "isp_stds.h" #include "ispmbox.h" #endif #ifdef __svr4__ +#include "isp_stds.h" #include "ispmbox.h" #endif -#define ISP_CORE_VERSION_MAJOR 2 -#define ISP_CORE_VERSION_MINOR 11 +#define ISP_CORE_VERSION_MAJOR 3 +#define ISP_CORE_VERSION_MINOR 0 /* * Vector for bus specific code to provide specific services. @@ -52,17 +56,17 @@ typedef struct ispsoftc ispsoftc_t; struct ispmdvec { int (*dv_rd_isr) - (ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *); - uint16_t (*dv_rd_reg) (ispsoftc_t *, int); - void (*dv_wr_reg) (ispsoftc_t *, int, uint16_t); + (ispsoftc_t *, uint32_t *, uint16_t *, uint16_t *); + uint32_t (*dv_rd_reg) (ispsoftc_t *, int); + void (*dv_wr_reg) (ispsoftc_t *, int, uint32_t); int (*dv_mbxdma) (ispsoftc_t *); int (*dv_dmaset) - (ispsoftc_t *, XS_T *, ispreq_t *, uint16_t *, uint16_t); - void (*dv_dmaclr) (ispsoftc_t *, XS_T *, uint16_t); + (ispsoftc_t *, XS_T *, ispreq_t *, uint32_t *, uint32_t); + void (*dv_dmaclr) (ispsoftc_t *, XS_T *, uint32_t); void (*dv_reset0) (ispsoftc_t *); void (*dv_reset1) (ispsoftc_t *); void (*dv_dregs) (ispsoftc_t *, const char *); - uint16_t *dv_ispfw; /* ptr to f/w */ + void * dv_ispfw; /* ptr to f/w */ uint16_t dv_conf1; uint16_t dv_clock; /* clock frequency */ }; @@ -122,6 +126,7 @@ struct ispmdvec { #define SYNC_SFORDEV 2 /* scratch, sync for ISP */ #define SYNC_SFORCPU 3 /* scratch, sync for CPU */ #define SYNC_REG 4 /* for registers */ +#define SYNC_ATIOQ 5 /* atio result queue (24xx) */ /* * Request/Response Queue defines and macros. @@ -148,7 +153,7 @@ struct ispmdvec { #define ISP_ADD_REQUEST(isp, nxti) \ MEMORYBARRIER(isp, SYNC_REQUEST, isp->isp_reqidx, QENTRY_LEN); \ - WRITE_REQUEST_QUEUE_IN_POINTER(isp, nxti); \ + ISP_WRITE(isp, isp->isp_rqstinrp, nxti); \ isp->isp_reqidx = nxti /* @@ -161,6 +166,7 @@ typedef struct { isp_cmd_dma_burst_enable: 1, isp_data_dma_burst_enabl: 1, isp_fifo_threshold : 3, + isp_ptisp : 1, isp_ultramode : 1, isp_diffmode : 1, isp_lvdmode : 1, @@ -222,32 +228,125 @@ typedef struct { /* * Fibre Channel Specifics */ -#define FL_PORT_ID 0x7e /* FL_Port Special ID */ -#define FC_PORT_ID 0x7f /* Fabric Controller Special ID */ -#define FC_SNS_ID 0x80 /* SNS Server Special ID */ +/* These are for 2100/2200/2300 cards */ +#define FL_ID 0x7e /* FL_Port Special ID */ +#define SNS_ID 0x80 /* SNS Server Special ID */ +#define NPH_MAX 0xfe -/* #define ISP_USE_GA_NXT 1 */ /* Use GA_NXT with switches */ -#ifndef GA_NXT_MAX -#define GA_NXT_MAX 256 -#endif +/* These are for 24XX cards */ +#define NPH_RESERVED 0x7F0 /* begin of reserved N-port handles */ +#define NPH_MGT_ID 0x7FA /* Management Server Special ID */ +#define NPH_SNS_ID 0x7FC /* SNS Server Special ID */ +#define NPH_FL_ID 0x7FE /* FL Port Special ID */ +#define NPH_MAX_24XX 0x800 +/* + * Limit for devices on an arbitrated loop. + */ +#define LOCAL_LOOP_LIM 126 + +/* + * Special Port IDs + */ +#define MANAGEMENT_PORT_ID 0xFFFFFA +#define SNS_PORT_ID 0xFFFFFC +#define FABRIC_PORT_ID 0xFFFFFE + + +/* + * FC Port Database entry. + * + * It has a handle that the f/w uses to address commands to a device. + * This handle's value may be assigned by the firmware (e.g., for local loop + * devices) or by the driver (e.g., for fabric devices). + * + * It has a state. If the state if VALID, that means that we've logged into + * the device. We also *may* have a initiator map index entry. This is a value + * from 0..MAX_FC_TARG that is used to index into the isp_ini_map array. If + * the value therein is non-zero, then that value minus one is used to index + * into the Port Database to find the handle for forming commands. There is + * back-index minus one value within to Port Database entry that tells us + * which entry in isp_ini_map points to us (to avoid searching). + * + * Local loop devices the firmware automatically performs PLOGI on for us + * (which is why that handle is imposed upon us). Fabric devices we assign + * a handle to and perform the PLOGI on. + * + * When a PORT DATABASE CHANGED asynchronous event occurs, we mark all VALID + * entries as PROBATIONAL. This allows us, if policy says to, just keep track + * of devices whose handles change but are otherwise the same device (and + * thus keep 'target' constant). + * + * In any case, we search all possible local loop handles. For each one that + * has a port database entity returned, we search for any PROBATIONAL entry + * that matches it and update as appropriate. Otherwise, as a new entry, we + * find room for it in the Port Database. We *try* and use the handle as the + * index to put it into the Database, but that's just an optimization. We mark + * the entry VALID and make sure that the target index is updated and correct. + * + * When we get done searching the local loop, we then search similarily for + * a list of devices we've gotten from the fabric name controller (if we're + * on a fabric). VALID marking is also done similarily. + * + * When all of this is done, we can march through the database and clean up + * any entry that is still PROBATIONAL (these represent devices which have + * departed). Then we're done and can resume normal operations. + * + * Negative invariants that we try and test for are: + * + * + There can never be two non-NIL entries with the same { Port, Node } WWN + * duples. + * + * + There can never be two non-NIL entries with the same handle. + * + * + There can never be two non-NIL entries which have the same ini_map_idx + * value. + */ +typedef struct { + uint16_t handle; + uint16_t ini_map_idx : 12, + autologin : 1, /* F/W does PLOGI/PLOGO */ + state : 3; + uint32_t : 6, + roles : 2, + portid : 24; + uint32_t : 6, + new_roles : 2, + new_portid : 24; + uint64_t node_wwn; + uint64_t port_wwn; +} fcportdb_t; + +#define FC_PORTDB_STATE_NIL 0 +#define FC_PORTDB_STATE_PROBATIONAL 1 +#define FC_PORTDB_STATE_DEAD 2 +#define FC_PORTDB_STATE_CHANGED 3 +#define FC_PORTDB_STATE_NEW 4 +#define FC_PORTDB_STATE_PENDING_VALID 5 +#define FC_PORTDB_STATE_VALID 7 + +/* + * FC card specific information + */ typedef struct { - uint32_t : 13, + uint32_t : 10, + isp_tmode : 1, + isp_2klogin : 1, + isp_sccfw : 1, isp_gbspeed : 3, : 1, - isp_iid_set : 1, - loop_seen_once : 1, + : 1, + : 1, isp_loopstate : 4, /* Current Loop State */ isp_fwstate : 4, /* ISP F/W state */ isp_gotdparms : 1, isp_topo : 3, - isp_onfabric : 1; + loop_seen_once : 1; uint32_t : 8, isp_portid : 24; /* S_ID */ uint16_t isp_fwoptions; uint16_t isp_xfwoptions; uint16_t isp_zfwoptions; - uint16_t isp_iid; /* 'initiator' id */ uint16_t isp_loopid; /* hard loop id */ uint16_t isp_fwattr; /* firmware attributes */ uint16_t isp_execthrottle; @@ -258,34 +357,8 @@ typedef struct { uint16_t isp_maxfrmlen; uint64_t isp_nodewwn; uint64_t isp_portwwn; - /* - * Port Data Base. This is indexed by 'target', which is invariate. - * However, elements within can move around due to loop changes, - * so the actual loop ID passed to the F/W is in this structure. - * The first time the loop is seen up, loopid will match the index - * (except for fabric nodes which are above mapped above FC_SNS_ID - * and are completely virtual), but subsequent LIPs can cause things - * to move around. - */ - struct lportdb { - uint32_t loopid : 16, - : 2, - fc4_type : 4, - last_fabric_dev : 1, - relogin : 1, - force_logout : 1, - was_fabric_dev : 1, - fabric_dev : 1, - loggedin : 1, - roles : 2, - tvalid : 1, - valid : 1; - uint32_t port_type : 8, - portid : 24; - uint64_t node_wwn; - uint64_t port_wwn; - } portdb[MAX_FC_TARG], tport[FC_PORT_ID]; - + fcportdb_t portdb[MAX_FC_TARG]; + uint16_t isp_ini_map[MAX_FC_TARG]; /* * Scratch DMA mapped in area to fetch Port Database stuff, etc. */ @@ -308,10 +381,10 @@ typedef struct { #define LOOP_NIL 0 #define LOOP_LIP_RCVD 1 #define LOOP_PDB_RCVD 2 -#define LOOP_SCANNING_FABRIC 3 -#define LOOP_FSCAN_DONE 4 -#define LOOP_SCANNING_LOOP 5 -#define LOOP_LSCAN_DONE 6 +#define LOOP_SCANNING_LOOP 3 +#define LOOP_LSCAN_DONE 4 +#define LOOP_SCANNING_FABRIC 5 +#define LOOP_FSCAN_DONE 6 #define LOOP_SYNCING_PDB 7 #define LOOP_READY 8 @@ -350,7 +423,7 @@ struct ispsoftc { uint32_t isp_clock : 8, /* input clock */ : 4, - isp_port : 1, /* 23XX only */ + isp_port : 1, /* 23XX/24XX only */ isp_failed : 1, /* board failed */ isp_open : 1, /* opened (ioctl) */ isp_touched : 1, /* board ever seen? */ @@ -361,10 +434,12 @@ struct ispsoftc { uint32_t isp_confopts; /* config options */ - uint16_t isp_rqstinrp; /* register for REQINP */ - uint16_t isp_rqstoutrp; /* register for REQOUTP */ - uint16_t isp_respinrp; /* register for RESINP */ - uint16_t isp_respoutrp; /* register for RESOUTP */ + uint32_t isp_rqstinrp; /* register for REQINP */ + uint32_t isp_rqstoutrp; /* register for REQOUTP */ + uint32_t isp_respinrp; /* register for RESINP */ + uint32_t isp_respoutrp; /* register for RESOUTP */ + uint32_t isp_atioinrp; /* register for ATIOINP */ + uint32_t isp_atiooutrp; /* register for ATIOOUTP */ /* * Instrumentation @@ -388,13 +463,13 @@ struct ispsoftc { isp_sendmarker : 2, /* send a marker entry */ isp_update : 2, /* update parameters */ isp_nactive : 16; /* how many commands active */ - volatile uint16_t isp_reqodx; /* index of last ISP pickup */ - volatile uint16_t isp_reqidx; /* index of next request */ - volatile uint16_t isp_residx; /* index of next result */ - volatile uint16_t isp_resodx; /* index of next result */ - volatile uint16_t isp_rspbsy; - volatile uint16_t isp_lasthdls; /* last handle seed */ - volatile uint16_t isp_obits; /* mailbox command output */ + volatile uint32_t isp_reqodx; /* index of last ISP pickup */ + volatile uint32_t isp_reqidx; /* index of next request */ + volatile uint32_t isp_residx; /* index of next result */ + volatile uint32_t isp_resodx; /* index of next result */ + volatile uint32_t isp_rspbsy; + volatile uint32_t isp_lasthdls; /* last handle seed */ + volatile uint32_t isp_obits; /* mailbox command output */ volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE]; volatile uint16_t isp_lastmbxcmd; /* last mbox command sent */ volatile uint16_t isp_mbxwrk0; @@ -422,6 +497,11 @@ struct ispsoftc { void * isp_result; XS_DMA_ADDR_T isp_rquest_dma; XS_DMA_ADDR_T isp_result_dma; +#ifdef ISP_TARGET_MODE + /* for 24XX only */ + void * isp_atioq; + XS_DMA_ADDR_T isp_atioq_dma; +#endif }; #define SDPARAM(isp) ((sdparam *) (isp)->isp_param) @@ -454,6 +534,7 @@ struct ispsoftc { #define ISP_CFG_OWNFSZ 0x400 /* override NVRAM frame size */ #define ISP_CFG_OWNLOOPID 0x800 /* override NVRAM loopid */ #define ISP_CFG_OWNEXCTHROTTLE 0x1000 /* override NVRAM execution throttle */ +#define ISP_CFG_FOURGB 0x2000 /* force 4GB connection (24XX only) */ /* * Prior to calling isp_reset for the first time, the outer layer @@ -491,6 +572,7 @@ struct ispsoftc { */ #define ISP_CODE_ORG 0x1000 /* default f/w code start */ #define ISP_CODE_ORG_2300 0x0800 /* ..except for 2300s */ +#define ISP_CODE_ORG_2400 0x100000 /* ..and 2400s */ #define ISP_FW_REV(maj, min, mic) ((maj << 24) | (min << 16) | mic) #define ISP_FW_MAJOR(code) ((code >> 24) & 0xff) #define ISP_FW_MINOR(code) ((code >> 16) & 0xff) @@ -501,6 +583,8 @@ struct ispsoftc { #define ISP_FW_MICROX(xp) (xp[2]) #define ISP_FW_NEWER_THAN(i, major, minor, micro) \ (ISP_FW_REVX((i)->isp_fwrev) > ISP_FW_REV(major, minor, micro)) +#define ISP_FW_OLDER_THAN(i, major, minor, micro) \ + (ISP_FW_REVX((i)->isp_fwrev) < ISP_FW_REV(major, minor, micro)) /* * Bus (implementation) types @@ -539,7 +623,6 @@ struct ispsoftc { #define ISP_HA_FC_2312 0x40 #define ISP_HA_FC_2322 0x50 #define ISP_HA_FC_2400 0x60 -#define ISP_HA_FC_2422 0x61 #define IS_SCSI(isp) (isp->isp_type & ISP_HA_SCSI) #define IS_1240(isp) (isp->isp_type == ISP_HA_SCSI_1240) @@ -557,8 +640,8 @@ struct ispsoftc { #define IS_FC(isp) ((isp)->isp_type & ISP_HA_FC) #define IS_2100(isp) ((isp)->isp_type == ISP_HA_FC_2100) #define IS_2200(isp) ((isp)->isp_type == ISP_HA_FC_2200) -#define IS_23XX(isp) \ - ((isp)->isp_type >= ISP_HA_FC_2300 && (isp)->isp_type < ISP_HA_FC_2400) +#define IS_23XX(isp) ((isp)->isp_type >= ISP_HA_FC_2300 && \ + (isp)->isp_type < ISP_HA_FC_2400) #define IS_2300(isp) ((isp)->isp_type == ISP_HA_FC_2300) #define IS_2312(isp) ((isp)->isp_type == ISP_HA_FC_2312) #define IS_2322(isp) ((isp)->isp_type == ISP_HA_FC_2322) @@ -567,10 +650,10 @@ struct ispsoftc { /* * DMA related macros */ -#define DMA_WD3(x) ((((uint64_t)x) >> 48) & 0xffff) -#define DMA_WD2(x) ((((uint64_t)x) >> 32) & 0xffff) -#define DMA_WD1(x) (((x) >> 16) & 0xffff) -#define DMA_WD0(x) (((x) & 0xffff)) +#define DMA_WD3(x) (((uint16_t)(((uint64_t)x) >> 48)) & 0xffff) +#define DMA_WD2(x) (((uint16_t)(((uint64_t)x) >> 32)) & 0xffff) +#define DMA_WD1(x) ((uint16_t)((x) >> 16) & 0xffff) +#define DMA_WD0(x) ((uint16_t)((x) & 0xffff)) #define DMA_LO32(x) ((uint32_t) (x)) #define DMA_HI32(x) ((uint32_t)(((uint64_t)x) >> 32)) @@ -609,7 +692,7 @@ void isp_fw_dump(ispsoftc_t *isp); * semaphore register and first mailbox register (if appropriate). This also * means that most spurious/bogus interrupts not for us can be filtered first. */ -void isp_intr(ispsoftc_t *, uint16_t, uint16_t, uint16_t); +void isp_intr(ispsoftc_t *, uint32_t, uint16_t, uint16_t); /* @@ -672,7 +755,7 @@ typedef enum { ISPCTL_SCAN_LOOP, /* (Re)scan Local Loop */ ISPCTL_PDB_SYNC, /* Synchronize Port Database */ ISPCTL_SEND_LIP, /* Send a LIP */ - ISPCTL_GET_POSMAP, /* Get FC-AL position map */ + ISPCTL_GET_PORTNAME, /* get portname from an N-port handle */ ISPCTL_RUN_MBOXCMD, /* run a mailbox command */ ISPCTL_TOGGLE_TMODE, /* toggle target mode */ ISPCTL_GET_PDB /* get a single port database entry */ @@ -728,8 +811,10 @@ typedef enum { ISPASYNC_LIP, /* LIP Received */ ISPASYNC_LOOP_RESET, /* Loop Reset Received */ ISPASYNC_CHANGE_NOTIFY, /* FC Change Notification */ - ISPASYNC_FABRIC_DEV, /* FC Fabric Device Arrival */ - ISPASYNC_PROMENADE, /* FC Objects coming && going */ + ISPASYNC_DEV_ARRIVED, /* FC Device Arrival */ + ISPASYNC_DEV_CHANGED, /* FC Device Change */ + ISPASYNC_DEV_STAYED, /* FC Device Stayed the Same */ + ISPASYNC_DEV_GONE, /* FC Device Depart */ ISPASYNC_TARGET_NOTIFY, /* target asynchronous notification event */ ISPASYNC_TARGET_ACTION, /* target action requested */ ISPASYNC_CONF_CHANGE, /* Platform Configuration Change */ @@ -804,7 +889,7 @@ int isp_async(ispsoftc_t *, ispasync_t, void *); * of the same object is consistent. * * MBOX_ACQUIRE(ispsoftc_t *) acquire lock on mailbox regs - * MBOX_WAIT_COMPLETE(ispsoftc_t *) wait for mailbox cmd to be done + * MBOX_WAIT_COMPLETE(ispsoftc_t *, mbreg_t *) wait for cmd to be done * MBOX_NOTIFY_COMPLETE(ispsoftc_t *) notification of mbox cmd donee * MBOX_RELEASE(ispsoftc_t *) release lock on mailbox regs * |
