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