1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5 *that the following conditions are met:
6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8 *2. Redistributions in binary form must reproduce the above copyright notice,
9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10 *with the distribution.
12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
23 ********************************************************************************/
27 #include <dev/pms/freebsd/driver/common/osenv.h>
28 #include <dev/pms/freebsd/driver/common/ostypes.h>
29 #include <dev/pms/freebsd/driver/common/osdebug.h>
31 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
32 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
33 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
35 #include <dev/pms/RefTisa/discovery/api/dm.h>
36 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
37 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
39 #include <dev/pms/RefTisa/discovery/dm/dmlist.h>
41 #include <dev/pms/RefTisa/tisa/api/tiscsi.h>
46 typedef void (*dmSMPCompleted_t) (
55 /* timer functions ; both I and T */
56 typedef void (*dmTimerCBFunc_t)(dmRoot_t *dmRoot, void *timerData1, void *timerData2, void *timerData3);
59 /** \brief data structure for timer request
60 * Timer requests are enqueued and dequeued using dmList_t
61 * and have a callback function
63 typedef struct dmTimerRequest_s {
64 /* the number of ticks */
69 dmTimerCBFunc_t timerCBFunc;
74 typedef struct dmRootOsData_s {
75 dmRoot_t *dmRoot; /**< Pointer back to dmRoot */
76 void *dmAllShared; /**< Pointer to dmContext_t */
77 void *dmIni; /**< Pointer to SAS/SATA initiator */
80 typedef struct DMSASAddressID_s
82 bit32 sasAddressLo; /**< HOST SAS address lower part */
83 bit32 sasAddressHi; /**< HOST SAS address higher part */
84 bit8 phyIdentifier; /**< PHY IDENTIFIER of the PHY */
89 typedef struct dmDiscovery_s
91 dmList_t discoveringExpanderList;
92 dmList_t UpdiscoveringExpanderList;
93 // tdList_t freeExpanderList;
95 DMSASAddressID_t sasAddressIDDiscoverError;
96 agsaSATAIdentifyData_t *pSataIdentifyData;
97 struct dmExpander_s *RootExp; /* Root expander of discovery */
99 bit32 type; /* discovery type: TDSA_DISCOVERY_OPTION_FULL_START
100 or TDSA_DISCOVERY_OPTION_INCREMENTAL_START*/
102 bit32 configureRouteRetries;
103 bit32 deviceRetistrationRetries;
104 dmTimerRequest_t discoveryTimer;
105 dmTimerRequest_t configureRouteTimer;
106 dmTimerRequest_t deviceRegistrationTimer;
107 dmTimerRequest_t BCTimer; /* Broadcast Change timer for ResetTriggerred */
108 smpRespDiscover_t SMPDiscoverResp;
109 smpRespDiscover2_t SMPDiscover2Resp;
110 bit32 pendingSMP; /* the number of pending SMP for this discovery */
111 bit32 SeenBC; /* received Broadcast change */
112 bit32 forcedOK; /* report DiscOK when chance is missed */
113 dmTimerRequest_t SMPBusyTimer; /* SMP retry timer for saSMPStart busy */
114 bit32 SMPRetries; /* number of SMP retries when LL returns busy for saSMPStart*/
115 bit32 ResetTriggerred; /* Hard/Link reset triggerred by discovery */
116 dmTimerRequest_t DiscoverySMPTimer; /* discovery-related SMP application Timer */
118 bit32 DeferredError; /* Deferred Error for SAS 2 */
119 bit32 ConfiguresOthers; /* exp configures others; no routing configuration */
122 typedef struct dmSASSubID_s
126 bit8 initiator_ssp_stp_smp;
127 bit8 target_ssp_stp_smp;
131 struct dmDeviceData_s;
133 typedef struct dmIntPortContext_s
135 /**< current number of devices in this PortContext */
137 bit32 DiscoveryState;
138 bit32 DiscoveryAbortInProgress;
139 /* passed by tiINIDiscoverTargets()
140 eg) discovery or rediscovery ....
142 bit32 discoveryOptions;
143 /* Discovery ready is given? */
144 bit32 DiscoveryRdyGiven;
145 /* Port has received link up */
148 bit32 numAvailableTargets;
149 /* flag: indicates that discovery is trigggered by tiINIDiscoverTargets */
150 bit32 osInitiatedDiscovery;
152 bit32 id; /* for debugging only */
153 dmList_t FreeLink; /**< free portcontext list */
154 dmList_t MainLink; /**< in-use portcontext list */
155 /**< SAS address of the remote device */
156 bit32 sasRemoteAddressHi; /**< SAS address high part */
157 bit32 sasRemoteAddressLo; /**< SAS address low part */
158 /**< SAS ID frame of the remote device */
159 agsaSASIdentify_t sasIDframe;
161 /**< SAS address of the local device*/
162 bit32 sasLocalAddressHi; /**< SAS address high part */
163 bit32 sasLocalAddressLo; /**< SAS address low part */
165 /**< the list of PhyID belonging to this port */
166 bit8 PhyIDList[DM_MAX_NUM_PHYS];
168 dmPortContext_t *dmPortContext;
172 /* used in tiINIDiscoverTarget() */
174 agsaPortContext_t *agPortContext;
175 /* maybe needs timers for saPhyStart() */
177 bit8 nativeSATAMode; /* boolean flag: whether the port is in Native SATA mode */
178 bit8 remoteSignature[8]; /* the remote signature of the port is the port is in native SATA mode */
180 bit8 directAttatchedSAS; /* boolean flag: whether the port connected directly to SAS end device*/
181 /* SAS/SATA discovery information such as discoveringExpanderList */
182 dmDiscovery_t discovery;
185 bit32 RegisteredDevNums; /* registered number of devices */
186 bit32 eventPhyID; /* used for saHwEventAck() */
187 bit32 Transient; /* transient period between link up and link down/port recovery */
188 bit32 RegFailed; /* Registration of expander belonging to this port failure */
190 } dmIntPortContext_t;
192 typedef struct dmDeviceData_s {
194 dmList_t FreeLink; /* free dev list */
195 dmList_t MainLink; /* main(in use) dev list */
196 dmList_t IncDisLink; /* Used for incremental Discovery only */
197 bit32 id; /* for debugging only */
199 /* used in tiINIIOStart() */
201 // agsaDevHandle_t *agDevHandle;
203 /* for SAS; remote device */
204 // agsaSASDeviceInfo_t agSASDeviceInfo;
205 /* device's sas address */
206 DMSASAddressID_t SASAddressID;
207 bit8 initiator_ssp_stp_smp;
208 bit8 target_ssp_stp_smp;
211 /* SATA specific data */
212 bit8 satSignature[8]; /* SATA device Signature*/
214 /**< pointer to tdsaPortcontext which the device belongs to */
215 struct dmIntPortContext_s *dmPortContext;
216 /* validity of device */
219 bit8 processed; /* used in TD discovery */
223 agsaDeviceInfo_t agDeviceInfo;
224 dmDeviceInfo_t dmDeviceInfo;
225 agsaContext_t agContext; /* used in saRegisterNewDevice()*/
226 /**< pointer to dmExpander if Device is expander */
227 struct dmExpander_s *dmExpander;
228 struct dmDeviceData_s *ExpDevice; /* Expander device which this device is attached to */
230 bit8 phyID; /* PhyID this device is attached to SPC or expander */
231 agsaSASIdentify_t sasIdentify; /* used only in TD discovery */
234 bit8 directlyAttached;
235 bit8 SASSpecDeviceType; /* 0 - 3; SAS_NO_DEVICE - SAS_FANOUT_EXPANDER_DEVICE */
238 agsaContext_t agDeviceResetContext; /* used in saLocalPhyControl() */
239 bit32 TRflag; /* transport recovery flag; used only for tiINITransportRecovery */
240 bit32 ResetCnt; /* number of reset to the device */
241 bit32 registered; /* registered to LL */
242 bit32 reported; /* reproted to TDM */
243 bit32 MCN; /* MCN; initialized to 0; current value in discovery */
244 bit32 MCNDone; /* done in updating MCN */
245 bit32 PrevMCN; /* MCN; initialized to 0; previous value in discovery */
250 typedef struct dmExpander_s
252 /* start of dmDeviceData */
254 dmList_t FreeLink; /* free dev list */
255 dmList_t MainLink; /* main(in use) dev list */
257 bit32 id; /* for debugging only */
258 bit32 InQID; /* Inbound queue ID */
259 bit32 OutQID; /* Outbound queue ID */
261 /* used in tiINIIOStart() */
263 agsaDevHandle_t *agDevHandle;
265 dmList_t linkNode; /**< the link node data structure of the expander */
266 dmList_t upNode; /**< the link node data structure of the expander */
267 dmDeviceData_t *dmDevice; /**< the pointer to the device data */
268 struct dmExpander_s *dmUpStreamExpander; /**< the pointer to the upstream expander device */
269 bit8 hasUpStreamDevice;
270 bit8 discoveringPhyId;
271 bit16 routingIndex; /* maximum routing table index reported by expander */
272 bit16 currentIndex[DM_MAX_EXPANDER_PHYS]; /* routing table index in use */
273 /*ReportPhySataSend in DM */
274 dmDeviceData_t *dmDeviceToProcess; /* on some callbacks, this is a link to the device of interest */
276 bit32 configSASAddressHi;
277 bit32 configSASAddressLo;
278 struct dmExpander_s *dmCurrentDownStreamExpander;
279 bit8 upStreamPhys[DM_MAX_EXPANDER_PHYS];
280 bit16 numOfUpStreamPhys;
281 bit16 currentUpStreamPhyIndex;
282 bit32 upStreamSASAddressHi;
283 bit32 upStreamSASAddressLo;
284 bit32 underDiscovering;
285 bit32 configRouteTable: 1;
286 bit32 configuring: 1;
287 bit32 configReserved: 30;
289 bit32 id; /* for debugging */
291 struct dmExpander_s *dmReturnginExpander;
292 bit8 downStreamPhys[DM_MAX_EXPANDER_PHYS];
293 bit16 numOfDownStreamPhys;
294 bit8 currentDownStreamPhyIndex;
295 bit32 discoverSMPAllowed; /* used only for configurable routers */
296 bit8 routingAttribute[DM_MAX_EXPANDER_PHYS];
297 bit32 configSASAddressHiTable[DM_MAX_DEV];
298 bit32 configSASAddressLoTable[DM_MAX_DEV];
299 bit32 configSASAddrTableIndex;
301 bit32 SAS2; /* supports SAS2 spec of not. The value of LONG RESPONSE
302 in report general response */
303 bit32 TTTSupported; /* Table to Table is supported */
304 bit32 UndoDueToTTTSupported; /* flag that indicates undo exp, device, route
305 configuration due to TTT */
309 typedef struct dmIndirectSMPRequestBody_s {
313 } dmIndirectSMPRequestBody_t;
316 should DM allocate a pool of SMP and manages it
318 depend on ostiAllocMemory()
320 typedef struct dmSMPRequestBody_s {
322 dmSMPCompleted_t SMPCompletionFunc;/* must be the second */
325 tiDeviceHandle_t *tiDevHandle; /* not used for TD generated SMP */
327 agsaIORequest_t agIORequest;
328 agsaSASRequestBody_t agSASRequestBody;
329 agsaSATAInitiatorRequest_t agSATARequestBody;
331 //agsaSMPFrame_t SMPRsp;
332 dmDeviceData_t *dmDevice;
336 // can this be simply dmExpander_t
337 dmDeviceData_t *dmDevice;
338 tiIORequest_t *CurrentTaskTag; /* SMP is used for simulate target reset */
341 // dmExpander_t *dmExpander;
342 dmIntPortContext_t *dmPortContext; /* portcontext where SMP is sent from */
343 bit8 smpPayload[SMP_DIRECT_PAYLOAD_LIMIT]; /* for smp retries;
344 only for direct SMP */
345 bit32 retries; /* number of retries */
346 /* for indirect SMP req/rsp */
348 bit32 IndirectSMPUpper32;
349 bit32 IndirectSMPLower32;
350 /* used only when SMP is INDIRECT SMP request. On SMP completion,
351 this is used to free up INDIRECT SMP response
353 void *IndirectSMPResponse; /* dmSMPRequestBody_t */
358 void *IndirectSMPReqosMemHandle;
359 void *IndirectSMPReq;
360 bit32 IndirectSMPReqLen;
361 bit32 IndirectSMPReqUpper32;
362 bit32 IndirectSMPReqLower32;
363 void *IndirectSMPResposMemHandle;
364 void *IndirectSMPResp;
365 bit32 IndirectSMPRespLen;
366 bit32 IndirectSMPRespUpper32;
367 bit32 IndirectSMPRespLower32;
370 agsaContext_t agContext;
371 } dmSMPRequestBody_t;
374 typedef struct dmIntContext_s {
375 /**< agsaRoot_t->osData points to this */
376 struct dmRootOsData_s dmRootOsData;
380 dmRoot_t dmRootInt; /* for interrupt */
381 dmRoot_t dmRootNonInt; /* for non-interrupt */
386 /**< software-related initialization params used in saInitialize() */
387 dmSwConfig_t SwConfig;
389 /**< timers used commonly in SAS/SATA */
391 /**< pointer to PortContext memory; */
392 dmIntPortContext_t *PortContextMem;
394 dmList_t FreePortContextList;
395 dmList_t MainPortContextList;
397 /**< pointer to Device memory */
398 dmDeviceData_t *DeviceMem;
399 dmList_t FreeDeviceList;
400 dmList_t MainDeviceList;
402 /**< pointer to Expander memory */
403 dmExpander_t *ExpanderMem;
404 dmList_t freeExpanderList;
405 dmList_t mainExpanderList;
407 /**< pointer to SMP command memory */
408 dmSMPRequestBody_t *SMPMem;
409 dmList_t freeSMPList;
411 /**< pointer to Indirect SMP request/repsonse memory */
412 bit8 *IndirectSMPMem;
413 bit32 IndirectSMPUpper32;
414 bit32 IndirectSMPLower32;
415 bit32 itNexusTimeout;
416 bit32 MaxRetryDiscovery;
421 typedef struct dmIntRoot_s
423 /**<< common data structure for SAS/SATA */
424 dmIntContext_t dmAllShared;
427 #endif /* __DMTYPES_H__ */