]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/pms/RefTisa/sat/src/smsathw.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / dev / pms / RefTisa / sat / src / smsathw.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 #include <sys/cdefs.h>
23 __FBSDID("$FreeBSD$");
24 #include <dev/pms/config.h>
25
26 #include <dev/pms/freebsd/driver/common/osenv.h>
27 #include <dev/pms/freebsd/driver/common/ostypes.h>
28 #include <dev/pms/freebsd/driver/common/osdebug.h>
29
30 #include <dev/pms/RefTisa/tisa/api/titypes.h>
31
32 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
33 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
34 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
35
36 #include <dev/pms/RefTisa/sat/api/sm.h>
37 #include <dev/pms/RefTisa/sat/api/smapi.h>
38 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
39
40 #include <dev/pms/RefTisa/sat/src/smdefs.h>
41 #include <dev/pms/RefTisa/sat/src/smproto.h>
42 #include <dev/pms/RefTisa/sat/src/smtypes.h>
43
44 /*
45  * This table is used to map LL Layer saSATAStart() status to TISA status.
46  */
47
48
49 FORCEINLINE bit32  
50 smsataLLIOStart(
51                 smRoot_t                  *smRoot, 
52                 smIORequest_t             *smIORequest,
53                 smDeviceHandle_t          *smDeviceHandle,
54                 smScsiInitiatorRequest_t  *smScsiRequest,
55                 smSatIOContext_t          *satIOContext
56                )
57 {
58   smDeviceData_t              *oneDeviceData  = (smDeviceData_t *)smDeviceHandle->smData;
59   smIntRoot_t                 *smIntRoot      = (smIntRoot_t *) smRoot->smData;
60   smIntContext_t              *smAllShared    = (smIntContext_t *)&(smIntRoot->smAllShared);
61   smIORequestBody_t           *smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
62   smDeviceData_t              *pSatDevData   = satIOContext->pSatDevData;
63   smSatInternalIo_t           *satIntIo      = satIOContext->satIntIoContext;
64   agsaRoot_t                  *agRoot        = smAllShared->agRoot;
65   agsaIORequest_t             *agIORequest   = &(smIORequestBody->agIORequest);
66   agsaDevHandle_t             *agDevHandle   = oneDeviceData->agDevHandle;
67   agsaSATAInitiatorRequest_t  *agSATAReq     = &(smIORequestBody->transport.SATA.agSATARequestBody);
68   bit32                       RLERecovery    = agFALSE;
69   bit32                       status         = SM_RC_FAILURE;
70   bit32                       nQNumber       = 0;
71   /* 
72    * If this is a super I/O request, check for optional settings.
73    * Be careful. Use the superRequest pointer for all references 
74    * in this block of code.
75    */
76   agSATAReq->option = 0;
77   if (satIOContext->superIOFlag)
78   {
79     smSuperScsiInitiatorRequest_t *superRequest = (smSuperScsiInitiatorRequest_t *) smScsiRequest;
80
81     if (superRequest->flags & SM_SCSI_INITIATOR_ENCRYPT)
82     {
83       /* Copy all of the relevant encrypt information  */
84       agSATAReq->option |= AGSA_SATA_ENABLE_ENCRYPTION;
85       sm_memcpy(&agSATAReq->encrypt, &superRequest->Encrypt, sizeof(agsaEncrypt_t));
86     }
87     {
88       /* initialize expDataLength */
89       if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA ||  
90           satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT ||
91           satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT )
92       { 
93         smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
94       }
95       else
96       {
97         smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength;
98       }
99           
100       agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength;
101     }
102   } 
103   else
104   {
105     /* initialize expDataLength */
106     if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA ||  
107         satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT ||
108         satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT )
109     { 
110       smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
111     }
112     else
113     {
114       smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength;
115     }
116
117     agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength;
118   }
119
120   if ( (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) && 
121        (satIOContext->pFis->h.command == SAT_READ_LOG_EXT) )
122   {
123      RLERecovery = agTRUE;
124   }
125
126   /* check max io, be sure to free */
127   if ( (pSatDevData->satDriveState != SAT_DEV_STATE_IN_RECOVERY) ||
128        (RLERecovery == agTRUE) )  
129   {
130     if (RLERecovery == agFALSE) /* RLE is not checked against pending IO's */
131     {
132 #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
133       bit32 volatile satPendingNCQIO = 0;
134       bit32 volatile satPendingNONNCQIO = 0;
135       bit32 volatile satPendingIO = 0;
136
137       tdsmInterlockedExchange(smRoot, &satPendingNCQIO, pSatDevData->satPendingNCQIO);
138       tdsmInterlockedExchange(smRoot, &satPendingNONNCQIO, pSatDevData->satPendingNONNCQIO);
139       tdsmInterlockedExchange(smRoot, &satPendingIO, pSatDevData->satPendingIO);
140 #endif
141     
142       if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
143            (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
144       {
145       #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
146         if ( satPendingNCQIO >= pSatDevData->satNCQMaxIO ||
147              satPendingNONNCQIO != 0)
148         {
149           SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id));
150           SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 
151                     satPendingNONNCQIO, satPendingIO));
152           /* free resource */
153           smsatFreeIntIoResource( smRoot,
154                                   pSatDevData,
155                                   satIntIo); 
156           return SM_RC_DEVICE_BUSY;
157         }
158       #else
159         tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
160         if (pSatDevData->satPendingNCQIO >= pSatDevData->satNCQMaxIO ||
161             pSatDevData->satPendingNONNCQIO != 0)
162         {
163           SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id));
164           SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 
165                     pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
166           tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
167           /* free resource */
168           smsatFreeIntIoResource( smRoot,
169                                   pSatDevData,
170                                   satIntIo); 
171           return SM_RC_DEVICE_BUSY;
172         }
173         tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
174       #endif
175       
176       }
177       else if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_D2H_PKT) ||
178                 (satIOContext->reqType == AGSA_SATA_PROTOCOL_H2D_PKT) ||
179                 (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_PKT) )
180       {
181         sm_memcpy(agSATAReq->scsiCDB, smScsiRequest->scsiCmnd.cdb, 16);    
182       #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
183         if ( satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX ||
184              satPendingNCQIO != 0)
185         {
186           SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id));
187           SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 
188                     satPendingNONNCQIO, satPendingIO));
189           /* free resource */
190           smsatFreeIntIoResource( smRoot,
191                                   pSatDevData,
192                                   satIntIo); 
193           return SM_RC_DEVICE_BUSY;
194         }
195       #else
196         tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
197         if ( pSatDevData->satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX ||
198              pSatDevData->satPendingNCQIO != 0)
199         {
200           SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id));
201           SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 
202                     pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
203           tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
204           /* free resource */
205           smsatFreeIntIoResource( smRoot,
206                                   pSatDevData,
207                                   satIntIo); 
208           return SM_RC_DEVICE_BUSY;
209         }
210         tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
211       #endif
212       
213       }
214       else
215       {
216 #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
217         if ( satPendingNONNCQIO >= SAT_NONNCQ_MAX ||
218              satPendingNCQIO != 0)
219         {
220           SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id));
221           SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 
222                     satPendingNONNCQIO, satPendingIO));
223           /* free resource */
224           smsatFreeIntIoResource( smRoot,
225                                   pSatDevData,
226                                   satIntIo); 
227           return SM_RC_DEVICE_BUSY;
228         }
229 #else
230         tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
231         if (pSatDevData->satPendingNONNCQIO >= SAT_NONNCQ_MAX ||
232             pSatDevData->satPendingNCQIO != 0)
233         {
234           SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id));
235           SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 
236                     pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
237           tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
238           /* free resource */
239           smsatFreeIntIoResource( smRoot,
240                                   pSatDevData,
241                                   satIntIo); 
242           return SM_RC_DEVICE_BUSY;
243         }
244         tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
245 #endif
246       }
247     } /* RLE */
248     /* for internal SATA command only */
249     if (satIOContext->satOrgIOContext != agNULL)
250     {  
251       /* Initialize tiIORequest */
252       smIORequestBody->smIORequest = smIORequest;
253       if (smIORequest == agNULL)
254       {
255         SM_DBG1(("smsataLLIOStart: 1 check!!!\n"));
256       }
257     }
258     /* Initialize tiDevhandle */
259     smIORequestBody->smDevHandle = smDeviceHandle;
260        
261     /* Initializes Scatter Gather and ESGL */
262     status = smsatIOPrepareSGL( smRoot, 
263                                 smIORequestBody, 
264                                 &smScsiRequest->smSgl1, 
265                                 smScsiRequest->sglVirtualAddr );
266       
267     if (status != SM_RC_SUCCESS)
268     {
269       SM_DBG1(("smsataLLIOStart: can't get SGL!!!\n"));
270       /* free resource */
271       smsatFreeIntIoResource( smRoot,
272                               pSatDevData,
273                               satIntIo);
274       return status;
275     }
276
277     /* Initialize LL Layer agIORequest */    
278     agIORequest->osData = (void *) smIORequestBody;
279     agIORequest->sdkData = agNULL; /* SA takes care of this */
280
281     smIORequestBody->ioStarted = agTRUE;
282     smIORequestBody->ioCompleted = agFALSE;
283
284     /* assign tag value for SATA */
285     if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
286          (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
287     {
288       if (agFALSE == smsatTagAlloc(smRoot, pSatDevData, &satIOContext->sataTag))
289       {
290         SM_DBG1(("smsataLLIOStart: No more NCQ tag!!!\n"));
291         smIORequestBody->ioStarted = agFALSE;
292         smIORequestBody->ioCompleted = agTRUE;
293         return SM_RC_DEVICE_BUSY;
294       }
295       SM_DBG3(("smsataLLIOStart: ncq tag 0x%x\n",satIOContext->sataTag));
296     }
297     else
298     {
299       satIOContext->sataTag = 0xFF;
300     }
301   }
302   else /* AGSA_SATA_PROTOCOL_SRST_ASSERT or AGSA_SATA_PROTOCOL_SRST_DEASSERT 
303           or SAT_CHECK_POWER_MODE as ABORT */
304   {
305     agsaSgl_t          *agSgl;
306   
307     /* for internal SATA command only */
308     if (satIOContext->satOrgIOContext != agNULL)
309     {  
310       /* Initialize tiIORequest */
311       smIORequestBody->smIORequest = smIORequest;
312       if (smIORequest == agNULL)
313       {
314         SM_DBG1(("smsataLLIOStart: 2 check!!!\n"));
315       }
316     }
317     /* Initialize tiDevhandle */
318     smIORequestBody->smDevHandle = smDeviceHandle;
319     
320     
321     smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
322     /* SGL for SATA request */
323     agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl);
324     agSgl->len = 0;
325
326     agSgl->sgUpper = 0;
327     agSgl->sgLower = 0;
328     agSgl->len = 0;
329     SM_CLEAR_ESGL_EXTEND(agSgl->extReserved);
330   
331     /* Initialize LL Layer agIORequest */
332     agIORequest = &(smIORequestBody->agIORequest);
333     agIORequest->osData = (void *) smIORequestBody;
334     agIORequest->sdkData = agNULL; /* SA takes care of this */
335
336     smIORequestBody->ioStarted = agTRUE;
337     smIORequestBody->ioCompleted = agFALSE;
338   
339     /* setting the data length */
340     agSATAReq->dataLength = 0;
341   
342   }
343
344
345   smIORequestBody->reTries = 0;
346   
347 #ifdef TD_INTERNAL_DEBUG
348   smhexdump("smsataLLIOStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 
349   smhexdump("smsataLLIOStart LL", (bit8 *)&agSATAReq->fis.fisRegHostToDev,
350             sizeof(agsaFisRegHostToDevice_t));
351 #endif  
352
353   SM_DBG6(("smsataLLIOStart: agDevHandle %p\n", agDevHandle));
354
355   /* to get better IO performance, rotate the OBQ number on main IO path */
356   if (smScsiRequest == agNULL)
357   {
358     nQNumber = 0;
359   }
360   else
361   {
362     switch (smScsiRequest->scsiCmnd.cdb[0])
363     {
364       case SCSIOPC_READ_10:
365       case SCSIOPC_WRITE_10:
366       case SCSIOPC_READ_6:
367       case SCSIOPC_WRITE_6:
368       case SCSIOPC_READ_12:
369       case SCSIOPC_WRITE_12:
370       case SCSIOPC_READ_16:
371       case SCSIOPC_WRITE_16:
372          nQNumber = tdsmRotateQnumber(smRoot, smDeviceHandle);
373          break;
374
375       default:
376          nQNumber = 0;
377          break;
378     }
379   }
380
381   SM_DBG3(("sataLLIOStart: Lock in\n"));
382   
383 #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
384   if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
385        (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
386   {
387      tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNCQIO); 
388   }
389   else
390   {
391      tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNONNCQIO);
392   }
393   tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingIO);
394 #else
395   tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
396   if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
397        (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
398   {
399      pSatDevData->satPendingNCQIO++;
400   }
401   else
402   {
403      pSatDevData->satPendingNONNCQIO++;
404   }    
405   pSatDevData->satPendingIO++;
406
407   SMLIST_INIT_ELEMENT (&satIOContext->satIoContextLink);
408   SMLIST_ENQUEUE_AT_TAIL (&satIOContext->satIoContextLink, &pSatDevData->satIoLinkList);
409   tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
410 #endif
411   /* post SATA command to low level MPI */
412   status = saSATAStart( agRoot,
413                         agIORequest,
414                         nQNumber,                        
415                         agDevHandle,
416                         satIOContext->reqType,
417                         agSATAReq,
418                         satIOContext->sataTag,
419                         smllSATACompleted
420                         );
421     
422   if (status != AGSA_RC_SUCCESS)
423   {
424     if (status == AGSA_RC_BUSY)
425     {
426       SM_DBG1(("smsataLLIOStart: saSATAStart busy!!!\n")); 
427       status = SM_RC_BUSY;
428     }
429     else
430     {
431       SM_DBG1(("smsataLLIOStart: saSATAStart failed!!!\n"));
432       status = SM_RC_FAILURE;
433     }
434
435     if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
436          (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
437     {
438       smsatTagRelease(smRoot, pSatDevData, satIOContext->sataTag);
439     }
440
441 #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
442     if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
443          (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
444     {
445       tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNCQIO);
446     }
447     else
448     {
449       tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNONNCQIO);
450     }
451     tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingIO);      
452 #else
453     if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
454          (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
455     {
456       tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
457       oneDeviceData->satPendingNCQIO--;
458       oneDeviceData->satPendingIO--;
459       SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink);
460       tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
461     }
462     else
463     {
464       tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
465       oneDeviceData->satPendingNONNCQIO--;
466       oneDeviceData->satPendingIO--;
467       SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink);
468       tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);     
469     }    
470 #endif /* CCFLAG_OPTIMIZE_SAT_LOCK */
471     
472     /* Free the ESGL pages associated with this I/O */
473     smIORequestBody->ioStarted = agFALSE;
474     smIORequestBody->ioCompleted = agTRUE;
475     return (status);
476   }
477   
478   return SM_RC_SUCCESS;
479 }              
480
481
482 osGLOBAL FORCEINLINE bit32 
483 smsatIOPrepareSGL(
484                   smRoot_t                 *smRoot,
485                   smIORequestBody_t        *smIORequestBody,
486                   smSgl_t                  *smSgl1,
487                   void                     *sglVirtualAddr
488                   )
489 {
490   agsaSgl_t          *agSgl;
491   
492   /* Uppper should be zero-out */
493   SM_DBG5(("smsatIOPrepareSGL: start\n"));
494   
495   SM_DBG5(("smsatIOPrepareSGL: smSgl1->upper %d smSgl1->lower %d smSgl1->len %d\n", 
496     smSgl1->upper, smSgl1->lower, smSgl1->len));
497   SM_DBG5(("smsatIOPrepareSGL: smSgl1->type %d\n", smSgl1->type)); 
498
499   /* SGL for SATA request */
500   agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl);
501   agSgl->len = 0;
502
503   if (smSgl1 == agNULL)
504   {
505     SM_DBG1(("smsatIOPrepareSGL: Error smSgl1 is NULL!!!\n"));
506     return tiError;
507   }
508
509   if (smIORequestBody->IOType.InitiatorRegIO.expDataLength == 0)
510   {
511     SM_DBG3(("smsatIOPrepareSGL: expDataLength is 0\n"));
512     agSgl->sgUpper = 0;
513     agSgl->sgLower = 0;
514     agSgl->len = 0;
515     SM_CLEAR_ESGL_EXTEND(agSgl->extReserved);
516     return SM_RC_SUCCESS;
517   }
518
519   agSgl->sgUpper = smSgl1->upper;
520   agSgl->sgLower = smSgl1->lower;
521   agSgl->len = smSgl1->len;
522   agSgl->extReserved = smSgl1->type;
523
524   return SM_RC_SUCCESS;
525
526 }                 
527
528
529
530