]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdsmp.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / dev / pms / RefTisa / tisa / sassata / sas / tgt / ttdsmp.c
1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved. 
3 *
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
7 *following disclaimer. 
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. 
11 *
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
20
21 ********************************************************************************/
22 /*******************************************************************************/
23 /** \file
24  *
25  * $RCSfile: ttdsmp.c,v $
26  *
27  * Copyright 2006 PMC-Sierra, Inc.
28  *
29  * $Author: hasungwo $
30  * $Revision: 112322 $
31  * $Date: 2012-01-04 19:23:42 -0800 (Wed, 04 Jan 2012) $
32  *
33  * This file contains initiator IO related functions in TD layer
34  *
35  */
36 #include <osenv.h>
37 #include <ostypes.h>
38 #include <osdebug.h>
39
40 #include <sa.h>
41 #include <saapi.h>
42 #include <saosapi.h>
43
44 #include <titypes.h>
45 #include <ostiapi.h>
46 #include <tiapi.h>
47 #include <tiglobal.h>
48
49 #include <tdtypes.h>
50 #include <osstring.h>
51 #include <tdutil.h>
52
53 #ifdef INITIATOR_DRIVER
54 #include <itdtypes.h>
55 #include <itddefs.h>
56 #include <itdglobl.h>
57 #endif
58
59 #ifdef TARGET_DRIVER
60 #include "ttdglobl.h"
61 #include "ttdtxchg.h"
62 #include "ttdtypes.h"
63 #endif
64
65 #include <tdsatypes.h>
66 #include <tdproto.h>
67
68 osGLOBAL void
69 ttdsaSMPCompleted(
70                   agsaRoot_t            *agRoot,
71                   agsaIORequest_t       *agIORequest,
72                   bit32                 agIOStatus,
73                   //agsaSMPFrameHeader_t  *agFrameHeader, //(TP)
74                   bit32                 agIOInfoLen,
75                   agsaFrameHandle_t     agFrameHandle
76                  )
77 {
78   tdsaRootOsData_t       *osData = (tdsaRootOsData_t *)agRoot->osData;
79   tiRoot_t               *tiRoot = (tiRoot_t *)osData->tiRoot;
80   ttdsaXchg_t            *ttdsaXchg    = (ttdsaXchg_t *)agIORequest->osData;
81
82   /* cf) ttdsaIOCompleted */
83   TI_DBG1(("ttdsaSMPCompleted: start\n"));
84   if (tiRoot == agNULL)
85   {
86     TI_DBG1(("ttdsaSMPCompleted: tiRoot is NULL, wrong\n"));
87     return;
88   }
89
90   if (ttdsaXchg == agNULL)
91   {
92     TI_DBG1(("ttdsaSMPCompleted: ttdsaXchg is NULL, wrong\n"));
93     return;
94   }
95
96   ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
97
98
99   /* to-do: no callback to OS layer */
100   return;
101 }
102
103 osGLOBAL void
104 ttdsaNotSupportRespSend(
105                         agsaRoot_t            *agRoot,
106                         agsaDevHandle_t       *agDevHandle,
107                         ttdsaXchg_t           *ttdsaXchg,
108                         bit8                  smpfn
109                         )
110 {
111   bit32                     agRequestType;
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)*/
117
118   TI_DBG1(("ttdsaNotSupportSend:\n"));
119   agRequestType = AGSA_SMP_TGT_RESPONSE;
120
121   agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest);
122
123   agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody);
124   agSMPFrame = &(agSASRequestBody->smpFrame);
125
126   osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t));    /*(TP)*/
127
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;
133
134   /*old*/
135   //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
136   //agSMPFrame->frameHeader.smpFunction = smpfn;
137   //agSMPFrame->frameHeader.smpFunctionResult = UNKNOWN_SMP_FUNCTION; /* unknown smp */
138
139   osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4);            /*TP)*/
140
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 */
145
146   //agSMPFrame->phyId = ttdsaXchg->SMPphyId;
147
148 #ifdef RPM_SOC
149   /* not work yet because of high priority q */
150   saSMPStart(
151              agRoot,
152              agIORequest,
153              agDevHandle,
154              agRequestType,
155              agSASRequestBody,
156              &ossaSMPCompleted
157              );
158 #else
159   saSMPStart(
160              agRoot,
161              agIORequest,
162              0, /* queue number */
163              agDevHandle,
164              agRequestType,
165              agSASRequestBody,
166              &ossaSMPCompleted
167              );
168 #endif
169   return;
170 }
171
172 osGLOBAL void
173 ttdsaDiscoverRespSend(
174                       agsaRoot_t            *agRoot,
175                       agsaDevHandle_t       *agDevHandle,
176                       ttdsaXchg_t           *ttdsaXchg
177                       )
178 {
179   bit32                     agRequestType;
180   agsaSASRequestBody_t      *agSASRequestBody;
181   agsaSMPFrame_t            *agSMPFrame;
182   smpRespDiscover_t         *Resp;
183   smp_resp_t                *SMPResp;
184   agsaIORequest_t           *agIORequest;
185   bit8                       SMPPayload[SMP_DIRECT_PAYLOAD_LIMIT];    /*(TP)*/
186   tdssSMPFrameHeader_t       tdSMPFrameHeader;              /*(TP)*/
187
188   TI_DBG1(("ttdsaDiscoverRespSend:\n"));
189
190   agRequestType = AGSA_SMP_TGT_RESPONSE;
191
192   SMPResp = (smp_resp_t *)ttdsaXchg->smpresp.virtAddr;
193
194   agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest);
195
196   agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody);
197   agSMPFrame = &(agSASRequestBody->smpFrame);
198
199   osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t));    /*(TP)*/
200
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;
206
207   /*old*/
208   //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
209   //agSMPFrame->frameHeader.smpFunction = SMP_DISCOVER; /* discover */
210   //agSMPFrame->frameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED;
211
212   osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4);            /*TP)*/
213
214   agSMPFrame->outFrameBuf = SMPPayload;                 /*(TP)*/
215   agSMPFrame->outFrameAddrUpper32 = ttdsaXchg->smpresp.phyAddrUpper;
216   agSMPFrame->outFrameAddrLower32 = ttdsaXchg->smpresp.phyAddrLower;
217   agSMPFrame->outFrameLen = sizeof(smpRespDiscover_t);
218
219   //agSMPFrame->phyId = ttdsaXchg->SMPphyId;
220
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;
240
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;
249
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);
258
259 #ifdef RPM_SOC
260   /* not work yet because of high priority q */
261   saSMPStart(
262              agRoot,
263              agIORequest,
264              agDevHandle,
265              agRequestType,
266              agSASRequestBody,
267              &ossaSMPCompleted
268              );
269 #else
270   saSMPStart(
271              agRoot,
272              agIORequest,
273              0, /* queue number */
274              agDevHandle,
275              agRequestType,
276              agSASRequestBody,
277              &ossaSMPCompleted
278              );
279 #endif
280   return;
281 }
282
283 osGLOBAL void
284 ttdsaReportGeneralRespSend(
285                            agsaRoot_t            *agRoot,
286                            agsaDevHandle_t       *agDevHandle,
287                            ttdsaXchg_t           *ttdsaXchg
288                            )
289 {
290   bit32                     agRequestType;
291   agsaSASRequestBody_t      *agSASRequestBody;
292   agsaSMPFrame_t            *agSMPFrame;
293   smpRespReportGeneral_t    *Resp;
294   smp_resp_t                *SMPResp;
295   agsaIORequest_t           *agIORequest;
296   bit8                       SMPPayload[SMP_DIRECT_PAYLOAD_LIMIT];    /*(TP)*/
297   tdssSMPFrameHeader_t       tdSMPFrameHeader;              /*(TP)*/
298
299   TI_DBG1(("ttdsaReportGeneralRespSend:\n"));
300
301   agRequestType = AGSA_SMP_TGT_RESPONSE;
302
303   SMPResp = (smp_resp_t *)ttdsaXchg->smpresp.virtAddr;
304
305   agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest);
306
307   agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody);
308   agSMPFrame = &(agSASRequestBody->smpFrame);
309
310   osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t));    /*(TP)*/
311
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;
316
317   /*old*/
318   //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */
319   //agSMPFrame->frameHeader.smpFunction = SMP_REPORT_GENERAL; /* report general */
320   //agSMPFrame->frameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED;
321
322   osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4);            /*(TP)*/
323
324   agSMPFrame->outFrameBuf = SMPPayload;                 /*(TP)*/
325   agSMPFrame->outFrameAddrUpper32 = ttdsaXchg->smpresp.phyAddrUpper;
326   agSMPFrame->outFrameAddrLower32 = ttdsaXchg->smpresp.phyAddrLower;
327   agSMPFrame->outFrameLen = sizeof(smpRespReportGeneral_t);
328
329   //agSMPFrame->phyId = ttdsaXchg->SMPphyId;
330
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));
340
341 #ifdef RPM_SOC
342   /* not work yet because of high priority q */
343   saSMPStart(
344              agRoot,
345              agIORequest,
346              agDevHandle,
347              agRequestType,
348              agSASRequestBody,
349               &ossaSMPCompleted
350              );
351  #else
352   saSMPStart(
353              agRoot,
354              agIORequest,
355              0, /* queue number */
356              agDevHandle,
357              agRequestType,
358              agSASRequestBody,
359              &ossaSMPCompleted
360              );
361 #endif
362   return;
363 }
364
365
366 osGLOBAL void
367 ttdsaSMPReqReceived(
368                     agsaRoot_t            *agRoot,
369                     agsaDevHandle_t       *agDevHandle,
370                     agsaSMPFrameHeader_t  *agFrameHeader,
371                     agsaFrameHandle_t     agFrameHandle,
372                     bit32                 agFrameLength,
373                     bit32                 phyId
374                     )
375 {
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;
380
381
382   TI_DBG1(("ttdsaSMPReqReceived: start\n"));
383
384   oneDeviceData = (tdsaDeviceData_t *)agDevHandle->osData;
385
386   if (oneDeviceData == agNULL)
387   {
388     TI_DBG1(("ttdsaSMPReqReceived: no device data\n"));
389     return;
390   }
391
392   ttdsaXchg = ttdsaXchgGetStruct(agRoot);
393
394   if (ttdsaXchg == agNULL)
395   {
396     TI_DBG1(("ttdsaSMPReqReceived: no free xchg structures\n"));
397     return;
398   }
399
400
401   oneDeviceData->agDevHandle = agDevHandle;
402   oneDeviceData->agRoot = agRoot;
403
404   /* saving the device */
405   ttdsaXchg->DeviceData = oneDeviceData;
406
407   ttdsaXchg->agRoot  = agRoot;
408   ttdsaXchg->tiRoot  = tiRoot;
409
410   ttdsaXchg->SMPRequestBody.agIORequest.sdkData = agNULL;
411
412   ttdsaXchg->SMPphyId = phyId;
413
414   switch ( agFrameHeader->smpFunction )
415   {
416   case SMP_REPORT_GENERAL:
417   {
418     /* must spec p392, rev7*/
419     TI_DBG1(("ttdsaSMPReqReceived: REPORT_GENERAL\n"));
420     ttdsaReportGeneralRespSend(agRoot, agDevHandle, ttdsaXchg);
421     break;
422   }
423   case SMP_REPORT_MANUFACTURE_INFORMATION:
424   {
425     /* optional, spec p394, rev7*/
426     TI_DBG1(("ttdsaSMPReqReceived: REPORT_MANUFACTURE_INFORMATION\n"));
427     ttdsaNotSupportRespSend(agRoot, agDevHandle, ttdsaXchg, SMP_REPORT_MANUFACTURE_INFORMATION);
428     break;
429   }
430   case SMP_DISCOVER:
431   {
432     /* must, spec p398, rev7*/
433     TI_DBG1(("ttdsaSMPReqReceived: DISCOVER\n"));
434     ttdsaDiscoverRespSend(agRoot, agDevHandle, ttdsaXchg);
435     break;
436   }
437   default:
438   {
439     TI_DBG1(("ttdsaSMPReqReceived: UKNOWN or not yet supported 0x%x\n", agFrameHeader->smpFunction));
440     ttdsaNotSupportRespSend(agRoot, agDevHandle, ttdsaXchg, (bit8) agFrameHeader->smpFunction);
441     break;
442   }
443   }
444
445   return;
446 }