/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#ifndef _PMCS_DEF_H
#define _PMCS_DEF_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
} pmcs_dtype_t;
/*
* This structure defines a PHY device that represents what we
* are connected to.
*
* The eight real physical PHYs that are in the PMC8X6G are represented
* as an array of eight of these structures which define what these
* real PHYs are connected to.
*
* Depending upon what is actually connected to each PHY, the
* type set will define what we're connected to. If it is
* a direct SATA connection, the phy will describe a SATA endpoint
* If it is a direct SAS connection, it will describe a SAS
* endpoint.
*
* If it is an EXPANDER, this will describe the edge of an expander.
* As we perform discovery on what is in an EXPANDER we define an
* additional list of phys that represent what the Expander is connected to.
*/
/*
* Number of usecs to wait after last noted activate/deactivate callback
* before possibly restarting discovery
*/
struct pmcs_phy {
/* within PMCS_MAX_DS_RECOVERY_TIME time frame */
struct {
} state;
/*
* Attached port phy mask and target port phymask. With 16 bytes
* we can represent a phymask for anything with up to 64 ports
*/
};
/* maximum number of ds recovery retries (ds_recovery_retries) */
/* max time allowed for successful recovery */
/* ds recovery on same same phy is not allowed within this interval */
/*
* Inbound and Outbound Queue Related Definitions.
*
* The PMC8X6G has a programmable number of inbound and outbound circular
* queues for use in message passing between the host and the PMC8X6G
* (up to 64 queues for the Rev C Chip). This driver does not use all
* possible queues.
*
* Each Queue is given 4K of consistent memory and we set a 64 byte size for
* the queue entry size (this gives us 256 queue entries per queue).
*
* This allocation then continues up a further PMCS_SCRATCH_SIZE bytes
* that the driver uses as a temporary scratch area for things like
* SMP discovery.
*
* This control area looks like this:
*
* Offset What
* ------------------------------------------------
* 0 IQ 0 Consumer Index
* 4 IQ 1 Consumer Index
* 8..255 ...
* 252..255 IQ 63 Consumer Index
* 256 OQ 0 Producer Index
* 260 OQ 1 Producer Index
* 264..259 ....
* 508..511 OQ 63 Producer Index
* 512..512+PMCS_SCRATCH_SIZE-1 Scratch area.
*/
#define IQCI_BASE_OFFSET 0
/*
* Work related structures. Each one of these structures is paired
* with *any* command that is fed to the PMC8X6G via one of the
* Inbound Queues. The work structure has a tag to compare with
* the message that comes back out of an Outbound Queue. The
* work structure also points to the phy which this command is
* tied to. It also has a pointer a callback function (if defined).
* See that TAG Architecture below for the various kinds of
* dispositions of a work structure.
*/
/*
* Work Structure States
*
* NIL -> READY
* READY -> NIL
* READY -> ONCHIP
* ONCHIP -> INTR
* INTR -> READY
* INTR -> NIL
* INTR -> ABORTED
* INTR -> TIMED_OUT
* ABORTED -> NIL
* TIMED_OUT -> NIL
*/
typedef enum {
PMCS_WORK_STATE_NIL = 0,
struct pmcwork {
void *last_ptr;
void *last_arg;
};
/*
* This structure defines a PMC-Sierra defined firmware header.
*/
#pragma pack(4)
typedef struct {
#pragma pack()
/*
* Offlevel work as a bit pattern.
*/
#define PMCS_WORK_DISCOVER 0
/*
* The actual values as they appear in work_flags
*/
/*
* This structure is used by this function to test MPI (and interrupts)
* after MPI has been started to make sure it's working reliably.
*/
typedef struct {
} echo_test_t;
/*
* Tag Architecture. The PMC has 32 bit tags for MPI messages.
* We use this tag this way.
*
* bits what
* ------------------------
* 31 done bit
* 30 non-io cmd bit
* 29..28 tag type
* 27..12 rolling serial number
* 11..0 index into work area to get pmcwork structure
*
* A tag type of NONE means that nobody is waiting on any results,
* so the interrupt code frees the work structure that has this
* tag.
*
* A tag type of CBACK means that the the interrupt handler
* takes the tag 'arg' in the work structure to be a callback
* function pointer (see pmcs_cb_t). The callee is responsible
* for freeing the work structure that has this tag.
*
* A tag type of WAIT means that the issuer of the work needs
* be woken up from interrupt level when the command completes
* (or times out). If work structure tag 'arg' is non-null,
* up to 2*PMCS_QENTRY_SIZE bits of data from the Outbound Queue
* entry may be copied to the area pointed to by 'arg'. This
* allows issuers to get directly at the results of the command
* they issed. The synchronization point for the issuer and the
* interrupt code for command done notification is the setting
* of the 'DONE' bit in the tag as stored in the work structure.
*/
#define PMCS_TAG_TYPE_FREE 0
#define PMCS_TAG_INDEX_SHIFT 0
#define PMCS_TAG_TYPE(x) \
(((x) & PMCS_TAG_TYPE_MASK) >> PMCS_TAG_TYPE_SHIFT)
#define PMCS_TAG_SERNO(x) \
(((x) & PMCS_TAG_SERNO_MASK) >> PMCS_TAG_SERNO_SHIFT)
#define PMCS_TAG_INDEX(x) \
(((x) & PMCS_TAG_INDEX_MASK) >> PMCS_TAG_INDEX_SHIFT)
#define PMCS_TAG_FREE 0
#define PMCS_COMMAND_DONE(x) \
#define PMCS_COMMAND_ACTIVE(x) \
/*
* Miscellaneous Definitions
*/
#define CLEAN_MESSAGE(m, x) { \
int _j = x; \
while (_j < PMCS_MSG_SIZE) { \
m[_j++] = 0; \
} \
}
#define COPY_MESSAGE(t, f, a) { \
int _j; \
} \
while (_j < PMCS_MSG_SIZE) { \
t[_j++] = 0; \
} \
}
p->changed = 1; \
p->enum_attempts = 0
p->changed = 1; \
p->enum_attempts = 0
(PMCS_IOMB_IN_SAS(oq, c))
/*
* Check to see if the requested work bit is set. Either way, the bit will
* be cleared upon return.
*/
/*
* Check to see if the requested work bit is set. The value will not be
* changed in this case. The atomic_xx_nv operations can be quite expensive
* so this should not be used in non-DEBUG code.
*/
#define WAIT_FOR(p, t, r) \
r = 0; \
while (!PMCS_COMMAND_DONE(p)) { \
if (!PMCS_COMMAND_DONE(p) && _ret < 0) { \
r = 1; \
break; \
} \
}
/*
* Signal the next I/O completion thread to start running.
*/
} \
}
/*
*/
/* usecs to SCSA watchdog ticks */
/*
* More misc
*/
#define PMCS_VALID_LINK_RATE(r) \
((r == SAS_LINK_RATE_1_5GBIT) || (r == SAS_LINK_RATE_3GBIT) || \
(r == SAS_LINK_RATE_6GBIT))
/*
*/
((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
/*
*/
typedef struct {
/* Target-specific data */
/* PHY-specific data */
/* Log data */
} pmcs_tbuf_t;
/*
* Firmware event log header format
*/
typedef struct pmcs_fw_event_hdr_s {
/*
* Firmware event log entry format
*/
typedef struct pmcs_fw_event_entry_s {
/*
* Receptacle information
*/
#ifdef __cplusplus
}
#endif
#endif /* _PMCS_DEF_H */