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 sadisc.c
24 * \brief The file implements the functions to do SAS/SATA discovery
25 */
26
27 /******************************************************************************/
28
29 #include <sys/cdefs.h>
30 #include <dev/pms/config.h>
31
32 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
33 #ifdef SA_ENABLE_TRACE_FUNCTIONS
34 #ifdef siTraceFileID
35 #undef siTraceFileID
36 #endif
37 #define siTraceFileID 'C'
38 #endif
39
40 /******************************************************************************/
41 /*! \brief Start/Abort SAS/SATA discovery
42 *
43 * Start/Abort SAS/SATA discovery
44 *
45 * \param agRoot Handles for this instance of SAS/SATA hardware
46 * \param agPortContext Pointer to this instance of port context
47 * \param type Specifies the type(s) of discovery operation to start or cancel
48 * \param option Specified the discovery option
49 *
50 * \return If discovery is started/aborted successfully
51 * - \e AGSA_RC_SUCCESS discovery is started/aborted successfully
52 * - \e AGSA_RC_FAILURE discovery is not started/aborted successfully
53 *
54 */
55 /*******************************************************************************/
saDiscover(agsaRoot_t * agRoot,agsaPortContext_t * agPortContext,bit32 type,bit32 option)56 GLOBAL bit32 saDiscover(
57 agsaRoot_t *agRoot,
58 agsaPortContext_t *agPortContext,
59 bit32 type,
60 bit32 option
61 )
62 {
63 /* Currently not supported */
64 return AGSA_RC_FAILURE;
65 }
66
67 /******************************************************************************/
68 /*! \brief Function for target to remove stale initiator device handle
69 *
70 * function is called to ask the LL layer to remove all LL layer and SPC firmware
71 * internal resources associated with a device handle
72 *
73 * \param agRoot Handles for this instance of SAS/SATA hardware
74 * \param agDevHandle Handle of the device that this I/O request will be made on
75 *
76 * \return If the device handle is removed successfully
77 * - \e AGSA_RC_SUCCESS the device handle is removed successfully
78 * - \e AGSA_RC_BUSY the device is busy, cannot be removed now
79 *
80 */
81 /*******************************************************************************/
saDeregisterDeviceHandle(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaDevHandle_t * agDevHandle,bit32 queueNum)82 GLOBAL bit32 saDeregisterDeviceHandle(
83 agsaRoot_t *agRoot,
84 agsaContext_t *agContext,
85 agsaDevHandle_t *agDevHandle,
86 bit32 queueNum
87 )
88 {
89 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
90 agsaDeviceDesc_t *pDevice;
91 agsaPort_t *pPort;
92 bit32 ret = AGSA_RC_SUCCESS;
93 bit32 deviceid, portid;
94 bit32 deviceIdx;
95
96 OS_ASSERT(agDevHandle != agNULL, "saDeregisterDeviceHandle agDevHandle is NULL");
97
98 smTraceFuncEnter(hpDBG_VERY_LOUD, "za");
99
100 if(agNULL == agDevHandle)
101 {
102 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "za");
103 return AGSA_RC_FAILURE;
104 }
105
106 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
107
108 OS_ASSERT(pDevice != agNULL, "saDeregisterDeviceHandle pDevice is NULL");
109 if(pDevice == agNULL)
110 {
111 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "za");
112 return AGSA_RC_FAILURE;
113 }
114
115 /* find device id */
116 deviceid = pDevice->DeviceMapIndex;
117 deviceIdx = deviceid & DEVICE_ID_BITS;
118 OS_ASSERT(deviceIdx < MAX_IO_DEVICE_ENTRIES, "deviceIdx MAX_IO_DEVICE_ENTRIES");
119 pPort = pDevice->pPort;
120 /* find port id */
121 portid = pPort->portId;
122
123 SA_DBG3(("saDeregisterDeviceHandle: start DeviceHandle %p\n", agDevHandle));
124 SA_DBG1(("saDeregisterDeviceHandle: deviceId 0x%x Device Context %p\n", deviceid, pDevice));
125
126 if ((deviceid != saRoot->DeviceMap[deviceIdx].DeviceIdFromFW) ||
127 (pDevice != saRoot->DeviceMap[deviceIdx].DeviceHandle))
128 {
129 SA_DBG1(("saDeregisterDeviceHandle: Not match failure\n"));
130 ret = AGSA_RC_FAILURE;
131 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "za");
132 return ret;
133 }
134
135 /* Build IOMB and send it to SPC */
136 ret = mpiDeregDevHandleCmd(agRoot, agContext, pDevice, deviceid, portid, queueNum);
137
138 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "za");
139 return ret;
140 }
141
142 /******************************************************************************/
143 /*! \brief Function for target to remove stale initiator device handle
144 *
145 * function is called to ask the LL layer to remove all LL layer internal resources
146 * associated with a device handle
147 *
148 * \param agRoot Handles for this instance of SAS/SATA hardware
149 * \param agDevHandle Handle of the device that this I/O request will be made on
150 *
151 * \return If the device handle is removed successfully
152 * - \e AGSA_RC_SUCCESS the device handle is removed successfully
153 * - \e AGSA_RC_BUSY the device is busy, cannot be removed now
154 *
155 */
156 /*******************************************************************************/
siRemoveDevHandle(agsaRoot_t * agRoot,agsaDevHandle_t * agDevHandle)157 GLOBAL bit32 siRemoveDevHandle(
158 agsaRoot_t *agRoot,
159 agsaDevHandle_t *agDevHandle
160 )
161 {
162 agsaDeviceDesc_t *pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
163 agsaPort_t *pPort;
164 bit32 ret = AGSA_RC_SUCCESS;
165
166 OS_ASSERT(pDevice != agNULL, "siRemoveDevHandle is NULL");
167 smTraceFuncEnter(hpDBG_VERY_LOUD,"zb");
168
169 if (pDevice == agNULL)
170 {
171 SA_DBG1(("siRemoveDevHandle: pDevice is NULL \n"));
172 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zb");
173 return AGSA_RC_FAILURE;
174 }
175
176 /* If it's to remove an initiator device handle */
177 if ( &(pDevice->initiatorDevHandle) == agDevHandle )
178 {
179 (pDevice->initiatorDevHandle).sdkData = agNULL;
180 }
181 /* If it's to remove an target device handle */
182 else if ( &(pDevice->targetDevHandle) == agDevHandle )
183 {
184 (pDevice->targetDevHandle).sdkData = agNULL;
185 }
186 else
187 {
188 SA_ASSERT(agFALSE, "");
189 }
190
191 /* remove the device descriptor if it doesn't have either initiator handle and target handle */
192 if ( (agNULL == (pDevice->initiatorDevHandle).sdkData)
193 && (agNULL == (pDevice->targetDevHandle).sdkData) )
194 {
195 /* Find the port of the device */
196 pPort = pDevice->pPort;
197
198 /* remove the device descriptor free discover list */
199 switch ( pDevice->deviceType )
200 {
201 case STP_DEVICE: /* fall through */
202 case SSP_SMP_DEVICE:
203 case DIRECT_SATA_DEVICE:
204 {
205 SA_DBG3(("siRemoveDevHandle: remove device context %p\n", pDevice));
206 siPortDeviceRemove(agRoot, pPort, pDevice, agTRUE);
207 break;
208 }
209 default:
210 {
211 SA_DBG1(("siRemoveDevHandle: switch. Not calling siPortDeviceRemove %d\n", pDevice->deviceType));
212 break;
213 }
214 }
215 }
216 else
217 {
218 SA_DBG1(("siRemoveDevHandle: else. Not caling siPortDeviceRemove\n"));
219 }
220 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zb");
221 return ret;
222 }
223
224 /******************************************************************************/
225 /*! \brief Get Device Handles from a specific local port
226 *
227 * Get a Device Handles
228 *
229 * \param agRoot Handles for this instance of SAS/SATA hardware
230 * \param agsaContext Pointer to this API context
231 * \param agPortContext Pointer to this instance of port context
232 * \param flags Device flags
233 * \param agDev[] Pointer of array of device handles
234 * \param MaxDevs Specified Maximum number of Device Handles
235 *
236 * \return If GetDeviceHandles is successfully or failure
237 * - \e AGSA_RC_SUCCESS GetDeviceHandles is successfully
238 * - \e AGSA_RC_FAILURE GetDeviceHandles is not successfully
239 *
240 */
241 /*******************************************************************************/
saGetDeviceHandles(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaPortContext_t * agPortContext,bit32 flags,agsaDevHandle_t * agDev[],bit32 skipCount,bit32 MaxDevs)242 GLOBAL bit32 saGetDeviceHandles(
243 agsaRoot_t *agRoot,
244 agsaContext_t *agContext,
245 bit32 queueNum,
246 agsaPortContext_t *agPortContext,
247 bit32 flags,
248 agsaDevHandle_t *agDev[],
249 bit32 skipCount,
250 bit32 MaxDevs
251 )
252 {
253 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
254 agsaPort_t *pPort = (agsaPort_t *) (agPortContext->sdkData);
255 bit32 portIndex, i;
256 bit32 ret = AGSA_RC_SUCCESS;
257
258 OS_ASSERT(pPort != agNULL, "saGetDeviceHandles is NULL");
259 smTraceFuncEnter(hpDBG_VERY_LOUD,"zc");
260
261 if (pPort == agNULL)
262 {
263 SA_DBG1(("saGetDeviceHandles: pPort is NULL \n"));
264 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zc");
265 return AGSA_RC_FAILURE;
266 }
267
268 SA_DBG1(("saGetDeviceHandles: start portId %d\n", pPort->portId));
269
270 /* save the device handles arrary pointer */
271 for (i = 0; i < MaxDevs; i ++)
272 {
273 saRoot->DeviceHandle[i] = agDev[i];
274 }
275
276 /* send GET_DEVICE_HANDLE IOMB to SPC */
277 portIndex = pPort->portId;
278 mpiGetDeviceHandleCmd(agRoot, agContext, portIndex, flags, MaxDevs, queueNum, skipCount);
279
280 /* return */
281 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zc");
282 return ret;
283 }
284
285 /******************************************************************************/
286 /*! \brief Register New Device from a specific local port
287 *
288 * Register New Device API
289 *
290 * \param agRoot Handles for this instance of SAS/SATA hardware
291 * \param agContext Pointer to this API context
292 * \param agDeviceInfo Pointer to this instance of device info
293 * \param agPortContext Pointer to this instance of port context
294 *
295 * \return If discovery is started/aborted successfully
296 * - \e AGSA_RC_SUCCESS discovery is started/aborted successfully
297 * - \e AGSA_RC_FAILURE discovery is not started/aborted successfully
298 *
299 */
300 /*******************************************************************************/
saRegisterNewDevice(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaDeviceInfo_t * agDeviceInfo,agsaPortContext_t * agPortContext,bit16 hostAssignedDeviceId)301 GLOBAL bit32 saRegisterNewDevice(
302 agsaRoot_t *agRoot,
303 agsaContext_t *agContext,
304 bit32 queueNum,
305 agsaDeviceInfo_t *agDeviceInfo,
306 agsaPortContext_t *agPortContext,
307 bit16 hostAssignedDeviceId
308 )
309 {
310 bit32 ret = AGSA_RC_SUCCESS;
311 agsaRegDevCmd_t payload;
312 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
313 agsaIORequestDesc_t *pRequest;
314 agsaPort_t *pPort = (agsaPort_t *) (agPortContext->sdkData);
315 agsaSASIdentify_t remoteIdentify;
316 bit32 i, phyId, sDTypeRate;
317 agsaDeviceDesc_t *pDevice = agNULL;
318
319 OS_ASSERT(pPort != agNULL, "saRegisterNewDevice is NULL");
320 OS_ASSERT(saRoot != agNULL, "saRoot is NULL");
321 smTraceFuncEnter(hpDBG_VERY_LOUD,"zd");
322
323 if(saRoot == agNULL)
324 {
325 SA_DBG1(("saRegisterNewDevice: saRoot == agNULL\n"));
326 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zd");
327 return(AGSA_RC_FAILURE);
328 }
329
330 if (pPort == agNULL)
331 {
332 SA_DBG1(("saRegisterNewDevice: pPort is NULL \n"));
333 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zd");
334 return AGSA_RC_FAILURE;
335 }
336
337 SA_DBG2(("saRegisterNewDevice: start portId %d Port Context %p\n", pPort->portId, agPortContext));
338
339 SA_DBG2(("saRegisterNewDevice: smpTimeout 0x%x\n", agDeviceInfo->smpTimeout));
340 SA_DBG2(("saRegisterNewDevice: it_NexusTimeout 0x%x\n", agDeviceInfo->it_NexusTimeout));
341 SA_DBG2(("saRegisterNewDevice: firstBurstSize 0x%x\n", agDeviceInfo->firstBurstSize));
342 SA_DBG2(("saRegisterNewDevice: devType_S_Rate 0x%x\n", agDeviceInfo->devType_S_Rate));
343 SA_DBG2(("saRegisterNewDevice: flag 0x%x\n", agDeviceInfo->flag));
344 SA_DBG2(("saRegisterNewDevice: hostAssignedDeviceId 0x%x\n",hostAssignedDeviceId ));
345 SA_DBG2(("saRegisterNewDevice: Addr 0x%02x%02x%02x%02x 0x%02x%02x%02x%02x\n",
346 agDeviceInfo->sasAddressHi[0],agDeviceInfo->sasAddressHi[1],agDeviceInfo->sasAddressHi[2],agDeviceInfo->sasAddressHi[3],
347 agDeviceInfo->sasAddressLo[0],agDeviceInfo->sasAddressLo[1],agDeviceInfo->sasAddressLo[2],agDeviceInfo->sasAddressLo[3] ));
348
349 agDeviceInfo->devType_S_Rate &= DEV_LINK_RATE;
350
351 /*
352 Using agsaDeviceInfo_t, fill in only sas address and device type
353 of identify address frame
354 */
355 si_memset(&remoteIdentify, 0, sizeof(agsaSASIdentify_t));
356 for (i=0;i<4;i++)
357 {
358 remoteIdentify.sasAddressHi[i] = agDeviceInfo->sasAddressHi[i];
359 remoteIdentify.sasAddressLo[i] = agDeviceInfo->sasAddressLo[i];
360 }
361 remoteIdentify.deviceType_addressFrameType = (bit8)(agDeviceInfo->devType_S_Rate & 0xC0);
362
363 /* Get request from free IORequests */
364 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
365 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
366
367 /* If no LL Control request entry available */
368 if ( agNULL == pRequest )
369 {
370 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/
371 if(agNULL != pRequest)
372 {
373 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
374 SA_DBG1(("saRegisterNewDevice, using saRoot->freeReservedRequests\n"));
375 }
376 else
377 {
378 SA_DBG1(("saRegisterNewDevice, No request from free list Not using saRoot->freeReservedRequests\n"));
379 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
380 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "zd");
381 return AGSA_RC_BUSY;
382 }
383 }
384 else
385 {
386 /* If LL Control request entry avaliable */
387 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
388 }
389
390 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
391 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
392 saRoot->IOMap[pRequest->HTag].agContext = agContext;
393 pRequest->valid = agTRUE;
394
395 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
396 /* checking bit5 for SATA direct device */
397 if (!(agDeviceInfo->devType_S_Rate & 0x20))
398 {
399 /* SAS device */
400 /* Add SAS device to the device list */
401 pDevice = siPortSASDeviceAdd(agRoot,
402 pPort,
403 remoteIdentify,
404 agFALSE,
405 agDeviceInfo->smpTimeout,
406 agDeviceInfo->it_NexusTimeout,
407 agDeviceInfo->firstBurstSize,
408 agDeviceInfo->devType_S_Rate,
409 (agDeviceInfo->flag & DEV_INFO_MASK));
410 }
411 else
412 {
413 /* SATA device */
414 /* Add SATA device to the device list */
415 pDevice = siPortSATADeviceAdd(agRoot,
416 pPort,
417 agNULL,
418 agNULL, /* no signature */
419 agFALSE,
420 0,
421 agDeviceInfo->smpTimeout,
422 agDeviceInfo->it_NexusTimeout,
423 agDeviceInfo->firstBurstSize,
424 agDeviceInfo->devType_S_Rate,
425 (agDeviceInfo->flag & DEV_INFO_MASK));
426 }
427
428 SA_DBG1(("saRegisterNewDevice: Device Context %p, TypeRate 0x%x\n", pDevice, agDeviceInfo->devType_S_Rate));
429
430 pRequest->pDevice = pDevice;
431
432 /* adjust the flag bit to build the IOMB; use only bit0 and 1 */
433 sDTypeRate = agDeviceInfo->devType_S_Rate << SHIFT24;
434 sDTypeRate |= (agDeviceInfo->flag & 0x01);
435 /* set AWT flag */
436 sDTypeRate |= (agDeviceInfo->flag & 0x02) << 1;
437
438 /* If the host assigned device ID is used, then set the HA bit. */
439 if ( hostAssignedDeviceId != 0 )
440 {
441 sDTypeRate |= 2;
442 SA_DBG3(("saRegisterNewDevice:hostAssignedDeviceId 0x%x sDTypeRate 0x%x\n",hostAssignedDeviceId,sDTypeRate ));
443 }
444
445 /* Add the MCN field */
446
447 sDTypeRate |= ((agDeviceInfo->flag >> DEV_INFO_MCN_SHIFT) & 0xf) << 4;
448
449 /* Add the IR field */
450 sDTypeRate |= ((agDeviceInfo->flag >> DEV_INFO_IR_SHIFT) & 0x1) << 3;
451
452 /* Add the ATAPI protocol flag */
453 sDTypeRate |= ((agDeviceInfo->flag & ATAPI_DEVICE_FLAG) << SHIFT9 );
454
455 /* Add the AWT flag */
456 sDTypeRate |= (agDeviceInfo->flag & AWT_DEVICE_FLAG) ? (1 << SHIFT2) : 0;
457
458 /* Add the XFER_READY flag */
459 sDTypeRate |= (agDeviceInfo->flag & XFER_RDY_PRIORTY_DEVICE_FLAG) ? (1 << SHIFT31) : 0;
460 if(agDeviceInfo->flag & XFER_RDY_PRIORTY_DEVICE_FLAG)
461 {
462 SA_DBG1(("saRegisterNewDevice: sflag XFER_RDY_PRIORTY_DEVICE_FLAG sDTypeRate 0x%x\n",sDTypeRate ));
463 }
464 #ifdef CCFLAG_FORCE_AWT_ON
465 sDTypeRate |= (1 << SHIFT2);
466 SA_DBG1(("saRegisterNewDevice: Force AWT_DEVICE_FLAG sDTypeRate 0x%x\n",sDTypeRate ));
467 #endif /* CCFLAG_FORCE_AWT_ON */
468
469 /* create payload for IOMB */
470 si_memset(&payload, 0, sizeof(agsaRegDevCmd_t));
471
472 SA_DBG2(("saRegisterNewDevice,flag 0x%08X\n",agDeviceInfo->flag));
473 if ((agDeviceInfo->devType_S_Rate & 0x30) == 0x20)
474 {
475 if(smIS_SPC(agRoot))
476 {
477 /* direct SATA device */
478 phyId = (agDeviceInfo->flag & 0xF0);
479 }
480 else
481 {
482 phyId = (agDeviceInfo->flag & 0xF0) << SHIFT4;
483 }
484 }
485 else
486 {
487 phyId = 0;
488 }
489
490 smTrace(hpDBG_VERY_LOUD,"QQ",phyId);
491 /* TP:QQ phyId */
492 smTrace(hpDBG_VERY_LOUD,"QR",pPort->portId);
493 /* TP:QR portId */
494 smTrace(hpDBG_VERY_LOUD,"QS",sDTypeRate);
495 /* TP:QS sDTypeRate */
496 smTrace(hpDBG_VERY_LOUD,"QT",agDeviceInfo->it_NexusTimeout);
497 /* TP:QT agDeviceInfo->it_NexusTimeout */
498
499 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, phyIdportId), (bit32)(pPort->portId & PORTID_MASK) | phyId);
500 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, dTypeLRateAwtHa), sDTypeRate);
501 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, ITNexusTimeOut), (agDeviceInfo->it_NexusTimeout));
502
503 smTrace(hpDBG_VERY_LOUD,"QT",(bit32)(pPort->portId & PORTID_MASK) | phyId);
504 /* TP:QT phyIdportId */
505 /* no conversion is needed since SAS address is in BE format */
506 payload.sasAddrHi = *(bit32*)agDeviceInfo->sasAddressHi;
507 payload.sasAddrLo = *(bit32*)agDeviceInfo->sasAddressLo;
508
509 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, tag), pRequest->HTag);
510 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, DeviceId), ((bit32)hostAssignedDeviceId) << 16);
511
512 if(smIS_SPC(agRoot))
513 {
514 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SPC_REG_DEV, IOMB_SIZE64, queueNum);
515 }
516 else
517 {
518 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_REG_DEV, IOMB_SIZE64, queueNum);
519 }
520
521 if (AGSA_RC_SUCCESS != ret)
522 {
523 /* return the request to free pool */
524 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
525 /* remove the request from IOMap */
526 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
527 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
528 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
529 pRequest->valid = agFALSE;
530
531 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
532 {
533 SA_DBG1(("saRegisterNewDevice: saving pRequest (%p) for later use\n", pRequest));
534 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
535 }
536 else
537 {
538 /* return the request to free pool */
539 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
540 }
541 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
542 SA_DBG1(("saRegisterNewDevice, sending IOMB failed\n" ));
543 }
544 SA_DBG3(("saRegisterNewDevice: end\n"));
545
546 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "zd");
547 return ret;
548 }
549
550 /******************************************************************************/
551 /*! \brief Register a callback for a specific event
552 *
553 * Register a callback for a Event API
554 *
555 * \param agRoot Handles for this instance of SAS/SATA hardware
556 * \param eventSourceType Event Type
557 * \param callbackPtr Function pointer to OS layer
558 *
559 * \return
560 * - \e AGSA_RC_SUCCESS
561 * - \e AGSA_RC_FAILURE
562 *
563 */
564 /*******************************************************************************/
saRegisterEventCallback(agsaRoot_t * agRoot,bit32 eventSourceType,ossaGenericCB_t callbackPtr)565 GLOBAL bit32 saRegisterEventCallback(
566 agsaRoot_t *agRoot,
567 bit32 eventSourceType,
568 ossaGenericCB_t callbackPtr
569 )
570 {
571 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
572 bit32 ret = AGSA_RC_FAILURE;
573
574 SA_DBG3(("saRegisterEventCallback: start\n"));
575 switch (eventSourceType)
576 {
577 case OSSA_EVENT_SOURCE_DEVICE_HANDLE_ADDED:
578 saRoot->DeviceRegistrationCB = (ossaDeviceRegistrationCB_t)callbackPtr;
579 ret = AGSA_RC_SUCCESS;
580 break;
581 case OSSA_EVENT_SOURCE_DEVICE_HANDLE_REMOVED:
582 saRoot->DeviceDeregistrationCB = (ossaDeregisterDeviceHandleCB_t) callbackPtr;
583 ret = AGSA_RC_SUCCESS;
584 break;
585 default:
586 SA_DBG1(("saRegisterEventCallback: not allowed case %d\n", eventSourceType));
587 ret = AGSA_RC_FAILURE;
588 break;
589 }
590 return ret;
591 }
592
593 /******************************************************************************/
594 /*! \brief Get Device Information
595 *
596 * Get SAS/SATA device information API
597 *
598 * \param agRoot Handles for this instance of SAS/SATA hardware
599 * \param option device general information or extended information
600 * \param agDevHandle Pointer of device handle
601 *
602 * \return
603 * - \e AGSA_RC_SUCCESS
604 * - \e AGSA_RC_FAILURE
605 *
606 */
607 /*******************************************************************************/
saGetDeviceInfo(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 option,bit32 queueNum,agsaDevHandle_t * agDevHandle)608 GLOBAL bit32 saGetDeviceInfo(
609 agsaRoot_t *agRoot,
610 agsaContext_t *agContext,
611 bit32 option,
612 bit32 queueNum,
613 agsaDevHandle_t *agDevHandle
614 )
615 {
616 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
617 agsaDeviceDesc_t *pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
618 bit32 deviceid;
619 bit32 ret = AGSA_RC_FAILURE;
620
621 OS_ASSERT(pDevice != agNULL, "saGetDeviceInfo is NULL");
622 smTraceFuncEnter(hpDBG_VERY_LOUD,"ze");
623
624 if (pDevice == agNULL)
625 {
626 SA_DBG1(("saGetDeviceInfo: pDevice is NULL \n"));
627 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "ze");
628 return AGSA_RC_FAILURE;
629 }
630
631 /* Get deviceid */
632 deviceid = pDevice->DeviceMapIndex;
633 SA_DBG3(("saGetDeviceInfo: start pDevice %p, deviceId %d\n", pDevice, deviceid));
634
635 /* verify the agDeviceHandle with the one in the deviceMap */
636 if ((deviceid != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceIdFromFW) ||
637 (pDevice != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceHandle))
638 {
639 SA_DBG1(("saGetDeviceInfo: Not match failure or device not exist\n"));
640 ret = AGSA_RC_FAILURE;
641 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "ze");
642 return ret;
643 }
644
645 /* send IOMB to the SPC */
646 ret = mpiGetDeviceInfoCmd(agRoot, agContext, deviceid, option, queueNum);
647
648 SA_DBG3(("saGetDeviceInfo: end\n"));
649 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "ze");
650 return ret;
651 }
652
653 /******************************************************************************/
654 /*! \brief Set Device Information
655 *
656 * Set SAS/SATA device information API
657 *
658 * \param agRoot Handles for this instance of SAS/SATA hardware
659 * \param agContext Pointer to this API context
660 * \param queueNum IQ/OQ number
661 * \param agDevHandle Pointer of device handle
662 * \param option device general information or extended information
663 * \param param Parameter of Set Device Infomation
664 *
665 * \return
666 * - \e AGSA_RC_SUCCESS
667 * - \e AGSA_RC_FAILURE
668 *
669 */
670 /*******************************************************************************/
saSetDeviceInfo(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaDevHandle_t * agDevHandle,bit32 option,bit32 param,ossaSetDeviceInfoCB_t agCB)671 GLOBAL bit32 saSetDeviceInfo(
672 agsaRoot_t *agRoot,
673 agsaContext_t *agContext,
674 bit32 queueNum,
675 agsaDevHandle_t *agDevHandle,
676 bit32 option,
677 bit32 param,
678 ossaSetDeviceInfoCB_t agCB
679 )
680 {
681 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
682 agsaDeviceDesc_t *pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
683 bit32 deviceid;
684 bit32 ret = AGSA_RC_FAILURE;
685
686 OS_ASSERT(pDevice != agNULL, "saSetDeviceInfo is NULL");
687 smTraceFuncEnter(hpDBG_VERY_LOUD,"zf");
688
689 SA_DBG2(("saSetDeviceInfo: start pDevice %p, option=0x%x param=0x0%x\n", pDevice, option, param));
690 if(agNULL == pDevice )
691 {
692 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zf");
693 return ret;
694 }
695
696
697 /* Get deviceid */
698 deviceid = pDevice->DeviceMapIndex;
699 pDevice->option = option;
700 pDevice->param = param;
701
702 SA_DBG3(("saSetDeviceInfo: deviceId %d\n", deviceid));
703
704 /* verify the agDeviceHandle with the one in the deviceMap */
705 if ((deviceid != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceIdFromFW) ||
706 (pDevice != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceHandle))
707 {
708 SA_DBG1(("saSetDeviceInfo: Not match failure or device not exist\n"));
709 ret = AGSA_RC_FAILURE;
710 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zf");
711 return ret;
712 }
713
714 /* send IOMB to the SPC */
715 ret = mpiSetDeviceInfoCmd(agRoot, agContext, deviceid, option, queueNum, param, agCB);
716
717 SA_DBG3(("saSetDeviceInfo: end\n"));
718 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "zf");
719 return ret;
720 }
721
722 /******************************************************************************/
723 /*! \brief Get Device State
724 *
725 * Get SAS/SATA device state API
726 *
727 * \param agRoot Handles for this instance of SAS/SATA hardware
728 * \param agContext Pointer to this API context
729 * \param queueNum IQ/OQ number
730 * \param agDevHandle Pointer of device handler
731 *
732 * \return
733 * - \e AGSA_RC_SUCCESS
734 * - \e AGSA_RC_FAILURE
735 *
736 */
737 /*******************************************************************************/
saGetDeviceState(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaDevHandle_t * agDevHandle)738 GLOBAL bit32 saGetDeviceState(
739 agsaRoot_t *agRoot,
740 agsaContext_t *agContext,
741 bit32 queueNum,
742 agsaDevHandle_t *agDevHandle
743 )
744 {
745 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
746 agsaDeviceDesc_t *pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
747 bit32 deviceid;
748 bit32 ret = AGSA_RC_FAILURE;
749
750 OS_ASSERT(pDevice != agNULL, "saGetDeviceState is NULL");
751 smTraceFuncEnter(hpDBG_VERY_LOUD,"zg");
752
753 if (pDevice == agNULL)
754 {
755 SA_DBG1(("saGetDeviceState: pDevice is NULL \n"));
756 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zg");
757 return AGSA_RC_FAILURE;
758 }
759
760 SA_DBG3(("saGetDeviceState: start pDevice %p\n", pDevice));
761
762 /* Get deviceid */
763 deviceid = pDevice->DeviceMapIndex;
764
765 /* verify the agDeviceHandle with the one in the deviceMap */
766 if ((deviceid != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceIdFromFW) ||
767 (pDevice != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceHandle))
768 {
769 SA_DBG1(("saGetDeviceState: Not match failure or device not exist\n"));
770 ret = AGSA_RC_FAILURE;
771 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zg");
772 return ret;
773 }
774
775 /* send IOMB to the SPC */
776 ret = mpiGetDeviceStateCmd(agRoot, agContext, deviceid, queueNum);
777
778 SA_DBG3(("saGetDeviceState: end\n"));
779 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "zg");
780 return ret;
781 }
782
783 /******************************************************************************/
784 /*! \brief Set Device State
785 *
786 * Set SAS/SATA device state API
787 *
788 * \param agRoot Handles for this instance of SAS/SATA hardware
789 * \param agContext Pointer to this API context
790 * \param queueNum IQ/OQ number
791 * \param agDevHandle Pointer of device handler
792 * \param newDeviceState new device state
793 *
794 * \return
795 * - \e AGSA_RC_SUCCESS
796 * - \e AGSA_RC_FAILURE
797 *
798 */
799 /*******************************************************************************/
saSetDeviceState(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaDevHandle_t * agDevHandle,bit32 newDeviceState)800 GLOBAL bit32 saSetDeviceState(
801 agsaRoot_t *agRoot,
802 agsaContext_t *agContext,
803 bit32 queueNum,
804 agsaDevHandle_t *agDevHandle,
805 bit32 newDeviceState
806 )
807 {
808 agsaLLRoot_t *saRoot;
809 agsaDeviceDesc_t *pDevice;
810 bit32 deviceid;
811 bit32 ret = AGSA_RC_FAILURE;
812
813 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
814 OS_ASSERT(saRoot != agNULL, "saSetDeviceState saRoot");
815
816 if(saRoot == agNULL )
817 {
818 SA_DBG1(("saSetDeviceState: saRoot is NULL\n"));
819 return ret;
820 }
821
822 OS_ASSERT(agDevHandle != agNULL, "saSetDeviceState agDevHandle is NULL");
823
824 smTraceFuncEnter(hpDBG_VERY_LOUD,"zh");
825
826 if(agDevHandle == agNULL )
827 {
828 SA_DBG1(("saSetDeviceState: agDevHandle is NULL\n"));
829 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zh");
830 return ret;
831 }
832
833 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
834
835 OS_ASSERT(pDevice != agNULL, "saSetDeviceState pDevice is NULL");
836
837 SA_DBG3(("saSetDeviceState: start pDevice %p\n", pDevice));
838
839 if(pDevice == agNULL )
840 {
841 SA_DBG1(("saSetDeviceState: pDevice is NULL\n"));
842 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zh");
843 return ret;
844 }
845 /* Get deviceid */
846 deviceid = pDevice->DeviceMapIndex;
847
848 /* verify the agDeviceHandle with the one in the deviceMap */
849 if ((deviceid != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceIdFromFW) ||
850 (pDevice != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceHandle))
851 {
852 SA_DBG1(("saSetDeviceState: Not match failure or device not exist\n"));
853 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "zh");
854 return ret;
855 }
856
857 /* send IOMB to the SPC */
858 ret = mpiSetDeviceStateCmd(agRoot, agContext, deviceid, newDeviceState, queueNum);
859
860 SA_DBG3(("saSetDeviceState: end\n"));
861 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "zh");
862 return ret;
863 }
864