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
21 ********************************************************************************/
22 /*******************************************************************************/
25 * $RCSfile: ttdsmp.c,v $
27 * Copyright 2006 PMC-Sierra, Inc.
31 * $Date: 2012-01-04 19:23:42 -0800 (Wed, 04 Jan 2012) $
33 * This file contains initiator IO related functions in TD layer
53 #ifdef INITIATOR_DRIVER
65 #include <tdsatypes.h>
71 agsaIORequest_t *agIORequest,
73 //agsaSMPFrameHeader_t *agFrameHeader, //(TP)
75 agsaFrameHandle_t agFrameHandle
78 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
79 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
80 ttdsaXchg_t *ttdsaXchg = (ttdsaXchg_t *)agIORequest->osData;
82 /* cf) ttdsaIOCompleted */
83 TI_DBG1(("ttdsaSMPCompleted: start\n"));
86 TI_DBG1(("ttdsaSMPCompleted: tiRoot is NULL, wrong\n"));
90 if (ttdsaXchg == agNULL)
92 TI_DBG1(("ttdsaSMPCompleted: ttdsaXchg is NULL, wrong\n"));
96 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
99 /* to-do: no callback to OS layer */
104 ttdsaNotSupportRespSend(
106 agsaDevHandle_t *agDevHandle,
107 ttdsaXchg_t *ttdsaXchg,
112 agsaSASRequestBody_t *agSASRequestBody;
113 agsaSMPFrame_t *agSMPFrame;
114 agsaIORequest_t *agIORequest;
115 bit8 SMPPayload[SMP_DIRECT_PAYLOAD_LIMIT]; /*(TP)*/
116 tdssSMPFrameHeader_t tdSMPFrameHeader; /*(TP)*/
118 TI_DBG1(("ttdsaNotSupportSend:\n"));
119 agRequestType = AGSA_SMP_TGT_RESPONSE;
121 agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest);
123 agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody);
124 agSMPFrame = &(agSASRequestBody->smpFrame);
126 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); /*(TP)*/
128 /* smp header */ /*(TP)*/
129 tdSMPFrameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
130 tdSMPFrameHeader.smpFunction = smpfn;
131 tdSMPFrameHeader.smpFunctionResult = UNKNOWN_SMP_FUNCTION; /* unknown smp */
132 tdSMPFrameHeader.smpReserved = 0;
135 //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
136 //agSMPFrame->frameHeader.smpFunction = smpfn;
137 //agSMPFrame->frameHeader.smpFunctionResult = UNKNOWN_SMP_FUNCTION; /* unknown smp */
139 osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4); /*TP)*/
141 agSMPFrame->outFrameBuf = SMPPayload; /*(TP)*/
142 agSMPFrame->outFrameAddrUpper32 = ttdsaXchg->smpresp.phyAddrUpper;
143 agSMPFrame->outFrameAddrLower32 = ttdsaXchg->smpresp.phyAddrLower;
144 agSMPFrame->outFrameLen = 0; /* no smp response payload */
146 //agSMPFrame->phyId = ttdsaXchg->SMPphyId;
149 /* not work yet because of high priority q */
162 0, /* queue number */
173 ttdsaDiscoverRespSend(
175 agsaDevHandle_t *agDevHandle,
176 ttdsaXchg_t *ttdsaXchg
180 agsaSASRequestBody_t *agSASRequestBody;
181 agsaSMPFrame_t *agSMPFrame;
182 smpRespDiscover_t *Resp;
184 agsaIORequest_t *agIORequest;
185 bit8 SMPPayload[SMP_DIRECT_PAYLOAD_LIMIT]; /*(TP)*/
186 tdssSMPFrameHeader_t tdSMPFrameHeader; /*(TP)*/
188 TI_DBG1(("ttdsaDiscoverRespSend:\n"));
190 agRequestType = AGSA_SMP_TGT_RESPONSE;
192 SMPResp = (smp_resp_t *)ttdsaXchg->smpresp.virtAddr;
194 agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest);
196 agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody);
197 agSMPFrame = &(agSASRequestBody->smpFrame);
199 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); /*(TP)*/
201 /* smp header */ /*(TP)*/
202 tdSMPFrameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
203 tdSMPFrameHeader.smpFunction = SMP_DISCOVER; /* discover */
204 tdSMPFrameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED;
205 tdSMPFrameHeader.smpReserved = 0;
208 //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
209 //agSMPFrame->frameHeader.smpFunction = SMP_DISCOVER; /* discover */
210 //agSMPFrame->frameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED;
212 osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4); /*TP)*/
214 agSMPFrame->outFrameBuf = SMPPayload; /*(TP)*/
215 agSMPFrame->outFrameAddrUpper32 = ttdsaXchg->smpresp.phyAddrUpper;
216 agSMPFrame->outFrameAddrLower32 = ttdsaXchg->smpresp.phyAddrLower;
217 agSMPFrame->outFrameLen = sizeof(smpRespDiscover_t);
219 //agSMPFrame->phyId = ttdsaXchg->SMPphyId;
221 /* smp response payload */
222 Resp = (smpRespDiscover_t *)&(SMPResp->RespData);
223 osti_memset(Resp, 0, sizeof(smpRespDiscover_t));
224 /* temp, hardcode smp discover response */
225 /* needs to read contents from ID frame */
226 /* assumption: for now, attached to edge expander */
227 Resp->phyIdentifier = 0;
228 Resp->attachedDeviceType = SAS_EDGE_EXPANDER_DEVICE;
229 Resp->negotiatedPhyLinkRate = 0x9; /* enabled, 1.5G */
230 Resp->attached_Ssp_Stp_Smp_Sata_Initiator = 0;
231 Resp->attached_SataPS_Ssp_Stp_Smp_Sata_Target = 0x2; /* SMP target */
232 Resp->sasAddressHi[3] = 0x01;
233 Resp->sasAddressHi[2] = 0x02;
234 Resp->sasAddressHi[1] = 0x03;
235 Resp->sasAddressHi[0] = 0x04;
236 Resp->sasAddressLo[3] = 0x05;
237 Resp->sasAddressLo[2] = 0x06;
238 Resp->sasAddressLo[1] = 0x07;
239 Resp->sasAddressLo[0] = 0x08;
241 Resp->attachedSasAddressHi[3] = 0x01;
242 Resp->attachedSasAddressHi[2] = 0x01;
243 Resp->attachedSasAddressHi[1] = 0x01;
244 Resp->attachedSasAddressHi[0] = 0x01;
245 Resp->attachedSasAddressLo[3] = 0x02;
246 Resp->attachedSasAddressLo[2] = 0x02;
247 Resp->attachedSasAddressLo[1] = 0x02;
248 Resp->attachedSasAddressLo[0] = 0x02;
250 Resp->attachedPhyIdentifier = 0;
251 Resp->programmedAndHardware_MinPhyLinkRate = 0x8; /* not programmable and 1.5 G */
252 Resp->programmedAndHardware_MaxPhyLinkRate = 0x8; /* not programmable and 1.5 G */
253 Resp->phyChangeCount = 0; /* No broadcast(Change) received */
254 Resp->virtualPhy_partialPathwayTimeout = 0x7; /* no virutal phy and see spec 10.4.3.5, p 404 rev 7 */
255 Resp->routingAttribute = 0;
256 osti_memset(&Resp->reserved13, 0, 5);
257 osti_memset(&Resp->vendorSpecific, 0, 2);
260 /* not work yet because of high priority q */
273 0, /* queue number */
284 ttdsaReportGeneralRespSend(
286 agsaDevHandle_t *agDevHandle,
287 ttdsaXchg_t *ttdsaXchg
291 agsaSASRequestBody_t *agSASRequestBody;
292 agsaSMPFrame_t *agSMPFrame;
293 smpRespReportGeneral_t *Resp;
295 agsaIORequest_t *agIORequest;
296 bit8 SMPPayload[SMP_DIRECT_PAYLOAD_LIMIT]; /*(TP)*/
297 tdssSMPFrameHeader_t tdSMPFrameHeader; /*(TP)*/
299 TI_DBG1(("ttdsaReportGeneralRespSend:\n"));
301 agRequestType = AGSA_SMP_TGT_RESPONSE;
303 SMPResp = (smp_resp_t *)ttdsaXchg->smpresp.virtAddr;
305 agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest);
307 agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody);
308 agSMPFrame = &(agSASRequestBody->smpFrame);
310 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); /*(TP)*/
312 tdSMPFrameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
313 tdSMPFrameHeader.smpFunction = SMP_REPORT_GENERAL; /* report general */
314 tdSMPFrameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED;
315 tdSMPFrameHeader.smpReserved = 0;
318 //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
319 //agSMPFrame->frameHeader.smpFunction = SMP_REPORT_GENERAL; /* report general */
320 //agSMPFrame->frameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED;
322 osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4); /*(TP)*/
324 agSMPFrame->outFrameBuf = SMPPayload; /*(TP)*/
325 agSMPFrame->outFrameAddrUpper32 = ttdsaXchg->smpresp.phyAddrUpper;
326 agSMPFrame->outFrameAddrLower32 = ttdsaXchg->smpresp.phyAddrLower;
327 agSMPFrame->outFrameLen = sizeof(smpRespReportGeneral_t);
329 //agSMPFrame->phyId = ttdsaXchg->SMPphyId;
331 /* smp response payload */
332 Resp = (smpRespReportGeneral_t *)&(SMPResp->RespData);
333 osti_memset(Resp, 0, sizeof(smpRespReportGeneral_t));
334 /* temp, hardcode smp general response */
335 Resp->expanderChangeCount16[0] = 1;
336 Resp->expanderRouteIndexes16[0] = 2;
337 Resp->numOfPhys = 0x5; /* 0x1; */
338 Resp->configuring_configurable = 0;
339 tdhexdump("smp general response", (bit8 *)Resp, sizeof(smpRespReportGeneral_t));
342 /* not work yet because of high priority q */
355 0, /* queue number */
369 agsaDevHandle_t *agDevHandle,
370 agsaSMPFrameHeader_t *agFrameHeader,
371 agsaFrameHandle_t agFrameHandle,
376 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
377 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
378 ttdsaXchg_t *ttdsaXchg;
379 tdsaDeviceData_t *oneDeviceData = agNULL;
382 TI_DBG1(("ttdsaSMPReqReceived: start\n"));
384 oneDeviceData = (tdsaDeviceData_t *)agDevHandle->osData;
386 if (oneDeviceData == agNULL)
388 TI_DBG1(("ttdsaSMPReqReceived: no device data\n"));
392 ttdsaXchg = ttdsaXchgGetStruct(agRoot);
394 if (ttdsaXchg == agNULL)
396 TI_DBG1(("ttdsaSMPReqReceived: no free xchg structures\n"));
401 oneDeviceData->agDevHandle = agDevHandle;
402 oneDeviceData->agRoot = agRoot;
404 /* saving the device */
405 ttdsaXchg->DeviceData = oneDeviceData;
407 ttdsaXchg->agRoot = agRoot;
408 ttdsaXchg->tiRoot = tiRoot;
410 ttdsaXchg->SMPRequestBody.agIORequest.sdkData = agNULL;
412 ttdsaXchg->SMPphyId = phyId;
414 switch ( agFrameHeader->smpFunction )
416 case SMP_REPORT_GENERAL:
418 /* must spec p392, rev7*/
419 TI_DBG1(("ttdsaSMPReqReceived: REPORT_GENERAL\n"));
420 ttdsaReportGeneralRespSend(agRoot, agDevHandle, ttdsaXchg);
423 case SMP_REPORT_MANUFACTURE_INFORMATION:
425 /* optional, spec p394, rev7*/
426 TI_DBG1(("ttdsaSMPReqReceived: REPORT_MANUFACTURE_INFORMATION\n"));
427 ttdsaNotSupportRespSend(agRoot, agDevHandle, ttdsaXchg, SMP_REPORT_MANUFACTURE_INFORMATION);
432 /* must, spec p398, rev7*/
433 TI_DBG1(("ttdsaSMPReqReceived: DISCOVER\n"));
434 ttdsaDiscoverRespSend(agRoot, agDevHandle, ttdsaXchg);
439 TI_DBG1(("ttdsaSMPReqReceived: UKNOWN or not yet supported 0x%x\n", agFrameHeader->smpFunction));
440 ttdsaNotSupportRespSend(agRoot, agDevHandle, ttdsaXchg, (bit8) agFrameHeader->smpFunction);