1 /*******************************************************************************
2 **
3 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
4 *
5 *Redistribution and use in source and binary forms, with or without modification, are permitted provided
6 *that the following conditions are met:
7 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 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 with the distribution.
10 *
11 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
12 *
13 *INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14 *ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
15 *SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16 *OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
17 *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
18 *THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
19 **
20 *******************************************************************************/
21
22 #include <sys/cdefs.h>
23 __FBSDID("$FreeBSD$");
24 #include <dev/pms/config.h>
25
26 #define MAJOR_REVISION 1
27 #define MINOR_REVISION 3
28 #define BUILD_REVISION 10800
29
30 #include <sys/param.h> // defines used in kernel.h
31 #include <sys/ioccom.h>
32 #include <sys/module.h>
33 #include <sys/systm.h>
34 #include <sys/errno.h>
35 #include <sys/kernel.h> // types used in module initialization
36 #include <sys/conf.h> // cdevsw struct
37 #include <sys/uio.h> // uio struct
38 #include <sys/types.h>
39 #include <sys/malloc.h>
40 #include <sys/bus.h> // structs, prototypes for pci bus stuff
41 #include <machine/bus.h>
42 #include <sys/rman.h>
43 #include <machine/resource.h>
44 #include <vm/vm.h> // 1. for vtophys
45 #include <vm/pmap.h> // 2. for vtophys
46 #include <dev/pci/pcivar.h> // For pci_get macros
47 #include <dev/pci/pcireg.h>
48 #include <sys/endian.h>
49 #include <sys/lock.h>
50 #include <sys/mutex.h>
51 #include <sys/sema.h>
52 #include <sys/queue.h>
53 #include <sys/taskqueue.h>
54 #include <machine/atomic.h>
55 #include <sys/libkern.h>
56 #include <cam/cam.h>
57 #include <cam/cam_ccb.h>
58 #include <cam/cam_debug.h>
59 #include <cam/cam_periph.h> //
60 #include <cam/cam_sim.h>
61 #include <cam/cam_xpt_sim.h>
62 #include <cam/scsi/scsi_all.h>
63 #include <cam/scsi/scsi_message.h>
64 #include <sys/systm.h>
65 #include <sys/types.h>
66 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
67 #include <dev/pms/freebsd/driver/ini/src/agtiapi.h>
68 #include <dev/pms/freebsd/driver/ini/src/agtiproto.h>
69 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
70 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
71 #include <dev/pms/freebsd/driver/common/lxencrypt.h>
72
73 MALLOC_DEFINE( M_PMC_MCCB, "CCB List", "CCB List for PMCS driver" );
74
75 MALLOC_DEFINE( M_PMC_MSTL, "STLock malloc",
76 "allocated in agtiapi_attach as memory for lock use" );
77 MALLOC_DEFINE( M_PMC_MDVT, "ag_device_t malloc",
78 "allocated in agtiapi_attach as mem for ag_device_t pDevList" );
79 MALLOC_DEFINE( M_PMC_MPRT, "ag_portal_data_t malloc",
80 "allocated in agtiapi_attach as mem for *pPortalData" );
81 MALLOC_DEFINE( M_PMC_MDEV, "tiDeviceHandle_t * malloc",
82 "allocated in agtiapi_GetDevHandle as local mem for **agDev" );
83 MALLOC_DEFINE( M_PMC_MFLG, "lDevFlags * malloc",
84 "allocated in agtiapi_GetDevHandle as local mem for * flags" );
85 #ifdef LINUX_PERBI_SUPPORT
86 MALLOC_DEFINE( M_PMC_MSLR, "ag_slr_map_t malloc",
87 "mem allocated in agtiapi_attach for pSLRList" );
88 MALLOC_DEFINE( M_PMC_MTGT, "ag_tgt_map_t malloc",
89 "mem allocated in agtiapi_attach for pWWNList" );
90 #endif
91 MALLOC_DEFINE(TEMP,"tempbuff","buffer for payload");
92 MALLOC_DEFINE(TEMP2, "tempbuff", "buffer for agtiapi_getdevlist");
93 STATIC U32 agtiapi_intx_mode = 0;
94 STATIC U08 ag_Perbi = 0;
95 STATIC U32 agtiapi_polling_mode = 0;
96 STATIC U32 ag_card_good = 0; // * total card initialized
97 STATIC U32 ag_option_flag = 0; // * adjustable parameter flag
98 STATIC U32 agtiapi_1st_time = 1;
99 STATIC U32 ag_timeout_secs = 10; //Made timeout equivalent to linux
100
101 U32 gTiDebugLevel = 1;
102 S32 ag_encryption_enable = 0;
103 atomic_t outstanding_encrypted_io_count;
104
105 #define cache_line_size() CACHE_LINE_SIZE
106
107 #define PMCoffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
108
109 #define CPU_TO_LE32(dst, src) \
110 dst.lower = htole32(LOW_32_BITS(src)); \
111 dst.upper = htole32(HIGH_32_BITS(src))
112
113 #define CMND_TO_CHANNEL( ccb ) ( ccb->ccb_h.path_id )
114 #define CMND_TO_TARGET( ccb ) ( ccb->ccb_h.target_id )
115 #define CMND_TO_LUN( ccb ) ( ccb->ccb_h.target_lun )
116
117 STATIC U08 agtiapi_AddrModes[AGTIAPI_MAX_CHANNEL_NUM + 1] =
118 { AGTIAPI_PERIPHERAL };
119
120 #ifdef LINUX_PERBI_SUPPORT
121 // Holding area for target-WWN mapping assignments on the boot line
122 static ag_mapping_t *agMappingList = NULL; // modified by agtiapi_Setup()
123 #endif
124
125 // * For Debugging Purpose
126 #ifdef AGTIAPI_DEBUG
127 #define AGTIAPI_WWN(name, len) wwnprintk(name, len)
128 #else
129 #define AGTIAPI_WWN(name, len)
130 #endif
131
132
133 #define AGTIAPI_WWNPRINTK(name, len, format, a...) \
134 AGTIAPI_PRINTK(format "name ", a); \
135 AGTIAPI_WWN((unsigned char*)name, len);
136
137 #define AGTIAPI_ERR_WWNPRINTK(name, len, format, a...) \
138 printk(KERN_DEBUG format "name ", ## a); \
139 wwnprintk((unsigned char*)name, len);
140 #define AGTIAPI_CPY_DEV_INFO(root, dev, pDev) \
141 tiINIGetDeviceInfo(root, dev, &pDev->devInfo); \
142 wwncpy(pDev);
143
144 #ifdef AGTIAPI_LOCAL_LOCK
145
146 #define AG_CARD_LOCAL_LOCK(lock) ,(lock)
147 #define AG_SPIN_LOCK_IRQ(lock, flags)
148 #define AG_SPIN_UNLOCK_IRQ(lock, flags)
149 #define AG_SPIN_LOCK(lock)
150 #define AG_SPIN_UNLOCK(lock)
151 #define AG_GLOBAL_ARG(arg)
152 #define AG_PERF_SPINLOCK(lock)
153 #define AG_PERF_SPINLOCK_IRQ(lock, flags)
154
155
156 #define AG_LOCAL_LOCK(lock) if (lock) \
157 mtx_lock(lock)
158 #define AG_LOCAL_UNLOCK(lock) if (lock) \
159 mtx_unlock(lock)
160 #define AG_LOCAL_FLAGS(_flags) unsigned long _flags = 0
161 #endif
162
163
164 #define AG_GET_DONE_PCCB(pccb, pmcsc) \
165 { \
166 AG_LOCAL_LOCK(&pmcsc->doneLock); \
167 pccb = pmcsc->ccbDoneHead; \
168 if (pccb != NULL) \
169 { \
170 pmcsc->ccbDoneHead = NULL; \
171 pmcsc->ccbDoneTail = NULL; \
172 AG_LOCAL_UNLOCK(&pmcsc->doneLock); \
173 agtiapi_Done(pmcsc, pccb); \
174 } \
175 else \
176 AG_LOCAL_UNLOCK(&pmcsc->doneLock); \
177 }
178
179 #define AG_GET_DONE_SMP_PCCB(pccb, pmcsc) \
180 { \
181 AG_LOCAL_LOCK(&pmcsc->doneSMPLock); \
182 pccb = pmcsc->smpDoneHead; \
183 if (pccb != NULL) \
184 { \
185 pmcsc->smpDoneHead = NULL; \
186 pmcsc->smpDoneTail = NULL; \
187 AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \
188 agtiapi_SMPDone(pmcsc, pccb); \
189 } \
190 else \
191 AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \
192 }
193
194 #ifdef AGTIAPI_DUMP_IO_DEBUG
195 #define AG_IO_DUMPCCB(pccb) agtiapi_DumpCCB(pccb)
196 #else
197 #define AG_IO_DUMPCCB(pccb)
198 #endif
199
200 #define SCHED_DELAY_JIFFIES 4 /* in seconds */
201
202 #ifdef HOTPLUG_SUPPORT
203 #define AG_HOTPLUG_LOCK_INIT(lock) mxt_init(lock)
204 #define AG_LIST_LOCK(lock) mtx_lock(lock)
205 #define AG_LIST_UNLOCK(lock) mtx_unlock(lock)
206 #else
207 #define AG_HOTPLUG_LOCK_INIT(lock)
208 #define AG_LIST_LOCK(lock)
209 #define AG_LIST_UNLOCK(lock)
210 #endif
211
212 STATIC void agtiapi_CheckIOTimeout(void *data);
213
214
215
216 static ag_card_info_t agCardInfoList[ AGTIAPI_MAX_CARDS ]; // card info list
217 static void agtiapi_cam_action( struct cam_sim *, union ccb * );
218 static void agtiapi_cam_poll( struct cam_sim * );
219
220 // Function prototypes
221 static d_open_t agtiapi_open;
222 static d_close_t agtiapi_close;
223 static d_read_t agtiapi_read;
224 static d_write_t agtiapi_write;
225 static d_ioctl_t agtiapi_CharIoctl;
226 static void agtiapi_async(void *callback_arg, u_int32_t code,
227 struct cam_path *path, void *arg);
228 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth);
229
230 // Character device entry points
231 static struct cdevsw agtiapi_cdevsw = {
232 .d_version = D_VERSION,
233 .d_open = agtiapi_open,
234 .d_close = agtiapi_close,
235 .d_read = agtiapi_read,
236 .d_write = agtiapi_write,
237 .d_ioctl = agtiapi_CharIoctl,
238 .d_name = "pmspcv",
239 };
240
241 U32 maxTargets = 0;
242 U32 ag_portal_count = 0;
243
244 // In the cdevsw routines, we find our softc by using the si_drv1 member
245 // of struct cdev. We set this variable to point to our softc in our
246 // attach routine when we create the /dev entry.
247
agtiapi_open(struct cdev * dev,int oflags,int devtype,struct thread * td)248 int agtiapi_open( struct cdev *dev, int oflags, int devtype, struct thread *td )
249 {
250 struct agtiapi_softc *sc;
251 /* Look up our softc. */
252 sc = dev->si_drv1;
253 AGTIAPI_PRINTK("agtiapi_open\n");
254 AGTIAPI_PRINTK("Opened successfully. sc->my_dev %p\n", sc->my_dev);
255 return( 0 );
256 }
257
agtiapi_close(struct cdev * dev,int fflag,int devtype,struct thread * td)258 int agtiapi_close( struct cdev *dev, int fflag, int devtype, struct thread *td )
259 {
260 struct agtiapi_softc *sc;
261 // Look up our softc
262 sc = dev->si_drv1;
263 AGTIAPI_PRINTK("agtiapi_close\n");
264 AGTIAPI_PRINTK("Closed. sc->my_dev %p\n", sc->my_dev);
265 return( 0 );
266 }
267
agtiapi_read(struct cdev * dev,struct uio * uio,int ioflag)268 int agtiapi_read( struct cdev *dev, struct uio *uio, int ioflag )
269 {
270 struct agtiapi_softc *sc;
271 // Look up our softc
272 sc = dev->si_drv1;
273 AGTIAPI_PRINTK( "agtiapi_read\n" );
274 AGTIAPI_PRINTK( "Asked to read %lu bytes. sc->my_dev %p\n",
275 uio->uio_resid, sc->my_dev );
276 return( 0 );
277 }
278
agtiapi_write(struct cdev * dev,struct uio * uio,int ioflag)279 int agtiapi_write( struct cdev *dev, struct uio *uio, int ioflag )
280 {
281 struct agtiapi_softc *sc;
282 // Look up our softc
283 sc = dev->si_drv1;
284 AGTIAPI_PRINTK( "agtiapi_write\n" );
285 AGTIAPI_PRINTK( "Asked to write %lu bytes. sc->my_dev %p\n",
286 uio->uio_resid, sc->my_dev );
287 return( 0 );
288 }
289
agtiapi_getdevlist(struct agtiapi_softc * pCard,tiIOCTLPayload_t * agIOCTLPayload)290 int agtiapi_getdevlist( struct agtiapi_softc *pCard,
291 tiIOCTLPayload_t *agIOCTLPayload )
292 {
293 tdDeviceListPayload_t *pIoctlPayload =
294 (tdDeviceListPayload_t *) agIOCTLPayload->FunctionSpecificArea;
295 tdDeviceInfoIOCTL_t *pDeviceInfo = NULL;
296 bit8 *pDeviceInfoOrg;
297 tdsaDeviceData_t *pDeviceData = NULL;
298 tiDeviceHandle_t **devList = NULL;
299 tiDeviceHandle_t **devHandleArray = NULL;
300 tiDeviceHandle_t *pDeviceHandle = NULL;
301 bit32 x, memNeeded1;
302 bit32 count, total;
303 bit32 MaxDeviceCount;
304 bit32 ret_val=IOCTL_CALL_INVALID_CODE;
305 ag_portal_data_t *pPortalData;
306 bit8 *pDeviceHandleList = NULL;
307 AGTIAPI_PRINTK( "agtiapi_getdevlist: Enter\n" );
308
309 pDeviceInfoOrg = pIoctlPayload -> pDeviceInfo;
310 MaxDeviceCount = pCard->devDiscover;
311 if (MaxDeviceCount > pIoctlPayload->deviceLength )
312 {
313 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
314 MaxDeviceCount = pIoctlPayload->deviceLength;
315 ret_val = IOCTL_CALL_FAIL;
316 }
317 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
318 memNeeded1 = AG_ALIGNSIZE( MaxDeviceCount * sizeof(tiDeviceHandle_t *),
319 sizeof(void *) );
320 AGTIAPI_PRINTK("agtiapi_getdevlist: portCount %d\n", pCard->portCount);
321 devList = malloc(memNeeded1, TEMP2, M_WAITOK);
322 if (devList == NULL)
323 {
324 AGTIAPI_PRINTK("agtiapi_getdevlist: failed to allocate memory\n");
325 ret_val = IOCTL_CALL_FAIL;
326 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
327 return ret_val;
328 }
329 osti_memset(devList, 0, memNeeded1);
330 pPortalData = &pCard->pPortalData[0];
331 pDeviceHandleList = (bit8*)devList;
332 for (total = x = 0; x < pCard->portCount; x++, pPortalData++)
333 {
334 count = tiINIGetDeviceHandlesForWinIOCTL(&pCard->tiRoot,
335 &pPortalData->portalInfo.tiPortalContext,
336 ( tiDeviceHandle_t **)pDeviceHandleList ,MaxDeviceCount );
337 if (count == DISCOVERY_IN_PROGRESS)
338 {
339 AGTIAPI_PRINTK( "agtiapi_getdevlist: DISCOVERY_IN_PROGRESS on "
340 "portal %d\n", x );
341 free(devList, TEMP2);
342 ret_val = IOCTL_CALL_FAIL;
343 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
344 return ret_val;
345 }
346 total += count;
347 pDeviceHandleList+= count*sizeof(tiDeviceHandle_t *);
348 MaxDeviceCount-= count;
349 }
350 if (total > pIoctlPayload->deviceLength)
351 {
352 total = pIoctlPayload->deviceLength;
353 }
354 // dump device information from device handle list
355 count = 0;
356
357 devHandleArray = devList;
358 for (x = 0; x < pCard->devDiscover; x++)
359 {
360 pDeviceHandle = (tiDeviceHandle_t*)devHandleArray[x];
361 if (devList[x] != agNULL)
362 {
363 pDeviceData = devList [x]->tdData;
364
365 pDeviceInfo = (tdDeviceInfoIOCTL_t*)(pDeviceInfoOrg + sizeof(tdDeviceInfoIOCTL_t) * count);
366 if (pDeviceData != agNULL && pDeviceInfo != agNULL)
367 {
368 osti_memcpy( &pDeviceInfo->sasAddressHi,
369 pDeviceData->agDeviceInfo.sasAddressHi,
370 sizeof(bit32) );
371 osti_memcpy( &pDeviceInfo->sasAddressLo,
372 pDeviceData->agDeviceInfo.sasAddressLo,
373 sizeof(bit32) );
374 #if 0
375 pDeviceInfo->sasAddressHi =
376 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
377 pDeviceInfo->sasAddressLo =
378 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
379 #endif
380
381 pDeviceInfo->deviceType =
382 ( pDeviceData->agDeviceInfo.devType_S_Rate & 0x30 ) >> 4;
383 pDeviceInfo->linkRate =
384 pDeviceData->agDeviceInfo.devType_S_Rate & 0x0F;
385 pDeviceInfo->phyId = pDeviceData->phyID;
386 pDeviceInfo->ishost = pDeviceData->target_ssp_stp_smp;
387 pDeviceInfo->DeviceHandle= (unsigned long)pDeviceHandle;
388 if(pDeviceInfo->deviceType == 0x02)
389 {
390 bit8 *sasAddressHi;
391 bit8 *sasAddressLo;
392 tiIniGetDirectSataSasAddr(&pCard->tiRoot, pDeviceData->phyID, &sasAddressHi, &sasAddressLo);
393 pDeviceInfo->sasAddressHi = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressHi);
394 pDeviceInfo->sasAddressLo = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressLo) + pDeviceData->phyID + 16;
395 }
396 else
397 {
398 pDeviceInfo->sasAddressHi =
399 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
400 pDeviceInfo->sasAddressLo =
401 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
402 }
403
404 AGTIAPI_PRINTK( "agtiapi_getdevlist: devicetype %x\n",
405 pDeviceInfo->deviceType );
406 AGTIAPI_PRINTK( "agtiapi_getdevlist: linkrate %x\n",
407 pDeviceInfo->linkRate );
408 AGTIAPI_PRINTK( "agtiapi_getdevlist: phyID %x\n",
409 pDeviceInfo->phyId );
410 AGTIAPI_PRINTK( "agtiapi_getdevlist: addresshi %x\n",
411 pDeviceInfo->sasAddressHi );
412 AGTIAPI_PRINTK( "agtiapi_getdevlist: addresslo %x\n",
413 pDeviceInfo->sasAddressHi );
414 }
415 else
416 {
417 AGTIAPI_PRINTK( "agtiapi_getdevlist: pDeviceData %p or pDeviceInfo "
418 "%p is NULL %d\n", pDeviceData, pDeviceInfo, x );
419 }
420 count++;
421 }
422 }
423 pIoctlPayload->realDeviceCount = count;
424 AGTIAPI_PRINTK( "agtiapi_getdevlist: Exit RealDeviceCount = %d\n", count );
425 if (devList)
426 {
427 free(devList, TEMP2);
428 }
429 if(ret_val != IOCTL_CALL_FAIL)
430 {
431 ret_val = IOCTL_CALL_SUCCESS;
432 }
433 agIOCTLPayload->Status = IOCTL_ERR_STATUS_OK;
434 return ret_val;
435 }
436
437 /******************************************************************************
438 agtiapi_getCardInfo()
439
440 Purpose:
441 This function retrives the Card information
442 Parameters:
443
444 Return:
445 A number - error
446 0 - HBA has been detected
447 Note:
448 ******************************************************************************/
agtiapi_getCardInfo(struct agtiapi_softc * pCard,U32_64 size,void * buffer)449 int agtiapi_getCardInfo ( struct agtiapi_softc *pCard,
450 U32_64 size,
451 void *buffer )
452 {
453 CardInfo_t *pCardInfo;
454
455 pCardInfo = (CardInfo_t *)buffer;
456
457 pCardInfo->deviceId = pci_get_device(pCard->my_dev);
458 pCardInfo->vendorId =pci_get_vendor(pCard->my_dev) ;
459 memcpy( pCardInfo->pciMemBaseSpc,
460 pCard->pCardInfo->pciMemBaseSpc,
461 ((sizeof(U32_64))*PCI_NUMBER_BARS) );
462 pCardInfo->deviceNum = pci_get_slot(pCard->my_dev);
463 pCardInfo->pciMemBase = pCard->pCardInfo->pciMemBase;
464 pCardInfo->pciIOAddrLow = pCard->pCardInfo->pciIOAddrLow;
465 pCardInfo->pciIOAddrUp = pCard->pCardInfo->pciIOAddrUp;
466 pCardInfo->busNum =pci_get_bus(pCard->my_dev);
467 return 0;
468 }
469
agtiapi_adjust_queue_depth(struct cam_path * path,bit32 QueueDepth)470 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth)
471 {
472 struct ccb_relsim crs;
473 xpt_setup_ccb(&crs.ccb_h, path, 5);
474 crs.ccb_h.func_code = XPT_REL_SIMQ;
475 crs.ccb_h.flags = CAM_DEV_QFREEZE;
476 crs.release_flags = RELSIM_ADJUST_OPENINGS;
477 crs.openings = QueueDepth;
478 xpt_action((union ccb *)&crs);
479 if(crs.ccb_h.status != CAM_REQ_CMP) {
480 printf("XPT_REL_SIMQ failed\n");
481 }
482 }
483 static void
agtiapi_async(void * callback_arg,u_int32_t code,struct cam_path * path,void * arg)484 agtiapi_async(void *callback_arg, u_int32_t code,
485 struct cam_path *path, void *arg)
486 {
487 struct agtiapi_softc *pmsc;
488 U32 TID;
489 ag_device_t *targ;
490 pmsc = (struct agtiapi_softc*)callback_arg;
491 switch (code) {
492 case AC_FOUND_DEVICE:
493 {
494 struct ccb_getdev *cgd;
495 cgd = (struct ccb_getdev *)arg;
496 if (cgd == NULL) {
497 break;
498 }
499 TID = cgd->ccb_h.target_id;
500 if (TID >= 0 && TID < maxTargets){
501 if (pmsc != NULL){
502 TID = INDEX(pmsc, TID);
503 targ = &pmsc->pDevList[TID];
504 agtiapi_adjust_queue_depth(path, targ->qdepth);
505 }
506 }
507 break;
508 }
509 default:
510 break;
511 }
512 }
513 /******************************************************************************
514 agtiapi_CharIoctl()
515
516 Purpose:
517 This function handles the ioctl from application layer
518 Parameters:
519
520 Return:
521 A number - error
522 0 - HBA has been detected
523 Note:
524 ******************************************************************************/
agtiapi_CharIoctl(struct cdev * dev,u_long cmd,caddr_t data,int fflag,struct thread * td)525 static int agtiapi_CharIoctl( struct cdev *dev,
526 u_long cmd,
527 caddr_t data,
528 int fflag,
529 struct thread *td )
530 {
531 struct sema mx;
532 datatosend *load; // structure defined in lxcommon.h
533 tiIOCTLPayload_t *pIoctlPayload;
534 struct agtiapi_softc *pCard;
535 pCard=dev->si_drv1;
536 void *param1 = NULL;
537 void *param2 = NULL;
538 void *param3 = NULL;
539 U32 status = 0;
540 U32 retValue;
541 int err = 0;
542 int error = 0;
543 tdDeviceListPayload_t *pDeviceList = NULL;
544 unsigned long flags;
545
546 switch (cmd)
547 {
548 case AGTIAPI_IOCTL:
549 load=(datatosend*)data;
550 pIoctlPayload = malloc(load->datasize,TEMP,M_WAITOK);
551 AGTIAPI_PRINTK( "agtiapi_CharIoctl: old load->datasize = %d\n", load->datasize );
552 //Copy payload to kernel buffer, on success it returns 0
553 err = copyin(load->data,pIoctlPayload,load->datasize);
554 if (err)
555 {
556 status = IOCTL_CALL_FAIL;
557 return status;
558 }
559 sema_init(&mx,0,"sem");
560 pCard->pIoctlSem =&mx;
561 pCard->up_count = pCard->down_count = 0;
562 if ( pIoctlPayload->MajorFunction == IOCTL_MJ_GET_DEVICE_LIST )
563 {
564 retValue = agtiapi_getdevlist(pCard, pIoctlPayload);
565 if (retValue == 0)
566 {
567 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
568 status = IOCTL_CALL_SUCCESS;
569 }
570 else
571 {
572 pIoctlPayload->Status = IOCTL_CALL_FAIL;
573 status = IOCTL_CALL_FAIL;
574 }
575 //update new device length
576 pDeviceList = (tdDeviceListPayload_t*)pIoctlPayload->FunctionSpecificArea;
577 load->datasize =load->datasize - sizeof(tdDeviceInfoIOCTL_t) * (pDeviceList->deviceLength - pDeviceList->realDeviceCount);
578 AGTIAPI_PRINTK( "agtiapi_CharIoctl: new load->datasize = %d\n", load->datasize );
579
580 }
581 else if (pIoctlPayload->MajorFunction == IOCTL_MN_GET_CARD_INFO)
582 {
583 retValue = agtiapi_getCardInfo( pCard,
584 pIoctlPayload->Length,
585 (pIoctlPayload->FunctionSpecificArea) );
586 if (retValue == 0)
587 {
588 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
589 status = IOCTL_CALL_SUCCESS;
590 }
591 else
592 {
593 pIoctlPayload->Status = IOCTL_CALL_FAIL;
594 status = IOCTL_CALL_FAIL;
595 }
596 }
597 else if ( pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_DPMC_EVENT )
598 {
599 if ( pCard->flags & AGTIAPI_PORT_PANIC )
600 {
601 strcpy ( pIoctlPayload->FunctionSpecificArea, "DPMC LEAN\n" );
602 }
603 else
604 {
605 strcpy ( pIoctlPayload->FunctionSpecificArea, "do not dpmc lean\n" );
606 }
607 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
608 status = IOCTL_CALL_SUCCESS;
609 }
610 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_FATAL_ERROR )
611 {
612 AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_CHECK_FATAL_ERROR call received for card %d\n", pCard->cardNo);
613 //read port status to see if there is a fatal event
614 if(pCard->flags & AGTIAPI_PORT_PANIC)
615 {
616 printf("agtiapi_CharIoctl: Port Panic Status For Card %d is True\n",pCard->cardNo);
617 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_TRUE;
618 }
619 else
620 {
621 AGTIAPI_PRINTK("agtiapi_CharIoctl: Port Panic Status For Card %d is False\n",pCard->cardNo);
622 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_FALSE;
623 }
624 status = IOCTL_CALL_SUCCESS;
625 }
626 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE)
627 {
628 AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE call received for card %d\n", pCard->cardNo);
629 //set flags bit status to be a soft reset
630 pCard->flags |= AGTIAPI_SOFT_RESET;
631 //trigger soft reset for the card
632 retValue = agtiapi_ResetCard (pCard, &flags);
633
634 if(retValue == AGTIAPI_SUCCESS)
635 {
636 //clear port panic status
637 pCard->flags &= ~AGTIAPI_PORT_PANIC;
638 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERROR_SOFT_RESET_TRIG;
639 status = IOCTL_CALL_SUCCESS;
640 }
641 else
642 {
643 pIoctlPayload->Status = IOCTL_CALL_FAIL;
644 status = IOCTL_CALL_FAIL;
645 }
646 }
647 else
648 {
649 status = tiCOMMgntIOCTL( &pCard->tiRoot,
650 pIoctlPayload,
651 pCard,
652 param2,
653 param3 );
654 if (status == IOCTL_CALL_PENDING)
655 {
656 ostiIOCTLWaitForSignal(&pCard->tiRoot,NULL, NULL, NULL);
657 status = IOCTL_CALL_SUCCESS;
658 }
659 }
660 pCard->pIoctlSem = NULL;
661 err = 0;
662
663 //copy kernel buffer to userland buffer
664 err=copyout(pIoctlPayload,load->data,load->datasize);
665 if (err)
666 {
667 status = IOCTL_CALL_FAIL;
668 return status;
669 }
670 free(pIoctlPayload,TEMP);
671 pIoctlPayload=NULL;
672 break;
673 default:
674 error = ENOTTY;
675 break;
676 }
677 return(status);
678 }
679
680 /******************************************************************************
681 agtiapi_probe()
682
683 Purpose:
684 This function initialize and registere all detected HBAs.
685 The first function being called in driver after agtiapi_probe()
686 Parameters:
687 device_t dev (IN) - device pointer
688 Return:
689 A number - error
690 0 - HBA has been detected
691 Note:
692 ******************************************************************************/
agtiapi_probe(device_t dev)693 static int agtiapi_probe( device_t dev )
694 {
695 int retVal;
696 int thisCard;
697 ag_card_info_t *thisCardInst;
698
699 thisCard = device_get_unit( dev );
700 if ( thisCard >= AGTIAPI_MAX_CARDS )
701 {
702 device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" );
703 return (ENXIO); // maybe change to different return value?
704 }
705 thisCardInst = &agCardInfoList[ thisCard ];
706 retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard );
707 if ( retVal )
708 return (ENXIO); // maybe change to different return value?
709 return( BUS_PROBE_DEFAULT ); // successful probe
710 }
711
712
713 /******************************************************************************
714 agtiapi_attach()
715
716 Purpose:
717 This function initialize and registere all detected HBAs.
718 The first function being called in driver after agtiapi_probe()
719 Parameters:
720 device_t dev (IN) - device pointer
721 Return:
722 A number - error
723 0 - HBA has been detected
724 Note:
725 ******************************************************************************/
agtiapi_attach(device_t devx)726 static int agtiapi_attach( device_t devx )
727 {
728 // keeping get_unit call to once
729 int thisCard = device_get_unit( devx );
730 struct agtiapi_softc *pmsc;
731 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
732 ag_resource_info_t *pRscInfo;
733 int idx;
734 int lenRecv;
735 char buffer [256], *pLastUsedChar;
736 union ccb *ccb;
737 int bus, tid, lun;
738 struct ccb_setasync csa;
739
740 AGTIAPI_PRINTK("agtiapi_attach: start dev %p thisCard %d\n", devx, thisCard);
741 // AGTIAPI_PRINTK( "agtiapi_attach: entry pointer values A %p / %p\n",
742 // thisCardInst->pPCIDev, thisCardInst );
743 AGTIAPI_PRINTK( "agtiapi_attach: deviceID: 0x%x\n", pci_get_devid( devx ) );
744
745 TUNABLE_INT_FETCH( "DPMC_TIMEOUT_SECS", &ag_timeout_secs );
746 TUNABLE_INT_FETCH( "DPMC_TIDEBUG_LEVEL", &gTiDebugLevel );
747 // printf( "agtiapi_attach: debugLevel %d, timeout %d\n",
748 // gTiDebugLevel, ag_timeout_secs );
749 if ( ag_timeout_secs < 1 )
750 {
751 ag_timeout_secs = 1; // set minimum timeout value of 1 second
752 }
753 ag_timeout_secs = (ag_timeout_secs * 1000); // convert to millisecond notation
754
755 // Look up our softc and initialize its fields.
756 pmsc = device_get_softc( devx );
757 pmsc->my_dev = devx;
758
759 /* Get NumberOfPortals */
760 if ((ostiGetTransportParam(
761 &pmsc->tiRoot,
762 "Global",
763 "CardDefault",
764 agNULL,
765 agNULL,
766 agNULL,
767 agNULL,
768 "NumberOfPortals",
769 buffer,
770 255,
771 &lenRecv
772 ) == tiSuccess) && (lenRecv != 0))
773 {
774 if (osti_strncmp(buffer, "0x", 2) == 0)
775 {
776 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 0);
777 }
778 else
779 {
780 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 10);
781 }
782 if (ag_portal_count > AGTIAPI_MAX_PORTALS)
783 ag_portal_count = AGTIAPI_MAX_PORTALS;
784 }
785 else
786 {
787 ag_portal_count = AGTIAPI_MAX_PORTALS;
788 }
789 AGTIAPI_PRINTK( "agtiapi_attach: ag_portal_count=%d\n", ag_portal_count );
790 // initialize hostdata structure
791 pmsc->flags |= AGTIAPI_INIT_TIME | AGTIAPI_SCSI_REGISTERED |
792 AGTIAPI_INITIATOR;
793 pmsc->cardNo = thisCard;
794 pmsc->ccbTotal = 0;
795 pmsc->portCount = ag_portal_count;
796 pmsc->pCardInfo = thisCardInst;
797 pmsc->tiRoot.osData = pmsc;
798 pmsc->pCardInfo->pCard = (void *)pmsc;
799 pmsc->VidDid = ( pci_get_vendor(devx) << 16 ) | pci_get_device( devx );
800 pmsc->SimQFrozen = agFALSE;
801 pmsc->devq_flag = agFALSE;
802 pRscInfo = &thisCardInst->tiRscInfo;
803
804 osti_memset(buffer, 0, 256);
805 lenRecv = 0;
806
807 /* Get MaxTargets */
808 if ((ostiGetTransportParam(
809 &pmsc->tiRoot,
810 "Global",
811 "InitiatorParms",
812 agNULL,
813 agNULL,
814 agNULL,
815 agNULL,
816 "MaxTargets",
817 buffer,
818 sizeof(buffer),
819 &lenRecv
820 ) == tiSuccess) && (lenRecv != 0))
821 {
822 if (osti_strncmp(buffer, "0x", 2) == 0)
823 {
824 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
825 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 0 \n" );
826 }
827 else
828 {
829 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
830 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 10\n" );
831 }
832 }
833 else
834
835 {
836 if(Is_ADP8H(pmsc))
837 maxTargets = AGTIAPI_MAX_DEVICE_8H;
838 else if(Is_ADP7H(pmsc))
839 maxTargets = AGTIAPI_MAX_DEVICE_7H;
840 else
841 maxTargets = AGTIAPI_MAX_DEVICE;
842 }
843
844 if (maxTargets > AGTIAPI_HW_LIMIT_DEVICE)
845 {
846 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets: %d > AGTIAPI_HW_LIMIT_DEVICE: %d\n", maxTargets, AGTIAPI_HW_LIMIT_DEVICE );
847 AGTIAPI_PRINTK( "agtiapi_attach: change maxTargets = AGTIAPI_HW_LIMIT_DEVICE\n" );
848 maxTargets = AGTIAPI_HW_LIMIT_DEVICE;
849 }
850 pmsc->devDiscover = maxTargets ;
851
852 #ifdef HIALEAH_ENCRYPTION
853 ag_encryption_enable = 1;
854 if(ag_encryption_enable && pci_get_device(pmsc->pCardInfo->pPCIDev) ==
855 PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
856 {
857 pmsc->encrypt = 1;
858 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
859 printf("agtiapi_attach: Encryption Enabled\n" );
860 }
861 #endif
862 // ## for now, skip calls to ostiGetTransportParam(...)
863 // ## for now, skip references to DIF & EDC
864
865 // Create a /dev entry for this device. The kernel will assign us
866 // a major number automatically. We use the unit number of this
867 // device as the minor number and name the character device
868 // "agtiapi<unit>".
869 pmsc->my_cdev = make_dev( &agtiapi_cdevsw, thisCard, UID_ROOT, GID_WHEEL,
870 0600, "spcv%u", thisCard );
871 pmsc->my_cdev->si_drv1 = pmsc;
872
873 mtx_init( &thisCardInst->pmIOLock, "pmc SAS I/O lock",
874 NULL, MTX_DEF|MTX_RECURSE );
875
876 struct cam_devq *devq;
877
878 /* set the maximum number of pending IOs */
879 devq = cam_simq_alloc( AGTIAPI_MAX_CAM_Q_DEPTH );
880 if (devq == NULL)
881 {
882 AGTIAPI_PRINTK("agtiapi_attach: cam_simq_alloc is NULL\n" );
883 return( EIO );
884 }
885
886 struct cam_sim *lsim;
887 lsim = cam_sim_alloc( agtiapi_cam_action,
888 agtiapi_cam_poll,
889 "pmspcbsd",
890 pmsc,
891 thisCard,
892 &thisCardInst->pmIOLock,
893 1, // queued per target
894 AGTIAPI_MAX_CAM_Q_DEPTH, // max tag depth
895 devq );
896 if ( lsim == NULL ) {
897 cam_simq_free( devq );
898 AGTIAPI_PRINTK("agtiapi_attach: cam_sim_alloc is NULL\n" );
899 return( EIO );
900 }
901
902 pmsc->dev_scan = agFALSE;
903 //one cam sim per scsi bus
904 mtx_lock( &thisCardInst->pmIOLock );
905 if ( xpt_bus_register( lsim, devx, 0 ) != CAM_SUCCESS )
906 { // bus 0
907 cam_sim_free( lsim, TRUE );
908 mtx_unlock( &thisCardInst->pmIOLock );
909 AGTIAPI_PRINTK("agtiapi_attach: xpt_bus_register fails\n" );
910 return( EIO );
911 }
912
913 pmsc->sim = lsim;
914 bus = cam_sim_path(pmsc->sim);
915 tid = CAM_TARGET_WILDCARD;
916 lun = CAM_LUN_WILDCARD;
917 ccb = xpt_alloc_ccb_nowait();
918 if (ccb == agNULL)
919 {
920 mtx_unlock( &thisCardInst->pmIOLock );
921 cam_sim_free( lsim, TRUE );
922 cam_simq_free( devq );
923 return ( EIO );
924 }
925 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
926 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
927 {
928 mtx_unlock( &thisCardInst->pmIOLock );
929 cam_sim_free( lsim, TRUE );
930 cam_simq_free( devq );
931 xpt_free_ccb(ccb);
932 return( EIO );
933 }
934 pmsc->path = ccb->ccb_h.path;
935 xpt_setup_ccb(&csa.ccb_h, pmsc->path, 5);
936 csa.ccb_h.func_code = XPT_SASYNC_CB;
937 csa.event_enable = AC_FOUND_DEVICE;
938 csa.callback = agtiapi_async;
939 csa.callback_arg = pmsc;
940 xpt_action((union ccb *)&csa);
941 if (csa.ccb_h.status != CAM_REQ_CMP) {
942 AGTIAPI_PRINTK("agtiapi_attach: Unable to register AC_FOUND_DEVICE\n" );
943 }
944 lsim->devq = devq;
945 mtx_unlock( &thisCardInst->pmIOLock );
946
947
948
949
950 // get TD and lower layer memory requirements
951 tiCOMGetResource( &pmsc->tiRoot,
952 &pRscInfo->tiLoLevelResource,
953 &pRscInfo->tiInitiatorResource,
954 NULL,
955 &pRscInfo->tiSharedMem );
956
957 agtiapi_ScopeDMARes( thisCardInst );
958 AGTIAPI_PRINTK( "agtiapi_attach: size from the call agtiapi_ScopeDMARes"
959 " 0x%x \n", pmsc->typhn );
960
961 // initialize card information and get resource ready
962 if( agtiapi_InitResource( thisCardInst ) == AGTIAPI_FAIL ) {
963 AGTIAPI_PRINTK( "agtiapi_attach: Card %d initialize resource ERROR\n",
964 thisCard );
965 }
966
967 // begin: allocate and initialize card portal info resource
968 ag_portal_data_t *pPortalData;
969 if (pmsc->portCount == 0)
970 {
971 pmsc->pPortalData = NULL;
972 }
973 else
974 {
975 pmsc->pPortalData = (ag_portal_data_t *)
976 malloc( sizeof(ag_portal_data_t) * pmsc->portCount,
977 M_PMC_MPRT, M_ZERO | M_WAITOK );
978 if (pmsc->pPortalData == NULL)
979 {
980 AGTIAPI_PRINTK( "agtiapi_attach: Portal memory allocation ERROR\n" );
981 }
982 }
983
984 pPortalData = pmsc->pPortalData;
985 for( idx = 0; idx < pmsc->portCount; idx++ ) {
986 pPortalData->pCard = pmsc;
987 pPortalData->portalInfo.portID = idx;
988 pPortalData->portalInfo.tiPortalContext.osData = (void *)pPortalData;
989 pPortalData++;
990 }
991 // end: allocate and initialize card portal info resource
992
993 // begin: enable msix
994
995 // setup msix
996 // map to interrupt handler
997 int error = 0;
998 int mesgs = MAX_MSIX_NUM_VECTOR;
999 int i, cnt;
1000
1001 void (*intrHandler[MAX_MSIX_NUM_ISR])(void *arg) =
1002 {
1003 agtiapi_IntrHandler0,
1004 agtiapi_IntrHandler1,
1005 agtiapi_IntrHandler2,
1006 agtiapi_IntrHandler3,
1007 agtiapi_IntrHandler4,
1008 agtiapi_IntrHandler5,
1009 agtiapi_IntrHandler6,
1010 agtiapi_IntrHandler7,
1011 agtiapi_IntrHandler8,
1012 agtiapi_IntrHandler9,
1013 agtiapi_IntrHandler10,
1014 agtiapi_IntrHandler11,
1015 agtiapi_IntrHandler12,
1016 agtiapi_IntrHandler13,
1017 agtiapi_IntrHandler14,
1018 agtiapi_IntrHandler15
1019
1020 };
1021
1022 cnt = pci_msix_count(devx);
1023 AGTIAPI_PRINTK("supported MSIX %d\n", cnt); //this should be 64
1024 mesgs = MIN(mesgs, cnt);
1025 error = pci_alloc_msix(devx, &mesgs);
1026 if (error != 0) {
1027 printf( "pci_alloc_msix error %d\n", error );
1028 AGTIAPI_PRINTK("error %d\n", error);
1029 return( EIO );
1030 }
1031
1032 for(i=0; i < mesgs; i++) {
1033 pmsc->rscID[i] = i + 1;
1034 pmsc->irq[i] = bus_alloc_resource_any( devx,
1035 SYS_RES_IRQ,
1036 &pmsc->rscID[i],
1037 RF_ACTIVE );
1038 if( pmsc->irq[i] == NULL ) {
1039 printf( "RES_IRQ went terribly bad at %d\n", i );
1040 return( EIO );
1041 }
1042
1043 if ( (error = bus_setup_intr( devx, pmsc->irq[i],
1044 INTR_TYPE_CAM | INTR_MPSAFE,
1045 NULL,
1046 intrHandler[i],
1047 pmsc,
1048 &pmsc->intrcookie[i] )
1049 ) != 0 ) {
1050 device_printf( devx, "Failed to register handler" );
1051 return( EIO );
1052 }
1053 }
1054 pmsc->flags |= AGTIAPI_IRQ_REQUESTED;
1055 pmsc->pCardInfo->maxInterruptVectors = MAX_MSIX_NUM_VECTOR;
1056 // end: enable msix
1057
1058 int ret = 0;
1059 ret = agtiapi_InitCardSW(pmsc);
1060 if (ret == AGTIAPI_FAIL || ret == AGTIAPI_UNKNOWN)
1061 {
1062 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardSW failure %d\n",
1063 ret );
1064 return( EIO );
1065 }
1066
1067 pmsc->ccbFreeList = NULL;
1068 pmsc->ccbChainList = NULL;
1069 pmsc->ccbAllocList = NULL;
1070
1071 pmsc->flags |= ( AGTIAPI_INSTALLED );
1072
1073 ret = agtiapi_alloc_requests( pmsc );
1074 if( ret != 0 ) {
1075 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_requests failure %d\n",
1076 ret );
1077 return( EIO );
1078 }
1079
1080 ret = agtiapi_alloc_ostimem( pmsc );
1081 if (ret != AGTIAPI_SUCCESS)
1082 {
1083 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_ostimem failure %d\n",
1084 ret );
1085 return( EIO );
1086 }
1087
1088 ret = agtiapi_InitCardHW( pmsc );
1089 if (ret != 0)
1090 {
1091 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardHW failure %d\n",
1092 ret );
1093 return( EIO );
1094 }
1095
1096 #ifdef HIALEAH_ENCRYPTION
1097 if(pmsc->encrypt)
1098 {
1099 if((agtiapi_SetupEncryption(pmsc)) < 0)
1100 AGTIAPI_PRINTK("SetupEncryption returned less than 0\n");
1101 }
1102 #endif
1103
1104 pmsc->flags &= ~AGTIAPI_INIT_TIME;
1105 return( 0 );
1106 }
1107
1108 /******************************************************************************
1109 agtiapi_InitCardSW()
1110
1111 Purpose:
1112 Host Bus Adapter Initialization
1113 Parameters:
1114 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1115 Return:
1116 AGTIAPI_SUCCESS - success
1117 AGTIAPI_FAIL - fail
1118 Note:
1119 TBD, need chip register information
1120 ******************************************************************************/
agtiapi_InitCardSW(struct agtiapi_softc * pmsc)1121 STATIC agBOOLEAN agtiapi_InitCardSW( struct agtiapi_softc *pmsc )
1122 {
1123 ag_card_info_t *thisCardInst = pmsc->pCardInfo;
1124 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
1125 int initSWIdx;
1126
1127 // begin: agtiapi_InitCardSW()
1128 // now init some essential locks n agtiapi_InitCardSW
1129 mtx_init( &pmsc->sendLock, "local q send lock", NULL, MTX_DEF );
1130 mtx_init( &pmsc->doneLock, "local q done lock", NULL, MTX_DEF );
1131 mtx_init( &pmsc->sendSMPLock, "local q send lock", NULL, MTX_DEF );
1132 mtx_init( &pmsc->doneSMPLock, "local q done lock", NULL, MTX_DEF );
1133 mtx_init( &pmsc->ccbLock, "ccb list lock", NULL, MTX_DEF );
1134 mtx_init( &pmsc->devListLock, "hotP devListLock", NULL, MTX_DEF );
1135 mtx_init( &pmsc->memLock, "dynamic memory lock", NULL, MTX_DEF );
1136 mtx_init( &pmsc->freezeLock, "sim freeze lock", NULL, MTX_DEF | MTX_RECURSE);
1137
1138 // initialize lower layer resources
1139 //## if (pCard->flags & AGTIAPI_INIT_TIME) {
1140 #ifdef HIALEAH_ENCRYPTION
1141 /* Enable encryption if chip supports it */
1142 if (pci_get_device(pmsc->pCardInfo->pPCIDev) ==
1143 PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
1144 pmsc->encrypt = 1;
1145
1146 if (pmsc->encrypt)
1147 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
1148 #endif
1149 pmsc->flags &= ~(AGTIAPI_PORT_INITIALIZED | AGTIAPI_SYS_INTR_ON);
1150
1151
1152 // For now, up to 16 MSIX vectors are supported
1153 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.
1154 maxInterruptVectors = pmsc->pCardInfo->maxInterruptVectors;
1155 AGTIAPI_PRINTK( "agtiapi_InitCardSW: maxInterruptVectors set to %d",
1156 pmsc->pCardInfo->maxInterruptVectors );
1157 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.max_MSI_InterruptVectors = 0;
1158 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.flag = 0;
1159 pRscInfo->tiLoLevelResource.loLevelOption.maxNumOSLocks = 0;
1160
1161 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit root %p, dev %p, pmsc %p\n",
1162 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1163 if( tiCOMInit( &pmsc->tiRoot,
1164 &thisCardInst->tiRscInfo.tiLoLevelResource,
1165 &thisCardInst->tiRscInfo.tiInitiatorResource,
1166 NULL,
1167 &thisCardInst->tiRscInfo.tiSharedMem ) != tiSuccess ) {
1168 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit ERROR\n" );
1169 return AGTIAPI_FAIL;
1170 }
1171 int maxLocks;
1172 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
1173 pmsc->STLock = malloc( ( maxLocks * sizeof(struct mtx) ), M_PMC_MSTL,
1174 M_ZERO | M_WAITOK );
1175
1176 for( initSWIdx = 0; initSWIdx < maxLocks; initSWIdx++ )
1177 {
1178 // init all indexes
1179 mtx_init( &pmsc->STLock[initSWIdx], "LL & TD lock", NULL, MTX_DEF );
1180 }
1181
1182 if( tiCOMPortInit( &pmsc->tiRoot, agFALSE ) != tiSuccess ) {
1183 printf( "agtiapi_InitCardSW: tiCOMPortInit ERROR -- AGTIAPI_FAIL\n" );
1184 return AGTIAPI_FAIL;
1185 }
1186 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMPortInit"
1187 " root %p, dev %p, pmsc %p\n",
1188 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1189
1190 pmsc->flags |= AGTIAPI_PORT_INITIALIZED;
1191 pmsc->freezeSim = agFALSE;
1192
1193 #ifdef HIALEAH_ENCRYPTION
1194 atomic_set(&outstanding_encrypted_io_count, 0);
1195 /*fix below*/
1196 /*if(pmsc->encrypt && (pmsc->flags & AGTIAPI_INIT_TIME))
1197 if((agtiapi_SetupEncryptionPools(pmsc)) != 0)
1198 printf("SetupEncryptionPools failed\n"); */
1199 #endif
1200 return AGTIAPI_SUCCESS;
1201 // end: agtiapi_InitCardSW()
1202 }
1203
1204 /******************************************************************************
1205 agtiapi_InitCardHW()
1206
1207 Purpose:
1208 Host Bus Adapter Initialization
1209 Parameters:
1210 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1211 Return:
1212 AGTIAPI_SUCCESS - success
1213 AGTIAPI_FAIL - fail
1214 Note:
1215 TBD, need chip register information
1216 ******************************************************************************/
agtiapi_InitCardHW(struct agtiapi_softc * pmsc)1217 STATIC agBOOLEAN agtiapi_InitCardHW( struct agtiapi_softc *pmsc )
1218 {
1219 U32 numVal;
1220 U32 count;
1221 U32 loop;
1222 // begin: agtiapi_InitCardHW()
1223
1224 ag_portal_info_t *pPortalInfo = NULL;
1225 ag_portal_data_t *pPortalData;
1226
1227 // ISR is registered, enable chip interrupt.
1228 tiCOMSystemInterruptsActive( &pmsc->tiRoot, agTRUE );
1229 pmsc->flags |= AGTIAPI_SYS_INTR_ON;
1230
1231 numVal = sizeof(ag_device_t) * pmsc->devDiscover;
1232 pmsc->pDevList =
1233 (ag_device_t *)malloc( numVal, M_PMC_MDVT, M_ZERO | M_WAITOK );
1234 if( !pmsc->pDevList ) {
1235 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d DevList ERROR\n", numVal );
1236 panic( "agtiapi_InitCardHW\n" );
1237 return AGTIAPI_FAIL;
1238 }
1239
1240 #ifdef LINUX_PERBI_SUPPORT
1241 numVal = sizeof(ag_slr_map_t) * pmsc->devDiscover;
1242 pmsc->pSLRList =
1243 (ag_slr_map_t *)malloc( numVal, M_PMC_MSLR, M_ZERO | M_WAITOK );
1244 if( !pmsc->pSLRList ) {
1245 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d SLRList ERROR\n", numVal );
1246 panic( "agtiapi_InitCardHW SLRL\n" );
1247 return AGTIAPI_FAIL;
1248 }
1249
1250 numVal = sizeof(ag_tgt_map_t) * pmsc->devDiscover;
1251 pmsc->pWWNList =
1252 (ag_tgt_map_t *)malloc( numVal, M_PMC_MTGT, M_ZERO | M_WAITOK );
1253 if( !pmsc->pWWNList ) {
1254 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d WWNList ERROR\n", numVal );
1255 panic( "agtiapi_InitCardHW WWNL\n" );
1256 return AGTIAPI_FAIL;
1257 }
1258
1259 // Get the WWN_to_target_ID mappings from the
1260 // holding area which contains the input of the
1261 // system configuration file.
1262 if( ag_Perbi )
1263 agtiapi_GetWWNMappings( pmsc, agMappingList );
1264 else {
1265 agtiapi_GetWWNMappings( pmsc, 0 );
1266 if( agMappingList )
1267 printf( "agtiapi_InitCardHW: WWN PERBI disabled WARN\n" );
1268 }
1269 #endif
1270
1271 //agtiapi_DelaySec(5);
1272 DELAY( 500000 );
1273
1274 pmsc->tgtCount = 0;
1275
1276 pmsc->flags &= ~AGTIAPI_CB_DONE;
1277 pPortalData = pmsc->pPortalData;
1278
1279 //start port
1280
1281 for (count = 0; count < pmsc->portCount; count++)
1282 {
1283 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
1284
1285 pPortalInfo = &pPortalData->portalInfo;
1286 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
1287 AGTIAPI_PORT_DISC_READY |
1288 AGTIAPI_DISC_DONE |
1289 AGTIAPI_DISC_COMPLETE );
1290
1291 for (loop = 0; loop < AGTIAPI_LOOP_MAX; loop++)
1292 {
1293 AGTIAPI_PRINTK( "tiCOMPortStart entry data %p / %d / %p\n",
1294 &pmsc->tiRoot,
1295 pPortalInfo->portID,
1296 &pPortalInfo->tiPortalContext );
1297
1298 if( tiCOMPortStart( &pmsc->tiRoot,
1299 pPortalInfo->portID,
1300 &pPortalInfo->tiPortalContext,
1301 0 )
1302 != tiSuccess ) {
1303 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1304 agtiapi_DelayMSec( AGTIAPI_EXTRA_DELAY );
1305 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
1306 AGTIAPI_PRINTK( "tiCOMPortStart failed -- no loop, portalData %p\n",
1307 pPortalData );
1308 }
1309 else {
1310 AGTIAPI_PRINTK( "tiCOMPortStart success no loop, portalData %p\n",
1311 pPortalData );
1312 break;
1313 }
1314 } // end of for loop
1315 /* release lock */
1316 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1317
1318 if( loop >= AGTIAPI_LOOP_MAX ) {
1319 return AGTIAPI_FAIL;
1320 }
1321 tiCOMGetPortInfo( &pmsc->tiRoot,
1322 &pPortalInfo->tiPortalContext,
1323 &pPortalInfo->tiPortInfo );
1324 pPortalData++;
1325 }
1326
1327 /* discover target device */
1328 #ifndef HOTPLUG_SUPPORT
1329 agtiapi_DiscoverTgt( pCard );
1330 #endif
1331
1332
1333 pmsc->flags |= AGTIAPI_INSTALLED;
1334
1335 if( pmsc->flags & AGTIAPI_INIT_TIME ) {
1336 agtiapi_TITimer( (void *)pmsc );
1337 pmsc->flags |= AGTIAPI_TIMER_ON;
1338 }
1339
1340 return 0;
1341 }
1342
1343
1344
1345 /******************************************************************************
1346 agtiapi_IntrHandlerx_()
1347
1348 Purpose:
1349 Interrupt service routine.
1350 Parameters:
1351 void arg (IN) Pointer to the HBA data structure
1352 bit32 idx (IN) Vector index
1353 ******************************************************************************/
agtiapi_IntrHandlerx_(void * arg,int index)1354 void agtiapi_IntrHandlerx_( void *arg, int index )
1355 {
1356
1357 struct agtiapi_softc *pCard;
1358 int rv;
1359
1360 pCard = (struct agtiapi_softc *)arg;
1361
1362 #ifndef AGTIAPI_DPC
1363 ccb_t *pccb;
1364 #endif
1365
1366 AG_LOCAL_LOCK(&(pCard->pCardInfo->pmIOLock));
1367 AG_PERF_SPINLOCK(agtiapi_host_lock);
1368 if (pCard->flags & AGTIAPI_SHUT_DOWN)
1369 goto ext;
1370
1371 rv = tiCOMInterruptHandler(&pCard->tiRoot, index);
1372 if (rv == agFALSE)
1373 {
1374 /* not our irq */
1375 AG_SPIN_UNLOCK(agtiapi_host_lock);
1376 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1377 return;
1378 }
1379
1380
1381 #ifdef AGTIAPI_DPC
1382 tasklet_hi_schedule(&pCard->tasklet_dpc[idx]);
1383 #else
1384 /* consume all completed entries, 100 is random number to be big enough */
1385 tiCOMDelayedInterruptHandler(&pCard->tiRoot, index, 100, tiInterruptContext);
1386 AG_GET_DONE_PCCB(pccb, pCard);
1387 AG_GET_DONE_SMP_PCCB(pccb, pCard);
1388 #endif
1389
1390 ext:
1391 AG_SPIN_UNLOCK(agtiapi_host_lock);
1392 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1393 return;
1394
1395 }
1396
1397 /******************************************************************************
1398 agtiapi_IntrHandler0()
1399 Purpose: Interrupt service routine for interrupt vector index 0.
1400 Parameters: void arg (IN) Pointer to the HBA data structure
1401 ******************************************************************************/
agtiapi_IntrHandler0(void * arg)1402 void agtiapi_IntrHandler0( void *arg )
1403 {
1404 agtiapi_IntrHandlerx_( arg, 0 );
1405 return;
1406 }
1407
1408 /******************************************************************************
1409 agtiapi_IntrHandler1()
1410 Purpose: Interrupt service routine for interrupt vector index 1.
1411 Parameters: void arg (IN) Pointer to the HBA data structure
1412 ******************************************************************************/
agtiapi_IntrHandler1(void * arg)1413 void agtiapi_IntrHandler1( void *arg )
1414 {
1415 agtiapi_IntrHandlerx_( arg, 1 );
1416 return;
1417 }
1418
1419 /******************************************************************************
1420 agtiapi_IntrHandler2()
1421 Purpose: Interrupt service routine for interrupt vector index 2.
1422 Parameters: void arg (IN) Pointer to the HBA data structure
1423 ******************************************************************************/
agtiapi_IntrHandler2(void * arg)1424 void agtiapi_IntrHandler2( void *arg )
1425 {
1426 agtiapi_IntrHandlerx_( arg, 2 );
1427 return;
1428 }
1429
1430 /******************************************************************************
1431 agtiapi_IntrHandler3()
1432 Purpose: Interrupt service routine for interrupt vector index 3.
1433 Parameters: void arg (IN) Pointer to the HBA data structure
1434 ******************************************************************************/
agtiapi_IntrHandler3(void * arg)1435 void agtiapi_IntrHandler3( void *arg )
1436 {
1437 agtiapi_IntrHandlerx_( arg, 3 );
1438 return;
1439 }
1440
1441 /******************************************************************************
1442 agtiapi_IntrHandler4()
1443 Purpose: Interrupt service routine for interrupt vector index 4.
1444 Parameters: void arg (IN) Pointer to the HBA data structure
1445 ******************************************************************************/
agtiapi_IntrHandler4(void * arg)1446 void agtiapi_IntrHandler4( void *arg )
1447 {
1448 agtiapi_IntrHandlerx_( arg, 4 );
1449 return;
1450 }
1451
1452 /******************************************************************************
1453 agtiapi_IntrHandler5()
1454 Purpose: Interrupt service routine for interrupt vector index 5.
1455 Parameters: void arg (IN) Pointer to the HBA data structure
1456 ******************************************************************************/
agtiapi_IntrHandler5(void * arg)1457 void agtiapi_IntrHandler5( void *arg )
1458 {
1459 agtiapi_IntrHandlerx_( arg, 5 );
1460 return;
1461 }
1462
1463 /******************************************************************************
1464 agtiapi_IntrHandler6()
1465 Purpose: Interrupt service routine for interrupt vector index 6.
1466 Parameters: void arg (IN) Pointer to the HBA data structure
1467 ******************************************************************************/
agtiapi_IntrHandler6(void * arg)1468 void agtiapi_IntrHandler6( void *arg )
1469 {
1470 agtiapi_IntrHandlerx_( arg, 6 );
1471 return;
1472 }
1473
1474 /******************************************************************************
1475 agtiapi_IntrHandler7()
1476 Purpose: Interrupt service routine for interrupt vector index 7.
1477 Parameters: void arg (IN) Pointer to the HBA data structure
1478 ******************************************************************************/
agtiapi_IntrHandler7(void * arg)1479 void agtiapi_IntrHandler7( void *arg )
1480 {
1481 agtiapi_IntrHandlerx_( arg, 7 );
1482 return;
1483 }
1484
1485 /******************************************************************************
1486 agtiapi_IntrHandler8()
1487 Purpose: Interrupt service routine for interrupt vector index 8.
1488 Parameters: void arg (IN) Pointer to the HBA data structure
1489 ******************************************************************************/
agtiapi_IntrHandler8(void * arg)1490 void agtiapi_IntrHandler8( void *arg )
1491 {
1492 agtiapi_IntrHandlerx_( arg, 8 );
1493 return;
1494 }
1495
1496 /******************************************************************************
1497 agtiapi_IntrHandler9()
1498 Purpose: Interrupt service routine for interrupt vector index 9.
1499 Parameters: void arg (IN) Pointer to the HBA data structure
1500 ******************************************************************************/
agtiapi_IntrHandler9(void * arg)1501 void agtiapi_IntrHandler9( void *arg )
1502 {
1503 agtiapi_IntrHandlerx_( arg, 9 );
1504 return;
1505 }
1506
1507 /******************************************************************************
1508 agtiapi_IntrHandler10()
1509 Purpose: Interrupt service routine for interrupt vector index 10.
1510 Parameters: void arg (IN) Pointer to the HBA data structure
1511 ******************************************************************************/
agtiapi_IntrHandler10(void * arg)1512 void agtiapi_IntrHandler10( void *arg )
1513 {
1514 agtiapi_IntrHandlerx_( arg, 10 );
1515 return;
1516 }
1517
1518 /******************************************************************************
1519 agtiapi_IntrHandler11()
1520 Purpose: Interrupt service routine for interrupt vector index 11.
1521 Parameters: void arg (IN) Pointer to the HBA data structure
1522 ******************************************************************************/
agtiapi_IntrHandler11(void * arg)1523 void agtiapi_IntrHandler11( void *arg )
1524 {
1525 agtiapi_IntrHandlerx_( arg, 11 );
1526 return;
1527 }
1528
1529 /******************************************************************************
1530 agtiapi_IntrHandler12()
1531 Purpose: Interrupt service routine for interrupt vector index 12.
1532 Parameters: void arg (IN) Pointer to the HBA data structure
1533 ******************************************************************************/
agtiapi_IntrHandler12(void * arg)1534 void agtiapi_IntrHandler12( void *arg )
1535 {
1536 agtiapi_IntrHandlerx_( arg, 12 );
1537 return;
1538 }
1539
1540 /******************************************************************************
1541 agtiapi_IntrHandler13()
1542 Purpose: Interrupt service routine for interrupt vector index 13.
1543 Parameters: void arg (IN) Pointer to the HBA data structure
1544 ******************************************************************************/
agtiapi_IntrHandler13(void * arg)1545 void agtiapi_IntrHandler13( void *arg )
1546 {
1547 agtiapi_IntrHandlerx_( arg, 13 );
1548 return;
1549 }
1550
1551 /******************************************************************************
1552 agtiapi_IntrHandler14()
1553 Purpose: Interrupt service routine for interrupt vector index 14.
1554 Parameters: void arg (IN) Pointer to the HBA data structure
1555 ******************************************************************************/
agtiapi_IntrHandler14(void * arg)1556 void agtiapi_IntrHandler14( void *arg )
1557 {
1558 agtiapi_IntrHandlerx_( arg, 14 );
1559 return;
1560 }
1561
1562 /******************************************************************************
1563 agtiapi_IntrHandler15()
1564 Purpose: Interrupt service routine for interrupt vector index 15.
1565 Parameters: void arg (IN) Pointer to the HBA data structure
1566 ******************************************************************************/
agtiapi_IntrHandler15(void * arg)1567 void agtiapi_IntrHandler15( void *arg )
1568 {
1569 agtiapi_IntrHandlerx_( arg, 15 );
1570 return;
1571 }
1572
agtiapi_SglMemoryCB(void * arg,bus_dma_segment_t * dm_segs,int nseg,int error)1573 static void agtiapi_SglMemoryCB( void *arg,
1574 bus_dma_segment_t *dm_segs,
1575 int nseg,
1576 int error )
1577 {
1578 bus_addr_t *addr;
1579 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: start\n");
1580 if (error != 0)
1581 {
1582 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: error %d\n", error);
1583 panic("agtiapi_SglMemoryCB: error %d\n", error);
1584 return;
1585 }
1586 addr = arg;
1587 *addr = dm_segs[0].ds_addr;
1588 return;
1589 }
1590
agtiapi_MemoryCB(void * arg,bus_dma_segment_t * dm_segs,int nseg,int error)1591 static void agtiapi_MemoryCB( void *arg,
1592 bus_dma_segment_t *dm_segs,
1593 int nseg,
1594 int error )
1595 {
1596 bus_addr_t *addr;
1597 AGTIAPI_PRINTK("agtiapi_MemoryCB: start\n");
1598 if (error != 0)
1599 {
1600 AGTIAPI_PRINTK("agtiapi_MemoryCB: error %d\n", error);
1601 panic("agtiapi_MemoryCB: error %d\n", error);
1602 return;
1603 }
1604 addr = arg;
1605 *addr = dm_segs[0].ds_addr;
1606 return;
1607 }
1608
1609 /******************************************************************************
1610 agtiapi_alloc_requests()
1611
1612 Purpose:
1613 Allocates resources such as dma tag and timer
1614 Parameters:
1615 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1616 Return:
1617 AGTIAPI_SUCCESS - success
1618 AGTIAPI_FAIL - fail
1619 Note:
1620 ******************************************************************************/
agtiapi_alloc_requests(struct agtiapi_softc * pmcsc)1621 int agtiapi_alloc_requests( struct agtiapi_softc *pmcsc )
1622 {
1623
1624 int rsize, nsegs;
1625 U32 next_tick;
1626
1627 nsegs = AGTIAPI_NSEGS;
1628 rsize = AGTIAPI_MAX_DMA_SEGS; // 128
1629 AGTIAPI_PRINTK( "agtiapi_alloc_requests: MAXPHYS 0x%x PAGE_SIZE 0x%x \n",
1630 MAXPHYS, PAGE_SIZE );
1631 AGTIAPI_PRINTK( "agtiapi_alloc_requests: nsegs %d rsize %d \n",
1632 nsegs, rsize ); // 32, 128
1633 // This is for csio->data_ptr
1634 if( bus_dma_tag_create( agNULL, // parent
1635 1, // alignment
1636 0, // boundary
1637 BUS_SPACE_MAXADDR, // lowaddr
1638 BUS_SPACE_MAXADDR, // highaddr
1639 NULL, // filter
1640 NULL, // filterarg
1641 BUS_SPACE_MAXSIZE_32BIT, // maxsize
1642 nsegs, // nsegments
1643 BUS_SPACE_MAXSIZE_32BIT, // maxsegsize
1644 BUS_DMA_ALLOCNOW, // flags
1645 busdma_lock_mutex, // lockfunc
1646 &pmcsc->pCardInfo->pmIOLock, // lockarg
1647 &pmcsc->buffer_dmat ) ) {
1648 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1649 return( ENOMEM );
1650 }
1651
1652 // This is for tiSgl_t of pccb in agtiapi_PrepCCBs()
1653 rsize =
1654 (sizeof(tiSgl_t) * AGTIAPI_NSEGS) *
1655 AGTIAPI_CCB_PER_DEVICE * maxTargets;
1656 AGTIAPI_PRINTK( "agtiapi_alloc_requests: rsize %d \n", rsize ); // 32, 128
1657 if( bus_dma_tag_create( agNULL, // parent
1658 32, // alignment
1659 0, // boundary
1660 BUS_SPACE_MAXADDR_32BIT, // lowaddr
1661 BUS_SPACE_MAXADDR, // highaddr
1662 NULL, // filter
1663 NULL, // filterarg
1664 rsize, // maxsize
1665 1, // nsegments
1666 rsize, // maxsegsize
1667 BUS_DMA_ALLOCNOW, // flags
1668 NULL, // lockfunc
1669 NULL, // lockarg
1670 &pmcsc->tisgl_dmat ) ) {
1671 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1672 return( ENOMEM );
1673 }
1674
1675 if( bus_dmamem_alloc( pmcsc->tisgl_dmat,
1676 (void **)&pmcsc->tisgl_mem,
1677 BUS_DMA_NOWAIT,
1678 &pmcsc->tisgl_map ) ) {
1679 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot allocate SGL memory\n" );
1680 return( ENOMEM );
1681 }
1682
1683 bzero( pmcsc->tisgl_mem, rsize );
1684 bus_dmamap_load( pmcsc->tisgl_dmat,
1685 pmcsc->tisgl_map,
1686 pmcsc->tisgl_mem,
1687 rsize,
1688 agtiapi_SglMemoryCB,
1689 &pmcsc->tisgl_busaddr,
1690 BUS_DMA_NOWAIT /* 0 */ );
1691
1692 mtx_init( &pmcsc->OS_timer_lock, "OS timer lock", NULL, MTX_DEF );
1693 mtx_init( &pmcsc->IO_timer_lock, "IO timer lock", NULL, MTX_DEF );
1694 mtx_init( &pmcsc->devRmTimerLock, "targ rm timer lock", NULL, MTX_DEF );
1695 callout_init_mtx( &pmcsc->OS_timer, &pmcsc->OS_timer_lock, 0 );
1696 callout_init_mtx( &pmcsc->IO_timer, &pmcsc->IO_timer_lock, 0 );
1697 callout_init_mtx( &pmcsc->devRmTimer,
1698 &pmcsc->devRmTimerLock, 0);
1699
1700 next_tick = pmcsc->pCardInfo->tiRscInfo.tiLoLevelResource.
1701 loLevelOption.usecsPerTick / USEC_PER_TICK;
1702 AGTIAPI_PRINTK( "agtiapi_alloc_requests: before callout_reset, "
1703 "next_tick 0x%x\n", next_tick );
1704 callout_reset( &pmcsc->OS_timer, next_tick, agtiapi_TITimer, pmcsc );
1705 return 0;
1706 }
1707
1708 /******************************************************************************
1709 agtiapi_alloc_ostimem()
1710
1711 Purpose:
1712 Allocates memory used later in ostiAllocMemory
1713 Parameters:
1714 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA data structure
1715 Return:
1716 AGTIAPI_SUCCESS - success
1717 AGTIAPI_FAIL - fail
1718 Note:
1719 This is a pre-allocation for ostiAllocMemory() "non-cacheable" function calls
1720 ******************************************************************************/
agtiapi_alloc_ostimem(struct agtiapi_softc * pmcsc)1721 int agtiapi_alloc_ostimem( struct agtiapi_softc *pmcsc ) {
1722 int rsize, nomsize;
1723
1724 nomsize = 4096;
1725 rsize = AGTIAPI_DYNAMIC_MAX * nomsize; // 8M
1726 AGTIAPI_PRINTK("agtiapi_alloc_ostimem: rsize %d \n", rsize);
1727
1728 if( bus_dma_tag_create( agNULL, // parent
1729 32, // alignment
1730 0, // boundary
1731 BUS_SPACE_MAXADDR, // lowaddr
1732 BUS_SPACE_MAXADDR, // highaddr
1733 NULL, // filter
1734 NULL, // filterarg
1735 rsize, // maxsize (size)
1736 1, // number of segments
1737 rsize, // maxsegsize
1738 0, // flags
1739 NULL, // lockfunc
1740 NULL, // lockarg
1741 &pmcsc->osti_dmat ) ) {
1742 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Can't create no-cache mem tag\n" );
1743 return AGTIAPI_FAIL;
1744 }
1745
1746
1747 if( bus_dmamem_alloc( pmcsc->osti_dmat,
1748 &pmcsc->osti_mem,
1749 BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
1750 &pmcsc->osti_mapp ) ) {
1751 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Cannot allocate cache mem %d\n",
1752 rsize );
1753 return AGTIAPI_FAIL;
1754 }
1755
1756
1757 bus_dmamap_load( pmcsc->osti_dmat,
1758 pmcsc->osti_mapp,
1759 pmcsc->osti_mem,
1760 rsize,
1761 agtiapi_MemoryCB, // try reuse of CB for same goal
1762 &pmcsc->osti_busaddr,
1763 BUS_DMA_NOWAIT );
1764
1765 // populate all the ag_dma_addr_t osti_busaddr/mem fields with addresses for
1766 // handy reference when driver is in motion
1767 int idx;
1768 ag_card_info_t *pCardInfo = pmcsc->pCardInfo;
1769 ag_dma_addr_t *pMem;
1770
1771 for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) {
1772 pMem = &pCardInfo->dynamicMem[idx];
1773 pMem->nocache_busaddr = pmcsc->osti_busaddr + ( idx * nomsize );
1774 pMem->nocache_mem = (void*)((U64)pmcsc->osti_mem + ( idx * nomsize ));
1775 pCardInfo->freeDynamicMem[idx] = &pCardInfo->dynamicMem[idx];
1776 }
1777
1778 pCardInfo->topOfFreeDynamicMem = AGTIAPI_DYNAMIC_MAX;
1779
1780 return AGTIAPI_SUCCESS;
1781 }
1782
1783
1784 /******************************************************************************
1785 agtiapi_cam_action()
1786
1787 Purpose:
1788 Parses CAM frames and triggers a corresponding action
1789 Parameters:
1790 struct cam_sim *sim (IN) Pointer to SIM data structure
1791 union ccb * ccb (IN) Pointer to CAM ccb data structure
1792 Return:
1793 Note:
1794 ******************************************************************************/
agtiapi_cam_action(struct cam_sim * sim,union ccb * ccb)1795 static void agtiapi_cam_action( struct cam_sim *sim, union ccb * ccb )
1796 {
1797 struct agtiapi_softc *pmcsc;
1798 tiDeviceHandle_t *pDevHandle = NULL; // acts as flag as well
1799 tiDeviceInfo_t devInfo;
1800 int pathID, targetID, lunID;
1801 int lRetVal;
1802 U32 TID;
1803 U32 speed = 150000;
1804
1805 pmcsc = cam_sim_softc( sim );
1806 AGTIAPI_IO( "agtiapi_cam_action: start pmcs %p\n", pmcsc );
1807
1808 if (pmcsc == agNULL)
1809 {
1810 AGTIAPI_PRINTK( "agtiapi_cam_action: start pmcs is NULL\n" );
1811 return;
1812 }
1813 mtx_assert( &(pmcsc->pCardInfo->pmIOLock), MA_OWNED );
1814
1815 AGTIAPI_IO( "agtiapi_cam_action: cardNO %d func_code 0x%x\n", pmcsc->cardNo, ccb->ccb_h.func_code );
1816
1817 pathID = xpt_path_path_id( ccb->ccb_h.path );
1818 targetID = xpt_path_target_id( ccb->ccb_h.path );
1819 lunID = xpt_path_lun_id( ccb->ccb_h.path );
1820
1821 AGTIAPI_IO( "agtiapi_cam_action: P 0x%x T 0x%x L 0x%x\n",
1822 pathID, targetID, lunID );
1823
1824 switch (ccb->ccb_h.func_code)
1825 {
1826 case XPT_PATH_INQ:
1827 {
1828 struct ccb_pathinq *cpi;
1829
1830 /* See architecure book p180*/
1831 cpi = &ccb->cpi;
1832 cpi->version_num = 1;
1833 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_16;
1834 cpi->target_sprt = 0;
1835 cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN;
1836 cpi->hba_eng_cnt = 0;
1837 cpi->max_target = maxTargets - 1;
1838 cpi->max_lun = AGTIAPI_MAX_LUN;
1839 cpi->maxio = 1024 *1024; /* Max supported I/O size, in bytes. */
1840 cpi->initiator_id = 255;
1841 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1842 strlcpy(cpi->hba_vid, "PMC", HBA_IDLEN);
1843 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1844 cpi->unit_number = cam_sim_unit(sim);
1845 cpi->bus_id = cam_sim_bus(sim);
1846 // rate is set when XPT_GET_TRAN_SETTINGS is processed
1847 cpi->base_transfer_speed = 150000;
1848 cpi->transport = XPORT_SAS;
1849 cpi->transport_version = 0;
1850 cpi->protocol = PROTO_SCSI;
1851 cpi->protocol_version = SCSI_REV_SPC3;
1852 cpi->ccb_h.status = CAM_REQ_CMP;
1853 break;
1854 }
1855 case XPT_GET_TRAN_SETTINGS:
1856 {
1857 struct ccb_trans_settings *cts;
1858 struct ccb_trans_settings_sas *sas;
1859 struct ccb_trans_settings_scsi *scsi;
1860
1861 if ( pmcsc->flags & AGTIAPI_SHUT_DOWN )
1862 {
1863 return;
1864 }
1865
1866 cts = &ccb->cts;
1867 sas = &ccb->cts.xport_specific.sas;
1868 scsi = &cts->proto_specific.scsi;
1869
1870 cts->protocol = PROTO_SCSI;
1871 cts->protocol_version = SCSI_REV_SPC3;
1872 cts->transport = XPORT_SAS;
1873 cts->transport_version = 0;
1874
1875 sas->valid = CTS_SAS_VALID_SPEED;
1876
1877 /* this sets the "MB/s transfers" */
1878 if (pmcsc != NULL && targetID >= 0 && targetID < maxTargets)
1879 {
1880 if (pmcsc->pWWNList != NULL)
1881 {
1882 TID = INDEX(pmcsc, targetID);
1883 if (TID < maxTargets)
1884 {
1885 pDevHandle = pmcsc->pDevList[TID].pDevHandle;
1886 }
1887 }
1888 }
1889 if (pDevHandle)
1890 {
1891 tiINIGetDeviceInfo( &pmcsc->tiRoot, pDevHandle, &devInfo );
1892 switch (devInfo.info.devType_S_Rate & 0xF)
1893 {
1894 case 0x8: speed = 150000;
1895 break;
1896 case 0x9: speed = 300000;
1897 break;
1898 case 0xA: speed = 600000;
1899 break;
1900 case 0xB: speed = 1200000;
1901 break;
1902 default: speed = 150000;
1903 break;
1904 }
1905 }
1906 sas->bitrate = speed;
1907 scsi->valid = CTS_SCSI_VALID_TQ;
1908 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
1909 ccb->ccb_h.status = CAM_REQ_CMP;
1910 break;
1911 }
1912 case XPT_RESET_BUS:
1913 {
1914 lRetVal = agtiapi_eh_HostReset( pmcsc, ccb ); // usually works first time
1915 if ( SUCCESS == lRetVal )
1916 {
1917 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset success.\n" );
1918 }
1919 else
1920 {
1921 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset failed.\n" );
1922 }
1923 ccb->ccb_h.status = CAM_REQ_CMP;
1924 break;
1925 }
1926 case XPT_RESET_DEV:
1927 {
1928 ccb->ccb_h.status = CAM_REQ_CMP;
1929 break;
1930 }
1931 case XPT_ABORT:
1932 {
1933 ccb->ccb_h.status = CAM_REQ_CMP;
1934 break;
1935 }
1936 #if __FreeBSD_version >= 900026
1937 case XPT_SMP_IO:
1938 {
1939 agtiapi_QueueSMP( pmcsc, ccb );
1940 return;
1941 }
1942 #endif /* __FreeBSD_version >= 900026 */
1943 case XPT_SCSI_IO:
1944 {
1945 if(pmcsc->dev_scan == agFALSE)
1946 {
1947 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1948 break;
1949 }
1950 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
1951 {
1952 AGTIAPI_PRINTK( "agtiapi_cam_action: shutdown, XPT_SCSI_IO 0x%x\n",
1953 XPT_SCSI_IO );
1954 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1955 break;
1956 }
1957 else
1958 {
1959 AGTIAPI_IO( "agtiapi_cam_action: Zero XPT_SCSI_IO 0x%x, doing IOs\n",
1960 XPT_SCSI_IO );
1961 agtiapi_QueueCmnd_( pmcsc, ccb );
1962 return;
1963 }
1964 }
1965
1966 case XPT_CALC_GEOMETRY:
1967 {
1968 cam_calc_geometry(&ccb->ccg, 1);
1969 ccb->ccb_h.status = CAM_REQ_CMP;
1970 break;
1971 }
1972 default:
1973 {
1974 /*
1975 XPT_SET_TRAN_SETTINGS
1976 */
1977 AGTIAPI_IO( "agtiapi_cam_action: default function code 0x%x\n",
1978 ccb->ccb_h.func_code );
1979 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1980 break;
1981 }
1982 } /* switch */
1983 xpt_done(ccb);
1984 }
1985
1986
1987 /******************************************************************************
1988 agtiapi_GetCCB()
1989
1990 Purpose:
1991 Get a ccb from free list or allocate a new one
1992 Parameters:
1993 struct agtiapi_softc *pmcsc (IN) Pointer to HBA structure
1994 Return:
1995 Pointer to a ccb structure, or NULL if not available
1996 Note:
1997 ******************************************************************************/
agtiapi_GetCCB(struct agtiapi_softc * pmcsc)1998 STATIC pccb_t agtiapi_GetCCB( struct agtiapi_softc *pmcsc )
1999 {
2000 pccb_t pccb;
2001
2002 AGTIAPI_IO( "agtiapi_GetCCB: start\n" );
2003
2004 AG_LOCAL_LOCK( &pmcsc->ccbLock );
2005
2006 /* get the ccb from the head of the free list */
2007 if ((pccb = (pccb_t)pmcsc->ccbFreeList) != NULL)
2008 {
2009 pmcsc->ccbFreeList = (caddr_t *)pccb->pccbNext;
2010 pccb->pccbNext = NULL;
2011 pccb->flags = ACTIVE;
2012 pccb->startTime = 0;
2013 pmcsc->activeCCB++;
2014 AGTIAPI_IO( "agtiapi_GetCCB: re-allocated ccb %p\n", pccb );
2015 }
2016 else
2017 {
2018 AGTIAPI_PRINTK( "agtiapi_GetCCB: kmalloc ERROR - no ccb allocated\n" );
2019 }
2020
2021 AG_LOCAL_UNLOCK( &pmcsc->ccbLock );
2022 return pccb;
2023 }
2024
2025 /******************************************************************************
2026 agtiapi_QueueCmnd_()
2027
2028 Purpose:
2029 Calls for sending CCB and excuting on HBA.
2030 Parameters:
2031 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2032 union ccb * ccb (IN) Pointer to CAM ccb data structure
2033 Return:
2034 0 - Command is pending to execute
2035 1 - Command returned without further process
2036 Note:
2037 ******************************************************************************/
agtiapi_QueueCmnd_(struct agtiapi_softc * pmcsc,union ccb * ccb)2038 int agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb)
2039 {
2040 struct ccb_scsiio *csio = &ccb->csio;
2041 pccb_t pccb = agNULL; // call dequeue
2042 int status = tiSuccess;
2043 U32 Channel = CMND_TO_CHANNEL(ccb);
2044 U32 TID = CMND_TO_TARGET(ccb);
2045 U32 LUN = CMND_TO_LUN(ccb);
2046
2047 AGTIAPI_IO( "agtiapi_QueueCmnd_: start\n" );
2048
2049 /* no support for CBD > 16 */
2050 if (csio->cdb_len > 16)
2051 {
2052 AGTIAPI_PRINTK( "agtiapi_QueueCmnd_: unsupported CDB length %d\n",
2053 csio->cdb_len );
2054 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2055 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2056 ccb->ccb_h.status |= CAM_REQ_INVALID;//CAM_REQ_CMP;
2057 xpt_done(ccb);
2058 return tiError;
2059 }
2060 if (TID < 0 || TID >= maxTargets)
2061 {
2062 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: INVALID TID ERROR\n");
2063 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2064 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2065 ccb->ccb_h.status |= CAM_DEV_NOT_THERE;//CAM_REQ_CMP;
2066 xpt_done(ccb);
2067 return tiError;
2068 }
2069 /* get a ccb */
2070 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
2071 {
2072 ag_device_t *targ;
2073 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n");
2074 if (pmcsc != NULL)
2075 {
2076 TID = INDEX(pmcsc, TID);
2077 targ = &pmcsc->pDevList[TID];
2078 }
2079 if (targ != NULL)
2080 {
2081 agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth);
2082 }
2083 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2084 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2085 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2086 xpt_done(ccb);
2087 return tiBusy;
2088 }
2089 pccb->pmcsc = pmcsc;
2090 /* initialize Command Control Block (CCB) */
2091 pccb->targetId = TID;
2092 pccb->lun = LUN;
2093 pccb->channel = Channel;
2094 pccb->ccb = ccb; /* for struct scsi_cmnd */
2095 pccb->senseLen = csio->sense_len;
2096 pccb->startTime = ticks;
2097 pccb->pSenseData = (caddr_t) &csio->sense_data;
2098 pccb->tiSuperScsiRequest.flags = 0;
2099
2100 /* each channel is reserved for different addr modes */
2101 pccb->addrMode = agtiapi_AddrModes[Channel];
2102
2103 status = agtiapi_PrepareSGList(pmcsc, pccb);
2104 if (status != tiSuccess)
2105 {
2106 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: agtiapi_PrepareSGList failure\n");
2107 agtiapi_FreeCCB(pmcsc, pccb);
2108 if (status == tiReject)
2109 {
2110 ccb->ccb_h.status = CAM_REQ_INVALID;
2111 }
2112 else
2113 {
2114 ccb->ccb_h.status = CAM_REQ_CMP;
2115 }
2116 xpt_done( ccb );
2117 return tiError;
2118 }
2119 return status;
2120 }
2121
2122 /******************************************************************************
2123 agtiapi_DumpCDB()
2124
2125 Purpose:
2126 Prints out CDB
2127 Parameters:
2128 const char *ptitle (IN) A string to be printed
2129 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2130 Return:
2131 Note:
2132 ******************************************************************************/
agtiapi_DumpCDB(const char * ptitle,ccb_t * pccb)2133 STATIC void agtiapi_DumpCDB(const char *ptitle, ccb_t *pccb)
2134 {
2135 union ccb *ccb;
2136 struct ccb_scsiio *csio;
2137 bit8 cdb[64];
2138 int len;
2139
2140 if (pccb == NULL)
2141 {
2142 printf( "agtiapi_DumpCDB: no pccb here \n" );
2143 panic("agtiapi_DumpCDB: pccb is NULL. called from %s\n", ptitle);
2144 return;
2145 }
2146 ccb = pccb->ccb;
2147 if (ccb == NULL)
2148 {
2149 printf( "agtiapi_DumpCDB: no ccb here \n" );
2150 panic( "agtiapi_DumpCDB: pccb %p ccb %p flags %d ccb NULL! "
2151 "called from %s\n",
2152 pccb, pccb->ccb, pccb->flags, ptitle );
2153 return;
2154 }
2155 csio = &ccb->csio;
2156 if (csio == NULL)
2157 {
2158 printf( "agtiapi_DumpCDB: no csio here \n" );
2159 panic( "agtiapi_DumpCDB: pccb%p ccb%p flags%d csio NULL! called from %s\n",
2160 pccb, pccb->ccb, pccb->flags, ptitle );
2161 return;
2162 }
2163 len = MIN(64, csio->cdb_len);
2164 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2165 {
2166 bcopy(csio->cdb_io.cdb_ptr, &cdb[0], len);
2167 }
2168 else
2169 {
2170 bcopy(csio->cdb_io.cdb_bytes, &cdb[0], len);
2171 }
2172
2173 AGTIAPI_IO( "agtiapi_DumpCDB: pccb%p CDB0x%x csio->cdb_len %d"
2174 " len %d from %s\n",
2175 pccb, cdb[0],
2176 csio->cdb_len,
2177 len,
2178 ptitle );
2179 return;
2180 }
2181
2182 /******************************************************************************
2183 agtiapi_DoSoftReset()
2184
2185 Purpose:
2186 Do card reset
2187 Parameters:
2188 *data (IN) point to pmcsc (struct agtiapi_softc *)
2189 Return:
2190 Note:
2191 ******************************************************************************/
agtiapi_DoSoftReset(struct agtiapi_softc * pmcsc)2192 int agtiapi_DoSoftReset (struct agtiapi_softc *pmcsc)
2193 {
2194 int ret;
2195 unsigned long flags;
2196
2197 pmcsc->flags |= AGTIAPI_SOFT_RESET;
2198 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
2199 ret = agtiapi_ResetCard( pmcsc, &flags );
2200 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
2201
2202 if( ret != AGTIAPI_SUCCESS )
2203 return tiError;
2204
2205 return SUCCESS;
2206 }
2207
2208 /******************************************************************************
2209 agtiapi_CheckIOTimeout()
2210
2211 Purpose:
2212 Timeout function for SCSI IO or TM
2213 Parameters:
2214 *data (IN) point to pCard (ag_card_t *)
2215 Return:
2216 Note:
2217 ******************************************************************************/
agtiapi_CheckIOTimeout(void * data)2218 STATIC void agtiapi_CheckIOTimeout(void *data)
2219 {
2220 U32 status = AGTIAPI_SUCCESS;
2221 ccb_t *pccb;
2222 struct agtiapi_softc *pmcsc;
2223 pccb_t pccb_curr;
2224 pccb_t pccb_next;
2225 pmcsc = (struct agtiapi_softc *)data;
2226
2227 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Enter\n");
2228
2229 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Active CCB %d\n", pmcsc->activeCCB);
2230
2231 pccb = (pccb_t)pmcsc->ccbChainList;
2232
2233 /* if link is down, do nothing */
2234 if ((pccb == NULL) || (pmcsc->activeCCB == 0))
2235 {
2236 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: goto restart_timer\n");
2237 goto restart_timer;
2238 }
2239
2240 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
2241 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
2242 goto ext;
2243
2244 pccb_curr = pccb;
2245
2246 /* Walk thorugh the IO Chain linked list to find the pending io */
2247 /* Set the TM flag based on the pccb type, i.e SCSI IO or TM cmd */
2248 while (pccb_curr != NULL)
2249 {
2250 /* start from 1st ccb in the chain */
2251 pccb_next = pccb_curr->pccbChainNext;
2252 if( (pccb_curr->flags == 0) || (pccb_curr->tiIORequest.tdData == NULL) ||
2253 (pccb_curr->startTime == 0) /* && (pccb->startTime == 0) */)
2254 {
2255 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: move to next element\n");
2256 }
2257 else if ( ( (ticks-pccb_curr->startTime) >= ag_timeout_secs ) &&
2258 !(pccb_curr->flags & TIMEDOUT) )
2259 {
2260 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: pccb %p timed out, call TM "
2261 "function -- flags=%x startTime=%ld tdData = %p\n",
2262 pccb_curr, pccb_curr->flags, pccb->startTime,
2263 pccb_curr->tiIORequest.tdData );
2264 pccb_curr->flags |= TIMEDOUT;
2265 status = agtiapi_StartTM(pmcsc, pccb_curr);
2266 if (status == AGTIAPI_SUCCESS)
2267 {
2268 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: TM Request sent with "
2269 "success\n" );
2270 goto restart_timer;
2271 }
2272 else
2273 {
2274 #ifdef AGTIAPI_LOCAL_RESET
2275 /* abort request did not go through */
2276 AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Abort request failed\n");
2277 /* TODO: call Soft reset here */
2278 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout:in agtiapi_CheckIOTimeout() "
2279 "abort request did not go thru ==> soft reset#7, then "
2280 "restart timer\n" );
2281 agtiapi_DoSoftReset (pmcsc);
2282 goto restart_timer;
2283 #endif
2284 }
2285 }
2286 pccb_curr = pccb_next;
2287 }
2288 restart_timer:
2289 callout_reset(&pmcsc->IO_timer, 1*hz, agtiapi_CheckIOTimeout, pmcsc);
2290
2291 ext:
2292 AG_SPIN_UNLOCK_IRQ(agtiapi_host_lock, flags);
2293 return;
2294 }
2295
2296 /******************************************************************************
2297 agtiapi_StartTM()
2298
2299 Purpose:
2300 DDI calls for aborting outstanding IO command
2301 Parameters:
2302 struct scsi_cmnd *pccb (IN) Pointer to the command to be aborted
2303 unsigned long flags (IN/out) spinlock flags used in locking from
2304 calling layers
2305 Return:
2306 AGTIAPI_SUCCESS - success
2307 AGTIAPI_FAIL - fail
2308 ******************************************************************************/
2309 int
agtiapi_StartTM(struct agtiapi_softc * pCard,ccb_t * pccb)2310 agtiapi_StartTM(struct agtiapi_softc *pCard, ccb_t *pccb)
2311 {
2312 ccb_t *pTMccb = NULL;
2313 U32 status = AGTIAPI_SUCCESS;
2314 ag_device_t *pDevice = NULL;
2315 U32 TMstatus = tiSuccess;
2316 AGTIAPI_PRINTK( "agtiapi_StartTM: pccb %p, pccb->flags %x\n",
2317 pccb, pccb->flags );
2318 if (pccb == NULL)
2319 {
2320 AGTIAPI_PRINTK("agtiapi_StartTM: %p not found\n",pccb);
2321 status = AGTIAPI_SUCCESS;
2322 goto ext;
2323 }
2324 if (!pccb->tiIORequest.tdData)
2325 {
2326 /* should not be the case */
2327 AGTIAPI_PRINTK("agtiapi_StartTM: ccb %p flag 0x%x tid %d no tdData "
2328 "ERROR\n", pccb, pccb->flags, pccb->targetId);
2329 status = AGTIAPI_FAIL;
2330 }
2331 else
2332 {
2333 /* If timedout CCB is TM_ABORT_TASK command, issue LocalAbort first to
2334 clear pending TM_ABORT_TASK */
2335 /* Else Device State will not be put back to Operational, (refer FW) */
2336 if (pccb->flags & TASK_MANAGEMENT)
2337 {
2338 if (tiINIIOAbort(&pCard->tiRoot, &pccb->tiIORequest) != tiSuccess)
2339 {
2340 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort Request for Abort_TASK "
2341 "TM failed\n" );
2342 /* TODO: call Soft reset here */
2343 AGTIAPI_PRINTK( "agtiapi_StartTM: in agtiapi_StartTM() abort "
2344 "tiINIIOAbort() failed ==> soft reset#8\n" );
2345 agtiapi_DoSoftReset( pCard );
2346 }
2347 else
2348 {
2349 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort for Abort_TASK TM "
2350 "Request sent\n" );
2351 status = AGTIAPI_SUCCESS;
2352 }
2353 }
2354 else
2355 {
2356 /* get a ccb */
2357 if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
2358 {
2359 AGTIAPI_PRINTK("agtiapi_StartTM: TM resource unavailable!\n");
2360 status = AGTIAPI_FAIL;
2361 goto ext;
2362 }
2363 pTMccb->pmcsc = pCard;
2364 pTMccb->targetId = pccb->targetId;
2365 pTMccb->devHandle = pccb->devHandle;
2366 if (pTMccb->targetId >= pCard->devDiscover)
2367 {
2368 AGTIAPI_PRINTK("agtiapi_StartTM: Incorrect dev Id in TM!\n");
2369 status = AGTIAPI_FAIL;
2370 goto ext;
2371 }
2372 if (pTMccb->targetId < 0 || pTMccb->targetId >= maxTargets)
2373 {
2374 return AGTIAPI_FAIL;
2375 }
2376 if (INDEX(pCard, pTMccb->targetId) >= maxTargets)
2377 {
2378 return AGTIAPI_FAIL;
2379 }
2380 pDevice = &pCard->pDevList[INDEX(pCard, pTMccb->targetId)];
2381 if ((pDevice == NULL) || !(pDevice->flags & ACTIVE))
2382 {
2383 return AGTIAPI_FAIL;
2384 }
2385
2386 /* save pending io to issue local abort at Task mgmt CB */
2387 pTMccb->pccbIO = pccb;
2388 AGTIAPI_PRINTK( "agtiapi_StartTM: pTMccb %p flag %x tid %d via TM "
2389 "request !\n",
2390 pTMccb, pTMccb->flags, pTMccb->targetId );
2391 pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
2392 pTMccb->flags |= TASK_MANAGEMENT;
2393 TMstatus = tiINITaskManagement(&pCard->tiRoot,
2394 pccb->devHandle,
2395 AG_ABORT_TASK,
2396 &pccb->tiSuperScsiRequest.scsiCmnd.lun,
2397 &pccb->tiIORequest,
2398 &pTMccb->tiIORequest);
2399 if (TMstatus == tiSuccess)
2400 {
2401 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request success ccb "
2402 "%p, pTMccb %p\n",
2403 pccb, pTMccb );
2404 pTMccb->startTime = ticks;
2405 status = AGTIAPI_SUCCESS;
2406 }
2407 else if (TMstatus == tiIONoDevice)
2408 {
2409 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request tiIONoDevice ccb "
2410 "%p, pTMccb %p\n",
2411 pccb, pTMccb );
2412 status = AGTIAPI_SUCCESS;
2413 }
2414 else
2415 {
2416 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request failed ccb %p, "
2417 "pTMccb %p\n",
2418 pccb, pTMccb );
2419 status = AGTIAPI_FAIL;
2420 agtiapi_FreeTMCCB(pCard, pTMccb);
2421 /* TODO */
2422 /* call TM_TARGET_RESET */
2423 }
2424 }
2425 }
2426 ext:
2427 AGTIAPI_PRINTK("agtiapi_StartTM: return %d flgs %x\n", status,
2428 (pccb) ? pccb->flags : -1);
2429 return status;
2430 } /* agtiapi_StartTM */
2431
2432 #if __FreeBSD_version > 901000
2433 /******************************************************************************
2434 agtiapi_PrepareSGList()
2435
2436 Purpose:
2437 This function prepares scatter-gather list for the given ccb
2438 Parameters:
2439 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2440 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2441 Return:
2442 0 - success
2443 1 - failure
2444
2445 Note:
2446 ******************************************************************************/
agtiapi_PrepareSGList(struct agtiapi_softc * pmcsc,ccb_t * pccb)2447 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2448 {
2449 union ccb *ccb = pccb->ccb;
2450 struct ccb_scsiio *csio = &ccb->csio;
2451 struct ccb_hdr *ccbh = &ccb->ccb_h;
2452 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2453
2454 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2455 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2456
2457 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2458 {
2459 switch((ccbh->flags & CAM_DATA_MASK))
2460 {
2461 int error;
2462 struct bus_dma_segment seg;
2463 case CAM_DATA_VADDR:
2464 /* Virtual address that needs to translated into one or more physical address ranges. */
2465 // int error;
2466 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2467 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2468 error = bus_dmamap_load( pmcsc->buffer_dmat,
2469 pccb->CCB_dmamap,
2470 csio->data_ptr,
2471 csio->dxfer_len,
2472 agtiapi_PrepareSGListCB,
2473 pccb,
2474 BUS_DMA_NOWAIT/* 0 */ );
2475 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2476
2477 if (error == EINPROGRESS)
2478 {
2479 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2480 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2481 xpt_freeze_simq(pmcsc->sim, 1);
2482 pmcsc->SimQFrozen = agTRUE;
2483 ccbh->status |= CAM_RELEASE_SIMQ;
2484 }
2485 break;
2486 case CAM_DATA_PADDR:
2487 /* We have been given a pointer to single physical buffer. */
2488 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2489 //struct bus_dma_segment seg;
2490 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2491 seg.ds_addr =
2492 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2493 seg.ds_len = csio->dxfer_len;
2494 // * 0xFF to be defined
2495 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2496 break;
2497 default:
2498 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2499 return tiReject;
2500 }
2501 }
2502 else
2503 {
2504 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2505 }
2506 return tiSuccess;
2507 }
2508 #else
2509 /******************************************************************************
2510 agtiapi_PrepareSGList()
2511
2512 Purpose:
2513 This function prepares scatter-gather list for the given ccb
2514 Parameters:
2515 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2516 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2517 Return:
2518 0 - success
2519 1 - failure
2520
2521 Note:
2522 ******************************************************************************/
agtiapi_PrepareSGList(struct agtiapi_softc * pmcsc,ccb_t * pccb)2523 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2524 {
2525 union ccb *ccb = pccb->ccb;
2526 struct ccb_scsiio *csio = &ccb->csio;
2527 struct ccb_hdr *ccbh = &ccb->ccb_h;
2528 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2529 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2530 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2531
2532 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2533 {
2534 if ((ccbh->flags & CAM_SCATTER_VALID) == 0)
2535 {
2536 /* We've been given a pointer to a single buffer. */
2537 if ((ccbh->flags & CAM_DATA_PHYS) == 0)
2538 {
2539 /* Virtual address that needs to translated into one or more physical address ranges. */
2540 int error;
2541 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2542 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2543 error = bus_dmamap_load( pmcsc->buffer_dmat,
2544 pccb->CCB_dmamap,
2545 csio->data_ptr,
2546 csio->dxfer_len,
2547 agtiapi_PrepareSGListCB,
2548 pccb,
2549 BUS_DMA_NOWAIT/* 0 */ );
2550 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2551
2552 if (error == EINPROGRESS)
2553 {
2554 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2555 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2556 xpt_freeze_simq(pmcsc->sim, 1);
2557 pmcsc->SimQFrozen = agTRUE;
2558 ccbh->status |= CAM_RELEASE_SIMQ;
2559 }
2560 }
2561 else
2562 {
2563 /* We have been given a pointer to single physical buffer. */
2564 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2565 struct bus_dma_segment seg;
2566 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2567 seg.ds_addr =
2568 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2569 seg.ds_len = csio->dxfer_len;
2570 // * 0xFF to be defined
2571 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2572 }
2573 }
2574 else
2575 {
2576
2577 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2578 return tiReject;
2579 }
2580 }
2581 else
2582 {
2583 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2584 }
2585 return tiSuccess;
2586 }
2587
2588 #endif
2589 /******************************************************************************
2590 agtiapi_PrepareSGListCB()
2591
2592 Purpose:
2593 Callback function for bus_dmamap_load()
2594 This fuctions sends IO to LL layer.
2595 Parameters:
2596 void *arg (IN) Pointer to the HBA data structure
2597 bus_dma_segment_t *segs (IN) Pointer to dma segment
2598 int nsegs (IN) number of dma segment
2599 int error (IN) error
2600 Return:
2601 Note:
2602 ******************************************************************************/
agtiapi_PrepareSGListCB(void * arg,bus_dma_segment_t * segs,int nsegs,int error)2603 static void agtiapi_PrepareSGListCB( void *arg,
2604 bus_dma_segment_t *segs,
2605 int nsegs,
2606 int error )
2607 {
2608 pccb_t pccb = arg;
2609 union ccb *ccb = pccb->ccb;
2610 struct ccb_scsiio *csio = &ccb->csio;
2611
2612 struct agtiapi_softc *pmcsc;
2613 tiIniScsiCmnd_t *pScsiCmnd;
2614 bit32 i;
2615 bus_dmasync_op_t op;
2616 U32_64 phys_addr;
2617 U08 *CDB;
2618 int io_is_encryptable = 0;
2619 unsigned long long start_lba = 0;
2620 ag_device_t *pDev;
2621 U32 TID = CMND_TO_TARGET(ccb);
2622
2623 AGTIAPI_IO( "agtiapi_PrepareSGListCB: start, nsegs %d error 0x%x\n",
2624 nsegs, error );
2625 pmcsc = pccb->pmcsc;
2626
2627 if (error != tiSuccess)
2628 {
2629 if (error == 0xAABBCCDD || error == 0xAAAAAAAA)
2630 {
2631 // do nothing
2632 }
2633 else
2634 {
2635 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: error status 0x%x\n", error);
2636 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2637 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2638 agtiapi_FreeCCB(pmcsc, pccb);
2639 ccb->ccb_h.status = CAM_REQ_CMP;
2640 xpt_done(ccb);
2641 return;
2642 }
2643 }
2644
2645 if (nsegs > AGTIAPI_MAX_DMA_SEGS)
2646 {
2647 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: over the limit. nsegs %d"
2648 " AGTIAPI_MAX_DMA_SEGS %d\n",
2649 nsegs, AGTIAPI_MAX_DMA_SEGS );
2650 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2651 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2652 agtiapi_FreeCCB(pmcsc, pccb);
2653 ccb->ccb_h.status = CAM_REQ_CMP;
2654 xpt_done(ccb);
2655 return;
2656 }
2657
2658
2659 /* fill in IO information */
2660 pccb->dataLen = csio->dxfer_len;
2661
2662 /* start fill in sgl structure */
2663 if (nsegs == 1 && error == 0xAABBCCDD)
2664 {
2665 /* to be tested */
2666 /* A single physical buffer */
2667 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: nsegs is 1\n");
2668 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2669 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2670 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2671 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)segs->ds_addr;
2672 pccb->numSgElements = 1;
2673 }
2674 else if (nsegs == 0 && error == 0xAAAAAAAA)
2675 {
2676 /* no data transfer */
2677 AGTIAPI_IO( "agtiapi_PrepareSGListCB: no data transfer\n" );
2678 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2679 pccb->dataLen = 0;
2680 pccb->numSgElements = 0;
2681 }
2682 else
2683 {
2684 /* virtual/logical buffer */
2685 if (nsegs == 1)
2686 {
2687 pccb->dataLen = segs[0].ds_len;
2688
2689 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2690 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2691 pccb->tiSuperScsiRequest.agSgl1.len = htole32(segs[0].ds_len);
2692 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2693 pccb->numSgElements = nsegs;
2694
2695 }
2696 else
2697 {
2698 pccb->dataLen = 0;
2699 /* loop */
2700 for (i = 0; i < nsegs; i++)
2701 {
2702 pccb->sgList[i].len = htole32(segs[i].ds_len);
2703 CPU_TO_LE32(pccb->sgList[i], segs[i].ds_addr);
2704 pccb->sgList[i].type = htole32(tiSgl);
2705 pccb->dataLen += segs[i].ds_len;
2706
2707 } /* for */
2708 pccb->numSgElements = nsegs;
2709 /* set up sgl buffer address */
2710 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, pccb->tisgl_busaddr);
2711 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSglList);
2712 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2713 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2714 pccb->numSgElements = nsegs;
2715 } /* else */
2716 }
2717
2718 /* set data transfer direction */
2719 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2720 {
2721 op = BUS_DMASYNC_PREWRITE;
2722 pccb->tiSuperScsiRequest.dataDirection = tiDirectionOut;
2723 }
2724 else
2725 {
2726 op = BUS_DMASYNC_PREREAD;
2727 pccb->tiSuperScsiRequest.dataDirection = tiDirectionIn;
2728 }
2729
2730 pScsiCmnd = &pccb->tiSuperScsiRequest.scsiCmnd;
2731
2732 pScsiCmnd->expDataLength = pccb->dataLen;
2733
2734 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2735 {
2736 bcopy(csio->cdb_io.cdb_ptr, &pScsiCmnd->cdb[0], csio->cdb_len);
2737 }
2738 else
2739 {
2740 bcopy(csio->cdb_io.cdb_bytes, &pScsiCmnd->cdb[0],csio->cdb_len);
2741 }
2742
2743 CDB = &pScsiCmnd->cdb[0];
2744
2745 switch (CDB[0])
2746 {
2747 case REQUEST_SENSE: /* requires different buffer */
2748 /* This code should not be excercised because SAS support auto sense
2749 For the completeness, vtophys() is still used here.
2750 */
2751 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: QueueCmnd - REQUEST SENSE new\n");
2752 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->senseLen);
2753 phys_addr = vtophys(&csio->sense_data);
2754 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, phys_addr);
2755 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2756 pccb->dataLen = pccb->senseLen;
2757 pccb->numSgElements = 1;
2758 break;
2759 case INQUIRY:
2760 /* only using lun 0 for device type detection */
2761 pccb->flags |= AGTIAPI_INQUIRY;
2762 break;
2763 case TEST_UNIT_READY:
2764 case RESERVE:
2765 case RELEASE:
2766 case START_STOP:
2767 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2768 pccb->dataLen = 0;
2769 break;
2770 case READ_6:
2771 case WRITE_6:
2772 /* Extract LBA */
2773 start_lba = ((CDB[1] & 0x1f) << 16) |
2774 (CDB[2] << 8) |
2775 (CDB[3]);
2776 #ifdef HIALEAH_ENCRYPTION
2777 io_is_encryptable = 1;
2778 #endif
2779 break;
2780 case READ_10:
2781 case WRITE_10:
2782 case READ_12:
2783 case WRITE_12:
2784 /* Extract LBA */
2785 start_lba = (CDB[2] << 24) |
2786 (CDB[3] << 16) |
2787 (CDB[4] << 8) |
2788 (CDB[5]);
2789 #ifdef HIALEAH_ENCRYPTION
2790 io_is_encryptable = 1;
2791 #endif
2792 break;
2793 case READ_16:
2794 case WRITE_16:
2795 /* Extract LBA */
2796 start_lba = (CDB[2] << 24) |
2797 (CDB[3] << 16) |
2798 (CDB[4] << 8) |
2799 (CDB[5]);
2800 start_lba <<= 32;
2801 start_lba |= ((CDB[6] << 24) |
2802 (CDB[7] << 16) |
2803 (CDB[8] << 8) |
2804 (CDB[9]));
2805 #ifdef HIALEAH_ENCRYPTION
2806 io_is_encryptable = 1;
2807 #endif
2808 break;
2809 default:
2810 break;
2811 }
2812
2813 /* fill device lun based one address mode */
2814 agtiapi_SetLunField(pccb);
2815
2816 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
2817 {
2818 pccb->ccbStatus = tiIOFailed;
2819 pccb->scsiStatus = tiDetailNoLogin;
2820 agtiapi_FreeCCB(pmcsc, pccb);
2821 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2822 xpt_done(ccb);
2823 pccb->ccb = NULL;
2824 return;
2825 }
2826 if (INDEX(pmcsc, pccb->targetId) >= maxTargets)
2827 {
2828 pccb->ccbStatus = tiIOFailed;
2829 pccb->scsiStatus = tiDetailNoLogin;
2830 agtiapi_FreeCCB(pmcsc, pccb);
2831 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2832 xpt_done(ccb);
2833 pccb->ccb = NULL;
2834 return;
2835 }
2836 pDev = &pmcsc->pDevList[INDEX(pmcsc, pccb->targetId)];
2837
2838 #if 1
2839 if ((pmcsc->flags & EDC_DATA) &&
2840 (pDev->flags & EDC_DATA))
2841 {
2842 /*
2843 * EDC support:
2844 *
2845 * Possible command supported -
2846 * READ_6, READ_10, READ_12, READ_16, READ_LONG, READ_BUFFER,
2847 * READ_DEFECT_DATA, etc.
2848 * WRITE_6, WRITE_10, WRITE_12, WRITE_16, WRITE_LONG, WRITE_LONG2,
2849 * WRITE_BUFFER, WRITE_VERIFY, WRITE_VERIFY_12, etc.
2850 *
2851 * Do some data length adjustment and set chip operation instruction.
2852 */
2853 switch (CDB[0])
2854 {
2855 case READ_6:
2856 case READ_10:
2857 case READ_12:
2858 case READ_16:
2859 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2860 #ifdef AGTIAPI_TEST_DIF
2861 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2862 #endif
2863 pccb->flags |= EDC_DATA;
2864
2865 #ifdef TEST_VERIFY_AND_FORWARD
2866 pccb->tiSuperScsiRequest.Dif.flags =
2867 DIF_VERIFY_FORWARD | DIF_UDT_REF_BLOCK_COUNT;
2868 if(pDev->sector_size == 520) {
2869 pScsiCmnd->expDataLength += (pccb->dataLen / 512) * 8;
2870 } else if(pDev->sector_size == 4104) {
2871 pScsiCmnd->expDataLength += (pccb->dataLen / 4096) * 8;
2872 }
2873 #else
2874 #ifdef AGTIAPI_TEST_DIF
2875 pccb->tiSuperScsiRequest.Dif.flags =
2876 DIF_VERIFY_DELETE | DIF_UDT_REF_BLOCK_COUNT;
2877 #endif
2878 #endif
2879 #ifdef AGTIAPI_TEST_DIF
2880 switch(pDev->sector_size) {
2881 case 528:
2882 pccb->tiSuperScsiRequest.Dif.flags |=
2883 ( DIF_BLOCK_SIZE_520 << 16 );
2884 break;
2885 case 4104:
2886 pccb->tiSuperScsiRequest.Dif.flags |=
2887 ( DIF_BLOCK_SIZE_4096 << 16 );
2888 break;
2889 case 4168:
2890 pccb->tiSuperScsiRequest.Dif.flags |=
2891 ( DIF_BLOCK_SIZE_4160 << 16 );
2892 break;
2893 }
2894
2895 if(pCard->flags & EDC_DATA_CRC)
2896 pccb->tiSuperScsiRequest.Dif.flags |= DIF_CRC_VERIFICATION;
2897
2898 /* Turn on upper 4 bits of UVM */
2899 pccb->tiSuperScsiRequest.Dif.flags |= 0x03c00000;
2900
2901 #endif
2902 #ifdef AGTIAPI_TEST_DPL
2903 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2904 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2905 cmnd->result = SCSI_HOST(DID_ERROR);
2906 goto err;
2907 }
2908 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2909 #endif
2910 #ifdef AGTIAPI_TEST_DIF
2911 /* Set App Tag */
2912 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2913 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2914
2915 /* Set LBA in UDT array */
2916 if(CDB[0] == READ_6) {
2917 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2918 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2919 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2920 pccb->tiSuperScsiRequest.Dif.udtArray[5] = 0;
2921 } else if(CDB[0] == READ_10 || CDB[0] == READ_12) {
2922 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2923 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2924 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2925 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2926 } else if(CDB[0] == READ_16) {
2927 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[9];
2928 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[8];
2929 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[7];
2930 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[6];
2931 /* Note: 32 bits lost */
2932 }
2933 #endif
2934
2935 break;
2936 case WRITE_6:
2937 case WRITE_10:
2938 case WRITE_12:
2939 case WRITE_16:
2940 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2941 pccb->flags |= EDC_DATA;
2942 #ifdef AGTIAPI_TEST_DIF
2943 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2944 pccb->tiSuperScsiRequest.Dif.flags =
2945 DIF_INSERT | DIF_UDT_REF_BLOCK_COUNT;
2946 switch(pDev->sector_size) {
2947 case 528:
2948 pccb->tiSuperScsiRequest.Dif.flags |=
2949 (DIF_BLOCK_SIZE_520 << 16);
2950 break;
2951 case 4104:
2952 pccb->tiSuperScsiRequest.Dif.flags |=
2953 ( DIF_BLOCK_SIZE_4096 << 16 );
2954 break;
2955 case 4168:
2956 pccb->tiSuperScsiRequest.Dif.flags |=
2957 ( DIF_BLOCK_SIZE_4160 << 16 );
2958 break;
2959 }
2960
2961 /* Turn on upper 4 bits of UUM */
2962 pccb->tiSuperScsiRequest.Dif.flags |= 0xf0000000;
2963 #endif
2964 #ifdef AGTIAPI_TEST_DPL
2965 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2966 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2967 cmnd->result = SCSI_HOST(DID_ERROR);
2968 goto err;
2969 }
2970 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2971 #endif
2972 #ifdef AGTIAPI_TEST_DIF
2973 /* Set App Tag */
2974 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2975 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2976
2977 /* Set LBA in UDT array */
2978 if(CDB[0] == WRITE_6) {
2979 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2980 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2981 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2982 } else if(CDB[0] == WRITE_10 || CDB[0] == WRITE_12) {
2983 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2984 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2985 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2986 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2987 } else if(CDB[0] == WRITE_16) {
2988 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2989 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2990 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2991 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2992 /* Note: 32 bits lost */
2993 }
2994 #endif
2995 break;
2996 }
2997 }
2998 #endif /* end of DIF */
2999
3000 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
3001 {
3002 switch(csio->tag_action)
3003 {
3004 case MSG_HEAD_OF_Q_TAG:
3005 pScsiCmnd->taskAttribute = TASK_HEAD_OF_QUEUE;
3006 break;
3007 case MSG_ACA_TASK:
3008 pScsiCmnd->taskAttribute = TASK_ACA;
3009 break;
3010 case MSG_ORDERED_Q_TAG:
3011 pScsiCmnd->taskAttribute = TASK_ORDERED;
3012 break;
3013 case MSG_SIMPLE_Q_TAG: /* fall through */
3014 default:
3015 pScsiCmnd->taskAttribute = TASK_SIMPLE;
3016 break;
3017 }
3018 }
3019
3020 if (pccb->tiSuperScsiRequest.agSgl1.len != 0 && pccb->dataLen != 0)
3021 {
3022 /* should be just before start IO */
3023 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
3024 }
3025
3026 /*
3027 * If assigned pDevHandle is not available
3028 * then there is no need to send it to StartIO()
3029 */
3030 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
3031 {
3032 pccb->ccbStatus = tiIOFailed;
3033 pccb->scsiStatus = tiDetailNoLogin;
3034 agtiapi_FreeCCB(pmcsc, pccb);
3035 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3036 xpt_done(ccb);
3037 pccb->ccb = NULL;
3038 return;
3039 }
3040 TID = INDEX(pmcsc, pccb->targetId);
3041 if ((TID >= pmcsc->devDiscover) ||
3042 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle))
3043 {
3044 /*
3045 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: not sending ccb devH %p,"
3046 " target %d tid %d/%d card %p ERROR pccb %p\n",
3047 pccb->devHandle, pccb->targetId, TID,
3048 pmcsc->devDiscover, pmcsc, pccb );
3049 */
3050 pccb->ccbStatus = tiIOFailed;
3051 pccb->scsiStatus = tiDetailNoLogin;
3052 agtiapi_FreeCCB(pmcsc, pccb);
3053 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3054 xpt_done(ccb);
3055 pccb->ccb = NULL;
3056 return;
3057 }
3058 AGTIAPI_IO( "agtiapi_PrepareSGListCB: send ccb pccb->devHandle %p, "
3059 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3060 pccb->devHandle, pccb->targetId, TID, pmcsc->devDiscover,
3061 pmcsc );
3062 #ifdef HIALEAH_ENCRYPTION
3063 if(pmcsc->encrypt && io_is_encryptable) {
3064 agtiapi_SetupEncryptedIO(pmcsc, pccb, start_lba);
3065 } else{
3066 io_is_encryptable = 0;
3067 pccb->tiSuperScsiRequest.flags = 0;
3068 }
3069 #endif
3070 // put the request in send queue
3071 agtiapi_QueueCCB( pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3072 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb );
3073 agtiapi_StartIO(pmcsc);
3074 return;
3075 }
3076
3077 /******************************************************************************
3078 agtiapi_StartIO()
3079
3080 Purpose:
3081 Send IO request down for processing.
3082 Parameters:
3083 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3084 Return:
3085 Note:
3086 ******************************************************************************/
agtiapi_StartIO(struct agtiapi_softc * pmcsc)3087 STATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc )
3088 {
3089 ccb_t *pccb;
3090 int TID;
3091 ag_device_t *targ;
3092 struct ccb_relsim crs;
3093
3094 AGTIAPI_IO( "agtiapi_StartIO: start\n" );
3095
3096 AG_LOCAL_LOCK( &pmcsc->sendLock );
3097 pccb = pmcsc->ccbSendHead;
3098
3099 /* if link is down, do nothing */
3100 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3101 {
3102 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3103 AGTIAPI_PRINTK( "agtiapi_StartIO: goto ext\n" );
3104 goto ext;
3105 }
3106
3107
3108 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3109 {
3110 TID = INDEX(pmcsc, pccb->targetId);
3111 targ = &pmcsc->pDevList[TID];
3112 }
3113
3114
3115 /* clear send queue */
3116 pmcsc->ccbSendHead = NULL;
3117 pmcsc->ccbSendTail = NULL;
3118 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3119
3120 /* send all ccbs down */
3121 while (pccb)
3122 {
3123 pccb_t pccb_next;
3124 U32 status;
3125
3126 pccb_next = pccb->pccbNext;
3127 pccb->pccbNext = NULL;
3128
3129 if (!pccb->ccb)
3130 {
3131 AGTIAPI_PRINTK( "agtiapi_StartIO: pccb->ccb is NULL ERROR!\n" );
3132 pccb = pccb_next;
3133 continue;
3134 }
3135 AG_IO_DUMPCCB( pccb );
3136
3137 if (!pccb->devHandle)
3138 {
3139 agtiapi_DumpCCB( pccb );
3140 AGTIAPI_PRINTK( "agtiapi_StartIO: ccb NULL device ERROR!\n" );
3141 pccb = pccb_next;
3142 continue;
3143 }
3144 AGTIAPI_IO( "agtiapi_StartIO: ccb %p retry %d\n", pccb, pccb->retryCount );
3145
3146 #ifndef ABORT_TEST
3147 if( !pccb->devHandle || !pccb->devHandle->osData || /* in rmmod case */
3148 !(((ag_device_t *)(pccb->devHandle->osData))->flags & ACTIVE))
3149 {
3150 AGTIAPI_PRINTK( "agtiapi_StartIO: device %p not active! ERROR\n",
3151 pccb->devHandle );
3152 if( pccb->devHandle ) {
3153 AGTIAPI_PRINTK( "agtiapi_StartIO: device not active detail"
3154 " -- osData:%p\n",
3155 pccb->devHandle->osData );
3156 if( pccb->devHandle->osData ) {
3157 AGTIAPI_PRINTK( "agtiapi_StartIO: more device not active detail"
3158 " -- active flag:%d\n",
3159 ( (ag_device_t *)
3160 (pccb->devHandle->osData))->flags & ACTIVE );
3161 }
3162 }
3163 pccb->ccbStatus = tiIOFailed;
3164 pccb->scsiStatus = tiDetailNoLogin;
3165 agtiapi_Done( pmcsc, pccb );
3166 pccb = pccb_next;
3167 continue;
3168 }
3169 #endif
3170
3171 #ifdef FAST_IO_TEST
3172 status = agtiapi_FastIOTest( pmcsc, pccb );
3173 #else
3174 status = tiINISuperIOStart( &pmcsc->tiRoot,
3175 &pccb->tiIORequest,
3176 pccb->devHandle,
3177 &pccb->tiSuperScsiRequest,
3178 (void *)&pccb->tdIOReqBody,
3179 tiInterruptContext );
3180 #endif
3181 switch( status )
3182 {
3183 case tiSuccess:
3184 /*
3185 static int squelchCount = 0;
3186 if ( 200000 == squelchCount++ ) // squelch prints
3187 {
3188 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart stat tiSuccess %p\n",
3189 pccb );
3190 squelchCount = 0; // reset count
3191 }
3192 */
3193
3194
3195 break;
3196 case tiDeviceBusy:
3197 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiDeviceBusy %p\n",
3198 pccb->ccb );
3199 #ifdef LOGEVENT
3200 agtiapi_LogEvent( pmcsc,
3201 IOCTL_EVT_SEV_INFORMATIONAL,
3202 0,
3203 agNULL,
3204 0,
3205 "tiINIIOStart tiDeviceBusy " );
3206 #endif
3207 pccb->ccbStatus = tiIOFailed;
3208 pccb->scsiStatus = tiDeviceBusy;
3209 agtiapi_Done(pmcsc, pccb);
3210 break;
3211 case tiBusy:
3212
3213 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiBusy %p\n",
3214 pccb->ccb );
3215 #ifdef LOGEVENT
3216 agtiapi_LogEvent( pmcsc,
3217 IOCTL_EVT_SEV_INFORMATIONAL,
3218 0,
3219 agNULL,
3220 0,
3221 "tiINIIOStart tiBusy " );
3222 #endif
3223
3224 pccb->ccbStatus = tiIOFailed;
3225 pccb->scsiStatus = tiBusy;
3226 agtiapi_Done(pmcsc, pccb);
3227
3228 break;
3229 case tiIONoDevice:
3230 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiNoDevice %p "
3231 "ERROR\n", pccb->ccb );
3232 #ifdef LOGEVENT
3233 agtiapi_LogEvent( pmcsc,
3234 IOCTL_EVT_SEV_INFORMATIONAL,
3235 0,
3236 agNULL,
3237 0,
3238 "tiINIIOStart invalid device handle " );
3239 #endif
3240 #ifndef ABORT_TEST
3241 /* return command back to OS due to no device available */
3242 ((ag_device_t *)(pccb->devHandle->osData))->flags &= ~ACTIVE;
3243 pccb->ccbStatus = tiIOFailed;
3244 pccb->scsiStatus = tiDetailNoLogin;
3245 agtiapi_Done(pmcsc, pccb);
3246 #else
3247 /* for short cable pull, we want IO retried - 3-18-2005 */
3248 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3249 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
3250 #endif
3251 break;
3252 case tiError:
3253 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3254 pccb->ccb);
3255 #ifdef LOGEVENT
3256 agtiapi_LogEvent(pmcsc,
3257 IOCTL_EVT_SEV_INFORMATIONAL,
3258 0,
3259 agNULL,
3260 0,
3261 "tiINIIOStart tiError ");
3262 #endif
3263 pccb->ccbStatus = tiIOFailed;
3264 pccb->scsiStatus = tiDetailOtherError;
3265 agtiapi_Done(pmcsc, pccb);
3266 break;
3267 default:
3268 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3269 status, pccb->ccb);
3270 #ifdef LOGEVENT
3271 agtiapi_LogEvent(pmcsc,
3272 IOCTL_EVT_SEV_ERROR,
3273 0,
3274 agNULL,
3275 0,
3276 "tiINIIOStart unexpected status ");
3277 #endif
3278 pccb->ccbStatus = tiIOFailed;
3279 pccb->scsiStatus = tiDetailOtherError;
3280 agtiapi_Done(pmcsc, pccb);
3281 }
3282
3283 pccb = pccb_next;
3284 }
3285 ext:
3286 /* some IO requests might have been completed */
3287 AG_GET_DONE_PCCB(pccb, pmcsc);
3288 return;
3289 }
3290
3291 /******************************************************************************
3292 agtiapi_StartSMP()
3293
3294 Purpose:
3295 Send SMP request down for processing.
3296 Parameters:
3297 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3298 Return:
3299 Note:
3300 ******************************************************************************/
agtiapi_StartSMP(struct agtiapi_softc * pmcsc)3301 STATIC void agtiapi_StartSMP(struct agtiapi_softc *pmcsc)
3302 {
3303 ccb_t *pccb;
3304
3305 AGTIAPI_PRINTK("agtiapi_StartSMP: start\n");
3306
3307 AG_LOCAL_LOCK(&pmcsc->sendSMPLock);
3308 pccb = pmcsc->smpSendHead;
3309
3310 /* if link is down, do nothing */
3311 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3312 {
3313 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3314 AGTIAPI_PRINTK("agtiapi_StartSMP: goto ext\n");
3315 goto ext;
3316 }
3317
3318 /* clear send queue */
3319 pmcsc->smpSendHead = NULL;
3320 pmcsc->smpSendTail = NULL;
3321 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3322
3323 /* send all ccbs down */
3324 while (pccb)
3325 {
3326 pccb_t pccb_next;
3327 U32 status;
3328
3329 pccb_next = pccb->pccbNext;
3330 pccb->pccbNext = NULL;
3331
3332 if (!pccb->ccb)
3333 {
3334 AGTIAPI_PRINTK("agtiapi_StartSMP: pccb->ccb is NULL ERROR!\n");
3335 pccb = pccb_next;
3336 continue;
3337 }
3338
3339 if (!pccb->devHandle)
3340 {
3341 AGTIAPI_PRINTK("agtiapi_StartSMP: ccb NULL device ERROR!\n");
3342 pccb = pccb_next;
3343 continue;
3344 }
3345 pccb->flags |= TAG_SMP; // mark as SMP for later tracking
3346 AGTIAPI_PRINTK( "agtiapi_StartSMP: ccb %p retry %d\n",
3347 pccb, pccb->retryCount );
3348 status = tiINISMPStart( &pmcsc->tiRoot,
3349 &pccb->tiIORequest,
3350 pccb->devHandle,
3351 &pccb->tiSMPFrame,
3352 (void *)&pccb->tdIOReqBody,
3353 tiInterruptContext);
3354
3355 switch (status)
3356 {
3357 case tiSuccess:
3358 break;
3359 case tiBusy:
3360 AGTIAPI_PRINTK("agtiapi_StartSMP: tiINISMPStart status tiBusy %p\n",
3361 pccb->ccb);
3362 /* pending ccb back to send queue */
3363 agtiapi_QueueCCB(pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3364 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb);
3365 break;
3366 case tiError:
3367 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3368 pccb->ccb);
3369 pccb->ccbStatus = tiSMPFailed;
3370 agtiapi_SMPDone(pmcsc, pccb);
3371 break;
3372 default:
3373 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3374 status, pccb->ccb);
3375 pccb->ccbStatus = tiSMPFailed;
3376 agtiapi_SMPDone(pmcsc, pccb);
3377 }
3378
3379 pccb = pccb_next;
3380 }
3381 ext:
3382 /* some SMP requests might have been completed */
3383 AG_GET_DONE_SMP_PCCB(pccb, pmcsc);
3384
3385 return;
3386 }
3387
3388 #if __FreeBSD_version > 901000
3389 /******************************************************************************
3390 agtiapi_PrepareSMPSGList()
3391
3392 Purpose:
3393 This function prepares scatter-gather list for the given ccb
3394 Parameters:
3395 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3396 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3397 Return:
3398 0 - success
3399 1 - failure
3400
3401 Note:
3402 ******************************************************************************/
agtiapi_PrepareSMPSGList(struct agtiapi_softc * pmcsc,ccb_t * pccb)3403 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3404 {
3405 /* Pointer to CAM's ccb */
3406 union ccb *ccb = pccb->ccb;
3407 struct ccb_smpio *csmpio = &ccb->smpio;
3408 struct ccb_hdr *ccbh = &ccb->ccb_h;
3409
3410 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3411 switch((ccbh->flags & CAM_DATA_MASK))
3412 {
3413 case CAM_DATA_PADDR:
3414 case CAM_DATA_SG_PADDR:
3415 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address not supported\n");
3416 ccb->ccb_h.status = CAM_REQ_INVALID;
3417 xpt_done(ccb);
3418 return tiReject;
3419 case CAM_DATA_SG:
3420
3421 /*
3422 * Currently we do not support Multiple SG list
3423 * return error for now
3424 */
3425 if ( (csmpio->smp_request_sglist_cnt > 1)
3426 || (csmpio->smp_response_sglist_cnt > 1) )
3427 {
3428 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list not supported\n");
3429 ccb->ccb_h.status = CAM_REQ_INVALID;
3430 xpt_done(ccb);
3431 return tiReject;
3432 }
3433 }
3434 if ( csmpio->smp_request_sglist_cnt != 0 )
3435 {
3436 /*
3437 * Virtual address that needs to translated into
3438 * one or more physical address ranges.
3439 */
3440 int error;
3441 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3442 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3443 error = bus_dmamap_load( pmcsc->buffer_dmat,
3444 pccb->CCB_dmamap,
3445 csmpio->smp_request,
3446 csmpio->smp_request_len,
3447 agtiapi_PrepareSMPSGListCB,
3448 pccb,
3449 BUS_DMA_NOWAIT /* 0 */ );
3450
3451 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3452
3453 if (error == EINPROGRESS)
3454 {
3455 /*
3456 * So as to maintain ordering,
3457 * freeze the controller queue
3458 * until our mapping is
3459 * returned.
3460 */
3461 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3462 xpt_freeze_simq( pmcsc->sim, 1 );
3463 pmcsc->SimQFrozen = agTRUE;
3464 ccbh->status |= CAM_RELEASE_SIMQ;
3465 }
3466 }
3467 if( csmpio->smp_response_sglist_cnt != 0 )
3468 {
3469 /*
3470 * Virtual address that needs to translated into
3471 * one or more physical address ranges.
3472 */
3473 int error;
3474 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3475 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3476 error = bus_dmamap_load( pmcsc->buffer_dmat,
3477 pccb->CCB_dmamap,
3478 csmpio->smp_response,
3479 csmpio->smp_response_len,
3480 agtiapi_PrepareSMPSGListCB,
3481 pccb,
3482 BUS_DMA_NOWAIT /* 0 */ );
3483
3484 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3485
3486 if ( error == EINPROGRESS )
3487 {
3488 /*
3489 * So as to maintain ordering,
3490 * freeze the controller queue
3491 * until our mapping is
3492 * returned.
3493 */
3494 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3495 xpt_freeze_simq( pmcsc->sim, 1 );
3496 pmcsc->SimQFrozen = agTRUE;
3497 ccbh->status |= CAM_RELEASE_SIMQ;
3498 }
3499 }
3500
3501 else
3502 {
3503 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3504 (csmpio->smp_response_sglist_cnt == 0) )
3505 {
3506 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3507 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3508 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3509 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3510
3511 // 0xFF to be defined
3512 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3513 }
3514 pccb->tiSMPFrame.flag = 0;
3515 }
3516
3517 return tiSuccess;
3518 }
3519 #else
3520
3521 /******************************************************************************
3522 agtiapi_PrepareSMPSGList()
3523
3524 Purpose:
3525 This function prepares scatter-gather list for the given ccb
3526 Parameters:
3527 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3528 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3529 Return:
3530 0 - success
3531 1 - failure
3532
3533 Note:
3534 ******************************************************************************/
agtiapi_PrepareSMPSGList(struct agtiapi_softc * pmcsc,ccb_t * pccb)3535 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3536 {
3537 /* Pointer to CAM's ccb */
3538 union ccb *ccb = pccb->ccb;
3539 struct ccb_smpio *csmpio = &ccb->smpio;
3540 struct ccb_hdr *ccbh = &ccb->ccb_h;
3541
3542 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3543
3544 if (ccbh->flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS))
3545 {
3546 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address "
3547 "not supported\n" );
3548 ccb->ccb_h.status = CAM_REQ_INVALID;
3549 xpt_done(ccb);
3550 return tiReject;;
3551 }
3552
3553 if (ccbh->flags & CAM_SCATTER_VALID)
3554 {
3555 /*
3556 * Currently we do not support Multiple SG list
3557 * return error for now
3558 */
3559 if ( (csmpio->smp_request_sglist_cnt > 1)
3560 || (csmpio->smp_response_sglist_cnt > 1) )
3561 {
3562 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list "
3563 "not supported\n" );
3564 ccb->ccb_h.status = CAM_REQ_INVALID;
3565 xpt_done(ccb);
3566 return tiReject;;
3567 }
3568 if ( csmpio->smp_request_sglist_cnt != 0 )
3569 {
3570 /*
3571 * Virtual address that needs to translated into
3572 * one or more physical address ranges.
3573 */
3574 int error;
3575 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3576 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3577 error = bus_dmamap_load( pmcsc->buffer_dmat,
3578 pccb->CCB_dmamap,
3579 csmpio->smp_request,
3580 csmpio->smp_request_len,
3581 agtiapi_PrepareSMPSGListCB,
3582 pccb,
3583 BUS_DMA_NOWAIT /* 0 */ );
3584
3585 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3586
3587 if (error == EINPROGRESS)
3588 {
3589 /*
3590 * So as to maintain ordering,
3591 * freeze the controller queue
3592 * until our mapping is
3593 * returned.
3594 */
3595 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3596 xpt_freeze_simq( pmcsc->sim, 1 );
3597 pmcsc->SimQFrozen = agTRUE;
3598 ccbh->status |= CAM_RELEASE_SIMQ;
3599 }
3600 }
3601 if( csmpio->smp_response_sglist_cnt != 0 )
3602 {
3603 /*
3604 * Virtual address that needs to translated into
3605 * one or more physical address ranges.
3606 */
3607 int error;
3608 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3609 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3610 error = bus_dmamap_load( pmcsc->buffer_dmat,
3611 pccb->CCB_dmamap,
3612 csmpio->smp_response,
3613 csmpio->smp_response_len,
3614 agtiapi_PrepareSMPSGListCB,
3615 pccb,
3616 BUS_DMA_NOWAIT /* 0 */ );
3617
3618 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3619
3620 if ( error == EINPROGRESS )
3621 {
3622 /*
3623 * So as to maintain ordering,
3624 * freeze the controller queue
3625 * until our mapping is
3626 * returned.
3627 */
3628 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3629 xpt_freeze_simq( pmcsc->sim, 1 );
3630 pmcsc->SimQFrozen = agTRUE;
3631 ccbh->status |= CAM_RELEASE_SIMQ;
3632 }
3633 }
3634 }
3635 else
3636 {
3637 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3638 (csmpio->smp_response_sglist_cnt == 0) )
3639 {
3640 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3641 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3642 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3643 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3644
3645 // 0xFF to be defined
3646 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3647 }
3648 pccb->tiSMPFrame.flag = 0;
3649 }
3650
3651 return tiSuccess;
3652 }
3653
3654 #endif
3655 /******************************************************************************
3656 agtiapi_PrepareSMPSGListCB()
3657
3658 Purpose:
3659 Callback function for bus_dmamap_load()
3660 This fuctions sends IO to LL layer.
3661 Parameters:
3662 void *arg (IN) Pointer to the HBA data structure
3663 bus_dma_segment_t *segs (IN) Pointer to dma segment
3664 int nsegs (IN) number of dma segment
3665 int error (IN) error
3666 Return:
3667 Note:
3668 ******************************************************************************/
agtiapi_PrepareSMPSGListCB(void * arg,bus_dma_segment_t * segs,int nsegs,int error)3669 static void agtiapi_PrepareSMPSGListCB( void *arg,
3670 bus_dma_segment_t *segs,
3671 int nsegs,
3672 int error )
3673 {
3674 pccb_t pccb = arg;
3675 union ccb *ccb = pccb->ccb;
3676 struct agtiapi_softc *pmcsc;
3677 U32 TID = CMND_TO_TARGET(ccb);
3678 int status;
3679 tiDeviceHandle_t *tiExpDevHandle;
3680 tiPortalContext_t *tiExpPortalContext;
3681 ag_portal_info_t *tiExpPortalInfo;
3682
3683 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: start, nsegs %d error 0x%x\n",
3684 nsegs, error );
3685 pmcsc = pccb->pmcsc;
3686
3687 if ( error != tiSuccess )
3688 {
3689 if (error == 0xAABBCCDD)
3690 {
3691 // do nothing
3692 }
3693 else
3694 {
3695 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: error status 0x%x\n",
3696 error );
3697 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3698 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3699 agtiapi_FreeCCB( pmcsc, pccb );
3700 ccb->ccb_h.status = CAM_REQ_CMP;
3701 xpt_done( ccb );
3702 return;
3703 }
3704 }
3705
3706 if ( nsegs > AGTIAPI_MAX_DMA_SEGS )
3707 {
3708 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: over the limit. nsegs %d "
3709 "AGTIAPI_MAX_DMA_SEGS %d\n",
3710 nsegs, AGTIAPI_MAX_DMA_SEGS );
3711 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3712 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3713 agtiapi_FreeCCB( pmcsc, pccb );
3714 ccb->ccb_h.status = CAM_REQ_CMP;
3715 xpt_done( ccb );
3716 return;
3717 }
3718
3719 /*
3720 * If assigned pDevHandle is not available
3721 * then there is no need to send it to StartIO()
3722 */
3723 /* TODO: Add check for deviceType */
3724 if ( pccb->targetId < 0 || pccb->targetId >= maxTargets )
3725 {
3726 agtiapi_FreeCCB( pmcsc, pccb );
3727 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3728 xpt_done(ccb);
3729 pccb->ccb = NULL;
3730 return;
3731 }
3732 TID = INDEX( pmcsc, pccb->targetId );
3733 if ( (TID >= pmcsc->devDiscover) ||
3734 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle) )
3735 {
3736 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: not sending ccb devH %p, "
3737 "target %d tid %d/%d "
3738 "card %p ERROR pccb %p\n",
3739 pccb->devHandle,
3740 pccb->targetId,
3741 TID,
3742 pmcsc->devDiscover,
3743 pmcsc,
3744 pccb );
3745 agtiapi_FreeCCB( pmcsc, pccb );
3746 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3747 xpt_done( ccb );
3748 pccb->ccb = NULL;
3749 return;
3750 }
3751 /* TODO: add indirect handling */
3752 /* set the flag correctly based on Indiret SMP request and response */
3753
3754 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, "
3755 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3756 pccb->devHandle,
3757 pccb->targetId, TID,
3758 pmcsc->devDiscover,
3759 pmcsc );
3760 tiExpDevHandle = pccb->devHandle;
3761 tiExpPortalInfo = pmcsc->pDevList[TID].pPortalInfo;
3762 tiExpPortalContext = &tiExpPortalInfo->tiPortalContext;
3763 /* Look for the expander associated with the ses device */
3764 status = tiINIGetExpander( &pmcsc->tiRoot,
3765 tiExpPortalContext,
3766 pccb->devHandle,
3767 &tiExpDevHandle );
3768
3769 if ( status != tiSuccess )
3770 {
3771 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: Error getting Expander "
3772 "device\n" );
3773 agtiapi_FreeCCB( pmcsc, pccb );
3774 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3775 xpt_done( ccb );
3776 pccb->ccb = NULL;
3777 return;
3778 }
3779
3780 /* this is expander device */
3781 pccb->devHandle = tiExpDevHandle;
3782 /* put the request in send queue */
3783 agtiapi_QueueCCB( pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3784 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb );
3785
3786 agtiapi_StartSMP( pmcsc );
3787
3788 return;
3789 }
3790
3791
3792 /******************************************************************************
3793 agtiapi_Done()
3794
3795 Purpose:
3796 Processing completed ccbs
3797 Parameters:
3798 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3799 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3800 Return:
3801 Note:
3802 ******************************************************************************/
agtiapi_Done(struct agtiapi_softc * pmcsc,ccb_t * pccb)3803 STATIC void agtiapi_Done(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3804 {
3805 pccb_t pccb_curr = pccb;
3806 pccb_t pccb_next;
3807
3808 tiIniScsiCmnd_t *cmnd;
3809 union ccb * ccb;
3810
3811 AGTIAPI_IO("agtiapi_Done: start\n");
3812 while (pccb_curr)
3813 {
3814 /* start from 1st ccb in the chain */
3815 pccb_next = pccb_curr->pccbNext;
3816
3817 if (agtiapi_CheckError(pmcsc, pccb_curr) != 0)
3818 {
3819 /* send command back and release the ccb */
3820 cmnd = &pccb_curr->tiSuperScsiRequest.scsiCmnd;
3821
3822 if (cmnd->cdb[0] == RECEIVE_DIAGNOSTIC)
3823 {
3824 AGTIAPI_PRINTK("agtiapi_Done: RECEIVE_DIAG pg %d id %d cmnd %p pccb "
3825 "%p\n", cmnd->cdb[2], pccb_curr->targetId, cmnd,
3826 pccb_curr);
3827 }
3828
3829 CMND_DMA_UNMAP(pmcsc, ccb);
3830
3831 /* send the request back to the CAM */
3832 ccb = pccb_curr->ccb;
3833 agtiapi_FreeCCB(pmcsc, pccb_curr);
3834 xpt_done(ccb);
3835 }
3836 pccb_curr = pccb_next;
3837 }
3838 return;
3839 }
3840
3841 /******************************************************************************
3842 agtiapi_SMPDone()
3843
3844 Purpose:
3845 Processing completed ccbs
3846 Parameters:
3847 struct agtiapi_softc *pmcsc (IN) Ponter to HBA data structure
3848 ccb_t *pccb (IN) A pointer to the driver's own CCB, not
3849 CAM's CCB
3850 Return:
3851 Note:
3852 ******************************************************************************/
agtiapi_SMPDone(struct agtiapi_softc * pmcsc,ccb_t * pccb)3853 STATIC void agtiapi_SMPDone(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3854 {
3855 pccb_t pccb_curr = pccb;
3856 pccb_t pccb_next;
3857
3858 union ccb * ccb;
3859
3860 AGTIAPI_PRINTK("agtiapi_SMPDone: start\n");
3861
3862 while (pccb_curr)
3863 {
3864 /* start from 1st ccb in the chain */
3865 pccb_next = pccb_curr->pccbNext;
3866
3867 if (agtiapi_CheckSMPError(pmcsc, pccb_curr) != 0)
3868 {
3869 CMND_DMA_UNMAP(pmcsc, ccb);
3870
3871 /* send the request back to the CAM */
3872 ccb = pccb_curr->ccb;
3873 agtiapi_FreeSMPCCB(pmcsc, pccb_curr);
3874 xpt_done(ccb);
3875
3876 }
3877 pccb_curr = pccb_next;
3878 }
3879
3880 AGTIAPI_PRINTK("agtiapi_SMPDone: Done\n");
3881 return;
3882 }
3883
3884 /******************************************************************************
3885 agtiapi_hexdump()
3886
3887 Purpose:
3888 Utility function for dumping in hex
3889 Parameters:
3890 const char *ptitle (IN) A string to be printed
3891 bit8 *pbuf (IN) A pointer to a buffer to be printed.
3892 int len (IN) The lengther of the buffer
3893 Return:
3894 Note:
3895 ******************************************************************************/
agtiapi_hexdump(const char * ptitle,bit8 * pbuf,int len)3896 void agtiapi_hexdump(const char *ptitle, bit8 *pbuf, int len)
3897 {
3898 int i;
3899 AGTIAPI_PRINTK("%s - hexdump(len=%d):\n", ptitle, (int)len);
3900 if (!pbuf)
3901 {
3902 AGTIAPI_PRINTK("pbuf is NULL\n");
3903 return;
3904 }
3905 for (i = 0; i < len; )
3906 {
3907 if (len - i > 4)
3908 {
3909 AGTIAPI_PRINTK( " 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1],
3910 pbuf[i+2], pbuf[i+3] );
3911 i += 4;
3912 }
3913 else
3914 {
3915 AGTIAPI_PRINTK(" 0x%02x,", pbuf[i]);
3916 i++;
3917 }
3918 }
3919 AGTIAPI_PRINTK("\n");
3920 }
3921
3922
3923 /******************************************************************************
3924 agtiapi_CheckError()
3925
3926 Purpose:
3927 Processes status pertaining to the ccb -- whether it was
3928 completed successfully, aborted, or error encountered.
3929 Parameters:
3930 ag_card_t *pCard (IN) Pointer to HBA data structure
3931 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
3932 Return:
3933 0 - the command retry is required
3934 1 - the command process is completed
3935 Note:
3936
3937 ******************************************************************************/
agtiapi_CheckError(struct agtiapi_softc * pmcsc,ccb_t * pccb)3938 STATIC U32 agtiapi_CheckError(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3939 {
3940 ag_device_t *pDevice;
3941 // union ccb * ccb = pccb->ccb;
3942 union ccb * ccb;
3943 int is_error, TID;
3944
3945 if (pccb == NULL) {
3946 return 0;
3947 }
3948 ccb = pccb->ccb;
3949 AGTIAPI_IO("agtiapi_CheckError: start\n");
3950 if (ccb == NULL)
3951 {
3952 /* shouldn't be here but just in case we do */
3953 AGTIAPI_PRINTK("agtiapi_CheckError: CCB orphan = %p ERROR\n", pccb);
3954 agtiapi_FreeCCB(pmcsc, pccb);
3955 return 0;
3956 }
3957
3958 is_error = 1;
3959 pDevice = NULL;
3960 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3961 {
3962 if (pmcsc->pWWNList != NULL)
3963 {
3964 TID = INDEX(pmcsc, pccb->targetId);
3965 if (TID < maxTargets)
3966 {
3967 pDevice = &pmcsc->pDevList[TID];
3968 if (pDevice != NULL)
3969 {
3970 is_error = 0;
3971 }
3972 }
3973 }
3974 }
3975 if (is_error)
3976 {
3977 AGTIAPI_PRINTK("agtiapi_CheckError: pDevice == NULL\n");
3978 agtiapi_FreeCCB(pmcsc, pccb);
3979 return 0;
3980 }
3981
3982 /* SCSI status */
3983 ccb->csio.scsi_status = pccb->scsiStatus;
3984
3985 if(pDevice->CCBCount > 0){
3986 atomic_subtract_int(&pDevice->CCBCount,1);
3987 }
3988 AG_LOCAL_LOCK(&pmcsc->freezeLock);
3989 if(pmcsc->freezeSim == agTRUE)
3990 {
3991 pmcsc->freezeSim = agFALSE;
3992 xpt_release_simq(pmcsc->sim, 1);
3993 }
3994 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
3995
3996 switch (pccb->ccbStatus)
3997 {
3998 case tiIOSuccess:
3999 AGTIAPI_IO("agtiapi_CheckError: tiIOSuccess pccb %p\n", pccb);
4000 /* CAM status */
4001 if (pccb->scsiStatus == SCSI_STATUS_OK)
4002 {
4003 ccb->ccb_h.status = CAM_REQ_CMP;
4004 }
4005 else
4006 if (pccb->scsiStatus == SCSI_TASK_ABORTED)
4007 {
4008 ccb->ccb_h.status = CAM_REQ_ABORTED;
4009 }
4010 else
4011 {
4012 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
4013 }
4014 if (ccb->csio.scsi_status == SCSI_CHECK_CONDITION)
4015 {
4016 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
4017 }
4018
4019 break;
4020
4021 case tiIOOverRun:
4022 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOOverRun pccb %p\n", pccb);
4023 /* resid is ignored for this condition */
4024 ccb->csio.resid = 0;
4025 ccb->ccb_h.status = CAM_DATA_RUN_ERR;
4026 break;
4027 case tiIOUnderRun:
4028 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOUnderRun pccb %p\n", pccb);
4029 ccb->csio.resid = pccb->scsiStatus;
4030 ccb->ccb_h.status = CAM_REQ_CMP;
4031 ccb->csio.scsi_status = SCSI_STATUS_OK;
4032 break;
4033
4034 case tiIOFailed:
4035 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4036 pccb, pccb->scsiStatus, pccb->targetId );
4037 if (pccb->scsiStatus == tiDeviceBusy)
4038 {
4039 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - tiDetailBusy\n",
4040 pccb );
4041 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
4042 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4043 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0)
4044 {
4045 ccb->ccb_h.status |= CAM_DEV_QFRZN;
4046 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
4047 }
4048 }
4049 else if(pccb->scsiStatus == tiBusy)
4050 {
4051 AG_LOCAL_LOCK(&pmcsc->freezeLock);
4052 if(pmcsc->freezeSim == agFALSE)
4053 {
4054 pmcsc->freezeSim = agTRUE;
4055 xpt_freeze_simq(pmcsc->sim, 1);
4056 }
4057 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
4058 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4059 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4060 }
4061 else if (pccb->scsiStatus == tiDetailNoLogin)
4062 {
4063 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4064 "tiDetailNoLogin ERROR\n", pccb );
4065 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
4066 }
4067 else if (pccb->scsiStatus == tiDetailNotValid)
4068 {
4069 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4070 "tiDetailNotValid ERROR\n", pccb );
4071 ccb->ccb_h.status = CAM_REQ_INVALID;
4072 }
4073 else if (pccb->scsiStatus == tiDetailAbortLogin)
4074 {
4075 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4076 "tiDetailAbortLogin ERROR\n", pccb );
4077 ccb->ccb_h.status = CAM_REQ_ABORTED;
4078 }
4079 else if (pccb->scsiStatus == tiDetailAbortReset)
4080 {
4081 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4082 "tiDetailAbortReset ERROR\n", pccb );
4083 ccb->ccb_h.status = CAM_REQ_ABORTED;
4084 }
4085 else if (pccb->scsiStatus == tiDetailAborted)
4086 {
4087 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4088 "tiDetailAborted ERROR\n", pccb );
4089 ccb->ccb_h.status = CAM_REQ_ABORTED;
4090 }
4091 else if (pccb->scsiStatus == tiDetailOtherError)
4092 {
4093 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4094 "tiDetailOtherError ERROR\n", pccb );
4095 ccb->ccb_h.status = CAM_REQ_ABORTED;
4096 }
4097 break;
4098 case tiIODifError:
4099 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4100 pccb, pccb->scsiStatus, pccb->targetId );
4101 if (pccb->scsiStatus == tiDetailDifAppTagMismatch)
4102 {
4103 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - "
4104 "tiDetailDifAppTagMismatch\n", pccb );
4105 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4106 }
4107 else if (pccb->scsiStatus == tiDetailDifRefTagMismatch)
4108 {
4109 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4110 "tiDetailDifRefTagMismatch\n", pccb );
4111 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4112 }
4113 else if (pccb->scsiStatus == tiDetailDifCrcMismatch)
4114 {
4115 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4116 "tiDetailDifCrcMismatch\n", pccb );
4117 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4118 }
4119 break;
4120 #ifdef HIALEAH_ENCRYPTION
4121 case tiIOEncryptError:
4122 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4123 pccb, pccb->scsiStatus, pccb->targetId );
4124 if (pccb->scsiStatus == tiDetailDekKeyCacheMiss)
4125 {
4126 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4127 "tiDetailDekKeyCacheMiss ERROR\n",
4128 __FUNCTION__, pccb );
4129 ccb->ccb_h.status = CAM_REQ_ABORTED;
4130 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4131 }
4132 else if (pccb->scsiStatus == tiDetailDekIVMismatch)
4133 {
4134 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4135 "tiDetailDekIVMismatch ERROR\n", __FUNCTION__, pccb );
4136 ccb->ccb_h.status = CAM_REQ_ABORTED;
4137 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4138 }
4139 break;
4140 #endif
4141 default:
4142 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOdefault %d id %d ERROR\n",
4143 pccb, pccb->ccbStatus, pccb->targetId );
4144 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4145 break;
4146 }
4147
4148 return 1;
4149 }
4150
4151
4152 /******************************************************************************
4153 agtiapi_SMPCheckError()
4154
4155 Purpose:
4156 Processes status pertaining to the ccb -- whether it was
4157 completed successfully, aborted, or error encountered.
4158 Parameters:
4159 ag_card_t *pCard (IN) Pointer to HBA data structure
4160 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
4161 Return:
4162 0 - the command retry is required
4163 1 - the command process is completed
4164 Note:
4165
4166 ******************************************************************************/
agtiapi_CheckSMPError(struct agtiapi_softc * pmcsc,ccb_t * pccb)4167 STATIC U32 agtiapi_CheckSMPError( struct agtiapi_softc *pmcsc, ccb_t *pccb )
4168 {
4169 union ccb * ccb = pccb->ccb;
4170
4171 AGTIAPI_PRINTK("agtiapi_CheckSMPError: start\n");
4172
4173 if (!ccb)
4174 {
4175 /* shouldn't be here but just in case we do */
4176 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: CCB orphan = %p ERROR\n",
4177 pccb );
4178 agtiapi_FreeSMPCCB(pmcsc, pccb);
4179 return 0;
4180 }
4181
4182 switch (pccb->ccbStatus)
4183 {
4184 case tiSMPSuccess:
4185 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPSuccess pccb %p\n",
4186 pccb );
4187 /* CAM status */
4188 ccb->ccb_h.status = CAM_REQ_CMP;
4189 break;
4190 case tiSMPFailed:
4191 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPFailed pccb %p\n",
4192 pccb );
4193 /* CAM status */
4194 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4195 break;
4196 default:
4197 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: pccb %p tiSMPdefault %d "
4198 "id %d ERROR\n",
4199 pccb,
4200 pccb->ccbStatus,
4201 pccb->targetId );
4202 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4203 break;
4204 }
4205
4206
4207 return 1;
4208
4209 }
4210
4211 /******************************************************************************
4212 agtiapi_HandleEncryptedIOFailure():
4213
4214 Purpose:
4215 Parameters:
4216 Return:
4217 Note:
4218 Currently not used.
4219 ******************************************************************************/
agtiapi_HandleEncryptedIOFailure(ag_device_t * pDev,ccb_t * pccb)4220 void agtiapi_HandleEncryptedIOFailure(ag_device_t *pDev, ccb_t *pccb)
4221 {
4222
4223 AGTIAPI_PRINTK("agtiapi_HandleEncryptedIOFailure: start\n");
4224 return;
4225 }
4226
4227 /******************************************************************************
4228 agtiapi_Retry()
4229
4230 Purpose:
4231 Retry a ccb.
4232 Parameters:
4233 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA structure
4234 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4235 Return:
4236 Note:
4237 Currently not used.
4238 ******************************************************************************/
agtiapi_Retry(struct agtiapi_softc * pmcsc,ccb_t * pccb)4239 STATIC void agtiapi_Retry(struct agtiapi_softc *pmcsc, ccb_t *pccb)
4240 {
4241 pccb->retryCount++;
4242 pccb->flags = ACTIVE | AGTIAPI_RETRY;
4243 pccb->ccbStatus = 0;
4244 pccb->scsiStatus = 0;
4245 pccb->startTime = ticks;
4246
4247 AGTIAPI_PRINTK( "agtiapi_Retry: start\n" );
4248 AGTIAPI_PRINTK( "agtiapi_Retry: ccb %p retry %d flgs x%x\n", pccb,
4249 pccb->retryCount, pccb->flags );
4250
4251 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
4252 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
4253 return;
4254 }
4255
4256
4257 /******************************************************************************
4258 agtiapi_DumpCCB()
4259
4260 Purpose:
4261 Dump CCB for debuging
4262 Parameters:
4263 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4264 Return:
4265 Note:
4266 ******************************************************************************/
agtiapi_DumpCCB(ccb_t * pccb)4267 STATIC void agtiapi_DumpCCB(ccb_t *pccb)
4268 {
4269 AGTIAPI_PRINTK("agtiapi_DumpCCB: pccb %p, devHandle %p, tid %d, lun %d\n",
4270 pccb,
4271 pccb->devHandle,
4272 pccb->targetId,
4273 pccb->lun);
4274 AGTIAPI_PRINTK("flag 0x%x, add_mode 0x%x, ccbStatus 0x%x, scsiStatus 0x%x\n",
4275 pccb->flags,
4276 pccb->addrMode,
4277 pccb->ccbStatus,
4278 pccb->scsiStatus);
4279 AGTIAPI_PRINTK("scsi comand = 0x%x, numSgElements = %d\n",
4280 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4281 pccb->numSgElements);
4282 AGTIAPI_PRINTK("dataLen = 0x%x, sens_len = 0x%x\n",
4283 pccb->dataLen,
4284 pccb->senseLen);
4285 AGTIAPI_PRINTK("tiSuperScsiRequest:\n");
4286 AGTIAPI_PRINTK("scsiCmnd: expDataLength 0x%x, taskAttribute 0x%x\n",
4287 pccb->tiSuperScsiRequest.scsiCmnd.expDataLength,
4288 pccb->tiSuperScsiRequest.scsiCmnd.taskAttribute);
4289 AGTIAPI_PRINTK("cdb[0] = 0x%x, cdb[1] = 0x%x, cdb[2] = 0x%x, cdb[3] = 0x%x\n",
4290 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4291 pccb->tiSuperScsiRequest.scsiCmnd.cdb[1],
4292 pccb->tiSuperScsiRequest.scsiCmnd.cdb[2],
4293 pccb->tiSuperScsiRequest.scsiCmnd.cdb[3]);
4294 AGTIAPI_PRINTK("cdb[4] = 0x%x, cdb[5] = 0x%x, cdb[6] = 0x%x, cdb[7] = 0x%x\n",
4295 pccb->tiSuperScsiRequest.scsiCmnd.cdb[4],
4296 pccb->tiSuperScsiRequest.scsiCmnd.cdb[5],
4297 pccb->tiSuperScsiRequest.scsiCmnd.cdb[6],
4298 pccb->tiSuperScsiRequest.scsiCmnd.cdb[7]);
4299 AGTIAPI_PRINTK( "cdb[8] = 0x%x, cdb[9] = 0x%x, cdb[10] = 0x%x, "
4300 "cdb[11] = 0x%x\n",
4301 pccb->tiSuperScsiRequest.scsiCmnd.cdb[8],
4302 pccb->tiSuperScsiRequest.scsiCmnd.cdb[9],
4303 pccb->tiSuperScsiRequest.scsiCmnd.cdb[10],
4304 pccb->tiSuperScsiRequest.scsiCmnd.cdb[11] );
4305 AGTIAPI_PRINTK("agSgl1: upper 0x%x, lower 0x%x, len 0x%x, type %d\n",
4306 pccb->tiSuperScsiRequest.agSgl1.upper,
4307 pccb->tiSuperScsiRequest.agSgl1.lower,
4308 pccb->tiSuperScsiRequest.agSgl1.len,
4309 pccb->tiSuperScsiRequest.agSgl1.type);
4310 }
4311
4312 /******************************************************************************
4313 agtiapi_eh_HostReset()
4314
4315 Purpose:
4316 A new error handler of Host Reset command.
4317 Parameters:
4318 scsi_cmnd *cmnd (IN) Pointer to a command to the HBA to be reset
4319 Return:
4320 SUCCESS - success
4321 FAILED - fail
4322 Note:
4323 ******************************************************************************/
agtiapi_eh_HostReset(struct agtiapi_softc * pmcsc,union ccb * cmnd)4324 int agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4325 {
4326 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4327 cmnd );
4328
4329 if( cmnd == NULL )
4330 {
4331 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4332 return tiInvalidHandle;
4333 }
4334
4335 #ifdef LOGEVENT
4336 agtiapi_LogEvent( pmcsc,
4337 IOCTL_EVT_SEV_INFORMATIONAL,
4338 0,
4339 agNULL,
4340 0,
4341 "agtiapi_eh_HostReset! " );
4342 #endif
4343
4344 return agtiapi_DoSoftReset( pmcsc );
4345 }
4346
4347
agtiapi_eh_DeviceReset(struct agtiapi_softc * pmcsc,union ccb * cmnd)4348 int agtiapi_eh_DeviceReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4349 {
4350 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4351 cmnd );
4352
4353 if( cmnd == NULL )
4354 {
4355 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4356 return tiInvalidHandle;
4357 }
4358 return agtiapi_DoSoftReset( pmcsc );
4359 }
4360 /******************************************************************************
4361 agtiapi_QueueCCB()
4362
4363 Purpose:
4364 Put ccb in ccb queue at the tail
4365 Parameters:
4366 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4367 pccb_t *phead (IN) Double pointer to ccb queue head
4368 pccb_t *ptail (IN) Double pointer to ccb queue tail
4369 ccb_t *pccb (IN) Poiner to a ccb to be queued
4370 Return:
4371 Note:
4372 Put the ccb to the tail of queue
4373 ******************************************************************************/
agtiapi_QueueCCB(struct agtiapi_softc * pmcsc,pccb_t * phead,pccb_t * ptail,struct mtx * mutex,ccb_t * pccb)4374 STATIC void agtiapi_QueueCCB( struct agtiapi_softc *pmcsc,
4375 pccb_t *phead,
4376 pccb_t *ptail,
4377 #ifdef AGTIAPI_LOCAL_LOCK
4378 struct mtx *mutex,
4379 #endif
4380 ccb_t *pccb )
4381 {
4382 AGTIAPI_IO( "agtiapi_QueueCCB: start\n" );
4383 AGTIAPI_IO( "agtiapi_QueueCCB: %p to %p\n", pccb, phead );
4384 if (phead == NULL || ptail == NULL)
4385 {
4386 panic( "agtiapi_QueueCCB: phead %p ptail %p", phead, ptail );
4387 }
4388 pccb->pccbNext = NULL;
4389 AG_LOCAL_LOCK( mutex );
4390 if (*phead == NULL)
4391 {
4392 //WARN_ON(*ptail != NULL); /* critical, just get more logs */
4393 *phead = pccb;
4394 }
4395 else
4396 {
4397 //WARN_ON(*ptail == NULL); /* critical, just get more logs */
4398 if (*ptail)
4399 (*ptail)->pccbNext = pccb;
4400 }
4401 *ptail = pccb;
4402 AG_LOCAL_UNLOCK( mutex );
4403 return;
4404 }
4405
4406
4407 /******************************************************************************
4408 agtiapi_QueueCCB()
4409
4410 Purpose:
4411
4412 Parameters:
4413
4414
4415 Return:
4416 Note:
4417
4418 ******************************************************************************/
agtiapi_QueueSMP(struct agtiapi_softc * pmcsc,union ccb * ccb)4419 static int agtiapi_QueueSMP(struct agtiapi_softc *pmcsc, union ccb * ccb)
4420 {
4421 pccb_t pccb = agNULL; /* call dequeue */
4422 int status = tiSuccess;
4423 int targetID = xpt_path_target_id(ccb->ccb_h.path);
4424
4425 AGTIAPI_PRINTK("agtiapi_QueueSMP: start\n");
4426
4427 /* get a ccb */
4428 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
4429 {
4430 AGTIAPI_PRINTK("agtiapi_QueueSMP: GetCCB ERROR\n");
4431 ccb->ccb_h.status = CAM_REQ_CMP;
4432 xpt_done(ccb);
4433 return tiBusy;
4434 }
4435 pccb->pmcsc = pmcsc;
4436
4437 /* initialize Command Control Block (CCB) */
4438 pccb->targetId = targetID;
4439 pccb->ccb = ccb; /* for struct scsi_cmnd */
4440
4441 status = agtiapi_PrepareSMPSGList(pmcsc, pccb);
4442
4443 if (status != tiSuccess)
4444 {
4445 AGTIAPI_PRINTK("agtiapi_QueueSMP: agtiapi_PrepareSMPSGList failure\n");
4446 agtiapi_FreeCCB(pmcsc, pccb);
4447 if (status == tiReject)
4448 {
4449 ccb->ccb_h.status = CAM_REQ_INVALID;
4450 }
4451 else
4452 {
4453 ccb->ccb_h.status = CAM_REQ_CMP;
4454 }
4455 xpt_done(ccb);
4456 return tiError;
4457 }
4458
4459 return status;
4460 }
4461
4462 /******************************************************************************
4463 agtiapi_SetLunField()
4464
4465 Purpose:
4466 Set LUN field based on different address mode
4467 Parameters:
4468 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4469 Return:
4470 Note:
4471 ******************************************************************************/
agtiapi_SetLunField(ccb_t * pccb)4472 void agtiapi_SetLunField(ccb_t *pccb)
4473 {
4474 U08 *pchar;
4475
4476 pchar = (U08 *)&pccb->tiSuperScsiRequest.scsiCmnd.lun;
4477
4478 // AGTIAPI_PRINTK("agtiapi_SetLunField: start\n");
4479
4480 switch (pccb->addrMode)
4481 {
4482 case AGTIAPI_PERIPHERAL:
4483 *pchar++ = 0;
4484 *pchar = (U08)pccb->lun;
4485 break;
4486 case AGTIAPI_VOLUME_SET:
4487 *pchar++ = (AGTIAPI_VOLUME_SET << AGTIAPI_ADDRMODE_SHIFT) |
4488 (U08)((pccb->lun >> 8) & 0x3F);
4489 *pchar = (U08)pccb->lun;
4490 break;
4491 case AGTIAPI_LUN_ADDR:
4492 *pchar++ = (AGTIAPI_LUN_ADDR << AGTIAPI_ADDRMODE_SHIFT) |
4493 pccb->targetId;
4494 *pchar = (U08)pccb->lun;
4495 break;
4496 }
4497
4498
4499 }
4500
4501
4502 /*****************************************************************************
4503 agtiapi_FreeCCB()
4504
4505 Purpose:
4506 Free a ccb and put it back to ccbFreeList.
4507 Parameters:
4508 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4509 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4510 CAM's CCB
4511 Returns:
4512 Note:
4513 *****************************************************************************/
agtiapi_FreeCCB(struct agtiapi_softc * pmcsc,pccb_t pccb)4514 STATIC void agtiapi_FreeCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4515 {
4516 union ccb *ccb = pccb->ccb;
4517 bus_dmasync_op_t op;
4518
4519 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4520 AGTIAPI_IO( "agtiapi_FreeCCB: start %p\n", pccb );
4521
4522 #ifdef AGTIAPI_TEST_EPL
4523 tiEncrypt_t *encrypt;
4524 #endif
4525
4526 agtiapi_DumpCDB( "agtiapi_FreeCCB", pccb );
4527
4528 if (pccb->sgList != agNULL)
4529 {
4530 AGTIAPI_IO( "agtiapi_FreeCCB: pccb->sgList is NOT null\n" );
4531 }
4532 else
4533 {
4534 AGTIAPI_PRINTK( "agtiapi_FreeCCB: pccb->sgList is null\n" );
4535 }
4536
4537 /* set data transfer direction */
4538 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4539 {
4540 op = BUS_DMASYNC_POSTWRITE;
4541 }
4542 else
4543 {
4544 op = BUS_DMASYNC_POSTREAD;
4545 }
4546
4547 if (pccb->numSgElements == 0)
4548 {
4549 // do nothing
4550 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements zero\n" );
4551 }
4552 else if (pccb->numSgElements == 1)
4553 {
4554 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements is one\n" );
4555 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4556 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4557 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4558 }
4559 else
4560 {
4561 AGTIAPI_PRINTK( "agtiapi_FreeCCB: numSgElements 2 or higher \n" );
4562 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4563 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4564 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4565 }
4566
4567 #ifdef AGTIAPI_TEST_DPL
4568 if (pccb->tiSuperScsiRequest.Dif.enableDIFPerLA == TRUE) {
4569 if(pccb->dplPtr)
4570 memset( (char *) pccb->dplPtr,
4571 0,
4572 MAX_DPL_REGIONS * sizeof(dplaRegion_t) );
4573 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = FALSE;
4574 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrLo = 0;
4575 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrHi = 0;
4576 }
4577 #endif
4578
4579 #ifdef AGTIAPI_TEST_EPL
4580 encrypt = &pccb->tiSuperScsiRequest.Encrypt;
4581 if (encrypt->enableEncryptionPerLA == TRUE) {
4582 encrypt->enableEncryptionPerLA = FALSE;
4583 encrypt->EncryptionPerLAAddrLo = 0;
4584 encrypt->EncryptionPerLAAddrHi = 0;
4585 }
4586 #endif
4587
4588 #ifdef ENABLE_SATA_DIF
4589 if (pccb->holePtr && pccb->dmaHandleHole)
4590 pci_free_consistent( pmcsc->pCardInfo->pPCIDev,
4591 512,
4592 pccb->holePtr,
4593 pccb->dmaHandleHole );
4594 pccb->holePtr = 0;
4595 pccb->dmaHandleHole = 0;
4596 #endif
4597
4598 pccb->dataLen = 0;
4599 pccb->retryCount = 0;
4600 pccb->ccbStatus = 0;
4601 pccb->scsiStatus = 0;
4602 pccb->startTime = 0;
4603 pccb->dmaHandle = 0;
4604 pccb->numSgElements = 0;
4605 pccb->tiIORequest.tdData = 0;
4606 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4607
4608 #ifdef HIALEAH_ENCRYPTION
4609 if (pmcsc->encrypt)
4610 agtiapi_CleanupEncryptedIO(pmcsc, pccb);
4611 #endif
4612
4613 pccb->flags = 0;
4614 pccb->ccb = NULL;
4615 pccb->pccbIO = NULL;
4616 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4617 pmcsc->ccbFreeList = (caddr_t *)pccb;
4618
4619 pmcsc->activeCCB--;
4620
4621 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4622 return;
4623 }
4624
4625
4626 /******************************************************************************
4627 agtiapi_FlushCCBs()
4628
4629 Purpose:
4630 Flush all in processed ccbs.
4631 Parameters:
4632 ag_card_t *pCard (IN) Pointer to HBA data structure
4633 U32 flag (IN) Flag to call back
4634 Return:
4635 Note:
4636 ******************************************************************************/
agtiapi_FlushCCBs(struct agtiapi_softc * pCard,U32 flag)4637 STATIC void agtiapi_FlushCCBs( struct agtiapi_softc *pCard, U32 flag )
4638 {
4639 union ccb *ccb;
4640 ccb_t *pccb;
4641
4642 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: enter \n" );
4643 for( pccb = (pccb_t)pCard->ccbChainList;
4644 pccb != NULL;
4645 pccb = pccb->pccbChainNext ) {
4646 if( pccb->flags == 0 )
4647 {
4648 // printf( "agtiapi_FlushCCBs: nothing, continue \n" );
4649 continue;
4650 }
4651 ccb = pccb->ccb;
4652 if ( pccb->flags & ( TASK_MANAGEMENT | DEV_RESET ) )
4653 {
4654 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeTMCCB \n" );
4655 agtiapi_FreeTMCCB( pCard, pccb );
4656 }
4657 else
4658 {
4659 if ( pccb->flags & TAG_SMP )
4660 {
4661 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeSMPCCB \n" );
4662 agtiapi_FreeSMPCCB( pCard, pccb );
4663 }
4664 else
4665 {
4666 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeCCB \n" );
4667 agtiapi_FreeCCB( pCard, pccb );
4668 }
4669 if( ccb ) {
4670 CMND_DMA_UNMAP( pCard, ccb );
4671 if( flag == AGTIAPI_CALLBACK ) {
4672 ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
4673 xpt_done( ccb );
4674 }
4675 }
4676 }
4677 }
4678 }
4679
4680 /*****************************************************************************
4681 agtiapi_FreeSMPCCB()
4682
4683 Purpose:
4684 Free a ccb and put it back to ccbFreeList.
4685 Parameters:
4686 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4687 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4688 CAM's CCB
4689 Returns:
4690 Note:
4691 *****************************************************************************/
agtiapi_FreeSMPCCB(struct agtiapi_softc * pmcsc,pccb_t pccb)4692 STATIC void agtiapi_FreeSMPCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4693 {
4694 union ccb *ccb = pccb->ccb;
4695 bus_dmasync_op_t op;
4696
4697 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4698 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: start %p\n", pccb);
4699
4700 /* set data transfer direction */
4701 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4702 {
4703 op = BUS_DMASYNC_POSTWRITE;
4704 }
4705 else
4706 {
4707 op = BUS_DMASYNC_POSTREAD;
4708 }
4709
4710 if (pccb->numSgElements == 0)
4711 {
4712 // do nothing
4713 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 0\n");
4714 }
4715 else if (pccb->numSgElements == 1)
4716 {
4717 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 1\n");
4718 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4719 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4720 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4721 }
4722 else
4723 {
4724 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 2 or higher \n");
4725 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4726 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4727 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4728 }
4729
4730 /*dma api cleanning*/
4731 pccb->dataLen = 0;
4732 pccb->retryCount = 0;
4733 pccb->ccbStatus = 0;
4734 pccb->startTime = 0;
4735 pccb->dmaHandle = 0;
4736 pccb->numSgElements = 0;
4737 pccb->tiIORequest.tdData = 0;
4738 memset((void *)&pccb->tiSMPFrame, 0, AGSMP_INIT_XCHG_LEN);
4739
4740 pccb->flags = 0;
4741 pccb->ccb = NULL;
4742 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4743 pmcsc->ccbFreeList = (caddr_t *)pccb;
4744
4745 pmcsc->activeCCB--;
4746
4747 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4748 return;
4749
4750 }
4751
4752 /*****************************************************************************
4753 agtiapi_FreeTMCCB()
4754
4755 Purpose:
4756 Free a ccb and put it back to ccbFreeList.
4757 Parameters:
4758 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4759 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4760 CAM's CCB
4761 Returns:
4762 Note:
4763 *****************************************************************************/
agtiapi_FreeTMCCB(struct agtiapi_softc * pmcsc,pccb_t pccb)4764 STATIC void agtiapi_FreeTMCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4765 {
4766 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4767 AGTIAPI_PRINTK("agtiapi_FreeTMCCB: start %p\n", pccb);
4768 pccb->dataLen = 0;
4769 pccb->retryCount = 0;
4770 pccb->ccbStatus = 0;
4771 pccb->scsiStatus = 0;
4772 pccb->startTime = 0;
4773 pccb->dmaHandle = 0;
4774 pccb->numSgElements = 0;
4775 pccb->tiIORequest.tdData = 0;
4776 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4777 pccb->flags = 0;
4778 pccb->ccb = NULL;
4779 pccb->pccbIO = NULL;
4780 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4781 pmcsc->ccbFreeList = (caddr_t *)pccb;
4782 pmcsc->activeCCB--;
4783 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4784 return;
4785 }
4786 /******************************************************************************
4787 agtiapi_CheckAllVectors():
4788
4789 Purpose:
4790 Parameters:
4791 Return:
4792 Note:
4793 Currently, not used.
4794 ******************************************************************************/
agtiapi_CheckAllVectors(struct agtiapi_softc * pCard,bit32 context)4795 void agtiapi_CheckAllVectors( struct agtiapi_softc *pCard, bit32 context )
4796 {
4797 #ifdef SPC_MSIX_INTR
4798 if (!agtiapi_intx_mode)
4799 {
4800 int i;
4801
4802 for (i = 0; i < pCard->pCardInfo->maxInterruptVectors; i++)
4803 if (tiCOMInterruptHandler(&pCard->tiRoot, i) == agTRUE)
4804 tiCOMDelayedInterruptHandler(&pCard->tiRoot, i, 100, context);
4805 }
4806 else
4807 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4808 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4809 #else
4810 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4811 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4812 #endif
4813
4814 }
4815
4816
4817 /******************************************************************************
4818 agtiapi_CheckCB()
4819
4820 Purpose:
4821 Check call back function returned event for process completion
4822 Parameters:
4823 struct agtiapi_softc *pCard Pointer to card data structure
4824 U32 milisec (IN) Waiting time for expected event
4825 U32 flag (IN) Flag of the event to check
4826 U32 *pStatus (IN) Pointer to status of the card or port to check
4827 Return:
4828 AGTIAPI_SUCCESS - event comes as expected
4829 AGTIAPI_FAIL - event not coming
4830 Note:
4831 Currently, not used
4832 ******************************************************************************/
agtiapi_CheckCB(struct agtiapi_softc * pCard,U32 milisec,U32 flag,volatile U32 * pStatus)4833 agBOOLEAN agtiapi_CheckCB( struct agtiapi_softc *pCard,
4834 U32 milisec,
4835 U32 flag,
4836 volatile U32 *pStatus )
4837 {
4838 U32 msecsPerTick = pCard->pCardInfo->tiRscInfo.tiInitiatorResource.
4839 initiatorOption.usecsPerTick / 1000;
4840 S32 i = milisec/msecsPerTick;
4841 AG_GLOBAL_ARG( _flags );
4842
4843 AGTIAPI_PRINTK( "agtiapi_CheckCB: start\n" );
4844 AGTIAPI_FLOW( "agtiapi_CheckCB: start\n" );
4845
4846 if( i <= 0 )
4847 i = 1;
4848 while (i > 0)
4849 {
4850 if (*pStatus & TASK_MANAGEMENT)
4851 {
4852 if (*pStatus & AGTIAPI_CB_DONE)
4853 {
4854 if( flag == 0 || *pStatus & flag )
4855 return AGTIAPI_SUCCESS;
4856 else
4857 return AGTIAPI_FAIL;
4858 }
4859 }
4860 else if (pCard->flags & AGTIAPI_CB_DONE)
4861 {
4862 if( flag == 0 || *pStatus & flag )
4863 return AGTIAPI_SUCCESS;
4864 else
4865 return AGTIAPI_FAIL;
4866 }
4867
4868 agtiapi_DelayMSec( msecsPerTick );
4869
4870 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, _flags );
4871 tiCOMTimerTick( &pCard->tiRoot );
4872
4873 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
4874 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, _flags );
4875
4876 i--;
4877 }
4878
4879 if( *pStatus & TASK_MANAGEMENT )
4880 *pStatus |= TASK_TIMEOUT;
4881
4882 return AGTIAPI_FAIL;
4883 }
4884
4885
4886 /******************************************************************************
4887 agtiapi_DiscoverTgt()
4888
4889 Purpose:
4890 Discover available devices
4891 Parameters:
4892 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
4893 Return:
4894 Note:
4895 ******************************************************************************/
agtiapi_DiscoverTgt(struct agtiapi_softc * pCard)4896 STATIC void agtiapi_DiscoverTgt(struct agtiapi_softc *pCard)
4897 {
4898
4899 ag_portal_data_t *pPortalData;
4900 U32 count;
4901
4902 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: start\n");
4903 AGTIAPI_FLOW("agtiapi_DiscoverTgt\n");
4904 AGTIAPI_INIT("agtiapi_DiscoverTgt\n");
4905
4906 pPortalData = pCard->pPortalData;
4907 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4908 {
4909 pCard->flags &= ~AGTIAPI_CB_DONE;
4910 if (!(PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4911 {
4912 if (pCard->flags & AGTIAPI_INIT_TIME)
4913 {
4914 if (agtiapi_CheckCB(pCard, 5000, AGTIAPI_PORT_DISC_READY,
4915 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4916 {
4917 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Port %p / %d not ready for "
4918 "discovery\n",
4919 pPortalData, count );
4920 /*
4921 * There is no need to spend time on discovering device
4922 * if port is not ready to do so.
4923 */
4924 continue;
4925 }
4926 }
4927 else
4928 continue;
4929 }
4930
4931 AGTIAPI_FLOW( "agtiapi_DiscoverTgt: Portal %p DiscoverTargets starts\n",
4932 pPortalData );
4933 AGTIAPI_INIT_DELAY(1000);
4934
4935 pCard->flags &= ~AGTIAPI_CB_DONE;
4936 if (tiINIDiscoverTargets(&pCard->tiRoot,
4937 &pPortalData->portalInfo.tiPortalContext,
4938 FORCE_PERSISTENT_ASSIGN_MASK)
4939 != tiSuccess)
4940 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: tiINIDiscoverTargets ERROR\n");
4941
4942 /*
4943 * Should wait till discovery completion to start
4944 * next portal. However, lower layer have issue on
4945 * multi-portal case under Linux.
4946 */
4947 }
4948
4949 pPortalData = pCard->pPortalData;
4950 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4951 {
4952 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4953 {
4954 if (agtiapi_CheckCB(pCard, 20000, AGTIAPI_DISC_COMPLETE,
4955 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4956 {
4957 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE))
4958 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover complete, "
4959 "status 0x%x\n",
4960 pPortalData,
4961 PORTAL_STATUS(pPortalData) );
4962 else
4963 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover is not "
4964 "completed, status 0x%x\n",
4965 pPortalData, PORTAL_STATUS(pPortalData) );
4966 continue;
4967 }
4968 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %d discover target "
4969 "success\n",
4970 count );
4971 }
4972 }
4973
4974 /*
4975 * Calling to get device handle should be done per portal based
4976 * and better right after discovery is done. However, lower iscsi
4977 * layer may not returns discovery complete in correct sequence or we
4978 * ran out time. We get device handle for all portals together
4979 * after discovery is done or timed out.
4980 */
4981 pPortalData = pCard->pPortalData;
4982 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4983 {
4984 /*
4985 * We try to get device handle no matter
4986 * if discovery is completed or not.
4987 */
4988 if (PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)
4989 {
4990 U32 i;
4991
4992 for (i = 0; i < AGTIAPI_GET_DEV_MAX; i++)
4993 {
4994 if (agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 0, 0) != 0)
4995 break;
4996 agtiapi_DelayMSec(AGTIAPI_EXTRA_DELAY);
4997 }
4998
4999 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE) ||
5000 (pCard->tgtCount > 0))
5001 PORTAL_STATUS(pPortalData) |= ( AGTIAPI_DISC_DONE |
5002 AGTIAPI_PORT_LINK_UP );
5003 }
5004 }
5005
5006 return;
5007
5008 }
5009
5010
5011
5012 /******************************************************************************
5013 agtiapi_PrepCCBs()
5014
5015 Purpose:
5016 Prepares CCB including DMA map.
5017 Parameters:
5018 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5019 ccb_hdr_t *hdr (IN) Pointer to the CCB header
5020 U32 size (IN) size
5021 U32 max_ccb (IN) count
5022
5023 Return:
5024 Note:
5025 ******************************************************************************/
agtiapi_PrepCCBs(struct agtiapi_softc * pCard,ccb_hdr_t * hdr,U32 size,U32 max_ccb,int tid)5026 STATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard,
5027 ccb_hdr_t *hdr,
5028 U32 size,
5029 U32 max_ccb,
5030 int tid )
5031 {
5032
5033 int i;
5034 U32 hdr_sz, ccb_sz;
5035 ccb_t *pccb = NULL;
5036 int offset = 0;
5037 int nsegs = 0;
5038 int sgl_sz = 0;
5039
5040 AGTIAPI_PRINTK("agtiapi_PrepCCBs: start\n");
5041 offset = tid * AGTIAPI_CCB_PER_DEVICE;
5042 nsegs = AGTIAPI_NSEGS;
5043 sgl_sz = sizeof(tiSgl_t) * nsegs;
5044 AGTIAPI_PRINTK( "agtiapi_PrepCCBs: tid %d offset %d nsegs %d sizeof(tiSgl_t) "
5045 "%lu, max_ccb %d\n",
5046 tid,
5047 offset,
5048 nsegs,
5049 sizeof(tiSgl_t),
5050 max_ccb );
5051
5052 ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
5053 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5054
5055 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after cache line\n");
5056
5057 memset((void *)hdr, 0, size);
5058 hdr->next = pCard->ccbAllocList;
5059 pCard->ccbAllocList = hdr;
5060
5061 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after memset\n");
5062
5063 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5064
5065 for (i = 0; i < max_ccb; i++, pccb = (ccb_t*)((char*)pccb + ccb_sz))
5066 {
5067 pccb->tiIORequest.osData = (void *)pccb;
5068
5069 /*
5070 * Initially put all the ccbs on the free list
5071 * in addition to chainlist.
5072 * ccbChainList is a list of all available ccbs
5073 * (free/active everything)
5074 */
5075 pccb->pccbChainNext = (pccb_t)pCard->ccbChainList;
5076 pccb->pccbNext = (pccb_t)pCard->ccbFreeList;
5077
5078 pCard->ccbChainList = (caddr_t *)pccb;
5079 pCard->ccbFreeList = (caddr_t *)pccb;
5080 pCard->ccbTotal++;
5081
5082 #ifdef AGTIAPI_ALIGN_CHECK
5083 if (&pccb & 0x63)
5084 AGTIAPI_PRINTK("pccb = %p\n", pccb);
5085 if (pccb->devHandle & 0x63)
5086 AGTIAPI_PRINTK("devHandle addr = %p\n", &pccb->devHandle);
5087 if (&pccb->lun & 0x63)
5088 AGTIAPI_PRINTK("lun addr = %p\n", &pccb->lun);
5089 if (&pccb->targetId & 0x63)
5090 AGTIAPI_PRINTK("tig addr = %p\n", &pccb->targetId);
5091 if (&pccb->ccbStatus & 0x63)
5092 AGTIAPI_PRINTK("ccbStatus addr = %p\n", &pccb->ccbStatus);
5093 if (&pccb->scsiStatus & 0x63)
5094 AGTIAPI_PRINTK("scsiStatus addr = %p\n", &pccb->scsiStatus);
5095 if (&pccb->dataLen & 0x63)
5096 AGTIAPI_PRINTK("dataLen addr = %p\n", &pccb->dataLen);
5097 if (&pccb->senseLen & 0x63)
5098 AGTIAPI_PRINTK("senseLen addr = %p\n", &pccb->senseLen);
5099 if (&pccb->numSgElements & 0x63)
5100 AGTIAPI_PRINTK("numSgElements addr = %p\n", &pccb->numSgElements);
5101 if (&pccb->retryCount & 0x63)
5102 AGTIAPI_PRINTK("retry cnt addr = %p\n", &pccb->retryCount);
5103 if (&pccb->flags & 0x63)
5104 AGTIAPI_PRINTK("flag addr = %p\n", &pccb->flags);
5105 if (&pccb->pSenseData & 0x63)
5106 AGTIAPI_PRINTK("senseData addr = %p\n", &pccb->pSenseData);
5107 if (&pccb->sgList[0] & 0x63)
5108 AGTIAPI_PRINTK("SgList 0 = %p\n", &pccb->sgList[0]);
5109 if (&pccb->pccbNext & 0x63)
5110 AGTIAPI_PRINTK("ccb next = %p\n", &pccb->pccbNext);
5111 if (&pccb->pccbChainNext & 0x63)
5112 AGTIAPI_PRINTK("ccbChainNext = %p\n", &pccb->pccbChainNext);
5113 if (&pccb->cmd & 0x63)
5114 AGTIAPI_PRINTK("command = %p\n", &pccb->cmd);
5115 if( &pccb->startTime & 0x63 )
5116 AGTIAPI_PRINTK( "startTime = %p\n", &pccb->startTime );
5117 if (&pccb->tiIORequest & 0x63)
5118 AGTIAPI_PRINTK("tiIOReq addr = %p\n", &pccb->tiIORequest);
5119 if (&pccb->tdIOReqBody & 0x63)
5120 AGTIAPI_PRINTK("tdIORequestBody addr = %p\n", &pccb->tdIOReqBody);
5121 if (&pccb->tiSuperScsiRequest & 0x63)
5122 AGTIAPI_PRINTK( "InitiatorExchange addr = %p\n",
5123 &pccb->tiSuperScsiRequest );
5124 #endif
5125 if ( bus_dmamap_create( pCard->buffer_dmat, 0, &pccb->CCB_dmamap ) !=
5126 tiSuccess)
5127 {
5128 AGTIAPI_PRINTK("agtiapi_PrepCCBs: can't create dma\n");
5129 return;
5130 }
5131 /* assigns tiSgl_t memory to pccb */
5132 pccb->sgList = (void*)((U64)pCard->tisgl_mem + ((i + offset) * sgl_sz));
5133 pccb->tisgl_busaddr = pCard->tisgl_busaddr + ((i + offset) * sgl_sz);
5134 pccb->ccb = NULL;
5135 pccb->pccbIO = NULL;
5136 pccb->startTime = 0;
5137 }
5138
5139 #ifdef AGTIAPI_ALIGN_CHECK
5140 AGTIAPI_PRINTK("ccb size = %d / %d\n", sizeof(ccb_t), ccb_sz);
5141 #endif
5142 return;
5143 }
5144
5145 /******************************************************************************
5146 agtiapi_InitCCBs()
5147
5148 Purpose:
5149 Create and initialize per card based CCB pool.
5150 Parameters:
5151 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5152 int tgtCount (IN) Count
5153 Return:
5154 Total number of ccb allocated
5155 Note:
5156 ******************************************************************************/
agtiapi_InitCCBs(struct agtiapi_softc * pCard,int tgtCount,int tid)5157 STATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid)
5158 {
5159
5160 U32 max_ccb, size, ccb_sz, hdr_sz;
5161 int no_allocs = 0, i;
5162 ccb_hdr_t *hdr = NULL;
5163
5164 AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n");
5165 AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5166 AGTIAPI_FLOW("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5167
5168 #ifndef HOTPLUG_SUPPORT
5169 if (pCard->tgtCount > AGSA_MAX_INBOUND_Q)
5170 return 1;
5171 #else
5172 if (tgtCount > AGSA_MAX_INBOUND_Q)
5173 tgtCount = AGSA_MAX_INBOUND_Q;
5174 #endif
5175
5176 max_ccb = tgtCount * AGTIAPI_CCB_PER_DEVICE;// / 4; // TBR
5177 ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
5178 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5179 size = ccb_sz * max_ccb + hdr_sz;
5180
5181 for (i = 0; i < (1 << no_allocs); i++)
5182 {
5183 hdr = (ccb_hdr_t*)malloc( size, M_PMC_MCCB, M_NOWAIT );
5184 if( !hdr )
5185 {
5186 panic( "agtiapi_InitCCBs: bug!!!\n" );
5187 }
5188 else
5189 {
5190 agtiapi_PrepCCBs( pCard, hdr, size, max_ccb, tid );
5191 }
5192 }
5193
5194 return 1;
5195
5196 }
5197
5198
5199 #ifdef LINUX_PERBI_SUPPORT
5200 /******************************************************************************
5201 agtiapi_GetWWNMappings()
5202
5203 Purpose:
5204 Get the mappings from target IDs to WWNs, if any.
5205 Store them in the WWN_list array, indexed by target ID.
5206 Leave the devListIndex field blank; this will be filled-in later.
5207 Parameters:
5208 ag_card_t *pCard (IN) Pointer to HBA data structure
5209 ag_mapping_t *pMapList (IN) Pointer to mapped device list
5210 Return:
5211 Note: The boot command line parameters are used to load the
5212 mapping information, which is contained in the system
5213 configuration file.
5214 ******************************************************************************/
agtiapi_GetWWNMappings(struct agtiapi_softc * pCard,ag_mapping_t * pMapList)5215 STATIC void agtiapi_GetWWNMappings( struct agtiapi_softc *pCard,
5216 ag_mapping_t *pMapList )
5217 {
5218 int devDisc;
5219 int lIdx = 0;
5220 ag_tgt_map_t *pWWNList;
5221 ag_slr_map_t *pSLRList;
5222 ag_device_t *pDevList;
5223
5224 if( !pCard )
5225 panic( "agtiapi_GetWWNMappings: no pCard \n" );
5226
5227 AGTIAPI_PRINTK( "agtiapi_GetWWNMappings: start\n" );
5228
5229 pWWNList = pCard->pWWNList;
5230 pSLRList = pCard->pSLRList;
5231 pDevList = pCard->pDevList;
5232 pCard->numTgtHardMapped = 0;
5233 devDisc = pCard->devDiscover;
5234
5235 pWWNList[devDisc-1].devListIndex = maxTargets;
5236 pSLRList[devDisc-1].localeNameLen = -2;
5237 pSLRList[devDisc-1].remoteNameLen = -2;
5238 pDevList[devDisc-1].targetId = maxTargets;
5239
5240 /*
5241 * Get the mappings from holding area which contains
5242 * the input of the system file and store them
5243 * in the WWN_list array, indexed by target ID.
5244 */
5245 for ( lIdx = 0; lIdx < devDisc - 1; lIdx++) {
5246 pWWNList[lIdx].flags = 0;
5247 pWWNList[lIdx].devListIndex = maxTargets;
5248 pSLRList[lIdx].localeNameLen = -1;
5249 pSLRList[lIdx].remoteNameLen = -1;
5250 }
5251
5252 // this is where we would propagate values fed to pMapList
5253
5254 } /* agtiapi_GetWWNMappings */
5255
5256 #endif
5257
5258
5259 /******************************************************************************
5260 agtiapi_FindWWNListNext()
5261 Purpose:
5262 finds first available new (unused) wwn list entry
5263
5264 Parameters:
5265 ag_tgt_map_t *pWWNList Pointer to head of wwn list
5266 int lstMax Number of entries in WWNList
5267 Return:
5268 index into WWNList indicating available entry space;
5269 if available entry space is not found, return negative value
5270 ******************************************************************************/
agtiapi_FindWWNListNext(ag_tgt_map_t * pWWNList,int lstMax)5271 STATIC int agtiapi_FindWWNListNext( ag_tgt_map_t *pWWNList, int lstMax )
5272 {
5273 int lLstIdx;
5274
5275 for ( lLstIdx = 0; lLstIdx < lstMax; lLstIdx++ )
5276 {
5277 if ( pWWNList[lLstIdx].devListIndex == lstMax &&
5278 pWWNList[lLstIdx].targetLen == 0 )
5279 {
5280 AGTIAPI_PRINTK( "agtiapi_FindWWNListNext: %d %d %d %d v. %d\n",
5281 lLstIdx,
5282 pWWNList[lLstIdx].devListIndex,
5283 pWWNList[lLstIdx].targetLen,
5284 pWWNList[lLstIdx].portId,
5285 lstMax );
5286 return lLstIdx;
5287 }
5288 }
5289 return -1;
5290 }
5291
5292
5293 /******************************************************************************
5294 agtiapi_GetDevHandle()
5295
5296 Purpose:
5297 Get device handle. Handles will be placed in the
5298 devlist array with same order as TargetList provided and
5299 will be mapped to a scsi target id and registered to OS later.
5300 Parameters:
5301 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5302 ag_portal_info_t *pPortalInfo (IN) Pointer to the portal data structure
5303 U32 eType (IN) Port event
5304 U32 eStatus (IN) Port event status
5305 Return:
5306 Number of device handle slot present
5307 Note:
5308 The sequence of device handle will match the sequence of taregt list
5309 ******************************************************************************/
agtiapi_GetDevHandle(struct agtiapi_softc * pCard,ag_portal_info_t * pPortalInfo,U32 eType,U32 eStatus)5310 STATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard,
5311 ag_portal_info_t *pPortalInfo,
5312 U32 eType,
5313 U32 eStatus )
5314 {
5315 ag_device_t *pDevice;
5316 // tiDeviceHandle_t *agDev[pCard->devDiscover];
5317 tiDeviceHandle_t **agDev;
5318 int devIdx, szdv, devTotal, cmpsetRtn;
5319 int lDevIndex = 0, lRunScanFlag = FALSE;
5320 int *lDevFlags;
5321 tiPortInfo_t portInfT;
5322 ag_device_t lTmpDevice;
5323 ag_tgt_map_t *pWWNList;
5324 ag_slr_map_t *pSLRList;
5325 bit32 lReadRm;
5326 bit16 lReadCt;
5327
5328
5329 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: start\n" );
5330 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: pCard->devDiscover %d / tgtCt %d\n",
5331 pCard->devDiscover, pCard->tgtCount );
5332 AGTIAPI_FLOW( "agtiapi_GetDevHandle: portalInfo %p\n", pPortalInfo );
5333 AGTIAPI_INIT_DELAY( 1000 );
5334
5335 agDev = (tiDeviceHandle_t **) malloc( sizeof(tiDeviceHandle_t *) * pCard->devDiscover,
5336 M_PMC_MDEV, M_ZERO | M_NOWAIT);
5337 if (agDev == NULL)
5338 {
5339 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc agDev[]\n" );
5340 return 0;
5341 }
5342
5343 lDevFlags = (int *) malloc( sizeof(int) * pCard->devDiscover,
5344 M_PMC_MFLG, M_ZERO | M_NOWAIT );
5345 if (lDevFlags == NULL)
5346 {
5347 free((caddr_t)agDev, M_PMC_MDEV);
5348 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc lDevFlags[]\n" );
5349 return 0;
5350 }
5351
5352 pWWNList = pCard->pWWNList;
5353 pSLRList = pCard->pSLRList;
5354
5355 memset( (void *)agDev, 0, sizeof(void *) * pCard->devDiscover );
5356 memset( lDevFlags, 0, sizeof(int) * pCard->devDiscover );
5357
5358 // get device handles
5359 devTotal = tiINIGetDeviceHandles( &pCard->tiRoot,
5360 &pPortalInfo->tiPortalContext,
5361 (tiDeviceHandle_t **)agDev,
5362 pCard->devDiscover );
5363
5364 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: portalInfo %p port id %d event %u "
5365 "status %u card %p pCard->devDiscover %d devTotal %d "
5366 "pPortalInfo->devTotal %d pPortalInfo->devPrev %d "
5367 "AGTIAPI_INIT_TIME %x\n",
5368 pPortalInfo, pPortalInfo->portID, eType, eStatus, pCard,
5369 pCard->devDiscover, devTotal, pPortalInfo->devTotal,
5370 pPortalInfo->devPrev,
5371 pCard->flags & AGTIAPI_INIT_TIME );
5372
5373 // reset devTotal from any previous runs of this
5374 pPortalInfo->devPrev = devTotal;
5375 pPortalInfo->devTotal = devTotal;
5376
5377 AG_LIST_LOCK( &pCard->devListLock );
5378
5379 if ( tiCOMGetPortInfo( &pCard->tiRoot,
5380 &pPortalInfo->tiPortalContext,
5381 &portInfT )
5382 != tiSuccess)
5383 {
5384 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: tiCOMGetPortInfo did not succeed. \n" );
5385 }
5386
5387
5388 szdv = sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
5389 if (szdv > pCard->devDiscover)
5390 {
5391 szdv = pCard->devDiscover;
5392 }
5393
5394 // reconstructing dev list via comparison of wwn
5395
5396 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5397 {
5398 if ( agDev[devIdx] != NULL )
5399 {
5400 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n",
5401 // devIdx, agDev[devIdx] );
5402
5403 // pack temp device structure for tiINIGetDeviceInfo call
5404 pDevice = &lTmpDevice;
5405 pDevice->devType = DIRECT_DEVICE;
5406 pDevice->pCard = (void *)pCard;
5407 pDevice->flags = ACTIVE;
5408 pDevice->pPortalInfo = pPortalInfo;
5409 pDevice->pDevHandle = agDev[devIdx];
5410 pDevice->qbusy = agFALSE;
5411
5412 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: idx %d / %d : %p \n",
5413 // devIdx, pCard->devDiscover, agDev[devIdx] );
5414
5415 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx],
5416 &pDevice->devInfo );
5417
5418 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: wwn sizes %ld %d/%d ",
5419 // sizeof(pDevice->targetName),
5420 // pDevice->devInfo.osAddress1,
5421 // pDevice->devInfo.osAddress2 );
5422
5423 wwncpy( pDevice );
5424 wwnprintk( (unsigned char*)pDevice->targetName, pDevice->targetLen );
5425
5426 for ( lDevIndex = 0; lDevIndex < szdv; lDevIndex++ ) // match w/ wwn list
5427 {
5428 if ( (pCard->pDevList[lDevIndex].portalId == pPortalInfo->portID) &&
5429 pDevice->targetLen > 0 &&
5430 portInfT.localNameLen > 0 &&
5431 portInfT.remoteNameLen > 0 &&
5432 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen > 0 &&
5433 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen > 0 &&
5434 ( portInfT.localNameLen ==
5435 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen ) &&
5436 ( portInfT.remoteNameLen ==
5437 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen ) &&
5438 memcmp( pWWNList[lDevIndex].targetName, pDevice->targetName,
5439 pDevice->targetLen ) == 0 &&
5440 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].localeName,
5441 portInfT.localName,
5442 portInfT.localNameLen ) == 0 &&
5443 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteName,
5444 portInfT.remoteName,
5445 portInfT.remoteNameLen ) == 0 )
5446 {
5447 AGTIAPI_PRINTK( " pWWNList match @ %d/%d/%d \n",
5448 lDevIndex, devIdx, pPortalInfo->portID );
5449
5450 if ( (pCard->pDevList[lDevIndex].targetId == lDevIndex) &&
5451 ( pPortalInfo->pDevList[lDevIndex] ==
5452 &pCard->pDevList[lDevIndex] ) ) // active
5453 {
5454
5455 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: dev in use %d of %d/%d\n",
5456 lDevIndex, devTotal, pPortalInfo->portID );
5457 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev handle
5458 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5459 lReadRm = atomic_readandclear_32( &pWWNList[lDevIndex].devRemoved );
5460 if ( lReadRm ) // cleared timeout, now remove count for timer
5461 {
5462 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: clear timer count for"
5463 " %d of %d\n",
5464 lDevIndex, pPortalInfo->portID );
5465 atomic_subtract_16( &pCard->rmChkCt, 1 );
5466 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5467 if ( 0 == lReadCt )
5468 {
5469 callout_stop( &pCard->devRmTimer );
5470 }
5471 }
5472 break;
5473 }
5474
5475 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: goin fresh on %d of %d/%d\n",
5476 lDevIndex, // reactivate now
5477 devTotal, pPortalInfo->portID );
5478
5479 // pDevice going fresh
5480 lRunScanFlag = TRUE; // scan and clear outstanding removals
5481
5482 // pCard->tgtCount++; ##
5483 pDevice->targetId = lDevIndex;
5484 pDevice->portalId = pPortalInfo->portID;
5485
5486 memcpy ( &pCard->pDevList[lDevIndex], pDevice, sizeof(lTmpDevice) );
5487 agDev[devIdx]->osData = (void *)&pCard->pDevList[lDevIndex];
5488 if ( agtiapi_InitCCBs( pCard, 1, pDevice->targetId ) == 0 )
5489 {
5490 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: InitCCB "
5491 "tgtCnt %d ERROR!\n", pCard->tgtCount );
5492 AG_LIST_UNLOCK( &pCard->devListLock );
5493 free((caddr_t)lDevFlags, M_PMC_MFLG);
5494 free((caddr_t)agDev, M_PMC_MDEV);
5495 return 0;
5496 }
5497 pPortalInfo->pDevList[lDevIndex] = &pCard->pDevList[lDevIndex]; // (ag_device_t *)
5498 if ( 0 == lDevFlags[devIdx] )
5499 {
5500 pPortalInfo->devTotal++;
5501 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5502 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5503 }
5504 else
5505 {
5506 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: odd dev handle "
5507 "status inspect %d %d %d\n",
5508 lDevFlags[devIdx], devIdx, lDevIndex );
5509 pPortalInfo->devTotal++;
5510 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5511 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5512
5513 }
5514 break;
5515 }
5516 }
5517 // end: match this wwn with previous wwn list
5518
5519 // we have an agDev entry, but no pWWNList target for it
5520 if ( !(lDevFlags[devIdx] & DPMC_LEANFLAG_AGDEVUSED) )
5521 { // flag dev handle not accounted for yet
5522 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOWWNLIST;
5523 // later, get an empty pDevice and map this agDev.
5524 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: devIdx %d flags 0x%x, %d\n",
5525 // devIdx, lDevFlags[devIdx], (lDevFlags[devIdx] & 8) );
5526 }
5527 }
5528 else
5529 {
5530 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOAGDEVYT; // known empty agDev handle
5531 }
5532 }
5533
5534 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: all WWN all the time, "
5535 // "devLstIdx/flags/(WWNL)portId ... \n" );
5536 // review device list for further action needed
5537 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5538 {
5539 if ( lDevFlags[devIdx] & DPMC_LEANFLAG_NOWWNLIST ) // new target, register
5540 {
5541 int lNextDyad; // find next available dyad entry
5542
5543 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: register new target, "
5544 "devIdx %d -- %d \n", devIdx, pCard->devDiscover );
5545 lRunScanFlag = TRUE; // scan and clear outstanding removals
5546 for ( lNextDyad = 0; lNextDyad < pCard->devDiscover; lNextDyad++ )
5547 {
5548 if ( pSLRList[lNextDyad].localeNameLen < 0 &&
5549 pSLRList[lNextDyad].remoteNameLen < 0 )
5550 break;
5551 }
5552
5553 if ( lNextDyad == pCard->devDiscover )
5554 {
5555 printf( "agtiapi_GetDevHandle: failed to find available SAS LR\n" );
5556 AG_LIST_UNLOCK( &pCard->devListLock );
5557 free( (caddr_t)lDevFlags, M_PMC_MFLG );
5558 free( (caddr_t)agDev, M_PMC_MDEV );
5559 return 0;
5560 }
5561 // index of new entry
5562 lDevIndex = agtiapi_FindWWNListNext( pWWNList, pCard->devDiscover );
5563 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: listIdx new target %d of %d/%d\n",
5564 lDevIndex, devTotal, pPortalInfo->portID );
5565 if ( 0 > lDevIndex )
5566 {
5567 printf( "agtiapi_GetDevHandle: WARNING -- WWNList exhausted.\n" );
5568 continue;
5569 }
5570
5571 pDevice = &pCard->pDevList[lDevIndex];
5572
5573 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], &pDevice->devInfo );
5574 wwncpy( pDevice );
5575 agtiapi_InitCCBs( pCard, 1, lDevIndex );
5576
5577 pDevice->pCard = (void *)pCard;
5578 pDevice->devType = DIRECT_DEVICE;
5579
5580 // begin to populate new WWNList entry
5581 memcpy( pWWNList[lDevIndex].targetName, pDevice->targetName, pDevice->targetLen );
5582 pWWNList[lDevIndex].targetLen = pDevice->targetLen;
5583
5584 pWWNList[lDevIndex].flags = SOFT_MAPPED;
5585 pWWNList[lDevIndex].portId = pPortalInfo->portID;
5586 pWWNList[lDevIndex].devListIndex = lDevIndex;
5587 pWWNList[lDevIndex].sasLrIdx = lNextDyad;
5588
5589 pSLRList[lNextDyad].localeNameLen = portInfT.localNameLen;
5590 pSLRList[lNextDyad].remoteNameLen = portInfT.remoteNameLen;
5591 memcpy( pSLRList[lNextDyad].localeName, portInfT.localName, portInfT.localNameLen );
5592 memcpy( pSLRList[lNextDyad].remoteName, portInfT.remoteName, portInfT.remoteNameLen );
5593 // end of populating new WWNList entry
5594
5595 pDevice->targetId = lDevIndex;
5596
5597 pDevice->flags = ACTIVE;
5598 pDevice->CCBCount = 0;
5599 pDevice->pDevHandle = agDev[devIdx];
5600 agDev[devIdx]->osData = (void*)pDevice;
5601
5602 pDevice->pPortalInfo = pPortalInfo;
5603 pDevice->portalId = pPortalInfo->portID;
5604 pPortalInfo->pDevList[lDevIndex] = (void*)pDevice;
5605 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // mark pDevice slot used
5606 }
5607
5608 if ( (pCard->pDevList[devIdx].portalId == pPortalInfo->portID) &&
5609 !(lDevFlags[devIdx] & DPMC_LEANFLAG_PDEVSUSED) ) // pDevice not used
5610 {
5611 pDevice = &pCard->pDevList[devIdx];
5612 //pDevice->flags &= ~ACTIVE;
5613 if ( ( pDevice->pDevHandle != NULL ||
5614 pPortalInfo->pDevList[devIdx] != NULL ) )
5615 {
5616 atomic_add_16( &pCard->rmChkCt, 1 ); // show count of lost device
5617
5618 if (FALSE == lRunScanFlag)
5619 {
5620
5621 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: targ dropped out %d of %d/%d\n",
5622 devIdx, devTotal, pPortalInfo->portID );
5623 // if ( 0 == pWWNList[devIdx].devRemoved ) '.devRemoved = 5;
5624 cmpsetRtn = atomic_cmpset_32( &pWWNList[devIdx].devRemoved, 0, 5 );
5625 if ( 0 == cmpsetRtn )
5626 {
5627 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: target %d timer already set\n",
5628 devIdx );
5629 }
5630 else
5631 {
5632 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5633 }
5634 }
5635 // else ... scan coming soon enough anyway, ignore timer for dropout
5636 }
5637 }
5638 } // end of for ( devIdx = 0; ...
5639
5640 AG_LIST_UNLOCK( &pCard->devListLock );
5641
5642 free((caddr_t)lDevFlags, M_PMC_MFLG);
5643 free((caddr_t)agDev, M_PMC_MDEV);
5644
5645 if ( TRUE == lRunScanFlag )
5646 agtiapi_clrRmScan( pCard );
5647
5648 return devTotal;
5649 } // end agtiapi_GetDevHandle
5650
5651 /******************************************************************************
5652 agtiapi_scan()
5653
5654 Purpose:
5655 Triggers CAM's scan
5656 Parameters:
5657 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5658 Return:
5659 Note:
5660 ******************************************************************************/
agtiapi_scan(struct agtiapi_softc * pmcsc)5661 static void agtiapi_scan(struct agtiapi_softc *pmcsc)
5662 {
5663 union ccb *ccb;
5664 int bus, tid, lun, card_no;
5665 static int num=0;
5666
5667 AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo);
5668
5669 bus = cam_sim_path(pmcsc->sim);
5670
5671 tid = CAM_TARGET_WILDCARD;
5672 lun = CAM_LUN_WILDCARD;
5673
5674 mtx_lock(&(pmcsc->pCardInfo->pmIOLock));
5675 ccb = xpt_alloc_ccb_nowait();
5676 if (ccb == agNULL)
5677 {
5678 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5679 return;
5680 }
5681 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
5682 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
5683 {
5684 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5685 xpt_free_ccb(ccb);
5686 return;
5687 }
5688
5689 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5690 pmcsc->dev_scan = agTRUE;
5691 xpt_rescan(ccb);
5692 return;
5693 }
5694
5695 /******************************************************************************
5696 agtiapi_DeQueueCCB()
5697
5698 Purpose:
5699 Remove a ccb from a queue
5700 Parameters:
5701 struct agtiapi_softc *pCard (IN) Pointer to the card structure
5702 pccb_t *phead (IN) Pointer to a head of ccb queue
5703 ccb_t *pccd (IN) Pointer to the ccb to be processed
5704 Return:
5705 AGTIAPI_SUCCESS - the ccb is removed from queue
5706 AGTIAPI_FAIL - the ccb is not found from queue
5707 Note:
5708 ******************************************************************************/
5709 STATIC agBOOLEAN
agtiapi_DeQueueCCB(struct agtiapi_softc * pCard,pccb_t * phead,pccb_t * ptail,struct mtx * lock,ccb_t * pccb)5710 agtiapi_DeQueueCCB(struct agtiapi_softc *pCard, pccb_t *phead, pccb_t *ptail,
5711 #ifdef AGTIAPI_LOCAL_LOCK
5712 struct mtx *lock,
5713 #endif
5714 ccb_t *pccb)
5715 {
5716 ccb_t *pccb_curr;
5717 U32 status = AGTIAPI_FAIL;
5718
5719 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5720
5721 if (pccb == NULL || *phead == NULL)
5722 {
5723 return AGTIAPI_FAIL;
5724 }
5725
5726 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5727 AG_LOCAL_LOCK(lock);
5728
5729 if (pccb == *phead)
5730 {
5731 *phead = (*phead)->pccbNext;
5732 if (pccb == *ptail)
5733 {
5734 *ptail = NULL;
5735 }
5736 else
5737 pccb->pccbNext = NULL;
5738 status = AGTIAPI_SUCCESS;
5739 }
5740 else
5741 {
5742 pccb_curr = *phead;
5743 while (pccb_curr->pccbNext != NULL)
5744 {
5745 if (pccb_curr->pccbNext == pccb)
5746 {
5747 pccb_curr->pccbNext = pccb->pccbNext;
5748 pccb->pccbNext = NULL;
5749 if (pccb == *ptail)
5750 {
5751 *ptail = pccb_curr;
5752 }
5753 else
5754 pccb->pccbNext = NULL;
5755 status = AGTIAPI_SUCCESS;
5756 break;
5757 }
5758 pccb_curr = pccb_curr->pccbNext;
5759 }
5760 }
5761 AG_LOCAL_UNLOCK(lock);
5762
5763 return status;
5764 }
5765
5766
wwnprintk(unsigned char * name,int len)5767 STATIC void wwnprintk( unsigned char *name, int len )
5768 {
5769 int i;
5770
5771 for (i = 0; i < len; i++, name++)
5772 AGTIAPI_PRINTK("%02x", *name);
5773 AGTIAPI_PRINTK("\n");
5774 }
5775 /*
5776 * SAS and SATA behind expander has 8 byte long unique address.
5777 * However, direct connect SATA device use 512 byte unique device id.
5778 * SPC uses remoteName to indicate length of ID and remoteAddress for the
5779 * address of memory that holding ID.
5780 */
wwncpy(ag_device_t * pDevice)5781 STATIC int wwncpy( ag_device_t *pDevice )
5782 {
5783 int rc = 0;
5784
5785 if (sizeof(pDevice->targetName) >= pDevice->devInfo.osAddress1 +
5786 pDevice->devInfo.osAddress2)
5787 {
5788 memcpy(pDevice->targetName,
5789 pDevice->devInfo.remoteName,
5790 pDevice->devInfo.osAddress1);
5791 memcpy(pDevice->targetName + pDevice->devInfo.osAddress1,
5792 pDevice->devInfo.remoteAddress,
5793 pDevice->devInfo.osAddress2);
5794 pDevice->targetLen = pDevice->devInfo.osAddress1 +
5795 pDevice->devInfo.osAddress2;
5796 rc = pDevice->targetLen;
5797 }
5798 else
5799 {
5800 AGTIAPI_PRINTK("WWN wrong size: %d + %d ERROR\n",
5801 pDevice->devInfo.osAddress1, pDevice->devInfo.osAddress2);
5802 rc = -1;
5803 }
5804 return rc;
5805 }
5806
5807
5808 /******************************************************************************
5809 agtiapi_ReleaseCCBs()
5810
5811 Purpose:
5812 Free all allocated CCB memories for the Host Adapter.
5813 Parameters:
5814 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5815 Return:
5816 Note:
5817 ******************************************************************************/
agtiapi_ReleaseCCBs(struct agtiapi_softc * pCard)5818 STATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard )
5819 {
5820
5821 ccb_hdr_t *hdr;
5822 U32 hdr_sz;
5823 ccb_t *pccb = NULL;
5824
5825 AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" );
5826
5827 #if ( defined AGTIAPI_TEST_DPL || defined AGTIAPI_TEST_EPL )
5828 ccb_t *pccb;
5829 #endif
5830
5831 #ifdef AGTIAPI_TEST_DPL
5832 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5833 pccb = pccb->pccbChainNext)
5834 {
5835 if(pccb->dplPtr && pccb->dplDma)
5836 pci_pool_free(pCard->dpl_ctx_pool, pccb->dplPtr, pccb->dplDma);
5837 }
5838 #endif
5839
5840 #ifdef AGTIAPI_TEST_EPL
5841 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5842 pccb = pccb->pccbChainNext)
5843 {
5844 if(pccb->epl_ptr && pccb->epl_dma_ptr)
5845 pci_pool_free(
5846 pCard->epl_ctx_pool,
5847 pccb->epl_ptr,
5848 pccb->epl_dma_ptr
5849 );
5850 }
5851 #endif
5852
5853 while ((hdr = pCard->ccbAllocList) != NULL)
5854 {
5855 pCard->ccbAllocList = hdr->next;
5856 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5857 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5858 if (pCard->buffer_dmat != NULL && pccb->CCB_dmamap != NULL)
5859 {
5860 bus_dmamap_destroy(pCard->buffer_dmat, pccb->CCB_dmamap);
5861 }
5862 free(hdr, M_PMC_MCCB);
5863 }
5864 pCard->ccbAllocList = NULL;
5865
5866
5867 return;
5868 }
5869
5870 /******************************************************************************
5871 agtiapi_TITimer()
5872
5873 Purpose:
5874 Timer tick for tisa common layer
5875 Parameters:
5876 void *data (IN) Pointer to the HBA data structure
5877 Return:
5878 Note:
5879 ******************************************************************************/
agtiapi_TITimer(void * data)5880 STATIC void agtiapi_TITimer( void *data )
5881 {
5882
5883 U32 next_tick;
5884 struct agtiapi_softc *pCard;
5885
5886 pCard = (struct agtiapi_softc *)data;
5887
5888 // AGTIAPI_PRINTK("agtiapi_TITimer: start\n");
5889 AG_GLOBAL_ARG( flags );
5890
5891 next_tick = pCard->pCardInfo->tiRscInfo.tiLoLevelResource.
5892 loLevelOption.usecsPerTick / USEC_PER_TICK;
5893
5894 if( next_tick == 0 ) /* no timer required */
5895 return;
5896 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
5897 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5898 goto ext;
5899 tiCOMTimerTick( &pCard->tiRoot ); /* tisa common layer timer tick */
5900
5901 //add for polling mode
5902 #ifdef PMC_SPC
5903 if( agtiapi_polling_mode )
5904 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
5905 #endif
5906 callout_reset( &pCard->OS_timer, next_tick, agtiapi_TITimer, pCard );
5907 ext:
5908 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
5909 return;
5910 }
5911
5912 /******************************************************************************
5913 agtiapi_clrRmScan()
5914
5915 Purpose:
5916 Clears device list entries scheduled for timeout and calls scan
5917 Parameters:
5918 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5919 ******************************************************************************/
agtiapi_clrRmScan(struct agtiapi_softc * pCard)5920 STATIC void agtiapi_clrRmScan( struct agtiapi_softc *pCard )
5921 {
5922 ag_tgt_map_t *pWWNList;
5923 ag_portal_info_t *pPortalInfo;
5924 ag_portal_data_t *pPortalData;
5925 int lIdx;
5926 bit32 lReadRm;
5927 bit16 lReadCt;
5928
5929 pWWNList = pCard->pWWNList;
5930
5931 AGTIAPI_PRINTK( "agtiapi_clrRmScan: start\n" );
5932
5933 AG_LIST_LOCK( &pCard->devListLock );
5934
5935 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5936 {
5937 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5938 if ( 0 == lReadCt )
5939 {
5940 break; // trim to who cares
5941 }
5942
5943 lReadRm = atomic_readandclear_32( &pWWNList[lIdx].devRemoved );
5944 if ( lReadRm > 0 )
5945 {
5946 pCard->pDevList[lIdx].flags &= ~ACTIVE;
5947 pCard->pDevList[lIdx].pDevHandle = NULL;
5948
5949 pPortalData = &pCard->pPortalData[pWWNList[lIdx].portId];
5950 pPortalInfo = &pPortalData->portalInfo;
5951 pPortalInfo->pDevList[lIdx] = NULL;
5952 AGTIAPI_PRINTK( "agtiapi_clrRmScan: cleared dev %d at port %d\n",
5953 lIdx, pWWNList[lIdx].portId );
5954 atomic_subtract_16( &pCard->rmChkCt, 1 );
5955 }
5956 }
5957 AG_LIST_UNLOCK( &pCard->devListLock );
5958
5959 agtiapi_scan( pCard );
5960 }
5961
5962
5963 /******************************************************************************
5964 agtiapi_devRmCheck()
5965
5966 Purpose:
5967 Timer tick to check for timeout on missing targets
5968 Removes device list entry when timeout is reached
5969 Parameters:
5970 void *data (IN) Pointer to the HBA data structure
5971 ******************************************************************************/
agtiapi_devRmCheck(void * data)5972 STATIC void agtiapi_devRmCheck( void *data )
5973 {
5974 struct agtiapi_softc *pCard;
5975 ag_tgt_map_t *pWWNList;
5976 int lIdx, cmpsetRtn, lRunScanFlag = FALSE;
5977 bit16 lReadCt;
5978 bit32 lReadRm;
5979
5980 pCard = ( struct agtiapi_softc * )data;
5981
5982 // routine overhead
5983 if ( callout_pending( &pCard->devRmTimer ) ) // callout was reset
5984 {
5985 return;
5986 }
5987 if ( !callout_active( &pCard->devRmTimer ) ) // callout was stopped
5988 {
5989 return;
5990 }
5991 callout_deactivate( &pCard->devRmTimer );
5992
5993 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5994 {
5995 return; // implicit timer clear
5996 }
5997
5998 pWWNList = pCard->pWWNList;
5999
6000 AG_LIST_LOCK( &pCard->devListLock );
6001 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
6002 if ( lReadCt )
6003 {
6004 if ( callout_pending(&pCard->devRmTimer) == FALSE )
6005 {
6006 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
6007 }
6008 else
6009 {
6010 AG_LIST_UNLOCK( &pCard->devListLock );
6011 return;
6012 }
6013
6014 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
6015 {
6016 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
6017 if ( 0 == lReadCt )
6018 {
6019 break; // if handled somewhere else, get out
6020 }
6021
6022 lReadRm = atomic_load_acq_32( &pWWNList[lIdx].devRemoved );
6023 if ( lReadRm > 0 )
6024 {
6025 if ( 1 == lReadRm ) // timed out
6026 { // no decrement of devRemoved as way to leave a clrRmScan marker
6027 lRunScanFlag = TRUE; // other devRemoved values are about to get wiped
6028 break; // ... so bail out
6029 }
6030 else
6031 {
6032 AGTIAPI_PRINTK( "agtiapi_devRmCheck: counting down dev %d @ %d; %d\n",
6033 lIdx, lReadRm, lReadCt );
6034 cmpsetRtn = atomic_cmpset_32( &pWWNList[lIdx].devRemoved,
6035 lReadRm,
6036 lReadRm-1 );
6037 if ( 0 == cmpsetRtn )
6038 {
6039 printf( "agtiapi_devRmCheck: %d decrement already handled\n",
6040 lIdx );
6041 }
6042 }
6043 }
6044 }
6045 AG_LIST_UNLOCK( &pCard->devListLock );
6046
6047 if ( TRUE == lRunScanFlag )
6048 agtiapi_clrRmScan( pCard );
6049 }
6050 else
6051 {
6052 AG_LIST_UNLOCK( &pCard->devListLock );
6053 }
6054
6055 return;
6056 }
6057
6058
agtiapi_cam_poll(struct cam_sim * asim)6059 static void agtiapi_cam_poll( struct cam_sim *asim )
6060 {
6061 return;
6062 }
6063
6064 /*****************************************************************************
6065 agtiapi_ResetCard()
6066
6067 Purpose:
6068 Hard or soft reset on the controller and resend any
6069 outstanding requests if needed.
6070 Parameters:
6071 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
6072 unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
6073 Return:
6074 AGTIAPI_SUCCESS - reset successful
6075 AGTIAPI_FAIL - reset failed
6076 Note:
6077 *****************************************************************************/
agtiapi_ResetCard(struct agtiapi_softc * pCard,unsigned long * flags)6078 U32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags )
6079 {
6080 ag_device_t *pDevice;
6081 U32 lIdx = 0;
6082 U32 lFlagVal;
6083 agBOOLEAN ret;
6084 ag_portal_info_t *pPortalInfo;
6085 ag_portal_data_t *pPortalData;
6086 U32 count, loop;
6087 int szdv;
6088
6089 if( pCard->flags & AGTIAPI_RESET ) {
6090 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" );
6091 return AGTIAPI_FAIL;
6092 }
6093
6094 AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n",
6095 pCard->resetCount );
6096 #ifdef LOGEVENT
6097 agtiapi_LogEvent( pCard,
6098 IOCTL_EVT_SEV_INFORMATIONAL,
6099 0,
6100 agNULL,
6101 0,
6102 "Reset initiator time = %d!",
6103 pCard->resetCount + 1 );
6104 #endif
6105
6106 pCard->flags |= AGTIAPI_RESET;
6107 pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS);
6108 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6109 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6110
6111 agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK );
6112
6113 for ( lIdx = 1; 3 >= lIdx; lIdx++ ) // we try reset up to 3 times
6114 {
6115 if( pCard->flags & AGTIAPI_SOFT_RESET )
6116 {
6117 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" );
6118 tiCOMReset( &pCard->tiRoot, tiSoftReset );
6119 }
6120 else
6121 {
6122 AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" );
6123 }
6124
6125 lFlagVal = AGTIAPI_RESET_SUCCESS;
6126 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6127 ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags );
6128 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags );
6129
6130 if( ret == AGTIAPI_FAIL )
6131 {
6132 AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, "
6133 "try again?\n" );
6134 }
6135 else
6136 {
6137 break;
6138 }
6139 }
6140 if ( 1 < lIdx )
6141 {
6142 if ( AGTIAPI_FAIL == ret )
6143 {
6144 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n",
6145 lIdx );
6146 }
6147 else
6148 {
6149 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n",
6150 lIdx );
6151 }
6152 }
6153 if( AGTIAPI_FAIL == ret )
6154 {
6155 printf( "agtiapi_ResetCard: reset ERROR\n" );
6156 pCard->flags &= ~AGTIAPI_INSTALLED;
6157 return AGTIAPI_FAIL;
6158 }
6159
6160 pCard->flags &= ~AGTIAPI_SOFT_RESET;
6161
6162 // disable all devices
6163 pDevice = pCard->pDevList;
6164 for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ )
6165 {
6166 /* if ( pDevice->flags & ACTIVE )
6167 {
6168 printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx );
6169 } */
6170 pDevice->flags &= ~ACTIVE;
6171 }
6172
6173 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6174 if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess )
6175 printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" );
6176 else
6177 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" );
6178
6179 if( !pCard->pDevList ) { // try to get a little sanity here
6180 AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n",
6181 pCard->pDevList );
6182 return AGTIAPI_FAIL;
6183 }
6184
6185 AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n",
6186 pCard->tgtCount, pCard->portCount );
6187 pCard->tgtCount = 0;
6188
6189 DELAY( 500000 );
6190
6191 pCard->flags &= ~AGTIAPI_CB_DONE;
6192
6193 pPortalData = pCard->pPortalData;
6194
6195 for( count = 0; count < pCard->portCount; count++ ) {
6196 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6197 pPortalInfo = &pPortalData->portalInfo;
6198 pPortalInfo->portStatus = 0;
6199 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
6200 AGTIAPI_PORT_DISC_READY |
6201 AGTIAPI_DISC_DONE |
6202 AGTIAPI_DISC_COMPLETE );
6203
6204 szdv =
6205 sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
6206 if (szdv > pCard->devDiscover)
6207 {
6208 szdv = pCard->devDiscover;
6209 }
6210
6211 for( lIdx = 0, loop = 0;
6212 lIdx < szdv && loop < pPortalInfo->devTotal;
6213 lIdx++ )
6214 {
6215 pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx];
6216 if( pDevice )
6217 {
6218 loop++;
6219 pDevice->pDevHandle = 0; // mark for availability in pCard->pDevList[]
6220 // don't erase more as the device is scheduled for removal on DPC
6221 }
6222 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n",
6223 pDevice, pPortalInfo->pDevList, lIdx );
6224 pPortalInfo->devTotal = pPortalInfo->devPrev = 0;
6225 }
6226
6227 for( lIdx = 0; lIdx < maxTargets; lIdx++ )
6228 { // we reconstruct dev list later in get dev handle
6229 pPortalInfo->pDevList[lIdx] = NULL;
6230 }
6231
6232 for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ )
6233 {
6234 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data "
6235 "%p / %d / %p\n",
6236 &pCard->tiRoot,
6237 pPortalInfo->portID,
6238 &pPortalInfo->tiPortalContext );
6239
6240 if( tiCOMPortStart( &pCard->tiRoot,
6241 pPortalInfo->portID,
6242 &pPortalInfo->tiPortalContext,
6243 0 )
6244 != tiSuccess )
6245 {
6246 printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n",
6247 pPortalInfo->portID );
6248 }
6249 else
6250 {
6251 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n",
6252 pPortalInfo->portID );
6253 break;
6254 }
6255 }
6256 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6257 tiCOMGetPortInfo( &pCard->tiRoot,
6258 &pPortalInfo->tiPortalContext,
6259 &pPortalInfo->tiPortInfo );
6260 pPortalData++;
6261 }
6262 // ## fail case: pCard->flags &= ~AGTIAPI_INSTALLED;
6263
6264
6265 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags);
6266
6267 if( !(pCard->flags & AGTIAPI_INSTALLED) ) // driver not installed !
6268 {
6269 printf( "agtiapi_ResetCard: error, driver not intstalled? "
6270 "!AGTIAPI_INSTALLED \n" );
6271 return AGTIAPI_FAIL;
6272 }
6273
6274 AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount );
6275
6276 #ifdef LOGEVENT
6277 agtiapi_LogEvent( pCard,
6278 IOCTL_EVT_SEV_INFORMATIONAL,
6279 0,
6280 agNULL,
6281 0,
6282 "Reset initiator total device = %d!",
6283 pCard->tgtCount );
6284 #endif
6285 pCard->resetCount++;
6286
6287 AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" );
6288 // clear send & done queue
6289 AG_LOCAL_LOCK( &pCard->sendLock );
6290 pCard->ccbSendHead = NULL;
6291 pCard->ccbSendTail = NULL;
6292 AG_LOCAL_UNLOCK( &pCard->sendLock );
6293
6294 AG_LOCAL_LOCK( &pCard->doneLock );
6295 pCard->ccbDoneHead = NULL;
6296 pCard->ccbDoneTail = NULL;
6297 AG_LOCAL_UNLOCK( &pCard->doneLock );
6298
6299 // clear smp queues also
6300 AG_LOCAL_LOCK( &pCard->sendSMPLock );
6301 pCard->smpSendHead = NULL;
6302 pCard->smpSendTail = NULL;
6303 AG_LOCAL_UNLOCK( &pCard->sendSMPLock );
6304
6305 AG_LOCAL_LOCK( &pCard->doneSMPLock );
6306 pCard->smpDoneHead = NULL;
6307 pCard->smpDoneTail = NULL;
6308 AG_LOCAL_UNLOCK( &pCard->doneSMPLock );
6309
6310 // finished with all reset stuff, now start things back up
6311 tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE );
6312 pCard->flags |= AGTIAPI_SYS_INTR_ON;
6313 pCard->flags |= AGTIAPI_HAD_RESET;
6314 pCard->flags &= ~AGTIAPI_RESET; // ##
6315 agtiapi_StartIO( pCard );
6316 AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" );
6317 return AGTIAPI_SUCCESS;
6318 } // agtiapi_ResetCard
6319
6320
6321 /******************************************************************************
6322 agtiapi_ReleaseHBA()
6323
6324 Purpose:
6325 Releases all resources previously acquired to support
6326 a specific Host Adapter, including the I/O Address range,
6327 and unregisters the agtiapi Host Adapter.
6328 Parameters:
6329 device_t dev (IN) - device pointer
6330 Return:
6331 always return 0 - success
6332 Note:
6333 ******************************************************************************/
agtiapi_ReleaseHBA(device_t dev)6334 int agtiapi_ReleaseHBA( device_t dev )
6335 {
6336
6337 int thisCard = device_get_unit( dev ); // keeping get_unit call to once
6338 int i;
6339 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
6340 struct ccb_setasync csa;
6341 struct agtiapi_softc *pCard;
6342 pCard = device_get_softc( dev );
6343 ag_card_info_t *pCardInfo = pCard->pCardInfo;
6344 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
6345
6346 AG_GLOBAL_ARG(flags);
6347
6348 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: start\n" );
6349
6350 if (thisCardInst != pCardInfo)
6351 {
6352 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p "
6353 "pCardInfo %p\n",
6354 thisCardInst,
6355 pCardInfo );
6356 panic( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p pCardInfo "
6357 "%p\n",
6358 thisCardInst,
6359 pCardInfo );
6360 return( EIO );
6361 }
6362
6363
6364 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA card %p\n", pCard );
6365 pCard->flags |= AGTIAPI_SHUT_DOWN;
6366
6367
6368 // remove timer
6369 if (pCard->flags & AGTIAPI_TIMER_ON)
6370 {
6371 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6372 callout_drain( &pCard->OS_timer );
6373 callout_drain( &pCard->devRmTimer );
6374 callout_drain(&pCard->IO_timer);
6375 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6376 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: timer released\n" );
6377 }
6378
6379 #ifdef HIALEAH_ENCRYPTION
6380 //Release encryption table memory - Fix it
6381 //if(pCard->encrypt && (pCard->flags & AGTIAPI_INSTALLED))
6382 //agtiapi_CleanupEncryption(pCard);
6383 #endif
6384
6385 /*
6386 * Shutdown the channel so that chip gets frozen
6387 * and it does not do any more pci-bus accesses.
6388 */
6389 if (pCard->flags & AGTIAPI_SYS_INTR_ON)
6390 {
6391 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6392 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6393 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: card interrupt off\n" );
6394 }
6395 if (pCard->flags & AGTIAPI_INSTALLED)
6396 {
6397 tiCOMShutDown( &pCard->tiRoot );
6398 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: low layers shutdown\n" );
6399 }
6400
6401 /*
6402 * first release IRQ, so that we do not get any more interrupts
6403 * from this host
6404 */
6405 if (pCard->flags & AGTIAPI_IRQ_REQUESTED)
6406 {
6407 if (!agtiapi_intx_mode)
6408 {
6409 int i;
6410 for (i = 0; i< MAX_MSIX_NUM_VECTOR; i++)
6411 {
6412 if (pCard->irq[i] != agNULL && pCard->rscID[i] != 0)
6413 {
6414 bus_teardown_intr(dev, pCard->irq[i], pCard->intrcookie[i]);
6415 bus_release_resource( dev,
6416 SYS_RES_IRQ,
6417 pCard->rscID[i],
6418 pCard->irq[i] );
6419 }
6420 }
6421 pci_release_msi(dev);
6422 }
6423 pCard->flags &= ~AGTIAPI_IRQ_REQUESTED;
6424
6425
6426
6427 #ifdef AGTIAPI_DPC
6428 for (i = 0; i < MAX_MSIX_NUM_DPC; i++)
6429 tasklet_kill(&pCard->tasklet_dpc[i]);
6430 #endif
6431 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: IRQ released\n");
6432 }
6433
6434 // release memory vs. alloc in agtiapi_alloc_ostimem; used in ostiAllocMemory
6435 if( pCard->osti_busaddr != 0 ) {
6436 bus_dmamap_unload( pCard->osti_dmat, pCard->osti_mapp );
6437 }
6438 if( pCard->osti_mem != NULL ) {
6439 bus_dmamem_free( pCard->osti_dmat, pCard->osti_mem, pCard->osti_mapp );
6440 }
6441 if( pCard->osti_dmat != NULL ) {
6442 bus_dma_tag_destroy( pCard->osti_dmat );
6443 }
6444
6445 /* unmap the mapped PCI memory */
6446 /* calls bus_release_resource( ,SYS_RES_MEMORY, ..) */
6447 agtiapi_ReleasePCIMem(thisCardInst);
6448
6449 /* release all ccbs */
6450 if (pCard->ccbTotal)
6451 {
6452 //calls bus_dmamap_destroy() for all pccbs
6453 agtiapi_ReleaseCCBs(pCard);
6454 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: CCB released\n");
6455 }
6456
6457 #ifdef HIALEAH_ENCRYPTION
6458 /*release encryption resources - Fix it*/
6459 if(pCard->encrypt)
6460 {
6461 /*Check that all IO's are completed */
6462 if(atomic_read (&outstanding_encrypted_io_count) > 0)
6463 {
6464 printf("%s: WARNING: %d outstanding encrypted IOs !\n", __FUNCTION__, atomic_read(&outstanding_encrypted_io_count));
6465 }
6466 //agtiapi_CleanupEncryptionPools(pCard);
6467 }
6468 #endif
6469
6470
6471 /* release device list */
6472 if( pCard->pDevList ) {
6473 free((caddr_t)pCard->pDevList, M_PMC_MDVT);
6474 pCard->pDevList = NULL;
6475 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: device list released\n");
6476 }
6477 #ifdef LINUX_PERBI_SUPPORT // ## review use of PERBI
6478 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: WWN list %p \n", pCard->pWWNList );
6479 if( pCard->pWWNList ) {
6480 free( (caddr_t)pCard->pWWNList, M_PMC_MTGT );
6481 pCard->pWWNList = NULL;
6482 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: WWN list released\n");
6483 }
6484 if( pCard->pSLRList ) {
6485 free( (caddr_t)pCard->pSLRList, M_PMC_MSLR );
6486 pCard->pSLRList = NULL;
6487 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: SAS Local Remote list released\n");
6488 }
6489
6490 #endif
6491 if (pCard->pPortalData)
6492 {
6493 free((caddr_t)pCard->pPortalData, M_PMC_MPRT);
6494 pCard->pPortalData = NULL;
6495 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: PortalData released\n");
6496 }
6497 //calls contigfree() or free()
6498 agtiapi_MemFree(pCardInfo);
6499 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: low level resource released\n");
6500
6501 #ifdef HOTPLUG_SUPPORT
6502 if (pCard->flags & AGTIAPI_PORT_INITIALIZED)
6503 {
6504 // agtiapi_FreeDevWorkList(pCard);
6505 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: (HP dev) work resources released\n");
6506 }
6507 #endif
6508
6509 /*
6510 * TBD, scsi_unregister may release wrong host data structure
6511 * which cause NULL pointer shows up.
6512 */
6513 if (pCard->flags & AGTIAPI_SCSI_REGISTERED)
6514 {
6515 pCard->flags &= ~AGTIAPI_SCSI_REGISTERED;
6516
6517
6518 #ifdef AGTIAPI_LOCAL_LOCK
6519 if (pCard->STLock)
6520 {
6521 //destroy mtx
6522 int maxLocks;
6523 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
6524
6525 for( i = 0; i < maxLocks; i++ )
6526 {
6527 mtx_destroy(&pCard->STLock[i]);
6528 }
6529 free(pCard->STLock, M_PMC_MSTL);
6530 pCard->STLock = NULL;
6531 }
6532 #endif
6533
6534 }
6535 ag_card_good--;
6536
6537 /* reset agtiapi_1st_time if this is the only card */
6538 if (!ag_card_good && !agtiapi_1st_time)
6539 {
6540 agtiapi_1st_time = 1;
6541 }
6542
6543 /* for tiSgl_t memeory */
6544 if (pCard->tisgl_busaddr != 0)
6545 {
6546 bus_dmamap_unload(pCard->tisgl_dmat, pCard->tisgl_map);
6547 }
6548 if (pCard->tisgl_mem != NULL)
6549 {
6550 bus_dmamem_free(pCard->tisgl_dmat, pCard->tisgl_mem, pCard->tisgl_map);
6551 }
6552 if (pCard->tisgl_dmat != NULL)
6553 {
6554 bus_dma_tag_destroy(pCard->tisgl_dmat);
6555 }
6556
6557 if (pCard->buffer_dmat != agNULL)
6558 {
6559 bus_dma_tag_destroy(pCard->buffer_dmat);
6560 }
6561
6562 if (pCard->sim != NULL)
6563 {
6564 mtx_lock(&thisCardInst->pmIOLock);
6565 xpt_setup_ccb(&csa.ccb_h, pCard->path, 5);
6566 csa.ccb_h.func_code = XPT_SASYNC_CB;
6567 csa.event_enable = 0;
6568 csa.callback = agtiapi_async;
6569 csa.callback_arg = pCard;
6570 xpt_action((union ccb *)&csa);
6571 xpt_free_path(pCard->path);
6572 // if (pCard->ccbTotal == 0)
6573 if (pCard->ccbTotal <= thisCard)
6574 {
6575 /*
6576 no link up so that simq has not been released.
6577 In order to remove cam, we call this.
6578 */
6579 xpt_release_simq(pCard->sim, 1);
6580 }
6581 xpt_bus_deregister(cam_sim_path(pCard->sim));
6582 cam_sim_free(pCard->sim, FALSE);
6583 mtx_unlock(&thisCardInst->pmIOLock);
6584 }
6585 if (pCard->devq != NULL)
6586 {
6587 cam_simq_free(pCard->devq);
6588 }
6589
6590 //destroy mtx
6591 mtx_destroy( &thisCardInst->pmIOLock );
6592 mtx_destroy( &pCard->sendLock );
6593 mtx_destroy( &pCard->doneLock );
6594 mtx_destroy( &pCard->sendSMPLock );
6595 mtx_destroy( &pCard->doneSMPLock );
6596 mtx_destroy( &pCard->ccbLock );
6597 mtx_destroy( &pCard->devListLock );
6598 mtx_destroy( &pCard->OS_timer_lock );
6599 mtx_destroy( &pCard->devRmTimerLock );
6600 mtx_destroy( &pCard->memLock );
6601 mtx_destroy( &pCard->freezeLock );
6602
6603 destroy_dev( pCard->my_cdev );
6604 memset((void *)pCardInfo, 0, sizeof(ag_card_info_t));
6605 return 0;
6606 }
6607
6608
6609 // Called during system shutdown after sync
agtiapi_shutdown(device_t dev)6610 static int agtiapi_shutdown( device_t dev )
6611 {
6612 AGTIAPI_PRINTK( "agtiapi_shutdown\n" );
6613 return( 0 );
6614 }
6615
agtiapi_suspend(device_t dev)6616 static int agtiapi_suspend( device_t dev ) // Device suspend routine.
6617 {
6618 AGTIAPI_PRINTK( "agtiapi_suspend\n" );
6619 return( 0 );
6620 }
6621
agtiapi_resume(device_t dev)6622 static int agtiapi_resume( device_t dev ) // Device resume routine.
6623 {
6624 AGTIAPI_PRINTK( "agtiapi_resume\n" );
6625 return( 0 );
6626 }
6627
6628 static device_method_t agtiapi_methods[] = { // Device interface
6629 DEVMETHOD( device_probe, agtiapi_probe ),
6630 DEVMETHOD( device_attach, agtiapi_attach ),
6631 DEVMETHOD( device_detach, agtiapi_ReleaseHBA ),
6632 DEVMETHOD( device_shutdown, agtiapi_shutdown ),
6633 DEVMETHOD( device_suspend, agtiapi_suspend ),
6634 DEVMETHOD( device_resume, agtiapi_resume ),
6635 { 0, 0 }
6636 };
6637
6638 static devclass_t pmspcv_devclass;
6639
6640 static driver_t pmspcv_driver = {
6641 "pmspcv",
6642 agtiapi_methods,
6643 sizeof( struct agtiapi_softc )
6644 };
6645
6646 DRIVER_MODULE( pmspcv, pci, pmspcv_driver, pmspcv_devclass, 0, 0 );
6647 MODULE_DEPEND( pmspcv, cam, 1, 1, 1 );
6648 MODULE_DEPEND( pmspcv, pci, 1, 1, 1 );
6649
6650 #include <dev/pms/freebsd/driver/common/lxosapi.c>
6651 #include <dev/pms/freebsd/driver/ini/src/osapi.c>
6652 #include <dev/pms/freebsd/driver/common/lxutil.c>
6653 #include <dev/pms/freebsd/driver/common/lxencrypt.c>
6654
6655
6656