1 /*******************************************************************************
3 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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.
11 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
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
20 *******************************************************************************/
22 #include <sys/cdefs.h>
23 __FBSDID("$FreeBSD$");
24 #include <dev/pms/config.h>
26 #define MAJOR_REVISION 1
27 #define MINOR_REVISION 3
28 #define BUILD_REVISION 10800
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>
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>
50 #include <sys/mutex.h>
52 #include <sys/queue.h>
53 #include <sys/taskqueue.h>
54 #include <machine/atomic.h>
55 #include <sys/libkern.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>
73 MALLOC_DEFINE( M_PMC_MCCB, "CCB List", "CCB List for PMCS driver" );
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" );
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
101 U32 gTiDebugLevel = 1;
102 S32 ag_encryption_enable = 0;
103 atomic_t outstanding_encrypted_io_count;
105 #define cache_line_size() CACHE_LINE_SIZE
107 #define PMCoffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
109 #define CPU_TO_LE32(dst, src) \
110 dst.lower = htole32(LOW_32_BITS(src)); \
111 dst.upper = htole32(HIGH_32_BITS(src))
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 )
117 STATIC U08 agtiapi_AddrModes[AGTIAPI_MAX_CHANNEL_NUM + 1] =
118 { AGTIAPI_PERIPHERAL };
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()
125 // * For Debugging Purpose
127 #define AGTIAPI_WWN(name, len) wwnprintk(name, len)
129 #define AGTIAPI_WWN(name, len)
133 #define AGTIAPI_WWNPRINTK(name, len, format, a...) \
134 AGTIAPI_PRINTK(format "name ", a); \
135 AGTIAPI_WWN((unsigned char*)name, len);
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); \
144 #ifdef AGTIAPI_LOCAL_LOCK
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)
156 #define AG_LOCAL_LOCK(lock) if (lock) \
158 #define AG_LOCAL_UNLOCK(lock) if (lock) \
160 #define AG_LOCAL_FLAGS(_flags) unsigned long _flags = 0
164 #define AG_GET_DONE_PCCB(pccb, pmcsc) \
166 AG_LOCAL_LOCK(&pmcsc->doneLock); \
167 pccb = pmcsc->ccbDoneHead; \
170 pmcsc->ccbDoneHead = NULL; \
171 pmcsc->ccbDoneTail = NULL; \
172 AG_LOCAL_UNLOCK(&pmcsc->doneLock); \
173 agtiapi_Done(pmcsc, pccb); \
176 AG_LOCAL_UNLOCK(&pmcsc->doneLock); \
179 #define AG_GET_DONE_SMP_PCCB(pccb, pmcsc) \
181 AG_LOCAL_LOCK(&pmcsc->doneSMPLock); \
182 pccb = pmcsc->smpDoneHead; \
185 pmcsc->smpDoneHead = NULL; \
186 pmcsc->smpDoneTail = NULL; \
187 AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \
188 agtiapi_SMPDone(pmcsc, pccb); \
191 AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \
194 #ifdef AGTIAPI_DUMP_IO_DEBUG
195 #define AG_IO_DUMPCCB(pccb) agtiapi_DumpCCB(pccb)
197 #define AG_IO_DUMPCCB(pccb)
200 #define SCHED_DELAY_JIFFIES 4 /* in seconds */
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)
207 #define AG_HOTPLUG_LOCK_INIT(lock)
208 #define AG_LIST_LOCK(lock)
209 #define AG_LIST_UNLOCK(lock)
212 STATIC void agtiapi_CheckIOTimeout(void *data);
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 * );
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);
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,
242 U32 ag_portal_count = 0;
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.
248 int agtiapi_open( struct cdev *dev, int oflags, int devtype, struct thread *td )
250 struct agtiapi_softc *sc;
251 /* Look up our softc. */
253 AGTIAPI_PRINTK("agtiapi_open\n");
254 AGTIAPI_PRINTK("Opened successfully. sc->my_dev %p\n", sc->my_dev);
258 int agtiapi_close( struct cdev *dev, int fflag, int devtype, struct thread *td )
260 struct agtiapi_softc *sc;
263 AGTIAPI_PRINTK("agtiapi_close\n");
264 AGTIAPI_PRINTK("Closed. sc->my_dev %p\n", sc->my_dev);
268 int agtiapi_read( struct cdev *dev, struct uio *uio, int ioflag )
270 struct agtiapi_softc *sc;
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 );
279 int agtiapi_write( struct cdev *dev, struct uio *uio, int ioflag )
281 struct agtiapi_softc *sc;
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 );
290 int agtiapi_getdevlist( struct agtiapi_softc *pCard,
291 tiIOCTLPayload_t *agIOCTLPayload )
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;
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" );
309 pDeviceInfoOrg = pIoctlPayload -> pDeviceInfo;
310 MaxDeviceCount = pCard->devDiscover;
311 if (MaxDeviceCount > pIoctlPayload->deviceLength )
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;
317 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
318 memNeeded1 = AG_ALIGNSIZE( MaxDeviceCount * sizeof(tiDeviceHandle_t *),
320 AGTIAPI_PRINTK("agtiapi_getdevlist: portCount %d\n", pCard->portCount);
321 devList = malloc(memNeeded1, TEMP2, M_WAITOK);
324 AGTIAPI_PRINTK("agtiapi_getdevlist: failed to allocate memory\n");
325 ret_val = IOCTL_CALL_FAIL;
326 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
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++)
334 count = tiINIGetDeviceHandlesForWinIOCTL(&pCard->tiRoot,
335 &pPortalData->portalInfo.tiPortalContext,
336 ( tiDeviceHandle_t **)pDeviceHandleList ,MaxDeviceCount );
337 if (count == DISCOVERY_IN_PROGRESS)
339 AGTIAPI_PRINTK( "agtiapi_getdevlist: DISCOVERY_IN_PROGRESS on "
341 free(devList, TEMP2);
342 ret_val = IOCTL_CALL_FAIL;
343 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
347 pDeviceHandleList+= count*sizeof(tiDeviceHandle_t *);
348 MaxDeviceCount-= count;
350 if (total > pIoctlPayload->deviceLength)
352 total = pIoctlPayload->deviceLength;
354 // dump device information from device handle list
357 devHandleArray = devList;
358 for (x = 0; x < pCard->devDiscover; x++)
360 pDeviceHandle = (tiDeviceHandle_t*)devHandleArray[x];
361 if (devList[x] != agNULL)
363 pDeviceData = devList [x]->tdData;
365 pDeviceInfo = (tdDeviceInfoIOCTL_t*)(pDeviceInfoOrg + sizeof(tdDeviceInfoIOCTL_t) * count);
366 if (pDeviceData != agNULL && pDeviceInfo != agNULL)
368 osti_memcpy( &pDeviceInfo->sasAddressHi,
369 pDeviceData->agDeviceInfo.sasAddressHi,
371 osti_memcpy( &pDeviceInfo->sasAddressLo,
372 pDeviceData->agDeviceInfo.sasAddressLo,
375 pDeviceInfo->sasAddressHi =
376 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
377 pDeviceInfo->sasAddressLo =
378 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
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)
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;
398 pDeviceInfo->sasAddressHi =
399 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
400 pDeviceInfo->sasAddressLo =
401 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
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 );
417 AGTIAPI_PRINTK( "agtiapi_getdevlist: pDeviceData %p or pDeviceInfo "
418 "%p is NULL %d\n", pDeviceData, pDeviceInfo, x );
423 pIoctlPayload->realDeviceCount = count;
424 AGTIAPI_PRINTK( "agtiapi_getdevlist: Exit RealDeviceCount = %d\n", count );
427 free(devList, TEMP2);
429 if(ret_val != IOCTL_CALL_FAIL)
431 ret_val = IOCTL_CALL_SUCCESS;
433 agIOCTLPayload->Status = IOCTL_ERR_STATUS_OK;
437 /******************************************************************************
438 agtiapi_getCardInfo()
441 This function retrives the Card information
446 0 - HBA has been detected
448 ******************************************************************************/
449 int agtiapi_getCardInfo ( struct agtiapi_softc *pCard,
453 CardInfo_t *pCardInfo;
455 pCardInfo = (CardInfo_t *)buffer;
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);
470 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth)
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");
484 agtiapi_async(void *callback_arg, u_int32_t code,
485 struct cam_path *path, void *arg)
487 struct agtiapi_softc *pmsc;
490 pmsc = (struct agtiapi_softc*)callback_arg;
492 case AC_FOUND_DEVICE:
494 struct ccb_getdev *cgd;
495 cgd = (struct ccb_getdev *)arg;
499 TID = cgd->ccb_h.target_id;
500 if (TID >= 0 && TID < maxTargets){
502 TID = INDEX(pmsc, TID);
503 targ = &pmsc->pDevList[TID];
504 agtiapi_adjust_queue_depth(path, targ->qdepth);
513 /******************************************************************************
517 This function handles the ioctl from application layer
522 0 - HBA has been detected
524 ******************************************************************************/
525 static int agtiapi_CharIoctl( struct cdev *dev,
532 datatosend *load; // structure defined in lxcommon.h
533 tiIOCTLPayload_t *pIoctlPayload;
534 struct agtiapi_softc *pCard;
540 tdDeviceListPayload_t *pDeviceList = NULL;
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);
553 status = IOCTL_CALL_FAIL;
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 )
561 retValue = agtiapi_getdevlist(pCard, pIoctlPayload);
564 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
565 status = IOCTL_CALL_SUCCESS;
569 pIoctlPayload->Status = IOCTL_CALL_FAIL;
570 status = IOCTL_CALL_FAIL;
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 );
578 else if (pIoctlPayload->MajorFunction == IOCTL_MN_GET_CARD_INFO)
580 retValue = agtiapi_getCardInfo( pCard,
581 pIoctlPayload->Length,
582 (pIoctlPayload->FunctionSpecificArea) );
585 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
586 status = IOCTL_CALL_SUCCESS;
590 pIoctlPayload->Status = IOCTL_CALL_FAIL;
591 status = IOCTL_CALL_FAIL;
594 else if ( pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_DPMC_EVENT )
596 if ( pCard->flags & AGTIAPI_PORT_PANIC )
598 strcpy ( pIoctlPayload->FunctionSpecificArea, "DPMC LEAN\n" );
602 strcpy ( pIoctlPayload->FunctionSpecificArea, "do not dpmc lean\n" );
604 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
605 status = IOCTL_CALL_SUCCESS;
607 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_FATAL_ERROR )
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)
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;
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;
621 status = IOCTL_CALL_SUCCESS;
623 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE)
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);
631 if(retValue == AGTIAPI_SUCCESS)
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;
640 pIoctlPayload->Status = IOCTL_CALL_FAIL;
641 status = IOCTL_CALL_FAIL;
646 status = tiCOMMgntIOCTL( &pCard->tiRoot,
651 if (status == IOCTL_CALL_PENDING)
653 ostiIOCTLWaitForSignal(&pCard->tiRoot,NULL, NULL, NULL);
654 status = IOCTL_CALL_SUCCESS;
657 pCard->pIoctlSem = NULL;
660 //copy kernel buffer to userland buffer
661 err=copyout(pIoctlPayload,load->data,load->datasize);
664 status = IOCTL_CALL_FAIL;
667 free(pIoctlPayload,TEMP);
677 /******************************************************************************
681 This function initialize and registere all detected HBAs.
682 The first function being called in driver after agtiapi_probe()
684 device_t dev (IN) - device pointer
687 0 - HBA has been detected
689 ******************************************************************************/
690 static int agtiapi_probe( device_t dev )
694 ag_card_info_t *thisCardInst;
696 thisCard = device_get_unit( dev );
697 if ( thisCard >= AGTIAPI_MAX_CARDS )
699 device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" );
700 return (ENXIO); // maybe change to different return value?
702 thisCardInst = &agCardInfoList[ thisCard ];
703 retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard );
705 return (ENXIO); // maybe change to different return value?
706 return( BUS_PROBE_DEFAULT ); // successful probe
710 /******************************************************************************
714 This function initialize and registere all detected HBAs.
715 The first function being called in driver after agtiapi_probe()
717 device_t dev (IN) - device pointer
720 0 - HBA has been detected
722 ******************************************************************************/
723 static int agtiapi_attach( device_t devx )
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;
732 char buffer [256], *pLastUsedChar;
735 struct ccb_setasync csa;
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 ) );
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 )
748 ag_timeout_secs = 1; // set minimum timeout value of 1 second
750 ag_timeout_secs = (ag_timeout_secs * 1000); // convert to millisecond notation
752 // Look up our softc and initialize its fields.
753 pmsc = device_get_softc( devx );
756 /* Get NumberOfPortals */
757 if ((ostiGetTransportParam(
769 ) == tiSuccess) && (lenRecv != 0))
771 if (osti_strncmp(buffer, "0x", 2) == 0)
773 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 0);
777 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 10);
779 if (ag_portal_count > AGTIAPI_MAX_PORTALS)
780 ag_portal_count = AGTIAPI_MAX_PORTALS;
784 ag_portal_count = AGTIAPI_MAX_PORTALS;
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 |
790 pmsc->cardNo = thisCard;
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;
801 osti_memset(buffer, 0, 256);
805 if ((ostiGetTransportParam(
817 ) == tiSuccess) && (lenRecv != 0))
819 if (osti_strncmp(buffer, "0x", 2) == 0)
821 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
822 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 0 \n" );
826 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
827 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 10\n" );
834 maxTargets = AGTIAPI_MAX_DEVICE_8H;
835 else if(Is_ADP7H(pmsc))
836 maxTargets = AGTIAPI_MAX_DEVICE_7H;
838 maxTargets = AGTIAPI_MAX_DEVICE;
841 if (maxTargets > AGTIAPI_HW_LIMIT_DEVICE)
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;
847 pmsc->devDiscover = maxTargets ;
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)
855 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
856 printf("agtiapi_attach: Encryption Enabled\n" );
859 // ## for now, skip calls to ostiGetTransportParam(...)
860 // ## for now, skip references to DIF & EDC
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
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;
870 mtx_init( &thisCardInst->pmIOLock, "pmc SAS I/O lock",
871 NULL, MTX_DEF|MTX_RECURSE );
873 struct cam_devq *devq;
875 /* set the maximum number of pending IOs */
876 devq = cam_simq_alloc( AGTIAPI_MAX_CAM_Q_DEPTH );
879 AGTIAPI_PRINTK("agtiapi_attach: cam_simq_alloc is NULL\n" );
883 struct cam_sim *lsim;
884 lsim = cam_sim_alloc( agtiapi_cam_action,
889 &thisCardInst->pmIOLock,
890 1, // queued per target
891 AGTIAPI_MAX_CAM_Q_DEPTH, // max tag depth
893 if ( lsim == NULL ) {
894 cam_simq_free( devq );
895 AGTIAPI_PRINTK("agtiapi_attach: cam_sim_alloc is NULL\n" );
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 )
904 cam_sim_free( lsim, TRUE );
905 mtx_unlock( &thisCardInst->pmIOLock );
906 AGTIAPI_PRINTK("agtiapi_attach: xpt_bus_register fails\n" );
911 bus = cam_sim_path(pmsc->sim);
912 tid = CAM_TARGET_WILDCARD;
913 lun = CAM_LUN_WILDCARD;
914 ccb = xpt_alloc_ccb_nowait();
917 mtx_unlock( &thisCardInst->pmIOLock );
918 cam_sim_free( lsim, TRUE );
919 cam_simq_free( devq );
922 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
923 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
925 mtx_unlock( &thisCardInst->pmIOLock );
926 cam_sim_free( lsim, TRUE );
927 cam_simq_free( devq );
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" );
942 mtx_unlock( &thisCardInst->pmIOLock );
947 // get TD and lower layer memory requirements
948 tiCOMGetResource( &pmsc->tiRoot,
949 &pRscInfo->tiLoLevelResource,
950 &pRscInfo->tiInitiatorResource,
952 &pRscInfo->tiSharedMem );
954 agtiapi_ScopeDMARes( thisCardInst );
955 AGTIAPI_PRINTK( "agtiapi_attach: size from the call agtiapi_ScopeDMARes"
956 " 0x%x \n", pmsc->typhn );
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",
964 // begin: allocate and initialize card portal info resource
965 ag_portal_data_t *pPortalData;
966 if (pmsc->portCount == 0)
968 pmsc->pPortalData = NULL;
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)
977 AGTIAPI_PRINTK( "agtiapi_attach: Portal memory allocation ERROR\n" );
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;
988 // end: allocate and initialize card portal info resource
990 // begin: enable msix
993 // map to interrupt handler
995 int mesgs = MAX_MSIX_NUM_VECTOR;
998 void (*intrHandler[MAX_MSIX_NUM_ISR])(void *arg) =
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
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);
1024 printf( "pci_alloc_msix error %d\n", error );
1025 AGTIAPI_PRINTK("error %d\n", error);
1029 for(i=0; i < mesgs; i++) {
1030 pmsc->rscID[i] = i + 1;
1031 pmsc->irq[i] = bus_alloc_resource_any( devx,
1035 if( pmsc->irq[i] == NULL ) {
1036 printf( "RES_IRQ went terribly bad at %d\n", i );
1040 if ( (error = bus_setup_intr( devx, pmsc->irq[i],
1041 INTR_TYPE_CAM | INTR_MPSAFE,
1045 &pmsc->intrcookie[i] )
1047 device_printf( devx, "Failed to register handler" );
1051 pmsc->flags |= AGTIAPI_IRQ_REQUESTED;
1052 pmsc->pCardInfo->maxInterruptVectors = MAX_MSIX_NUM_VECTOR;
1056 ret = agtiapi_InitCardSW(pmsc);
1057 if (ret == AGTIAPI_FAIL || ret == AGTIAPI_UNKNOWN)
1059 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardSW failure %d\n",
1064 pmsc->ccbFreeList = NULL;
1065 pmsc->ccbChainList = NULL;
1066 pmsc->ccbAllocList = NULL;
1068 pmsc->flags |= ( AGTIAPI_INSTALLED );
1070 ret = agtiapi_alloc_requests( pmsc );
1072 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_requests failure %d\n",
1077 ret = agtiapi_alloc_ostimem( pmsc );
1078 if (ret != AGTIAPI_SUCCESS)
1080 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_ostimem failure %d\n",
1085 ret = agtiapi_InitCardHW( pmsc );
1088 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardHW failure %d\n",
1093 #ifdef HIALEAH_ENCRYPTION
1096 if((agtiapi_SetupEncryption(pmsc)) < 0)
1097 AGTIAPI_PRINTK("SetupEncryption returned less than 0\n");
1101 pmsc->flags &= ~AGTIAPI_INIT_TIME;
1105 /******************************************************************************
1106 agtiapi_InitCardSW()
1109 Host Bus Adapter Initialization
1111 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1113 AGTIAPI_SUCCESS - success
1116 TBD, need chip register information
1117 ******************************************************************************/
1118 STATIC agBOOLEAN agtiapi_InitCardSW( struct agtiapi_softc *pmsc )
1120 ag_card_info_t *thisCardInst = pmsc->pCardInfo;
1121 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
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);
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)
1144 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
1146 pmsc->flags &= ~(AGTIAPI_PORT_INITIALIZED | AGTIAPI_SYS_INTR_ON);
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;
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,
1164 &thisCardInst->tiRscInfo.tiSharedMem ) != tiSuccess ) {
1165 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit ERROR\n" );
1166 return AGTIAPI_FAIL;
1169 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
1170 pmsc->STLock = malloc( ( maxLocks * sizeof(struct mtx) ), M_PMC_MSTL,
1171 M_ZERO | M_WAITOK );
1173 for( initSWIdx = 0; initSWIdx < maxLocks; initSWIdx++ )
1176 mtx_init( &pmsc->STLock[initSWIdx], "LL & TD lock", NULL, MTX_DEF );
1179 if( tiCOMPortInit( &pmsc->tiRoot, agFALSE ) != tiSuccess ) {
1180 printf( "agtiapi_InitCardSW: tiCOMPortInit ERROR -- AGTIAPI_FAIL\n" );
1181 return AGTIAPI_FAIL;
1183 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMPortInit"
1184 " root %p, dev %p, pmsc %p\n",
1185 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1187 pmsc->flags |= AGTIAPI_PORT_INITIALIZED;
1188 pmsc->freezeSim = agFALSE;
1190 #ifdef HIALEAH_ENCRYPTION
1191 atomic_set(&outstanding_encrypted_io_count, 0);
1193 /*if(pmsc->encrypt && (pmsc->flags & AGTIAPI_INIT_TIME))
1194 if((agtiapi_SetupEncryptionPools(pmsc)) != 0)
1195 printf("SetupEncryptionPools failed\n"); */
1197 return AGTIAPI_SUCCESS;
1198 // end: agtiapi_InitCardSW()
1201 /******************************************************************************
1202 agtiapi_InitCardHW()
1205 Host Bus Adapter Initialization
1207 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1209 AGTIAPI_SUCCESS - success
1212 TBD, need chip register information
1213 ******************************************************************************/
1214 STATIC agBOOLEAN agtiapi_InitCardHW( struct agtiapi_softc *pmsc )
1219 // begin: agtiapi_InitCardHW()
1221 ag_portal_info_t *pPortalInfo = NULL;
1222 ag_portal_data_t *pPortalData;
1224 // ISR is registered, enable chip interrupt.
1225 tiCOMSystemInterruptsActive( &pmsc->tiRoot, agTRUE );
1226 pmsc->flags |= AGTIAPI_SYS_INTR_ON;
1228 numVal = sizeof(ag_device_t) * pmsc->devDiscover;
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;
1237 #ifdef LINUX_PERBI_SUPPORT
1238 numVal = sizeof(ag_slr_map_t) * pmsc->devDiscover;
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;
1247 numVal = sizeof(ag_tgt_map_t) * pmsc->devDiscover;
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;
1256 // Get the WWN_to_target_ID mappings from the
1257 // holding area which contains the input of the
1258 // system configuration file.
1260 agtiapi_GetWWNMappings( pmsc, agMappingList );
1262 agtiapi_GetWWNMappings( pmsc, 0 );
1264 printf( "agtiapi_InitCardHW: WWN PERBI disabled WARN\n" );
1268 //agtiapi_DelaySec(5);
1273 pmsc->flags &= ~AGTIAPI_CB_DONE;
1274 pPortalData = pmsc->pPortalData;
1278 for (count = 0; count < pmsc->portCount; count++)
1280 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
1282 pPortalInfo = &pPortalData->portalInfo;
1283 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
1284 AGTIAPI_PORT_DISC_READY |
1286 AGTIAPI_DISC_COMPLETE );
1288 for (loop = 0; loop < AGTIAPI_LOOP_MAX; loop++)
1290 AGTIAPI_PRINTK( "tiCOMPortStart entry data %p / %d / %p\n",
1292 pPortalInfo->portID,
1293 &pPortalInfo->tiPortalContext );
1295 if( tiCOMPortStart( &pmsc->tiRoot,
1296 pPortalInfo->portID,
1297 &pPortalInfo->tiPortalContext,
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",
1307 AGTIAPI_PRINTK( "tiCOMPortStart success no loop, portalData %p\n",
1311 } // end of for loop
1313 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1315 if( loop >= AGTIAPI_LOOP_MAX ) {
1316 return AGTIAPI_FAIL;
1318 tiCOMGetPortInfo( &pmsc->tiRoot,
1319 &pPortalInfo->tiPortalContext,
1320 &pPortalInfo->tiPortInfo );
1324 /* discover target device */
1325 #ifndef HOTPLUG_SUPPORT
1326 agtiapi_DiscoverTgt( pCard );
1330 pmsc->flags |= AGTIAPI_INSTALLED;
1332 if( pmsc->flags & AGTIAPI_INIT_TIME ) {
1333 agtiapi_TITimer( (void *)pmsc );
1334 pmsc->flags |= AGTIAPI_TIMER_ON;
1342 /******************************************************************************
1343 agtiapi_IntrHandlerx_()
1346 Interrupt service routine.
1348 void arg (IN) Pointer to the HBA data structure
1349 bit32 idx (IN) Vector index
1350 ******************************************************************************/
1351 void agtiapi_IntrHandlerx_( void *arg, int index )
1354 struct agtiapi_softc *pCard;
1357 pCard = (struct agtiapi_softc *)arg;
1363 AG_LOCAL_LOCK(&(pCard->pCardInfo->pmIOLock));
1364 AG_PERF_SPINLOCK(agtiapi_host_lock);
1365 if (pCard->flags & AGTIAPI_SHUT_DOWN)
1368 rv = tiCOMInterruptHandler(&pCard->tiRoot, index);
1372 AG_SPIN_UNLOCK(agtiapi_host_lock);
1373 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1379 tasklet_hi_schedule(&pCard->tasklet_dpc[idx]);
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);
1388 AG_SPIN_UNLOCK(agtiapi_host_lock);
1389 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
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 ******************************************************************************/
1399 void agtiapi_IntrHandler0( void *arg )
1401 agtiapi_IntrHandlerx_( arg, 0 );
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 ******************************************************************************/
1410 void agtiapi_IntrHandler1( void *arg )
1412 agtiapi_IntrHandlerx_( arg, 1 );
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 ******************************************************************************/
1421 void agtiapi_IntrHandler2( void *arg )
1423 agtiapi_IntrHandlerx_( arg, 2 );
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 ******************************************************************************/
1432 void agtiapi_IntrHandler3( void *arg )
1434 agtiapi_IntrHandlerx_( arg, 3 );
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 ******************************************************************************/
1443 void agtiapi_IntrHandler4( void *arg )
1445 agtiapi_IntrHandlerx_( arg, 4 );
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 ******************************************************************************/
1454 void agtiapi_IntrHandler5( void *arg )
1456 agtiapi_IntrHandlerx_( arg, 5 );
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 ******************************************************************************/
1465 void agtiapi_IntrHandler6( void *arg )
1467 agtiapi_IntrHandlerx_( arg, 6 );
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 ******************************************************************************/
1476 void agtiapi_IntrHandler7( void *arg )
1478 agtiapi_IntrHandlerx_( arg, 7 );
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 ******************************************************************************/
1487 void agtiapi_IntrHandler8( void *arg )
1489 agtiapi_IntrHandlerx_( arg, 8 );
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 ******************************************************************************/
1498 void agtiapi_IntrHandler9( void *arg )
1500 agtiapi_IntrHandlerx_( arg, 9 );
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 ******************************************************************************/
1509 void agtiapi_IntrHandler10( void *arg )
1511 agtiapi_IntrHandlerx_( arg, 10 );
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 ******************************************************************************/
1520 void agtiapi_IntrHandler11( void *arg )
1522 agtiapi_IntrHandlerx_( arg, 11 );
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 ******************************************************************************/
1531 void agtiapi_IntrHandler12( void *arg )
1533 agtiapi_IntrHandlerx_( arg, 12 );
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 ******************************************************************************/
1542 void agtiapi_IntrHandler13( void *arg )
1544 agtiapi_IntrHandlerx_( arg, 13 );
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 ******************************************************************************/
1553 void agtiapi_IntrHandler14( void *arg )
1555 agtiapi_IntrHandlerx_( arg, 14 );
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 ******************************************************************************/
1564 void agtiapi_IntrHandler15( void *arg )
1566 agtiapi_IntrHandlerx_( arg, 15 );
1570 static void agtiapi_SglMemoryCB( void *arg,
1571 bus_dma_segment_t *dm_segs,
1576 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: start\n");
1579 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: error %d\n", error);
1580 panic("agtiapi_SglMemoryCB: error %d\n", error);
1584 *addr = dm_segs[0].ds_addr;
1588 static void agtiapi_MemoryCB( void *arg,
1589 bus_dma_segment_t *dm_segs,
1594 AGTIAPI_PRINTK("agtiapi_MemoryCB: start\n");
1597 AGTIAPI_PRINTK("agtiapi_MemoryCB: error %d\n", error);
1598 panic("agtiapi_MemoryCB: error %d\n", error);
1602 *addr = dm_segs[0].ds_addr;
1606 /******************************************************************************
1607 agtiapi_alloc_requests()
1610 Allocates resources such as dma tag and timer
1612 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1614 AGTIAPI_SUCCESS - success
1617 ******************************************************************************/
1618 int agtiapi_alloc_requests( struct agtiapi_softc *pmcsc )
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
1634 BUS_SPACE_MAXADDR, // lowaddr
1635 BUS_SPACE_MAXADDR, // highaddr
1638 BUS_SPACE_MAXSIZE_32BIT, // maxsize
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" );
1649 // This is for tiSgl_t of pccb in agtiapi_PrepCCBs()
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
1657 BUS_SPACE_MAXADDR_32BIT, // lowaddr
1658 BUS_SPACE_MAXADDR, // highaddr
1663 rsize, // maxsegsize
1664 BUS_DMA_ALLOCNOW, // flags
1667 &pmcsc->tisgl_dmat ) ) {
1668 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1672 if( bus_dmamem_alloc( pmcsc->tisgl_dmat,
1673 (void **)&pmcsc->tisgl_mem,
1675 &pmcsc->tisgl_map ) ) {
1676 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot allocate SGL memory\n" );
1680 bzero( pmcsc->tisgl_mem, rsize );
1681 bus_dmamap_load( pmcsc->tisgl_dmat,
1685 agtiapi_SglMemoryCB,
1686 &pmcsc->tisgl_busaddr,
1687 BUS_DMA_NOWAIT /* 0 */ );
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);
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 );
1705 /******************************************************************************
1706 agtiapi_alloc_ostimem()
1709 Allocates memory used later in ostiAllocMemory
1711 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA data structure
1713 AGTIAPI_SUCCESS - success
1716 This is a pre-allocation for ostiAllocMemory() "non-cacheable" function calls
1717 ******************************************************************************/
1718 int agtiapi_alloc_ostimem( struct agtiapi_softc *pmcsc ) {
1722 rsize = AGTIAPI_DYNAMIC_MAX * nomsize; // 8M
1723 AGTIAPI_PRINTK("agtiapi_alloc_ostimem: rsize %d \n", rsize);
1725 if( bus_dma_tag_create( agNULL, // parent
1728 BUS_SPACE_MAXADDR, // lowaddr
1729 BUS_SPACE_MAXADDR, // highaddr
1732 rsize, // maxsize (size)
1733 1, // number of segments
1734 rsize, // maxsegsize
1738 &pmcsc->osti_dmat ) ) {
1739 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Can't create no-cache mem tag\n" );
1740 return AGTIAPI_FAIL;
1744 if( bus_dmamem_alloc( pmcsc->osti_dmat,
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",
1750 return AGTIAPI_FAIL;
1754 bus_dmamap_load( pmcsc->osti_dmat,
1758 agtiapi_MemoryCB, // try reuse of CB for same goal
1759 &pmcsc->osti_busaddr,
1762 // populate all the ag_dma_addr_t osti_busaddr/mem fields with addresses for
1763 // handy reference when driver is in motion
1765 ag_card_info_t *pCardInfo = pmcsc->pCardInfo;
1766 ag_dma_addr_t *pMem;
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];
1775 pCardInfo->topOfFreeDynamicMem = AGTIAPI_DYNAMIC_MAX;
1777 return AGTIAPI_SUCCESS;
1781 /******************************************************************************
1782 agtiapi_cam_action()
1785 Parses CAM frames and triggers a corresponding action
1787 struct cam_sim *sim (IN) Pointer to SIM data structure
1788 union ccb * ccb (IN) Pointer to CAM ccb data structure
1791 ******************************************************************************/
1792 static void agtiapi_cam_action( struct cam_sim *sim, union ccb * ccb )
1794 struct agtiapi_softc *pmcsc;
1795 tiDeviceHandle_t *pDevHandle = NULL; // acts as flag as well
1796 tiDeviceInfo_t devInfo;
1797 int pathID, targetID, lunID;
1802 pmcsc = cam_sim_softc( sim );
1803 AGTIAPI_IO( "agtiapi_cam_action: start pmcs %p\n", pmcsc );
1805 if (pmcsc == agNULL)
1807 AGTIAPI_PRINTK( "agtiapi_cam_action: start pmcs is NULL\n" );
1810 mtx_assert( &(pmcsc->pCardInfo->pmIOLock), MA_OWNED );
1812 AGTIAPI_IO( "agtiapi_cam_action: cardNO %d func_code 0x%x\n", pmcsc->cardNo, ccb->ccb_h.func_code );
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 );
1818 AGTIAPI_IO( "agtiapi_cam_action: P 0x%x T 0x%x L 0x%x\n",
1819 pathID, targetID, lunID );
1821 switch (ccb->ccb_h.func_code)
1825 struct ccb_pathinq *cpi;
1827 /* See architecure book p180*/
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 cpi->maxio = 1024 *1024; /* Max supported I/O size, in bytes. */
1837 cpi->initiator_id = 255;
1838 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1839 strlcpy(cpi->hba_vid, "PMC", HBA_IDLEN);
1840 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1841 cpi->unit_number = cam_sim_unit(sim);
1842 cpi->bus_id = cam_sim_bus(sim);
1843 // rate is set when XPT_GET_TRAN_SETTINGS is processed
1844 cpi->base_transfer_speed = 150000;
1845 cpi->transport = XPORT_SAS;
1846 cpi->transport_version = 0;
1847 cpi->protocol = PROTO_SCSI;
1848 cpi->protocol_version = SCSI_REV_SPC3;
1849 cpi->ccb_h.status = CAM_REQ_CMP;
1852 case XPT_GET_TRAN_SETTINGS:
1854 struct ccb_trans_settings *cts;
1855 struct ccb_trans_settings_sas *sas;
1856 struct ccb_trans_settings_scsi *scsi;
1858 if ( pmcsc->flags & AGTIAPI_SHUT_DOWN )
1864 sas = &ccb->cts.xport_specific.sas;
1865 scsi = &cts->proto_specific.scsi;
1867 cts->protocol = PROTO_SCSI;
1868 cts->protocol_version = SCSI_REV_SPC3;
1869 cts->transport = XPORT_SAS;
1870 cts->transport_version = 0;
1872 sas->valid = CTS_SAS_VALID_SPEED;
1874 /* this sets the "MB/s transfers" */
1875 if (pmcsc != NULL && targetID >= 0 && targetID < maxTargets)
1877 if (pmcsc->pWWNList != NULL)
1879 TID = INDEX(pmcsc, targetID);
1880 if (TID < maxTargets)
1882 pDevHandle = pmcsc->pDevList[TID].pDevHandle;
1888 tiINIGetDeviceInfo( &pmcsc->tiRoot, pDevHandle, &devInfo );
1889 switch (devInfo.info.devType_S_Rate & 0xF)
1891 case 0x8: speed = 150000;
1893 case 0x9: speed = 300000;
1895 case 0xA: speed = 600000;
1897 case 0xB: speed = 1200000;
1899 default: speed = 150000;
1903 sas->bitrate = speed;
1904 scsi->valid = CTS_SCSI_VALID_TQ;
1905 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
1906 ccb->ccb_h.status = CAM_REQ_CMP;
1911 lRetVal = agtiapi_eh_HostReset( pmcsc, ccb ); // usually works first time
1912 if ( SUCCESS == lRetVal )
1914 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset success.\n" );
1918 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset failed.\n" );
1920 ccb->ccb_h.status = CAM_REQ_CMP;
1925 ccb->ccb_h.status = CAM_REQ_CMP;
1930 ccb->ccb_h.status = CAM_REQ_CMP;
1933 #if __FreeBSD_version >= 900026
1936 agtiapi_QueueSMP( pmcsc, ccb );
1939 #endif /* __FreeBSD_version >= 900026 */
1942 if(pmcsc->dev_scan == agFALSE)
1944 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1947 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
1949 AGTIAPI_PRINTK( "agtiapi_cam_action: shutdown, XPT_SCSI_IO 0x%x\n",
1951 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1956 AGTIAPI_IO( "agtiapi_cam_action: Zero XPT_SCSI_IO 0x%x, doing IOs\n",
1958 agtiapi_QueueCmnd_( pmcsc, ccb );
1963 case XPT_CALC_GEOMETRY:
1965 cam_calc_geometry(&ccb->ccg, 1);
1966 ccb->ccb_h.status = CAM_REQ_CMP;
1972 XPT_SET_TRAN_SETTINGS
1974 AGTIAPI_IO( "agtiapi_cam_action: default function code 0x%x\n",
1975 ccb->ccb_h.func_code );
1976 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1984 /******************************************************************************
1988 Get a ccb from free list or allocate a new one
1990 struct agtiapi_softc *pmcsc (IN) Pointer to HBA structure
1992 Pointer to a ccb structure, or NULL if not available
1994 ******************************************************************************/
1995 STATIC pccb_t agtiapi_GetCCB( struct agtiapi_softc *pmcsc )
1999 AGTIAPI_IO( "agtiapi_GetCCB: start\n" );
2001 AG_LOCAL_LOCK( &pmcsc->ccbLock );
2003 /* get the ccb from the head of the free list */
2004 if ((pccb = (pccb_t)pmcsc->ccbFreeList) != NULL)
2006 pmcsc->ccbFreeList = (caddr_t *)pccb->pccbNext;
2007 pccb->pccbNext = NULL;
2008 pccb->flags = ACTIVE;
2009 pccb->startTime = 0;
2011 AGTIAPI_IO( "agtiapi_GetCCB: re-allocated ccb %p\n", pccb );
2015 AGTIAPI_PRINTK( "agtiapi_GetCCB: kmalloc ERROR - no ccb allocated\n" );
2018 AG_LOCAL_UNLOCK( &pmcsc->ccbLock );
2022 /******************************************************************************
2023 agtiapi_QueueCmnd_()
2026 Calls for sending CCB and excuting on HBA.
2028 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2029 union ccb * ccb (IN) Pointer to CAM ccb data structure
2031 0 - Command is pending to execute
2032 1 - Command returned without further process
2034 ******************************************************************************/
2035 int agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb)
2037 struct ccb_scsiio *csio = &ccb->csio;
2038 pccb_t pccb = agNULL; // call dequeue
2039 int status = tiSuccess;
2040 U32 Channel = CMND_TO_CHANNEL(ccb);
2041 U32 TID = CMND_TO_TARGET(ccb);
2042 U32 LUN = CMND_TO_LUN(ccb);
2044 AGTIAPI_IO( "agtiapi_QueueCmnd_: start\n" );
2046 /* no support for CBD > 16 */
2047 if (csio->cdb_len > 16)
2049 AGTIAPI_PRINTK( "agtiapi_QueueCmnd_: unsupported CDB length %d\n",
2051 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2052 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2053 ccb->ccb_h.status |= CAM_REQ_INVALID;//CAM_REQ_CMP;
2057 if (TID < 0 || TID >= maxTargets)
2059 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: INVALID TID ERROR\n");
2060 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2061 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2062 ccb->ccb_h.status |= CAM_DEV_NOT_THERE;//CAM_REQ_CMP;
2067 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
2069 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n");
2073 TID = INDEX(pmcsc, TID);
2074 targ = &pmcsc->pDevList[TID];
2075 agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth);
2077 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2078 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2079 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2083 pccb->pmcsc = pmcsc;
2084 /* initialize Command Control Block (CCB) */
2085 pccb->targetId = TID;
2087 pccb->channel = Channel;
2088 pccb->ccb = ccb; /* for struct scsi_cmnd */
2089 pccb->senseLen = csio->sense_len;
2090 pccb->startTime = ticks;
2091 pccb->pSenseData = (caddr_t) &csio->sense_data;
2092 pccb->tiSuperScsiRequest.flags = 0;
2094 /* each channel is reserved for different addr modes */
2095 pccb->addrMode = agtiapi_AddrModes[Channel];
2097 status = agtiapi_PrepareSGList(pmcsc, pccb);
2098 if (status != tiSuccess)
2100 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: agtiapi_PrepareSGList failure\n");
2101 agtiapi_FreeCCB(pmcsc, pccb);
2102 if (status == tiReject)
2104 ccb->ccb_h.status = CAM_REQ_INVALID;
2108 ccb->ccb_h.status = CAM_REQ_CMP;
2116 /******************************************************************************
2122 const char *ptitle (IN) A string to be printed
2123 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2126 ******************************************************************************/
2127 STATIC void agtiapi_DumpCDB(const char *ptitle, ccb_t *pccb)
2130 struct ccb_scsiio *csio;
2136 printf( "agtiapi_DumpCDB: no pccb here \n" );
2137 panic("agtiapi_DumpCDB: pccb is NULL. called from %s\n", ptitle);
2143 printf( "agtiapi_DumpCDB: no ccb here \n" );
2144 panic( "agtiapi_DumpCDB: pccb %p ccb %p flags %d ccb NULL! "
2146 pccb, pccb->ccb, pccb->flags, ptitle );
2152 printf( "agtiapi_DumpCDB: no csio here \n" );
2153 panic( "agtiapi_DumpCDB: pccb%p ccb%p flags%d csio NULL! called from %s\n",
2154 pccb, pccb->ccb, pccb->flags, ptitle );
2157 len = MIN(64, csio->cdb_len);
2158 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2160 bcopy(csio->cdb_io.cdb_ptr, &cdb[0], len);
2164 bcopy(csio->cdb_io.cdb_bytes, &cdb[0], len);
2167 AGTIAPI_IO( "agtiapi_DumpCDB: pccb%p CDB0x%x csio->cdb_len %d"
2168 " len %d from %s\n",
2176 /******************************************************************************
2177 agtiapi_DoSoftReset()
2182 *data (IN) point to pmcsc (struct agtiapi_softc *)
2185 ******************************************************************************/
2186 int agtiapi_DoSoftReset (struct agtiapi_softc *pmcsc)
2189 unsigned long flags;
2191 pmcsc->flags |= AGTIAPI_SOFT_RESET;
2192 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
2193 ret = agtiapi_ResetCard( pmcsc, &flags );
2194 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
2196 if( ret != AGTIAPI_SUCCESS )
2202 /******************************************************************************
2203 agtiapi_CheckIOTimeout()
2206 Timeout function for SCSI IO or TM
2208 *data (IN) point to pCard (ag_card_t *)
2211 ******************************************************************************/
2212 STATIC void agtiapi_CheckIOTimeout(void *data)
2214 U32 status = AGTIAPI_SUCCESS;
2216 struct agtiapi_softc *pmcsc;
2219 pmcsc = (struct agtiapi_softc *)data;
2221 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Enter\n");
2223 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Active CCB %d\n", pmcsc->activeCCB);
2225 pccb = (pccb_t)pmcsc->ccbChainList;
2227 /* if link is down, do nothing */
2228 if ((pccb == NULL) || (pmcsc->activeCCB == 0))
2230 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: goto restart_timer\n");
2234 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
2235 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
2240 /* Walk thorugh the IO Chain linked list to find the pending io */
2241 /* Set the TM flag based on the pccb type, i.e SCSI IO or TM cmd */
2242 while (pccb_curr != NULL)
2244 /* start from 1st ccb in the chain */
2245 pccb_next = pccb_curr->pccbChainNext;
2246 if( (pccb_curr->flags == 0) || (pccb_curr->tiIORequest.tdData == NULL) ||
2247 (pccb_curr->startTime == 0) /* && (pccb->startTime == 0) */)
2249 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: move to next element\n");
2251 else if ( ( (ticks-pccb_curr->startTime) >= ag_timeout_secs ) &&
2252 !(pccb_curr->flags & TIMEDOUT) )
2254 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: pccb %p timed out, call TM "
2255 "function -- flags=%x startTime=%ld tdData = %p\n",
2256 pccb_curr, pccb_curr->flags, pccb->startTime,
2257 pccb_curr->tiIORequest.tdData );
2258 pccb_curr->flags |= TIMEDOUT;
2259 status = agtiapi_StartTM(pmcsc, pccb_curr);
2260 if (status == AGTIAPI_SUCCESS)
2262 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: TM Request sent with "
2268 #ifdef AGTIAPI_LOCAL_RESET
2269 /* abort request did not go through */
2270 AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Abort request failed\n");
2271 /* TODO: call Soft reset here */
2272 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout:in agtiapi_CheckIOTimeout() "
2273 "abort request did not go thru ==> soft reset#7, then "
2274 "restart timer\n" );
2275 agtiapi_DoSoftReset (pmcsc);
2280 pccb_curr = pccb_next;
2283 callout_reset(&pmcsc->IO_timer, 1*hz, agtiapi_CheckIOTimeout, pmcsc);
2286 AG_SPIN_UNLOCK_IRQ(agtiapi_host_lock, flags);
2290 /******************************************************************************
2294 DDI calls for aborting outstanding IO command
2296 struct scsi_cmnd *pccb (IN) Pointer to the command to be aborted
2297 unsigned long flags (IN/out) spinlock flags used in locking from
2300 AGTIAPI_SUCCESS - success
2302 ******************************************************************************/
2304 agtiapi_StartTM(struct agtiapi_softc *pCard, ccb_t *pccb)
2306 ccb_t *pTMccb = NULL;
2307 U32 status = AGTIAPI_SUCCESS;
2308 ag_device_t *pDevice = NULL;
2309 U32 TMstatus = tiSuccess;
2310 AGTIAPI_PRINTK( "agtiapi_StartTM: pccb %p, pccb->flags %x\n",
2311 pccb, pccb->flags );
2314 AGTIAPI_PRINTK("agtiapi_StartTM: %p not found\n",pccb);
2315 status = AGTIAPI_SUCCESS;
2318 if (!pccb->tiIORequest.tdData)
2320 /* should not be the case */
2321 AGTIAPI_PRINTK("agtiapi_StartTM: ccb %p flag 0x%x tid %d no tdData "
2322 "ERROR\n", pccb, pccb->flags, pccb->targetId);
2323 status = AGTIAPI_FAIL;
2327 /* If timedout CCB is TM_ABORT_TASK command, issue LocalAbort first to
2328 clear pending TM_ABORT_TASK */
2329 /* Else Device State will not be put back to Operational, (refer FW) */
2330 if (pccb->flags & TASK_MANAGEMENT)
2332 if (tiINIIOAbort(&pCard->tiRoot, &pccb->tiIORequest) != tiSuccess)
2334 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort Request for Abort_TASK "
2336 /* TODO: call Soft reset here */
2337 AGTIAPI_PRINTK( "agtiapi_StartTM: in agtiapi_StartTM() abort "
2338 "tiINIIOAbort() failed ==> soft reset#8\n" );
2339 agtiapi_DoSoftReset( pCard );
2343 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort for Abort_TASK TM "
2345 status = AGTIAPI_SUCCESS;
2351 if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
2353 AGTIAPI_PRINTK("agtiapi_StartTM: TM resource unavailable!\n");
2354 status = AGTIAPI_FAIL;
2357 pTMccb->pmcsc = pCard;
2358 pTMccb->targetId = pccb->targetId;
2359 pTMccb->devHandle = pccb->devHandle;
2360 if (pTMccb->targetId >= pCard->devDiscover)
2362 AGTIAPI_PRINTK("agtiapi_StartTM: Incorrect dev Id in TM!\n");
2363 status = AGTIAPI_FAIL;
2366 if (pTMccb->targetId < 0 || pTMccb->targetId >= maxTargets)
2368 return AGTIAPI_FAIL;
2370 if (INDEX(pCard, pTMccb->targetId) >= maxTargets)
2372 return AGTIAPI_FAIL;
2374 pDevice = &pCard->pDevList[INDEX(pCard, pTMccb->targetId)];
2375 if ((pDevice == NULL) || !(pDevice->flags & ACTIVE))
2377 return AGTIAPI_FAIL;
2380 /* save pending io to issue local abort at Task mgmt CB */
2381 pTMccb->pccbIO = pccb;
2382 AGTIAPI_PRINTK( "agtiapi_StartTM: pTMccb %p flag %x tid %d via TM "
2384 pTMccb, pTMccb->flags, pTMccb->targetId );
2385 pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
2386 pTMccb->flags |= TASK_MANAGEMENT;
2387 TMstatus = tiINITaskManagement(&pCard->tiRoot,
2390 &pccb->tiSuperScsiRequest.scsiCmnd.lun,
2392 &pTMccb->tiIORequest);
2393 if (TMstatus == tiSuccess)
2395 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request success ccb "
2398 pTMccb->startTime = ticks;
2399 status = AGTIAPI_SUCCESS;
2401 else if (TMstatus == tiIONoDevice)
2403 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request tiIONoDevice ccb "
2406 status = AGTIAPI_SUCCESS;
2410 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request failed ccb %p, "
2413 status = AGTIAPI_FAIL;
2414 agtiapi_FreeTMCCB(pCard, pTMccb);
2416 /* call TM_TARGET_RESET */
2421 AGTIAPI_PRINTK("agtiapi_StartTM: return %d flgs %x\n", status,
2422 (pccb) ? pccb->flags : -1);
2424 } /* agtiapi_StartTM */
2426 #if __FreeBSD_version > 901000
2427 /******************************************************************************
2428 agtiapi_PrepareSGList()
2431 This function prepares scatter-gather list for the given ccb
2433 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2434 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2440 ******************************************************************************/
2441 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2443 union ccb *ccb = pccb->ccb;
2444 struct ccb_scsiio *csio = &ccb->csio;
2445 struct ccb_hdr *ccbh = &ccb->ccb_h;
2446 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2448 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2449 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2451 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2453 switch((ccbh->flags & CAM_DATA_MASK))
2456 struct bus_dma_segment seg;
2457 case CAM_DATA_VADDR:
2458 /* Virtual address that needs to translated into one or more physical address ranges. */
2460 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2461 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2462 error = bus_dmamap_load( pmcsc->buffer_dmat,
2466 agtiapi_PrepareSGListCB,
2468 BUS_DMA_NOWAIT/* 0 */ );
2469 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2471 if (error == EINPROGRESS)
2473 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2474 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2475 xpt_freeze_simq(pmcsc->sim, 1);
2476 pmcsc->SimQFrozen = agTRUE;
2477 ccbh->status |= CAM_RELEASE_SIMQ;
2480 case CAM_DATA_PADDR:
2481 /* We have been given a pointer to single physical buffer. */
2482 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2483 //struct bus_dma_segment seg;
2484 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2486 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2487 seg.ds_len = csio->dxfer_len;
2488 // * 0xFF to be defined
2489 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2492 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2498 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2503 /******************************************************************************
2504 agtiapi_PrepareSGList()
2507 This function prepares scatter-gather list for the given ccb
2509 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2510 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2516 ******************************************************************************/
2517 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2519 union ccb *ccb = pccb->ccb;
2520 struct ccb_scsiio *csio = &ccb->csio;
2521 struct ccb_hdr *ccbh = &ccb->ccb_h;
2522 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2523 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2524 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2526 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2528 if ((ccbh->flags & CAM_SCATTER_VALID) == 0)
2530 /* We've been given a pointer to a single buffer. */
2531 if ((ccbh->flags & CAM_DATA_PHYS) == 0)
2533 /* Virtual address that needs to translated into one or more physical address ranges. */
2535 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2536 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2537 error = bus_dmamap_load( pmcsc->buffer_dmat,
2541 agtiapi_PrepareSGListCB,
2543 BUS_DMA_NOWAIT/* 0 */ );
2544 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2546 if (error == EINPROGRESS)
2548 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2549 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2550 xpt_freeze_simq(pmcsc->sim, 1);
2551 pmcsc->SimQFrozen = agTRUE;
2552 ccbh->status |= CAM_RELEASE_SIMQ;
2557 /* We have been given a pointer to single physical buffer. */
2558 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2559 struct bus_dma_segment seg;
2560 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2562 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2563 seg.ds_len = csio->dxfer_len;
2564 // * 0xFF to be defined
2565 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2571 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2577 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2583 /******************************************************************************
2584 agtiapi_PrepareSGListCB()
2587 Callback function for bus_dmamap_load()
2588 This fuctions sends IO to LL layer.
2590 void *arg (IN) Pointer to the HBA data structure
2591 bus_dma_segment_t *segs (IN) Pointer to dma segment
2592 int nsegs (IN) number of dma segment
2593 int error (IN) error
2596 ******************************************************************************/
2597 static void agtiapi_PrepareSGListCB( void *arg,
2598 bus_dma_segment_t *segs,
2603 union ccb *ccb = pccb->ccb;
2604 struct ccb_scsiio *csio = &ccb->csio;
2606 struct agtiapi_softc *pmcsc;
2607 tiIniScsiCmnd_t *pScsiCmnd;
2609 bus_dmasync_op_t op;
2612 int io_is_encryptable = 0;
2613 unsigned long long start_lba = 0;
2615 U32 TID = CMND_TO_TARGET(ccb);
2617 AGTIAPI_IO( "agtiapi_PrepareSGListCB: start, nsegs %d error 0x%x\n",
2619 pmcsc = pccb->pmcsc;
2621 if (error != tiSuccess)
2623 if (error == 0xAABBCCDD || error == 0xAAAAAAAA)
2629 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: error status 0x%x\n", error);
2630 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2631 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2632 agtiapi_FreeCCB(pmcsc, pccb);
2633 ccb->ccb_h.status = CAM_REQ_CMP;
2639 if (nsegs > AGTIAPI_MAX_DMA_SEGS)
2641 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: over the limit. nsegs %d"
2642 " AGTIAPI_MAX_DMA_SEGS %d\n",
2643 nsegs, AGTIAPI_MAX_DMA_SEGS );
2644 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2645 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2646 agtiapi_FreeCCB(pmcsc, pccb);
2647 ccb->ccb_h.status = CAM_REQ_CMP;
2653 /* fill in IO information */
2654 pccb->dataLen = csio->dxfer_len;
2656 /* start fill in sgl structure */
2657 if (nsegs == 1 && error == 0xAABBCCDD)
2660 /* A single physical buffer */
2661 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: nsegs is 1\n");
2662 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2663 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2664 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2665 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)segs->ds_addr;
2666 pccb->numSgElements = 1;
2668 else if (nsegs == 0 && error == 0xAAAAAAAA)
2670 /* no data transfer */
2671 AGTIAPI_IO( "agtiapi_PrepareSGListCB: no data transfer\n" );
2672 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2674 pccb->numSgElements = 0;
2678 /* virtual/logical buffer */
2681 pccb->dataLen = segs[0].ds_len;
2683 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2684 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2685 pccb->tiSuperScsiRequest.agSgl1.len = htole32(segs[0].ds_len);
2686 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2687 pccb->numSgElements = nsegs;
2694 for (i = 0; i < nsegs; i++)
2696 pccb->sgList[i].len = htole32(segs[i].ds_len);
2697 CPU_TO_LE32(pccb->sgList[i], segs[i].ds_addr);
2698 pccb->sgList[i].type = htole32(tiSgl);
2699 pccb->dataLen += segs[i].ds_len;
2702 pccb->numSgElements = nsegs;
2703 /* set up sgl buffer address */
2704 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, pccb->tisgl_busaddr);
2705 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSglList);
2706 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2707 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2708 pccb->numSgElements = nsegs;
2712 /* set data transfer direction */
2713 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2715 op = BUS_DMASYNC_PREWRITE;
2716 pccb->tiSuperScsiRequest.dataDirection = tiDirectionOut;
2720 op = BUS_DMASYNC_PREREAD;
2721 pccb->tiSuperScsiRequest.dataDirection = tiDirectionIn;
2724 pScsiCmnd = &pccb->tiSuperScsiRequest.scsiCmnd;
2726 pScsiCmnd->expDataLength = pccb->dataLen;
2728 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2730 bcopy(csio->cdb_io.cdb_ptr, &pScsiCmnd->cdb[0], csio->cdb_len);
2734 bcopy(csio->cdb_io.cdb_bytes, &pScsiCmnd->cdb[0],csio->cdb_len);
2737 CDB = &pScsiCmnd->cdb[0];
2741 case REQUEST_SENSE: /* requires different buffer */
2742 /* This code should not be excercised because SAS support auto sense
2743 For the completeness, vtophys() is still used here.
2745 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: QueueCmnd - REQUEST SENSE new\n");
2746 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->senseLen);
2747 phys_addr = vtophys(&csio->sense_data);
2748 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, phys_addr);
2749 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2750 pccb->dataLen = pccb->senseLen;
2751 pccb->numSgElements = 1;
2754 /* only using lun 0 for device type detection */
2755 pccb->flags |= AGTIAPI_INQUIRY;
2757 case TEST_UNIT_READY:
2761 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2767 start_lba = ((CDB[1] & 0x1f) << 16) |
2770 #ifdef HIALEAH_ENCRYPTION
2771 io_is_encryptable = 1;
2779 start_lba = (CDB[2] << 24) |
2783 #ifdef HIALEAH_ENCRYPTION
2784 io_is_encryptable = 1;
2790 start_lba = (CDB[2] << 24) |
2795 start_lba |= ((CDB[6] << 24) |
2799 #ifdef HIALEAH_ENCRYPTION
2800 io_is_encryptable = 1;
2807 /* fill device lun based one address mode */
2808 agtiapi_SetLunField(pccb);
2810 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
2812 pccb->ccbStatus = tiIOFailed;
2813 pccb->scsiStatus = tiDetailNoLogin;
2814 agtiapi_FreeCCB(pmcsc, pccb);
2815 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2820 if (INDEX(pmcsc, pccb->targetId) >= maxTargets)
2822 pccb->ccbStatus = tiIOFailed;
2823 pccb->scsiStatus = tiDetailNoLogin;
2824 agtiapi_FreeCCB(pmcsc, pccb);
2825 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2830 pDev = &pmcsc->pDevList[INDEX(pmcsc, pccb->targetId)];
2833 if ((pmcsc->flags & EDC_DATA) &&
2834 (pDev->flags & EDC_DATA))
2839 * Possible command supported -
2840 * READ_6, READ_10, READ_12, READ_16, READ_LONG, READ_BUFFER,
2841 * READ_DEFECT_DATA, etc.
2842 * WRITE_6, WRITE_10, WRITE_12, WRITE_16, WRITE_LONG, WRITE_LONG2,
2843 * WRITE_BUFFER, WRITE_VERIFY, WRITE_VERIFY_12, etc.
2845 * Do some data length adjustment and set chip operation instruction.
2853 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2854 #ifdef AGTIAPI_TEST_DIF
2855 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2857 pccb->flags |= EDC_DATA;
2859 #ifdef TEST_VERIFY_AND_FORWARD
2860 pccb->tiSuperScsiRequest.Dif.flags =
2861 DIF_VERIFY_FORWARD | DIF_UDT_REF_BLOCK_COUNT;
2862 if(pDev->sector_size == 520) {
2863 pScsiCmnd->expDataLength += (pccb->dataLen / 512) * 8;
2864 } else if(pDev->sector_size == 4104) {
2865 pScsiCmnd->expDataLength += (pccb->dataLen / 4096) * 8;
2868 #ifdef AGTIAPI_TEST_DIF
2869 pccb->tiSuperScsiRequest.Dif.flags =
2870 DIF_VERIFY_DELETE | DIF_UDT_REF_BLOCK_COUNT;
2873 #ifdef AGTIAPI_TEST_DIF
2874 switch(pDev->sector_size) {
2876 pccb->tiSuperScsiRequest.Dif.flags |=
2877 ( DIF_BLOCK_SIZE_520 << 16 );
2880 pccb->tiSuperScsiRequest.Dif.flags |=
2881 ( DIF_BLOCK_SIZE_4096 << 16 );
2884 pccb->tiSuperScsiRequest.Dif.flags |=
2885 ( DIF_BLOCK_SIZE_4160 << 16 );
2889 if(pCard->flags & EDC_DATA_CRC)
2890 pccb->tiSuperScsiRequest.Dif.flags |= DIF_CRC_VERIFICATION;
2892 /* Turn on upper 4 bits of UVM */
2893 pccb->tiSuperScsiRequest.Dif.flags |= 0x03c00000;
2896 #ifdef AGTIAPI_TEST_DPL
2897 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2898 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2899 cmnd->result = SCSI_HOST(DID_ERROR);
2902 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2904 #ifdef AGTIAPI_TEST_DIF
2906 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2907 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2909 /* Set LBA in UDT array */
2910 if(CDB[0] == READ_6) {
2911 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2912 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2913 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2914 pccb->tiSuperScsiRequest.Dif.udtArray[5] = 0;
2915 } else if(CDB[0] == READ_10 || CDB[0] == READ_12) {
2916 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2917 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2918 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2919 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2920 } else if(CDB[0] == READ_16) {
2921 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[9];
2922 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[8];
2923 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[7];
2924 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[6];
2925 /* Note: 32 bits lost */
2934 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2935 pccb->flags |= EDC_DATA;
2936 #ifdef AGTIAPI_TEST_DIF
2937 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2938 pccb->tiSuperScsiRequest.Dif.flags =
2939 DIF_INSERT | DIF_UDT_REF_BLOCK_COUNT;
2940 switch(pDev->sector_size) {
2942 pccb->tiSuperScsiRequest.Dif.flags |=
2943 (DIF_BLOCK_SIZE_520 << 16);
2946 pccb->tiSuperScsiRequest.Dif.flags |=
2947 ( DIF_BLOCK_SIZE_4096 << 16 );
2950 pccb->tiSuperScsiRequest.Dif.flags |=
2951 ( DIF_BLOCK_SIZE_4160 << 16 );
2955 /* Turn on upper 4 bits of UUM */
2956 pccb->tiSuperScsiRequest.Dif.flags |= 0xf0000000;
2958 #ifdef AGTIAPI_TEST_DPL
2959 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2960 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2961 cmnd->result = SCSI_HOST(DID_ERROR);
2964 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2966 #ifdef AGTIAPI_TEST_DIF
2968 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2969 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2971 /* Set LBA in UDT array */
2972 if(CDB[0] == WRITE_6) {
2973 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2974 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2975 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2976 } else if(CDB[0] == WRITE_10 || CDB[0] == WRITE_12) {
2977 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2978 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2979 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2980 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2981 } else if(CDB[0] == WRITE_16) {
2982 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2983 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2984 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2985 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2986 /* Note: 32 bits lost */
2992 #endif /* end of DIF */
2994 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
2996 switch(csio->tag_action)
2998 case MSG_HEAD_OF_Q_TAG:
2999 pScsiCmnd->taskAttribute = TASK_HEAD_OF_QUEUE;
3002 pScsiCmnd->taskAttribute = TASK_ACA;
3004 case MSG_ORDERED_Q_TAG:
3005 pScsiCmnd->taskAttribute = TASK_ORDERED;
3007 case MSG_SIMPLE_Q_TAG: /* fall through */
3009 pScsiCmnd->taskAttribute = TASK_SIMPLE;
3014 if (pccb->tiSuperScsiRequest.agSgl1.len != 0 && pccb->dataLen != 0)
3016 /* should be just before start IO */
3017 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
3021 * If assigned pDevHandle is not available
3022 * then there is no need to send it to StartIO()
3024 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
3026 pccb->ccbStatus = tiIOFailed;
3027 pccb->scsiStatus = tiDetailNoLogin;
3028 agtiapi_FreeCCB(pmcsc, pccb);
3029 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3034 TID = INDEX(pmcsc, pccb->targetId);
3035 if ((TID >= pmcsc->devDiscover) ||
3036 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle))
3039 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: not sending ccb devH %p,"
3040 " target %d tid %d/%d card %p ERROR pccb %p\n",
3041 pccb->devHandle, pccb->targetId, TID,
3042 pmcsc->devDiscover, pmcsc, pccb );
3044 pccb->ccbStatus = tiIOFailed;
3045 pccb->scsiStatus = tiDetailNoLogin;
3046 agtiapi_FreeCCB(pmcsc, pccb);
3047 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3052 AGTIAPI_IO( "agtiapi_PrepareSGListCB: send ccb pccb->devHandle %p, "
3053 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3054 pccb->devHandle, pccb->targetId, TID, pmcsc->devDiscover,
3056 #ifdef HIALEAH_ENCRYPTION
3057 if(pmcsc->encrypt && io_is_encryptable) {
3058 agtiapi_SetupEncryptedIO(pmcsc, pccb, start_lba);
3060 io_is_encryptable = 0;
3061 pccb->tiSuperScsiRequest.flags = 0;
3064 // put the request in send queue
3065 agtiapi_QueueCCB( pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3066 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb );
3067 agtiapi_StartIO(pmcsc);
3071 /******************************************************************************
3075 Send IO request down for processing.
3077 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3080 ******************************************************************************/
3081 STATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc )
3087 AGTIAPI_IO( "agtiapi_StartIO: start\n" );
3089 AG_LOCAL_LOCK( &pmcsc->sendLock );
3090 pccb = pmcsc->ccbSendHead;
3092 /* if link is down, do nothing */
3093 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3095 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3096 AGTIAPI_PRINTK( "agtiapi_StartIO: goto ext\n" );
3101 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3103 TID = INDEX(pmcsc, pccb->targetId);
3104 targ = &pmcsc->pDevList[TID];
3108 /* clear send queue */
3109 pmcsc->ccbSendHead = NULL;
3110 pmcsc->ccbSendTail = NULL;
3111 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3113 /* send all ccbs down */
3119 pccb_next = pccb->pccbNext;
3120 pccb->pccbNext = NULL;
3124 AGTIAPI_PRINTK( "agtiapi_StartIO: pccb->ccb is NULL ERROR!\n" );
3128 AG_IO_DUMPCCB( pccb );
3130 if (!pccb->devHandle)
3132 agtiapi_DumpCCB( pccb );
3133 AGTIAPI_PRINTK( "agtiapi_StartIO: ccb NULL device ERROR!\n" );
3137 AGTIAPI_IO( "agtiapi_StartIO: ccb %p retry %d\n", pccb, pccb->retryCount );
3140 if( !pccb->devHandle || !pccb->devHandle->osData || /* in rmmod case */
3141 !(((ag_device_t *)(pccb->devHandle->osData))->flags & ACTIVE))
3143 AGTIAPI_PRINTK( "agtiapi_StartIO: device %p not active! ERROR\n",
3145 if( pccb->devHandle ) {
3146 AGTIAPI_PRINTK( "agtiapi_StartIO: device not active detail"
3148 pccb->devHandle->osData );
3149 if( pccb->devHandle->osData ) {
3150 AGTIAPI_PRINTK( "agtiapi_StartIO: more device not active detail"
3151 " -- active flag:%d\n",
3153 (pccb->devHandle->osData))->flags & ACTIVE );
3156 pccb->ccbStatus = tiIOFailed;
3157 pccb->scsiStatus = tiDetailNoLogin;
3158 agtiapi_Done( pmcsc, pccb );
3165 status = agtiapi_FastIOTest( pmcsc, pccb );
3167 status = tiINISuperIOStart( &pmcsc->tiRoot,
3170 &pccb->tiSuperScsiRequest,
3171 (void *)&pccb->tdIOReqBody,
3172 tiInterruptContext );
3178 static int squelchCount = 0;
3179 if ( 200000 == squelchCount++ ) // squelch prints
3181 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart stat tiSuccess %p\n",
3183 squelchCount = 0; // reset count
3190 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiDeviceBusy %p\n",
3193 agtiapi_LogEvent( pmcsc,
3194 IOCTL_EVT_SEV_INFORMATIONAL,
3198 "tiINIIOStart tiDeviceBusy " );
3200 pccb->ccbStatus = tiIOFailed;
3201 pccb->scsiStatus = tiDeviceBusy;
3202 agtiapi_Done(pmcsc, pccb);
3206 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiBusy %p\n",
3209 agtiapi_LogEvent( pmcsc,
3210 IOCTL_EVT_SEV_INFORMATIONAL,
3214 "tiINIIOStart tiBusy " );
3217 pccb->ccbStatus = tiIOFailed;
3218 pccb->scsiStatus = tiBusy;
3219 agtiapi_Done(pmcsc, pccb);
3223 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiNoDevice %p "
3224 "ERROR\n", pccb->ccb );
3226 agtiapi_LogEvent( pmcsc,
3227 IOCTL_EVT_SEV_INFORMATIONAL,
3231 "tiINIIOStart invalid device handle " );
3234 /* return command back to OS due to no device available */
3235 ((ag_device_t *)(pccb->devHandle->osData))->flags &= ~ACTIVE;
3236 pccb->ccbStatus = tiIOFailed;
3237 pccb->scsiStatus = tiDetailNoLogin;
3238 agtiapi_Done(pmcsc, pccb);
3240 /* for short cable pull, we want IO retried - 3-18-2005 */
3241 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3242 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
3246 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3249 agtiapi_LogEvent(pmcsc,
3250 IOCTL_EVT_SEV_INFORMATIONAL,
3254 "tiINIIOStart tiError ");
3256 pccb->ccbStatus = tiIOFailed;
3257 pccb->scsiStatus = tiDetailOtherError;
3258 agtiapi_Done(pmcsc, pccb);
3261 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3264 agtiapi_LogEvent(pmcsc,
3265 IOCTL_EVT_SEV_ERROR,
3269 "tiINIIOStart unexpected status ");
3271 pccb->ccbStatus = tiIOFailed;
3272 pccb->scsiStatus = tiDetailOtherError;
3273 agtiapi_Done(pmcsc, pccb);
3279 /* some IO requests might have been completed */
3280 AG_GET_DONE_PCCB(pccb, pmcsc);
3284 /******************************************************************************
3288 Send SMP request down for processing.
3290 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3293 ******************************************************************************/
3294 STATIC void agtiapi_StartSMP(struct agtiapi_softc *pmcsc)
3298 AGTIAPI_PRINTK("agtiapi_StartSMP: start\n");
3300 AG_LOCAL_LOCK(&pmcsc->sendSMPLock);
3301 pccb = pmcsc->smpSendHead;
3303 /* if link is down, do nothing */
3304 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3306 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3307 AGTIAPI_PRINTK("agtiapi_StartSMP: goto ext\n");
3311 /* clear send queue */
3312 pmcsc->smpSendHead = NULL;
3313 pmcsc->smpSendTail = NULL;
3314 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3316 /* send all ccbs down */
3322 pccb_next = pccb->pccbNext;
3323 pccb->pccbNext = NULL;
3327 AGTIAPI_PRINTK("agtiapi_StartSMP: pccb->ccb is NULL ERROR!\n");
3332 if (!pccb->devHandle)
3334 AGTIAPI_PRINTK("agtiapi_StartSMP: ccb NULL device ERROR!\n");
3338 pccb->flags |= TAG_SMP; // mark as SMP for later tracking
3339 AGTIAPI_PRINTK( "agtiapi_StartSMP: ccb %p retry %d\n",
3340 pccb, pccb->retryCount );
3341 status = tiINISMPStart( &pmcsc->tiRoot,
3345 (void *)&pccb->tdIOReqBody,
3346 tiInterruptContext);
3353 AGTIAPI_PRINTK("agtiapi_StartSMP: tiINISMPStart status tiBusy %p\n",
3355 /* pending ccb back to send queue */
3356 agtiapi_QueueCCB(pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3357 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb);
3360 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3362 pccb->ccbStatus = tiSMPFailed;
3363 agtiapi_SMPDone(pmcsc, pccb);
3366 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3368 pccb->ccbStatus = tiSMPFailed;
3369 agtiapi_SMPDone(pmcsc, pccb);
3375 /* some SMP requests might have been completed */
3376 AG_GET_DONE_SMP_PCCB(pccb, pmcsc);
3381 #if __FreeBSD_version > 901000
3382 /******************************************************************************
3383 agtiapi_PrepareSMPSGList()
3386 This function prepares scatter-gather list for the given ccb
3388 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3389 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3395 ******************************************************************************/
3396 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3398 /* Pointer to CAM's ccb */
3399 union ccb *ccb = pccb->ccb;
3400 struct ccb_smpio *csmpio = &ccb->smpio;
3401 struct ccb_hdr *ccbh = &ccb->ccb_h;
3403 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3404 switch((ccbh->flags & CAM_DATA_MASK))
3406 case CAM_DATA_PADDR:
3407 case CAM_DATA_SG_PADDR:
3408 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address not supported\n");
3409 ccb->ccb_h.status = CAM_REQ_INVALID;
3415 * Currently we do not support Multiple SG list
3416 * return error for now
3418 if ( (csmpio->smp_request_sglist_cnt > 1)
3419 || (csmpio->smp_response_sglist_cnt > 1) )
3421 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list not supported\n");
3422 ccb->ccb_h.status = CAM_REQ_INVALID;
3427 if ( csmpio->smp_request_sglist_cnt != 0 )
3430 * Virtual address that needs to translated into
3431 * one or more physical address ranges.
3434 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3435 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3436 error = bus_dmamap_load( pmcsc->buffer_dmat,
3438 csmpio->smp_request,
3439 csmpio->smp_request_len,
3440 agtiapi_PrepareSMPSGListCB,
3442 BUS_DMA_NOWAIT /* 0 */ );
3444 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3446 if (error == EINPROGRESS)
3449 * So as to maintain ordering,
3450 * freeze the controller queue
3451 * until our mapping is
3454 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3455 xpt_freeze_simq( pmcsc->sim, 1 );
3456 pmcsc->SimQFrozen = agTRUE;
3457 ccbh->status |= CAM_RELEASE_SIMQ;
3460 if( csmpio->smp_response_sglist_cnt != 0 )
3463 * Virtual address that needs to translated into
3464 * one or more physical address ranges.
3467 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3468 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3469 error = bus_dmamap_load( pmcsc->buffer_dmat,
3471 csmpio->smp_response,
3472 csmpio->smp_response_len,
3473 agtiapi_PrepareSMPSGListCB,
3475 BUS_DMA_NOWAIT /* 0 */ );
3477 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3479 if ( error == EINPROGRESS )
3482 * So as to maintain ordering,
3483 * freeze the controller queue
3484 * until our mapping is
3487 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3488 xpt_freeze_simq( pmcsc->sim, 1 );
3489 pmcsc->SimQFrozen = agTRUE;
3490 ccbh->status |= CAM_RELEASE_SIMQ;
3496 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3497 (csmpio->smp_response_sglist_cnt == 0) )
3499 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3500 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3501 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3502 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3504 // 0xFF to be defined
3505 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3507 pccb->tiSMPFrame.flag = 0;
3514 /******************************************************************************
3515 agtiapi_PrepareSMPSGList()
3518 This function prepares scatter-gather list for the given ccb
3520 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3521 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3527 ******************************************************************************/
3528 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3530 /* Pointer to CAM's ccb */
3531 union ccb *ccb = pccb->ccb;
3532 struct ccb_smpio *csmpio = &ccb->smpio;
3533 struct ccb_hdr *ccbh = &ccb->ccb_h;
3535 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3537 if (ccbh->flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS))
3539 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address "
3540 "not supported\n" );
3541 ccb->ccb_h.status = CAM_REQ_INVALID;
3546 if (ccbh->flags & CAM_SCATTER_VALID)
3549 * Currently we do not support Multiple SG list
3550 * return error for now
3552 if ( (csmpio->smp_request_sglist_cnt > 1)
3553 || (csmpio->smp_response_sglist_cnt > 1) )
3555 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list "
3556 "not supported\n" );
3557 ccb->ccb_h.status = CAM_REQ_INVALID;
3561 if ( csmpio->smp_request_sglist_cnt != 0 )
3564 * Virtual address that needs to translated into
3565 * one or more physical address ranges.
3568 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3569 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3570 error = bus_dmamap_load( pmcsc->buffer_dmat,
3572 csmpio->smp_request,
3573 csmpio->smp_request_len,
3574 agtiapi_PrepareSMPSGListCB,
3576 BUS_DMA_NOWAIT /* 0 */ );
3578 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3580 if (error == EINPROGRESS)
3583 * So as to maintain ordering,
3584 * freeze the controller queue
3585 * until our mapping is
3588 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3589 xpt_freeze_simq( pmcsc->sim, 1 );
3590 pmcsc->SimQFrozen = agTRUE;
3591 ccbh->status |= CAM_RELEASE_SIMQ;
3594 if( csmpio->smp_response_sglist_cnt != 0 )
3597 * Virtual address that needs to translated into
3598 * one or more physical address ranges.
3601 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3602 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3603 error = bus_dmamap_load( pmcsc->buffer_dmat,
3605 csmpio->smp_response,
3606 csmpio->smp_response_len,
3607 agtiapi_PrepareSMPSGListCB,
3609 BUS_DMA_NOWAIT /* 0 */ );
3611 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3613 if ( error == EINPROGRESS )
3616 * So as to maintain ordering,
3617 * freeze the controller queue
3618 * until our mapping is
3621 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3622 xpt_freeze_simq( pmcsc->sim, 1 );
3623 pmcsc->SimQFrozen = agTRUE;
3624 ccbh->status |= CAM_RELEASE_SIMQ;
3630 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3631 (csmpio->smp_response_sglist_cnt == 0) )
3633 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3634 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3635 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3636 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3638 // 0xFF to be defined
3639 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3641 pccb->tiSMPFrame.flag = 0;
3648 /******************************************************************************
3649 agtiapi_PrepareSMPSGListCB()
3652 Callback function for bus_dmamap_load()
3653 This fuctions sends IO to LL layer.
3655 void *arg (IN) Pointer to the HBA data structure
3656 bus_dma_segment_t *segs (IN) Pointer to dma segment
3657 int nsegs (IN) number of dma segment
3658 int error (IN) error
3661 ******************************************************************************/
3662 static void agtiapi_PrepareSMPSGListCB( void *arg,
3663 bus_dma_segment_t *segs,
3668 union ccb *ccb = pccb->ccb;
3669 struct agtiapi_softc *pmcsc;
3670 U32 TID = CMND_TO_TARGET(ccb);
3672 tiDeviceHandle_t *tiExpDevHandle;
3673 tiPortalContext_t *tiExpPortalContext;
3674 ag_portal_info_t *tiExpPortalInfo;
3676 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: start, nsegs %d error 0x%x\n",
3678 pmcsc = pccb->pmcsc;
3680 if ( error != tiSuccess )
3682 if (error == 0xAABBCCDD)
3688 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: error status 0x%x\n",
3690 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3691 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3692 agtiapi_FreeCCB( pmcsc, pccb );
3693 ccb->ccb_h.status = CAM_REQ_CMP;
3699 if ( nsegs > AGTIAPI_MAX_DMA_SEGS )
3701 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: over the limit. nsegs %d "
3702 "AGTIAPI_MAX_DMA_SEGS %d\n",
3703 nsegs, AGTIAPI_MAX_DMA_SEGS );
3704 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3705 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3706 agtiapi_FreeCCB( pmcsc, pccb );
3707 ccb->ccb_h.status = CAM_REQ_CMP;
3713 * If assigned pDevHandle is not available
3714 * then there is no need to send it to StartIO()
3716 /* TODO: Add check for deviceType */
3717 if ( pccb->targetId < 0 || pccb->targetId >= maxTargets )
3719 agtiapi_FreeCCB( pmcsc, pccb );
3720 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3725 TID = INDEX( pmcsc, pccb->targetId );
3726 if ( (TID >= pmcsc->devDiscover) ||
3727 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle) )
3729 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: not sending ccb devH %p, "
3730 "target %d tid %d/%d "
3731 "card %p ERROR pccb %p\n",
3738 agtiapi_FreeCCB( pmcsc, pccb );
3739 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3744 /* TODO: add indirect handling */
3745 /* set the flag correctly based on Indiret SMP request and response */
3747 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, "
3748 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3750 pccb->targetId, TID,
3753 tiExpDevHandle = pccb->devHandle;
3754 tiExpPortalInfo = pmcsc->pDevList[TID].pPortalInfo;
3755 tiExpPortalContext = &tiExpPortalInfo->tiPortalContext;
3756 /* Look for the expander associated with the ses device */
3757 status = tiINIGetExpander( &pmcsc->tiRoot,
3762 if ( status != tiSuccess )
3764 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: Error getting Expander "
3766 agtiapi_FreeCCB( pmcsc, pccb );
3767 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3773 /* this is expander device */
3774 pccb->devHandle = tiExpDevHandle;
3775 /* put the request in send queue */
3776 agtiapi_QueueCCB( pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3777 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb );
3779 agtiapi_StartSMP( pmcsc );
3785 /******************************************************************************
3789 Processing completed ccbs
3791 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3792 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3795 ******************************************************************************/
3796 STATIC void agtiapi_Done(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3798 pccb_t pccb_curr = pccb;
3801 tiIniScsiCmnd_t *cmnd;
3804 AGTIAPI_IO("agtiapi_Done: start\n");
3807 /* start from 1st ccb in the chain */
3808 pccb_next = pccb_curr->pccbNext;
3810 if (agtiapi_CheckError(pmcsc, pccb_curr) != 0)
3812 /* send command back and release the ccb */
3813 cmnd = &pccb_curr->tiSuperScsiRequest.scsiCmnd;
3815 if (cmnd->cdb[0] == RECEIVE_DIAGNOSTIC)
3817 AGTIAPI_PRINTK("agtiapi_Done: RECEIVE_DIAG pg %d id %d cmnd %p pccb "
3818 "%p\n", cmnd->cdb[2], pccb_curr->targetId, cmnd,
3822 CMND_DMA_UNMAP(pmcsc, ccb);
3824 /* send the request back to the CAM */
3825 ccb = pccb_curr->ccb;
3826 agtiapi_FreeCCB(pmcsc, pccb_curr);
3829 pccb_curr = pccb_next;
3834 /******************************************************************************
3838 Processing completed ccbs
3840 struct agtiapi_softc *pmcsc (IN) Ponter to HBA data structure
3841 ccb_t *pccb (IN) A pointer to the driver's own CCB, not
3845 ******************************************************************************/
3846 STATIC void agtiapi_SMPDone(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3848 pccb_t pccb_curr = pccb;
3853 AGTIAPI_PRINTK("agtiapi_SMPDone: start\n");
3857 /* start from 1st ccb in the chain */
3858 pccb_next = pccb_curr->pccbNext;
3860 if (agtiapi_CheckSMPError(pmcsc, pccb_curr) != 0)
3862 CMND_DMA_UNMAP(pmcsc, ccb);
3864 /* send the request back to the CAM */
3865 ccb = pccb_curr->ccb;
3866 agtiapi_FreeSMPCCB(pmcsc, pccb_curr);
3870 pccb_curr = pccb_next;
3873 AGTIAPI_PRINTK("agtiapi_SMPDone: Done\n");
3877 /******************************************************************************
3881 Utility function for dumping in hex
3883 const char *ptitle (IN) A string to be printed
3884 bit8 *pbuf (IN) A pointer to a buffer to be printed.
3885 int len (IN) The lengther of the buffer
3888 ******************************************************************************/
3889 void agtiapi_hexdump(const char *ptitle, bit8 *pbuf, int len)
3892 AGTIAPI_PRINTK("%s - hexdump(len=%d):\n", ptitle, (int)len);
3895 AGTIAPI_PRINTK("pbuf is NULL\n");
3898 for (i = 0; i < len; )
3902 AGTIAPI_PRINTK( " 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1],
3903 pbuf[i+2], pbuf[i+3] );
3908 AGTIAPI_PRINTK(" 0x%02x,", pbuf[i]);
3912 AGTIAPI_PRINTK("\n");
3916 /******************************************************************************
3917 agtiapi_CheckError()
3920 Processes status pertaining to the ccb -- whether it was
3921 completed successfully, aborted, or error encountered.
3923 ag_card_t *pCard (IN) Pointer to HBA data structure
3924 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
3926 0 - the command retry is required
3927 1 - the command process is completed
3930 ******************************************************************************/
3931 STATIC U32 agtiapi_CheckError(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3933 ag_device_t *pDevice;
3934 // union ccb * ccb = pccb->ccb;
3942 AGTIAPI_IO("agtiapi_CheckError: start\n");
3945 /* shouldn't be here but just in case we do */
3946 AGTIAPI_PRINTK("agtiapi_CheckError: CCB orphan = %p ERROR\n", pccb);
3947 agtiapi_FreeCCB(pmcsc, pccb);
3953 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3955 if (pmcsc->pWWNList != NULL)
3957 TID = INDEX(pmcsc, pccb->targetId);
3958 if (TID < maxTargets)
3960 pDevice = &pmcsc->pDevList[TID];
3961 if (pDevice != NULL)
3970 AGTIAPI_PRINTK("agtiapi_CheckError: pDevice == NULL\n");
3971 agtiapi_FreeCCB(pmcsc, pccb);
3976 ccb->csio.scsi_status = pccb->scsiStatus;
3978 if(pDevice->CCBCount > 0){
3979 atomic_subtract_int(&pDevice->CCBCount,1);
3981 AG_LOCAL_LOCK(&pmcsc->freezeLock);
3982 if(pmcsc->freezeSim == agTRUE)
3984 pmcsc->freezeSim = agFALSE;
3985 xpt_release_simq(pmcsc->sim, 1);
3987 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
3989 switch (pccb->ccbStatus)
3992 AGTIAPI_IO("agtiapi_CheckError: tiIOSuccess pccb %p\n", pccb);
3994 if (pccb->scsiStatus == SCSI_STATUS_OK)
3996 ccb->ccb_h.status = CAM_REQ_CMP;
3999 if (pccb->scsiStatus == SCSI_TASK_ABORTED)
4001 ccb->ccb_h.status = CAM_REQ_ABORTED;
4005 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
4007 if (ccb->csio.scsi_status == SCSI_CHECK_CONDITION)
4009 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
4015 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOOverRun pccb %p\n", pccb);
4016 /* resid is ignored for this condition */
4017 ccb->csio.resid = 0;
4018 ccb->ccb_h.status = CAM_DATA_RUN_ERR;
4021 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOUnderRun pccb %p\n", pccb);
4022 ccb->csio.resid = pccb->scsiStatus;
4023 ccb->ccb_h.status = CAM_REQ_CMP;
4024 ccb->csio.scsi_status = SCSI_STATUS_OK;
4028 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4029 pccb, pccb->scsiStatus, pccb->targetId );
4030 if (pccb->scsiStatus == tiDeviceBusy)
4032 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - tiDetailBusy\n",
4034 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
4035 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4036 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0)
4038 ccb->ccb_h.status |= CAM_DEV_QFRZN;
4039 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
4042 else if(pccb->scsiStatus == tiBusy)
4044 AG_LOCAL_LOCK(&pmcsc->freezeLock);
4045 if(pmcsc->freezeSim == agFALSE)
4047 pmcsc->freezeSim = agTRUE;
4048 xpt_freeze_simq(pmcsc->sim, 1);
4050 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
4051 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4052 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4054 else if (pccb->scsiStatus == tiDetailNoLogin)
4056 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4057 "tiDetailNoLogin ERROR\n", pccb );
4058 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
4060 else if (pccb->scsiStatus == tiDetailNotValid)
4062 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4063 "tiDetailNotValid ERROR\n", pccb );
4064 ccb->ccb_h.status = CAM_REQ_INVALID;
4066 else if (pccb->scsiStatus == tiDetailAbortLogin)
4068 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4069 "tiDetailAbortLogin ERROR\n", pccb );
4070 ccb->ccb_h.status = CAM_REQ_ABORTED;
4072 else if (pccb->scsiStatus == tiDetailAbortReset)
4074 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4075 "tiDetailAbortReset ERROR\n", pccb );
4076 ccb->ccb_h.status = CAM_REQ_ABORTED;
4078 else if (pccb->scsiStatus == tiDetailAborted)
4080 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4081 "tiDetailAborted ERROR\n", pccb );
4082 ccb->ccb_h.status = CAM_REQ_ABORTED;
4084 else if (pccb->scsiStatus == tiDetailOtherError)
4086 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4087 "tiDetailOtherError ERROR\n", pccb );
4088 ccb->ccb_h.status = CAM_REQ_ABORTED;
4092 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4093 pccb, pccb->scsiStatus, pccb->targetId );
4094 if (pccb->scsiStatus == tiDetailDifAppTagMismatch)
4096 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - "
4097 "tiDetailDifAppTagMismatch\n", pccb );
4098 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4100 else if (pccb->scsiStatus == tiDetailDifRefTagMismatch)
4102 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4103 "tiDetailDifRefTagMismatch\n", pccb );
4104 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4106 else if (pccb->scsiStatus == tiDetailDifCrcMismatch)
4108 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4109 "tiDetailDifCrcMismatch\n", pccb );
4110 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4113 #ifdef HIALEAH_ENCRYPTION
4114 case tiIOEncryptError:
4115 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4116 pccb, pccb->scsiStatus, pccb->targetId );
4117 if (pccb->scsiStatus == tiDetailDekKeyCacheMiss)
4119 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4120 "tiDetailDekKeyCacheMiss ERROR\n",
4121 __FUNCTION__, pccb );
4122 ccb->ccb_h.status = CAM_REQ_ABORTED;
4123 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4125 else if (pccb->scsiStatus == tiDetailDekIVMismatch)
4127 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4128 "tiDetailDekIVMismatch ERROR\n", __FUNCTION__, pccb );
4129 ccb->ccb_h.status = CAM_REQ_ABORTED;
4130 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4135 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOdefault %d id %d ERROR\n",
4136 pccb, pccb->ccbStatus, pccb->targetId );
4137 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4145 /******************************************************************************
4146 agtiapi_SMPCheckError()
4149 Processes status pertaining to the ccb -- whether it was
4150 completed successfully, aborted, or error encountered.
4152 ag_card_t *pCard (IN) Pointer to HBA data structure
4153 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
4155 0 - the command retry is required
4156 1 - the command process is completed
4159 ******************************************************************************/
4160 STATIC U32 agtiapi_CheckSMPError( struct agtiapi_softc *pmcsc, ccb_t *pccb )
4162 union ccb * ccb = pccb->ccb;
4164 AGTIAPI_PRINTK("agtiapi_CheckSMPError: start\n");
4168 /* shouldn't be here but just in case we do */
4169 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: CCB orphan = %p ERROR\n",
4171 agtiapi_FreeSMPCCB(pmcsc, pccb);
4175 switch (pccb->ccbStatus)
4178 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPSuccess pccb %p\n",
4181 ccb->ccb_h.status = CAM_REQ_CMP;
4184 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPFailed pccb %p\n",
4187 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4190 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: pccb %p tiSMPdefault %d "
4195 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4204 /******************************************************************************
4205 agtiapi_HandleEncryptedIOFailure():
4212 ******************************************************************************/
4213 void agtiapi_HandleEncryptedIOFailure(ag_device_t *pDev, ccb_t *pccb)
4216 AGTIAPI_PRINTK("agtiapi_HandleEncryptedIOFailure: start\n");
4220 /******************************************************************************
4226 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA structure
4227 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4231 ******************************************************************************/
4232 STATIC void agtiapi_Retry(struct agtiapi_softc *pmcsc, ccb_t *pccb)
4235 pccb->flags = ACTIVE | AGTIAPI_RETRY;
4236 pccb->ccbStatus = 0;
4237 pccb->scsiStatus = 0;
4238 pccb->startTime = ticks;
4240 AGTIAPI_PRINTK( "agtiapi_Retry: start\n" );
4241 AGTIAPI_PRINTK( "agtiapi_Retry: ccb %p retry %d flgs x%x\n", pccb,
4242 pccb->retryCount, pccb->flags );
4244 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
4245 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
4250 /******************************************************************************
4254 Dump CCB for debuging
4256 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4259 ******************************************************************************/
4260 STATIC void agtiapi_DumpCCB(ccb_t *pccb)
4262 AGTIAPI_PRINTK("agtiapi_DumpCCB: pccb %p, devHandle %p, tid %d, lun %d\n",
4267 AGTIAPI_PRINTK("flag 0x%x, add_mode 0x%x, ccbStatus 0x%x, scsiStatus 0x%x\n",
4272 AGTIAPI_PRINTK("scsi comand = 0x%x, numSgElements = %d\n",
4273 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4274 pccb->numSgElements);
4275 AGTIAPI_PRINTK("dataLen = 0x%x, sens_len = 0x%x\n",
4278 AGTIAPI_PRINTK("tiSuperScsiRequest:\n");
4279 AGTIAPI_PRINTK("scsiCmnd: expDataLength 0x%x, taskAttribute 0x%x\n",
4280 pccb->tiSuperScsiRequest.scsiCmnd.expDataLength,
4281 pccb->tiSuperScsiRequest.scsiCmnd.taskAttribute);
4282 AGTIAPI_PRINTK("cdb[0] = 0x%x, cdb[1] = 0x%x, cdb[2] = 0x%x, cdb[3] = 0x%x\n",
4283 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4284 pccb->tiSuperScsiRequest.scsiCmnd.cdb[1],
4285 pccb->tiSuperScsiRequest.scsiCmnd.cdb[2],
4286 pccb->tiSuperScsiRequest.scsiCmnd.cdb[3]);
4287 AGTIAPI_PRINTK("cdb[4] = 0x%x, cdb[5] = 0x%x, cdb[6] = 0x%x, cdb[7] = 0x%x\n",
4288 pccb->tiSuperScsiRequest.scsiCmnd.cdb[4],
4289 pccb->tiSuperScsiRequest.scsiCmnd.cdb[5],
4290 pccb->tiSuperScsiRequest.scsiCmnd.cdb[6],
4291 pccb->tiSuperScsiRequest.scsiCmnd.cdb[7]);
4292 AGTIAPI_PRINTK( "cdb[8] = 0x%x, cdb[9] = 0x%x, cdb[10] = 0x%x, "
4294 pccb->tiSuperScsiRequest.scsiCmnd.cdb[8],
4295 pccb->tiSuperScsiRequest.scsiCmnd.cdb[9],
4296 pccb->tiSuperScsiRequest.scsiCmnd.cdb[10],
4297 pccb->tiSuperScsiRequest.scsiCmnd.cdb[11] );
4298 AGTIAPI_PRINTK("agSgl1: upper 0x%x, lower 0x%x, len 0x%x, type %d\n",
4299 pccb->tiSuperScsiRequest.agSgl1.upper,
4300 pccb->tiSuperScsiRequest.agSgl1.lower,
4301 pccb->tiSuperScsiRequest.agSgl1.len,
4302 pccb->tiSuperScsiRequest.agSgl1.type);
4305 /******************************************************************************
4306 agtiapi_eh_HostReset()
4309 A new error handler of Host Reset command.
4311 scsi_cmnd *cmnd (IN) Pointer to a command to the HBA to be reset
4316 ******************************************************************************/
4317 int agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4319 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4324 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4325 return tiInvalidHandle;
4329 agtiapi_LogEvent( pmcsc,
4330 IOCTL_EVT_SEV_INFORMATIONAL,
4334 "agtiapi_eh_HostReset! " );
4337 return agtiapi_DoSoftReset( pmcsc );
4341 /******************************************************************************
4345 Put ccb in ccb queue at the tail
4347 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4348 pccb_t *phead (IN) Double pointer to ccb queue head
4349 pccb_t *ptail (IN) Double pointer to ccb queue tail
4350 ccb_t *pccb (IN) Poiner to a ccb to be queued
4353 Put the ccb to the tail of queue
4354 ******************************************************************************/
4355 STATIC void agtiapi_QueueCCB( struct agtiapi_softc *pmcsc,
4358 #ifdef AGTIAPI_LOCAL_LOCK
4363 AGTIAPI_IO( "agtiapi_QueueCCB: start\n" );
4364 AGTIAPI_IO( "agtiapi_QueueCCB: %p to %p\n", pccb, phead );
4365 if (phead == NULL || ptail == NULL)
4367 panic( "agtiapi_QueueCCB: phead %p ptail %p", phead, ptail );
4369 pccb->pccbNext = NULL;
4370 AG_LOCAL_LOCK( mutex );
4373 //WARN_ON(*ptail != NULL); /* critical, just get more logs */
4378 //WARN_ON(*ptail == NULL); /* critical, just get more logs */
4380 (*ptail)->pccbNext = pccb;
4383 AG_LOCAL_UNLOCK( mutex );
4388 /******************************************************************************
4399 ******************************************************************************/
4400 static int agtiapi_QueueSMP(struct agtiapi_softc *pmcsc, union ccb * ccb)
4402 pccb_t pccb = agNULL; /* call dequeue */
4403 int status = tiSuccess;
4404 int targetID = xpt_path_target_id(ccb->ccb_h.path);
4406 AGTIAPI_PRINTK("agtiapi_QueueSMP: start\n");
4409 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
4411 AGTIAPI_PRINTK("agtiapi_QueueSMP: GetCCB ERROR\n");
4412 ccb->ccb_h.status = CAM_REQ_CMP;
4416 pccb->pmcsc = pmcsc;
4418 /* initialize Command Control Block (CCB) */
4419 pccb->targetId = targetID;
4420 pccb->ccb = ccb; /* for struct scsi_cmnd */
4422 status = agtiapi_PrepareSMPSGList(pmcsc, pccb);
4424 if (status != tiSuccess)
4426 AGTIAPI_PRINTK("agtiapi_QueueSMP: agtiapi_PrepareSMPSGList failure\n");
4427 agtiapi_FreeCCB(pmcsc, pccb);
4428 if (status == tiReject)
4430 ccb->ccb_h.status = CAM_REQ_INVALID;
4434 ccb->ccb_h.status = CAM_REQ_CMP;
4443 /******************************************************************************
4444 agtiapi_SetLunField()
4447 Set LUN field based on different address mode
4449 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4452 ******************************************************************************/
4453 void agtiapi_SetLunField(ccb_t *pccb)
4457 pchar = (U08 *)&pccb->tiSuperScsiRequest.scsiCmnd.lun;
4459 // AGTIAPI_PRINTK("agtiapi_SetLunField: start\n");
4461 switch (pccb->addrMode)
4463 case AGTIAPI_PERIPHERAL:
4465 *pchar = (U08)pccb->lun;
4467 case AGTIAPI_VOLUME_SET:
4468 *pchar++ = (AGTIAPI_VOLUME_SET << AGTIAPI_ADDRMODE_SHIFT) |
4469 (U08)((pccb->lun >> 8) & 0x3F);
4470 *pchar = (U08)pccb->lun;
4472 case AGTIAPI_LUN_ADDR:
4473 *pchar++ = (AGTIAPI_LUN_ADDR << AGTIAPI_ADDRMODE_SHIFT) |
4475 *pchar = (U08)pccb->lun;
4483 /*****************************************************************************
4487 Free a ccb and put it back to ccbFreeList.
4489 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4490 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4494 *****************************************************************************/
4495 STATIC void agtiapi_FreeCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4497 union ccb *ccb = pccb->ccb;
4498 bus_dmasync_op_t op;
4500 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4501 AGTIAPI_IO( "agtiapi_FreeCCB: start %p\n", pccb );
4503 #ifdef AGTIAPI_TEST_EPL
4504 tiEncrypt_t *encrypt;
4507 agtiapi_DumpCDB( "agtiapi_FreeCCB", pccb );
4509 if (pccb->sgList != agNULL)
4511 AGTIAPI_IO( "agtiapi_FreeCCB: pccb->sgList is NOT null\n" );
4515 AGTIAPI_PRINTK( "agtiapi_FreeCCB: pccb->sgList is null\n" );
4518 /* set data transfer direction */
4519 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4521 op = BUS_DMASYNC_POSTWRITE;
4525 op = BUS_DMASYNC_POSTREAD;
4528 if (pccb->numSgElements == 0)
4531 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements zero\n" );
4533 else if (pccb->numSgElements == 1)
4535 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements is one\n" );
4536 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4537 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4538 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4542 AGTIAPI_PRINTK( "agtiapi_FreeCCB: numSgElements 2 or higher \n" );
4543 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4544 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4545 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4548 #ifdef AGTIAPI_TEST_DPL
4549 if (pccb->tiSuperScsiRequest.Dif.enableDIFPerLA == TRUE) {
4551 memset( (char *) pccb->dplPtr,
4553 MAX_DPL_REGIONS * sizeof(dplaRegion_t) );
4554 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = FALSE;
4555 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrLo = 0;
4556 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrHi = 0;
4560 #ifdef AGTIAPI_TEST_EPL
4561 encrypt = &pccb->tiSuperScsiRequest.Encrypt;
4562 if (encrypt->enableEncryptionPerLA == TRUE) {
4563 encrypt->enableEncryptionPerLA = FALSE;
4564 encrypt->EncryptionPerLAAddrLo = 0;
4565 encrypt->EncryptionPerLAAddrHi = 0;
4569 #ifdef ENABLE_SATA_DIF
4570 if (pccb->holePtr && pccb->dmaHandleHole)
4571 pci_free_consistent( pmcsc->pCardInfo->pPCIDev,
4574 pccb->dmaHandleHole );
4576 pccb->dmaHandleHole = 0;
4580 pccb->retryCount = 0;
4581 pccb->ccbStatus = 0;
4582 pccb->scsiStatus = 0;
4583 pccb->startTime = 0;
4584 pccb->dmaHandle = 0;
4585 pccb->numSgElements = 0;
4586 pccb->tiIORequest.tdData = 0;
4587 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4589 #ifdef HIALEAH_ENCRYPTION
4591 agtiapi_CleanupEncryptedIO(pmcsc, pccb);
4596 pccb->pccbIO = NULL;
4597 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4598 pmcsc->ccbFreeList = (caddr_t *)pccb;
4602 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4607 /******************************************************************************
4611 Flush all in processed ccbs.
4613 ag_card_t *pCard (IN) Pointer to HBA data structure
4614 U32 flag (IN) Flag to call back
4617 ******************************************************************************/
4618 STATIC void agtiapi_FlushCCBs( struct agtiapi_softc *pCard, U32 flag )
4623 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: enter \n" );
4624 for( pccb = (pccb_t)pCard->ccbChainList;
4626 pccb = pccb->pccbChainNext ) {
4627 if( pccb->flags == 0 )
4629 // printf( "agtiapi_FlushCCBs: nothing, continue \n" );
4633 if ( pccb->flags & ( TASK_MANAGEMENT | DEV_RESET ) )
4635 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeTMCCB \n" );
4636 agtiapi_FreeTMCCB( pCard, pccb );
4640 if ( pccb->flags & TAG_SMP )
4642 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeSMPCCB \n" );
4643 agtiapi_FreeSMPCCB( pCard, pccb );
4647 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeCCB \n" );
4648 agtiapi_FreeCCB( pCard, pccb );
4651 CMND_DMA_UNMAP( pCard, ccb );
4652 if( flag == AGTIAPI_CALLBACK ) {
4653 ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
4661 /*****************************************************************************
4662 agtiapi_FreeSMPCCB()
4665 Free a ccb and put it back to ccbFreeList.
4667 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4668 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4672 *****************************************************************************/
4673 STATIC void agtiapi_FreeSMPCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4675 union ccb *ccb = pccb->ccb;
4676 bus_dmasync_op_t op;
4678 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4679 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: start %p\n", pccb);
4681 /* set data transfer direction */
4682 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4684 op = BUS_DMASYNC_POSTWRITE;
4688 op = BUS_DMASYNC_POSTREAD;
4691 if (pccb->numSgElements == 0)
4694 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 0\n");
4696 else if (pccb->numSgElements == 1)
4698 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 1\n");
4699 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4700 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4701 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4705 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 2 or higher \n");
4706 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4707 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4708 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4711 /*dma api cleanning*/
4713 pccb->retryCount = 0;
4714 pccb->ccbStatus = 0;
4715 pccb->startTime = 0;
4716 pccb->dmaHandle = 0;
4717 pccb->numSgElements = 0;
4718 pccb->tiIORequest.tdData = 0;
4719 memset((void *)&pccb->tiSMPFrame, 0, AGSMP_INIT_XCHG_LEN);
4723 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4724 pmcsc->ccbFreeList = (caddr_t *)pccb;
4728 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4733 /*****************************************************************************
4737 Free a ccb and put it back to ccbFreeList.
4739 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4740 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4744 *****************************************************************************/
4745 STATIC void agtiapi_FreeTMCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4747 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4748 AGTIAPI_PRINTK("agtiapi_FreeTMCCB: start %p\n", pccb);
4750 pccb->retryCount = 0;
4751 pccb->ccbStatus = 0;
4752 pccb->scsiStatus = 0;
4753 pccb->startTime = 0;
4754 pccb->dmaHandle = 0;
4755 pccb->numSgElements = 0;
4756 pccb->tiIORequest.tdData = 0;
4757 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4760 pccb->pccbIO = NULL;
4761 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4762 pmcsc->ccbFreeList = (caddr_t *)pccb;
4764 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4767 /******************************************************************************
4768 agtiapi_CheckAllVectors():
4774 Currently, not used.
4775 ******************************************************************************/
4776 void agtiapi_CheckAllVectors( struct agtiapi_softc *pCard, bit32 context )
4778 #ifdef SPC_MSIX_INTR
4779 if (!agtiapi_intx_mode)
4783 for (i = 0; i < pCard->pCardInfo->maxInterruptVectors; i++)
4784 if (tiCOMInterruptHandler(&pCard->tiRoot, i) == agTRUE)
4785 tiCOMDelayedInterruptHandler(&pCard->tiRoot, i, 100, context);
4788 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4789 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4791 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4792 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4798 /******************************************************************************
4802 Check call back function returned event for process completion
4804 struct agtiapi_softc *pCard Pointer to card data structure
4805 U32 milisec (IN) Waiting time for expected event
4806 U32 flag (IN) Flag of the event to check
4807 U32 *pStatus (IN) Pointer to status of the card or port to check
4809 AGTIAPI_SUCCESS - event comes as expected
4810 AGTIAPI_FAIL - event not coming
4813 ******************************************************************************/
4814 agBOOLEAN agtiapi_CheckCB( struct agtiapi_softc *pCard,
4817 volatile U32 *pStatus )
4819 U32 msecsPerTick = pCard->pCardInfo->tiRscInfo.tiInitiatorResource.
4820 initiatorOption.usecsPerTick / 1000;
4821 S32 i = milisec/msecsPerTick;
4822 AG_GLOBAL_ARG( _flags );
4824 AGTIAPI_PRINTK( "agtiapi_CheckCB: start\n" );
4825 AGTIAPI_FLOW( "agtiapi_CheckCB: start\n" );
4831 if (*pStatus & TASK_MANAGEMENT)
4833 if (*pStatus & AGTIAPI_CB_DONE)
4835 if( flag == 0 || *pStatus & flag )
4836 return AGTIAPI_SUCCESS;
4838 return AGTIAPI_FAIL;
4841 else if (pCard->flags & AGTIAPI_CB_DONE)
4843 if( flag == 0 || *pStatus & flag )
4844 return AGTIAPI_SUCCESS;
4846 return AGTIAPI_FAIL;
4849 agtiapi_DelayMSec( msecsPerTick );
4851 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, _flags );
4852 tiCOMTimerTick( &pCard->tiRoot );
4854 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
4855 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, _flags );
4860 if( *pStatus & TASK_MANAGEMENT )
4861 *pStatus |= TASK_TIMEOUT;
4863 return AGTIAPI_FAIL;
4867 /******************************************************************************
4868 agtiapi_DiscoverTgt()
4871 Discover available devices
4873 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
4876 ******************************************************************************/
4877 STATIC void agtiapi_DiscoverTgt(struct agtiapi_softc *pCard)
4880 ag_portal_data_t *pPortalData;
4883 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: start\n");
4884 AGTIAPI_FLOW("agtiapi_DiscoverTgt\n");
4885 AGTIAPI_INIT("agtiapi_DiscoverTgt\n");
4887 pPortalData = pCard->pPortalData;
4888 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4890 pCard->flags &= ~AGTIAPI_CB_DONE;
4891 if (!(PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4893 if (pCard->flags & AGTIAPI_INIT_TIME)
4895 if (agtiapi_CheckCB(pCard, 5000, AGTIAPI_PORT_DISC_READY,
4896 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4898 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Port %p / %d not ready for "
4900 pPortalData, count );
4902 * There is no need to spend time on discovering device
4903 * if port is not ready to do so.
4912 AGTIAPI_FLOW( "agtiapi_DiscoverTgt: Portal %p DiscoverTargets starts\n",
4914 AGTIAPI_INIT_DELAY(1000);
4916 pCard->flags &= ~AGTIAPI_CB_DONE;
4917 if (tiINIDiscoverTargets(&pCard->tiRoot,
4918 &pPortalData->portalInfo.tiPortalContext,
4919 FORCE_PERSISTENT_ASSIGN_MASK)
4921 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: tiINIDiscoverTargets ERROR\n");
4924 * Should wait till discovery completion to start
4925 * next portal. However, lower layer have issue on
4926 * multi-portal case under Linux.
4930 pPortalData = pCard->pPortalData;
4931 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4933 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4935 if (agtiapi_CheckCB(pCard, 20000, AGTIAPI_DISC_COMPLETE,
4936 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4938 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE))
4939 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover complete, "
4942 PORTAL_STATUS(pPortalData) );
4944 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover is not "
4945 "completed, status 0x%x\n",
4946 pPortalData, PORTAL_STATUS(pPortalData) );
4949 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %d discover target "
4956 * Calling to get device handle should be done per portal based
4957 * and better right after discovery is done. However, lower iscsi
4958 * layer may not returns discovery complete in correct sequence or we
4959 * ran out time. We get device handle for all portals together
4960 * after discovery is done or timed out.
4962 pPortalData = pCard->pPortalData;
4963 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4966 * We try to get device handle no matter
4967 * if discovery is completed or not.
4969 if (PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)
4973 for (i = 0; i < AGTIAPI_GET_DEV_MAX; i++)
4975 if (agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 0, 0) != 0)
4977 agtiapi_DelayMSec(AGTIAPI_EXTRA_DELAY);
4980 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE) ||
4981 (pCard->tgtCount > 0))
4982 PORTAL_STATUS(pPortalData) |= ( AGTIAPI_DISC_DONE |
4983 AGTIAPI_PORT_LINK_UP );
4993 /******************************************************************************
4997 Prepares CCB including DMA map.
4999 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5000 ccb_hdr_t *hdr (IN) Pointer to the CCB header
5002 U32 max_ccb (IN) count
5006 ******************************************************************************/
5007 STATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard,
5021 AGTIAPI_PRINTK("agtiapi_PrepCCBs: start\n");
5022 offset = tid * AGTIAPI_CCB_PER_DEVICE;
5023 nsegs = AGTIAPI_NSEGS;
5024 sgl_sz = sizeof(tiSgl_t) * nsegs;
5025 AGTIAPI_PRINTK( "agtiapi_PrepCCBs: tid %d offset %d nsegs %d sizeof(tiSgl_t) "
5026 "%lu, max_ccb %d\n",
5033 ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
5034 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5036 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after cache line\n");
5038 memset((void *)hdr, 0, size);
5039 hdr->next = pCard->ccbAllocList;
5040 pCard->ccbAllocList = hdr;
5042 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after memset\n");
5044 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5046 for (i = 0; i < max_ccb; i++, pccb = (ccb_t*)((char*)pccb + ccb_sz))
5048 pccb->tiIORequest.osData = (void *)pccb;
5051 * Initially put all the ccbs on the free list
5052 * in addition to chainlist.
5053 * ccbChainList is a list of all available ccbs
5054 * (free/active everything)
5056 pccb->pccbChainNext = (pccb_t)pCard->ccbChainList;
5057 pccb->pccbNext = (pccb_t)pCard->ccbFreeList;
5059 pCard->ccbChainList = (caddr_t *)pccb;
5060 pCard->ccbFreeList = (caddr_t *)pccb;
5063 #ifdef AGTIAPI_ALIGN_CHECK
5065 AGTIAPI_PRINTK("pccb = %p\n", pccb);
5066 if (pccb->devHandle & 0x63)
5067 AGTIAPI_PRINTK("devHandle addr = %p\n", &pccb->devHandle);
5068 if (&pccb->lun & 0x63)
5069 AGTIAPI_PRINTK("lun addr = %p\n", &pccb->lun);
5070 if (&pccb->targetId & 0x63)
5071 AGTIAPI_PRINTK("tig addr = %p\n", &pccb->targetId);
5072 if (&pccb->ccbStatus & 0x63)
5073 AGTIAPI_PRINTK("ccbStatus addr = %p\n", &pccb->ccbStatus);
5074 if (&pccb->scsiStatus & 0x63)
5075 AGTIAPI_PRINTK("scsiStatus addr = %p\n", &pccb->scsiStatus);
5076 if (&pccb->dataLen & 0x63)
5077 AGTIAPI_PRINTK("dataLen addr = %p\n", &pccb->dataLen);
5078 if (&pccb->senseLen & 0x63)
5079 AGTIAPI_PRINTK("senseLen addr = %p\n", &pccb->senseLen);
5080 if (&pccb->numSgElements & 0x63)
5081 AGTIAPI_PRINTK("numSgElements addr = %p\n", &pccb->numSgElements);
5082 if (&pccb->retryCount & 0x63)
5083 AGTIAPI_PRINTK("retry cnt addr = %p\n", &pccb->retryCount);
5084 if (&pccb->flags & 0x63)
5085 AGTIAPI_PRINTK("flag addr = %p\n", &pccb->flags);
5086 if (&pccb->pSenseData & 0x63)
5087 AGTIAPI_PRINTK("senseData addr = %p\n", &pccb->pSenseData);
5088 if (&pccb->sgList[0] & 0x63)
5089 AGTIAPI_PRINTK("SgList 0 = %p\n", &pccb->sgList[0]);
5090 if (&pccb->pccbNext & 0x63)
5091 AGTIAPI_PRINTK("ccb next = %p\n", &pccb->pccbNext);
5092 if (&pccb->pccbChainNext & 0x63)
5093 AGTIAPI_PRINTK("ccbChainNext = %p\n", &pccb->pccbChainNext);
5094 if (&pccb->cmd & 0x63)
5095 AGTIAPI_PRINTK("command = %p\n", &pccb->cmd);
5096 if( &pccb->startTime & 0x63 )
5097 AGTIAPI_PRINTK( "startTime = %p\n", &pccb->startTime );
5098 if (&pccb->tiIORequest & 0x63)
5099 AGTIAPI_PRINTK("tiIOReq addr = %p\n", &pccb->tiIORequest);
5100 if (&pccb->tdIOReqBody & 0x63)
5101 AGTIAPI_PRINTK("tdIORequestBody addr = %p\n", &pccb->tdIOReqBody);
5102 if (&pccb->tiSuperScsiRequest & 0x63)
5103 AGTIAPI_PRINTK( "InitiatorExchange addr = %p\n",
5104 &pccb->tiSuperScsiRequest );
5106 if ( bus_dmamap_create( pCard->buffer_dmat, 0, &pccb->CCB_dmamap ) !=
5109 AGTIAPI_PRINTK("agtiapi_PrepCCBs: can't create dma\n");
5112 /* assigns tiSgl_t memory to pccb */
5113 pccb->sgList = (void*)((U64)pCard->tisgl_mem + ((i + offset) * sgl_sz));
5114 pccb->tisgl_busaddr = pCard->tisgl_busaddr + ((i + offset) * sgl_sz);
5116 pccb->pccbIO = NULL;
5117 pccb->startTime = 0;
5120 #ifdef AGTIAPI_ALIGN_CHECK
5121 AGTIAPI_PRINTK("ccb size = %d / %d\n", sizeof(ccb_t), ccb_sz);
5126 /******************************************************************************
5130 Create and initialize per card based CCB pool.
5132 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5133 int tgtCount (IN) Count
5135 Total number of ccb allocated
5137 ******************************************************************************/
5138 STATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid)
5141 U32 max_ccb, size, ccb_sz, hdr_sz;
5142 int no_allocs = 0, i;
5143 ccb_hdr_t *hdr = NULL;
5145 AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n");
5146 AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5147 AGTIAPI_FLOW("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5149 #ifndef HOTPLUG_SUPPORT
5150 if (pCard->tgtCount > AGSA_MAX_INBOUND_Q)
5153 if (tgtCount > AGSA_MAX_INBOUND_Q)
5154 tgtCount = AGSA_MAX_INBOUND_Q;
5157 max_ccb = tgtCount * AGTIAPI_CCB_PER_DEVICE;// / 4; // TBR
5158 ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
5159 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5160 size = ccb_sz * max_ccb + hdr_sz;
5162 for (i = 0; i < (1 << no_allocs); i++)
5164 hdr = (ccb_hdr_t*)malloc( size, M_PMC_MCCB, M_NOWAIT );
5167 panic( "agtiapi_InitCCBs: bug!!!\n" );
5171 agtiapi_PrepCCBs( pCard, hdr, size, max_ccb, tid );
5180 #ifdef LINUX_PERBI_SUPPORT
5181 /******************************************************************************
5182 agtiapi_GetWWNMappings()
5185 Get the mappings from target IDs to WWNs, if any.
5186 Store them in the WWN_list array, indexed by target ID.
5187 Leave the devListIndex field blank; this will be filled-in later.
5189 ag_card_t *pCard (IN) Pointer to HBA data structure
5190 ag_mapping_t *pMapList (IN) Pointer to mapped device list
5192 Note: The boot command line parameters are used to load the
5193 mapping information, which is contained in the system
5195 ******************************************************************************/
5196 STATIC void agtiapi_GetWWNMappings( struct agtiapi_softc *pCard,
5197 ag_mapping_t *pMapList )
5201 ag_tgt_map_t *pWWNList;
5202 ag_slr_map_t *pSLRList;
5203 ag_device_t *pDevList;
5206 panic( "agtiapi_GetWWNMappings: no pCard \n" );
5208 AGTIAPI_PRINTK( "agtiapi_GetWWNMappings: start\n" );
5210 pWWNList = pCard->pWWNList;
5211 pSLRList = pCard->pSLRList;
5212 pDevList = pCard->pDevList;
5213 pCard->numTgtHardMapped = 0;
5214 devDisc = pCard->devDiscover;
5216 pWWNList[devDisc-1].devListIndex = maxTargets;
5217 pSLRList[devDisc-1].localeNameLen = -2;
5218 pSLRList[devDisc-1].remoteNameLen = -2;
5219 pDevList[devDisc-1].targetId = maxTargets;
5222 * Get the mappings from holding area which contains
5223 * the input of the system file and store them
5224 * in the WWN_list array, indexed by target ID.
5226 for ( lIdx = 0; lIdx < devDisc - 1; lIdx++) {
5227 pWWNList[lIdx].flags = 0;
5228 pWWNList[lIdx].devListIndex = maxTargets;
5229 pSLRList[lIdx].localeNameLen = -1;
5230 pSLRList[lIdx].remoteNameLen = -1;
5233 // this is where we would propagate values fed to pMapList
5235 } /* agtiapi_GetWWNMappings */
5240 /******************************************************************************
5241 agtiapi_FindWWNListNext()
5243 finds first available new (unused) wwn list entry
5246 ag_tgt_map_t *pWWNList Pointer to head of wwn list
5247 int lstMax Number of entries in WWNList
5249 index into WWNList indicating available entry space;
5250 if available entry space is not found, return negative value
5251 ******************************************************************************/
5252 STATIC int agtiapi_FindWWNListNext( ag_tgt_map_t *pWWNList, int lstMax )
5256 for ( lLstIdx = 0; lLstIdx < lstMax; lLstIdx++ )
5258 if ( pWWNList[lLstIdx].devListIndex == lstMax &&
5259 pWWNList[lLstIdx].targetLen == 0 )
5261 AGTIAPI_PRINTK( "agtiapi_FindWWNListNext: %d %d %d %d v. %d\n",
5263 pWWNList[lLstIdx].devListIndex,
5264 pWWNList[lLstIdx].targetLen,
5265 pWWNList[lLstIdx].portId,
5274 /******************************************************************************
5275 agtiapi_GetDevHandle()
5278 Get device handle. Handles will be placed in the
5279 devlist array with same order as TargetList provided and
5280 will be mapped to a scsi target id and registered to OS later.
5282 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5283 ag_portal_info_t *pPortalInfo (IN) Pointer to the portal data structure
5284 U32 eType (IN) Port event
5285 U32 eStatus (IN) Port event status
5287 Number of device handle slot present
5289 The sequence of device handle will match the sequence of taregt list
5290 ******************************************************************************/
5291 STATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard,
5292 ag_portal_info_t *pPortalInfo,
5296 ag_device_t *pDevice;
5297 // tiDeviceHandle_t *agDev[pCard->devDiscover];
5298 tiDeviceHandle_t **agDev;
5299 int devIdx, szdv, devTotal, cmpsetRtn;
5300 int lDevIndex = 0, lRunScanFlag = FALSE;
5302 tiPortInfo_t portInfT;
5303 ag_device_t lTmpDevice;
5304 ag_tgt_map_t *pWWNList;
5305 ag_slr_map_t *pSLRList;
5310 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: start\n" );
5311 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: pCard->devDiscover %d / tgtCt %d\n",
5312 pCard->devDiscover, pCard->tgtCount );
5313 AGTIAPI_FLOW( "agtiapi_GetDevHandle: portalInfo %p\n", pPortalInfo );
5314 AGTIAPI_INIT_DELAY( 1000 );
5316 agDev = (tiDeviceHandle_t **) malloc( sizeof(tiDeviceHandle_t *) * pCard->devDiscover,
5317 M_PMC_MDEV, M_ZERO | M_NOWAIT);
5320 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc agDev[]\n" );
5324 lDevFlags = (int *) malloc( sizeof(int) * pCard->devDiscover,
5325 M_PMC_MFLG, M_ZERO | M_NOWAIT );
5326 if (lDevFlags == NULL)
5328 free((caddr_t)agDev, M_PMC_MDEV);
5329 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc lDevFlags[]\n" );
5333 pWWNList = pCard->pWWNList;
5334 pSLRList = pCard->pSLRList;
5336 memset( (void *)agDev, 0, sizeof(void *) * pCard->devDiscover );
5337 memset( lDevFlags, 0, sizeof(int) * pCard->devDiscover );
5339 // get device handles
5340 devTotal = tiINIGetDeviceHandles( &pCard->tiRoot,
5341 &pPortalInfo->tiPortalContext,
5342 (tiDeviceHandle_t **)agDev,
5343 pCard->devDiscover );
5345 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: portalInfo %p port id %d event %u "
5346 "status %u card %p pCard->devDiscover %d devTotal %d "
5347 "pPortalInfo->devTotal %d pPortalInfo->devPrev %d "
5348 "AGTIAPI_INIT_TIME %x\n",
5349 pPortalInfo, pPortalInfo->portID, eType, eStatus, pCard,
5350 pCard->devDiscover, devTotal, pPortalInfo->devTotal,
5351 pPortalInfo->devPrev,
5352 pCard->flags & AGTIAPI_INIT_TIME );
5354 // reset devTotal from any previous runs of this
5355 pPortalInfo->devPrev = devTotal;
5356 pPortalInfo->devTotal = devTotal;
5358 AG_LIST_LOCK( &pCard->devListLock );
5360 if ( tiCOMGetPortInfo( &pCard->tiRoot,
5361 &pPortalInfo->tiPortalContext,
5365 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: tiCOMGetPortInfo did not succeed. \n" );
5369 szdv = sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
5370 if (szdv > pCard->devDiscover)
5372 szdv = pCard->devDiscover;
5375 // reconstructing dev list via comparison of wwn
5377 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5379 if ( agDev[devIdx] != NULL )
5381 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n",
5382 // devIdx, agDev[devIdx] );
5384 // pack temp device structure for tiINIGetDeviceInfo call
5385 pDevice = &lTmpDevice;
5386 pDevice->devType = DIRECT_DEVICE;
5387 pDevice->pCard = (void *)pCard;
5388 pDevice->flags = ACTIVE;
5389 pDevice->pPortalInfo = pPortalInfo;
5390 pDevice->pDevHandle = agDev[devIdx];
5391 pDevice->qbusy = agFALSE;
5393 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: idx %d / %d : %p \n",
5394 // devIdx, pCard->devDiscover, agDev[devIdx] );
5396 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx],
5397 &pDevice->devInfo );
5399 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: wwn sizes %ld %d/%d ",
5400 // sizeof(pDevice->targetName),
5401 // pDevice->devInfo.osAddress1,
5402 // pDevice->devInfo.osAddress2 );
5405 wwnprintk( (unsigned char*)pDevice->targetName, pDevice->targetLen );
5407 for ( lDevIndex = 0; lDevIndex < szdv; lDevIndex++ ) // match w/ wwn list
5409 if ( (pCard->pDevList[lDevIndex].portalId == pPortalInfo->portID) &&
5410 pDevice->targetLen > 0 &&
5411 portInfT.localNameLen > 0 &&
5412 portInfT.remoteNameLen > 0 &&
5413 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen > 0 &&
5414 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen > 0 &&
5415 ( portInfT.localNameLen ==
5416 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen ) &&
5417 ( portInfT.remoteNameLen ==
5418 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen ) &&
5419 memcmp( pWWNList[lDevIndex].targetName, pDevice->targetName,
5420 pDevice->targetLen ) == 0 &&
5421 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].localeName,
5423 portInfT.localNameLen ) == 0 &&
5424 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteName,
5425 portInfT.remoteName,
5426 portInfT.remoteNameLen ) == 0 )
5428 AGTIAPI_PRINTK( " pWWNList match @ %d/%d/%d \n",
5429 lDevIndex, devIdx, pPortalInfo->portID );
5431 if ( (pCard->pDevList[lDevIndex].targetId == lDevIndex) &&
5432 ( pPortalInfo->pDevList[lDevIndex] ==
5433 &pCard->pDevList[lDevIndex] ) ) // active
5436 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: dev in use %d of %d/%d\n",
5437 lDevIndex, devTotal, pPortalInfo->portID );
5438 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev handle
5439 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5440 lReadRm = atomic_readandclear_32( &pWWNList[lDevIndex].devRemoved );
5441 if ( lReadRm ) // cleared timeout, now remove count for timer
5443 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: clear timer count for"
5445 lDevIndex, pPortalInfo->portID );
5446 atomic_subtract_16( &pCard->rmChkCt, 1 );
5447 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5450 callout_stop( &pCard->devRmTimer );
5456 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: goin fresh on %d of %d/%d\n",
5457 lDevIndex, // reactivate now
5458 devTotal, pPortalInfo->portID );
5460 // pDevice going fresh
5461 lRunScanFlag = TRUE; // scan and clear outstanding removals
5463 // pCard->tgtCount++; ##
5464 pDevice->targetId = lDevIndex;
5465 pDevice->portalId = pPortalInfo->portID;
5467 memcpy ( &pCard->pDevList[lDevIndex], pDevice, sizeof(lTmpDevice) );
5468 agDev[devIdx]->osData = (void *)&pCard->pDevList[lDevIndex];
5469 if ( agtiapi_InitCCBs( pCard, 1, pDevice->targetId ) == 0 )
5471 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: InitCCB "
5472 "tgtCnt %d ERROR!\n", pCard->tgtCount );
5473 AG_LIST_UNLOCK( &pCard->devListLock );
5474 free((caddr_t)lDevFlags, M_PMC_MFLG);
5475 free((caddr_t)agDev, M_PMC_MDEV);
5478 pPortalInfo->pDevList[lDevIndex] = &pCard->pDevList[lDevIndex]; // (ag_device_t *)
5479 if ( 0 == lDevFlags[devIdx] )
5481 pPortalInfo->devTotal++;
5482 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5483 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5487 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: odd dev handle "
5488 "status inspect %d %d %d\n",
5489 lDevFlags[devIdx], devIdx, lDevIndex );
5490 pPortalInfo->devTotal++;
5491 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5492 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5498 // end: match this wwn with previous wwn list
5500 // we have an agDev entry, but no pWWNList target for it
5501 if ( !(lDevFlags[devIdx] & DPMC_LEANFLAG_AGDEVUSED) )
5502 { // flag dev handle not accounted for yet
5503 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOWWNLIST;
5504 // later, get an empty pDevice and map this agDev.
5505 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: devIdx %d flags 0x%x, %d\n",
5506 // devIdx, lDevFlags[devIdx], (lDevFlags[devIdx] & 8) );
5511 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOAGDEVYT; // known empty agDev handle
5515 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: all WWN all the time, "
5516 // "devLstIdx/flags/(WWNL)portId ... \n" );
5517 // review device list for further action needed
5518 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5520 if ( lDevFlags[devIdx] & DPMC_LEANFLAG_NOWWNLIST ) // new target, register
5522 int lNextDyad; // find next available dyad entry
5524 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: register new target, "
5525 "devIdx %d -- %d \n", devIdx, pCard->devDiscover );
5526 lRunScanFlag = TRUE; // scan and clear outstanding removals
5527 for ( lNextDyad = 0; lNextDyad < pCard->devDiscover; lNextDyad++ )
5529 if ( pSLRList[lNextDyad].localeNameLen < 0 &&
5530 pSLRList[lNextDyad].remoteNameLen < 0 )
5534 if ( lNextDyad == pCard->devDiscover )
5536 printf( "agtiapi_GetDevHandle: failed to find available SAS LR\n" );
5537 AG_LIST_UNLOCK( &pCard->devListLock );
5538 free( (caddr_t)lDevFlags, M_PMC_MFLG );
5539 free( (caddr_t)agDev, M_PMC_MDEV );
5542 // index of new entry
5543 lDevIndex = agtiapi_FindWWNListNext( pWWNList, pCard->devDiscover );
5544 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: listIdx new target %d of %d/%d\n",
5545 lDevIndex, devTotal, pPortalInfo->portID );
5546 if ( 0 > lDevIndex )
5548 printf( "agtiapi_GetDevHandle: WARNING -- WWNList exhausted.\n" );
5552 pDevice = &pCard->pDevList[lDevIndex];
5554 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], &pDevice->devInfo );
5556 agtiapi_InitCCBs( pCard, 1, lDevIndex );
5558 pDevice->pCard = (void *)pCard;
5559 pDevice->devType = DIRECT_DEVICE;
5561 // begin to populate new WWNList entry
5562 memcpy( pWWNList[lDevIndex].targetName, pDevice->targetName, pDevice->targetLen );
5563 pWWNList[lDevIndex].targetLen = pDevice->targetLen;
5565 pWWNList[lDevIndex].flags = SOFT_MAPPED;
5566 pWWNList[lDevIndex].portId = pPortalInfo->portID;
5567 pWWNList[lDevIndex].devListIndex = lDevIndex;
5568 pWWNList[lDevIndex].sasLrIdx = lNextDyad;
5570 pSLRList[lNextDyad].localeNameLen = portInfT.localNameLen;
5571 pSLRList[lNextDyad].remoteNameLen = portInfT.remoteNameLen;
5572 memcpy( pSLRList[lNextDyad].localeName, portInfT.localName, portInfT.localNameLen );
5573 memcpy( pSLRList[lNextDyad].remoteName, portInfT.remoteName, portInfT.remoteNameLen );
5574 // end of populating new WWNList entry
5576 pDevice->targetId = lDevIndex;
5578 pDevice->flags = ACTIVE;
5579 pDevice->CCBCount = 0;
5580 pDevice->pDevHandle = agDev[devIdx];
5581 agDev[devIdx]->osData = (void*)pDevice;
5583 pDevice->pPortalInfo = pPortalInfo;
5584 pDevice->portalId = pPortalInfo->portID;
5585 pPortalInfo->pDevList[lDevIndex] = (void*)pDevice;
5586 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // mark pDevice slot used
5589 if ( (pCard->pDevList[devIdx].portalId == pPortalInfo->portID) &&
5590 !(lDevFlags[devIdx] & DPMC_LEANFLAG_PDEVSUSED) ) // pDevice not used
5592 pDevice = &pCard->pDevList[devIdx];
5593 //pDevice->flags &= ~ACTIVE;
5594 if ( ( pDevice->pDevHandle != NULL ||
5595 pPortalInfo->pDevList[devIdx] != NULL ) )
5597 atomic_add_16( &pCard->rmChkCt, 1 ); // show count of lost device
5599 if (FALSE == lRunScanFlag)
5602 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: targ dropped out %d of %d/%d\n",
5603 devIdx, devTotal, pPortalInfo->portID );
5604 // if ( 0 == pWWNList[devIdx].devRemoved ) '.devRemoved = 5;
5605 cmpsetRtn = atomic_cmpset_32( &pWWNList[devIdx].devRemoved, 0, 5 );
5606 if ( 0 == cmpsetRtn )
5608 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: target %d timer already set\n",
5613 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5616 // else ... scan coming soon enough anyway, ignore timer for dropout
5619 } // end of for ( devIdx = 0; ...
5621 AG_LIST_UNLOCK( &pCard->devListLock );
5623 free((caddr_t)lDevFlags, M_PMC_MFLG);
5624 free((caddr_t)agDev, M_PMC_MDEV);
5626 if ( TRUE == lRunScanFlag )
5627 agtiapi_clrRmScan( pCard );
5630 } // end agtiapi_GetDevHandle
5632 /******************************************************************************
5638 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5641 ******************************************************************************/
5642 static void agtiapi_scan(struct agtiapi_softc *pmcsc)
5647 AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo);
5649 bus = cam_sim_path(pmcsc->sim);
5651 tid = CAM_TARGET_WILDCARD;
5652 lun = CAM_LUN_WILDCARD;
5654 mtx_lock(&(pmcsc->pCardInfo->pmIOLock));
5655 ccb = xpt_alloc_ccb_nowait();
5658 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5661 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
5662 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
5664 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5669 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5670 pmcsc->dev_scan = agTRUE;
5675 /******************************************************************************
5676 agtiapi_DeQueueCCB()
5679 Remove a ccb from a queue
5681 struct agtiapi_softc *pCard (IN) Pointer to the card structure
5682 pccb_t *phead (IN) Pointer to a head of ccb queue
5683 ccb_t *pccd (IN) Pointer to the ccb to be processed
5685 AGTIAPI_SUCCESS - the ccb is removed from queue
5686 AGTIAPI_FAIL - the ccb is not found from queue
5688 ******************************************************************************/
5690 agtiapi_DeQueueCCB(struct agtiapi_softc *pCard, pccb_t *phead, pccb_t *ptail,
5691 #ifdef AGTIAPI_LOCAL_LOCK
5697 U32 status = AGTIAPI_FAIL;
5699 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5701 if (pccb == NULL || *phead == NULL)
5703 return AGTIAPI_FAIL;
5706 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5707 AG_LOCAL_LOCK(lock);
5711 *phead = (*phead)->pccbNext;
5717 pccb->pccbNext = NULL;
5718 status = AGTIAPI_SUCCESS;
5723 while (pccb_curr->pccbNext != NULL)
5725 if (pccb_curr->pccbNext == pccb)
5727 pccb_curr->pccbNext = pccb->pccbNext;
5728 pccb->pccbNext = NULL;
5734 pccb->pccbNext = NULL;
5735 status = AGTIAPI_SUCCESS;
5738 pccb_curr = pccb_curr->pccbNext;
5741 AG_LOCAL_UNLOCK(lock);
5747 STATIC void wwnprintk( unsigned char *name, int len )
5751 for (i = 0; i < len; i++, name++)
5752 AGTIAPI_PRINTK("%02x", *name);
5753 AGTIAPI_PRINTK("\n");
5756 * SAS and SATA behind expander has 8 byte long unique address.
5757 * However, direct connect SATA device use 512 byte unique device id.
5758 * SPC uses remoteName to indicate length of ID and remoteAddress for the
5759 * address of memory that holding ID.
5761 STATIC int wwncpy( ag_device_t *pDevice )
5765 if (sizeof(pDevice->targetName) >= pDevice->devInfo.osAddress1 +
5766 pDevice->devInfo.osAddress2)
5768 memcpy(pDevice->targetName,
5769 pDevice->devInfo.remoteName,
5770 pDevice->devInfo.osAddress1);
5771 memcpy(pDevice->targetName + pDevice->devInfo.osAddress1,
5772 pDevice->devInfo.remoteAddress,
5773 pDevice->devInfo.osAddress2);
5774 pDevice->targetLen = pDevice->devInfo.osAddress1 +
5775 pDevice->devInfo.osAddress2;
5776 rc = pDevice->targetLen;
5780 AGTIAPI_PRINTK("WWN wrong size: %d + %d ERROR\n",
5781 pDevice->devInfo.osAddress1, pDevice->devInfo.osAddress2);
5788 /******************************************************************************
5789 agtiapi_ReleaseCCBs()
5792 Free all allocated CCB memories for the Host Adapter.
5794 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5797 ******************************************************************************/
5798 STATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard )
5805 AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" );
5807 #if ( defined AGTIAPI_TEST_DPL || defined AGTIAPI_TEST_EPL )
5811 #ifdef AGTIAPI_TEST_DPL
5812 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5813 pccb = pccb->pccbChainNext)
5815 if(pccb->dplPtr && pccb->dplDma)
5816 pci_pool_free(pCard->dpl_ctx_pool, pccb->dplPtr, pccb->dplDma);
5820 #ifdef AGTIAPI_TEST_EPL
5821 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5822 pccb = pccb->pccbChainNext)
5824 if(pccb->epl_ptr && pccb->epl_dma_ptr)
5826 pCard->epl_ctx_pool,
5833 while ((hdr = pCard->ccbAllocList) != NULL)
5835 pCard->ccbAllocList = hdr->next;
5836 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5837 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5838 if (pCard->buffer_dmat != NULL && pccb->CCB_dmamap != NULL)
5840 bus_dmamap_destroy(pCard->buffer_dmat, pccb->CCB_dmamap);
5842 free(hdr, M_PMC_MCCB);
5844 pCard->ccbAllocList = NULL;
5850 /******************************************************************************
5854 Timer tick for tisa common layer
5856 void *data (IN) Pointer to the HBA data structure
5859 ******************************************************************************/
5860 STATIC void agtiapi_TITimer( void *data )
5864 struct agtiapi_softc *pCard;
5866 pCard = (struct agtiapi_softc *)data;
5868 // AGTIAPI_PRINTK("agtiapi_TITimer: start\n");
5869 AG_GLOBAL_ARG( flags );
5871 next_tick = pCard->pCardInfo->tiRscInfo.tiLoLevelResource.
5872 loLevelOption.usecsPerTick / USEC_PER_TICK;
5874 if( next_tick == 0 ) /* no timer required */
5876 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
5877 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5879 tiCOMTimerTick( &pCard->tiRoot ); /* tisa common layer timer tick */
5881 //add for polling mode
5883 if( agtiapi_polling_mode )
5884 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
5886 callout_reset( &pCard->OS_timer, next_tick, agtiapi_TITimer, pCard );
5888 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
5892 /******************************************************************************
5896 Clears device list entries scheduled for timeout and calls scan
5898 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5899 ******************************************************************************/
5900 STATIC void agtiapi_clrRmScan( struct agtiapi_softc *pCard )
5902 ag_tgt_map_t *pWWNList;
5903 ag_portal_info_t *pPortalInfo;
5904 ag_portal_data_t *pPortalData;
5909 pWWNList = pCard->pWWNList;
5911 AGTIAPI_PRINTK( "agtiapi_clrRmScan: start\n" );
5913 AG_LIST_LOCK( &pCard->devListLock );
5915 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5917 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5920 break; // trim to who cares
5923 lReadRm = atomic_readandclear_32( &pWWNList[lIdx].devRemoved );
5926 pCard->pDevList[lIdx].flags &= ~ACTIVE;
5927 pCard->pDevList[lIdx].pDevHandle = NULL;
5929 pPortalData = &pCard->pPortalData[pWWNList[lIdx].portId];
5930 pPortalInfo = &pPortalData->portalInfo;
5931 pPortalInfo->pDevList[lIdx] = NULL;
5932 AGTIAPI_PRINTK( "agtiapi_clrRmScan: cleared dev %d at port %d\n",
5933 lIdx, pWWNList[lIdx].portId );
5934 atomic_subtract_16( &pCard->rmChkCt, 1 );
5937 AG_LIST_UNLOCK( &pCard->devListLock );
5939 agtiapi_scan( pCard );
5943 /******************************************************************************
5944 agtiapi_devRmCheck()
5947 Timer tick to check for timeout on missing targets
5948 Removes device list entry when timeout is reached
5950 void *data (IN) Pointer to the HBA data structure
5951 ******************************************************************************/
5952 STATIC void agtiapi_devRmCheck( void *data )
5954 struct agtiapi_softc *pCard;
5955 ag_tgt_map_t *pWWNList;
5956 int lIdx, cmpsetRtn, lRunScanFlag = FALSE;
5960 pCard = ( struct agtiapi_softc * )data;
5963 if ( callout_pending( &pCard->devRmTimer ) ) // callout was reset
5967 if ( !callout_active( &pCard->devRmTimer ) ) // callout was stopped
5971 callout_deactivate( &pCard->devRmTimer );
5973 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5975 return; // implicit timer clear
5978 pWWNList = pCard->pWWNList;
5980 AG_LIST_LOCK( &pCard->devListLock );
5981 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5984 if ( callout_pending(&pCard->devRmTimer) == FALSE )
5986 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5990 AG_LIST_UNLOCK( &pCard->devListLock );
5994 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5996 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5999 break; // if handled somewhere else, get out
6002 lReadRm = atomic_load_acq_32( &pWWNList[lIdx].devRemoved );
6005 if ( 1 == lReadRm ) // timed out
6006 { // no decrement of devRemoved as way to leave a clrRmScan marker
6007 lRunScanFlag = TRUE; // other devRemoved values are about to get wiped
6008 break; // ... so bail out
6012 AGTIAPI_PRINTK( "agtiapi_devRmCheck: counting down dev %d @ %d; %d\n",
6013 lIdx, lReadRm, lReadCt );
6014 cmpsetRtn = atomic_cmpset_32( &pWWNList[lIdx].devRemoved,
6017 if ( 0 == cmpsetRtn )
6019 printf( "agtiapi_devRmCheck: %d decrement already handled\n",
6025 AG_LIST_UNLOCK( &pCard->devListLock );
6027 if ( TRUE == lRunScanFlag )
6028 agtiapi_clrRmScan( pCard );
6032 AG_LIST_UNLOCK( &pCard->devListLock );
6039 static void agtiapi_cam_poll( struct cam_sim *asim )
6044 /*****************************************************************************
6048 Hard or soft reset on the controller and resend any
6049 outstanding requests if needed.
6051 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
6052 unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
6054 AGTIAPI_SUCCESS - reset successful
6055 AGTIAPI_FAIL - reset failed
6057 *****************************************************************************/
6058 U32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags )
6060 ag_device_t *pDevice;
6064 ag_portal_info_t *pPortalInfo;
6065 ag_portal_data_t *pPortalData;
6069 if( pCard->flags & AGTIAPI_RESET ) {
6070 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" );
6071 return AGTIAPI_FAIL;
6074 AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n",
6075 pCard->resetCount );
6077 agtiapi_LogEvent( pCard,
6078 IOCTL_EVT_SEV_INFORMATIONAL,
6082 "Reset initiator time = %d!",
6083 pCard->resetCount + 1 );
6086 pCard->flags |= AGTIAPI_RESET;
6087 pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS);
6088 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6089 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6091 agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK );
6093 for ( lIdx = 1; 3 >= lIdx; lIdx++ ) // we try reset up to 3 times
6095 if( pCard->flags & AGTIAPI_SOFT_RESET )
6097 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" );
6098 tiCOMReset( &pCard->tiRoot, tiSoftReset );
6102 AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" );
6105 lFlagVal = AGTIAPI_RESET_SUCCESS;
6106 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6107 ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags );
6108 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags );
6110 if( ret == AGTIAPI_FAIL )
6112 AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, "
6122 if ( AGTIAPI_FAIL == ret )
6124 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n",
6129 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n",
6133 if( AGTIAPI_FAIL == ret )
6135 printf( "agtiapi_ResetCard: reset ERROR\n" );
6136 pCard->flags &= ~AGTIAPI_INSTALLED;
6137 return AGTIAPI_FAIL;
6140 pCard->flags &= ~AGTIAPI_SOFT_RESET;
6142 // disable all devices
6143 pDevice = pCard->pDevList;
6144 for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ )
6146 /* if ( pDevice->flags & ACTIVE )
6148 printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx );
6150 pDevice->flags &= ~ACTIVE;
6153 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6154 if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess )
6155 printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" );
6157 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" );
6159 if( !pCard->pDevList ) { // try to get a little sanity here
6160 AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n",
6162 return AGTIAPI_FAIL;
6165 AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n",
6166 pCard->tgtCount, pCard->portCount );
6167 pCard->tgtCount = 0;
6171 pCard->flags &= ~AGTIAPI_CB_DONE;
6173 pPortalData = pCard->pPortalData;
6175 for( count = 0; count < pCard->portCount; count++ ) {
6176 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6177 pPortalInfo = &pPortalData->portalInfo;
6178 pPortalInfo->portStatus = 0;
6179 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
6180 AGTIAPI_PORT_DISC_READY |
6182 AGTIAPI_DISC_COMPLETE );
6185 sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
6186 if (szdv > pCard->devDiscover)
6188 szdv = pCard->devDiscover;
6191 for( lIdx = 0, loop = 0;
6192 lIdx < szdv && loop < pPortalInfo->devTotal;
6195 pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx];
6199 pDevice->pDevHandle = 0; // mark for availability in pCard->pDevList[]
6200 // don't erase more as the device is scheduled for removal on DPC
6202 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n",
6203 pDevice, pPortalInfo->pDevList, lIdx );
6204 pPortalInfo->devTotal = pPortalInfo->devPrev = 0;
6207 for( lIdx = 0; lIdx < maxTargets; lIdx++ )
6208 { // we reconstruct dev list later in get dev handle
6209 pPortalInfo->pDevList[lIdx] = NULL;
6212 for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ )
6214 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data "
6217 pPortalInfo->portID,
6218 &pPortalInfo->tiPortalContext );
6220 if( tiCOMPortStart( &pCard->tiRoot,
6221 pPortalInfo->portID,
6222 &pPortalInfo->tiPortalContext,
6226 printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n",
6227 pPortalInfo->portID );
6231 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n",
6232 pPortalInfo->portID );
6236 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6237 tiCOMGetPortInfo( &pCard->tiRoot,
6238 &pPortalInfo->tiPortalContext,
6239 &pPortalInfo->tiPortInfo );
6242 // ## fail case: pCard->flags &= ~AGTIAPI_INSTALLED;
6245 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags);
6247 if( !(pCard->flags & AGTIAPI_INSTALLED) ) // driver not installed !
6249 printf( "agtiapi_ResetCard: error, driver not intstalled? "
6250 "!AGTIAPI_INSTALLED \n" );
6251 return AGTIAPI_FAIL;
6254 AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount );
6257 agtiapi_LogEvent( pCard,
6258 IOCTL_EVT_SEV_INFORMATIONAL,
6262 "Reset initiator total device = %d!",
6265 pCard->resetCount++;
6267 AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" );
6268 // clear send & done queue
6269 AG_LOCAL_LOCK( &pCard->sendLock );
6270 pCard->ccbSendHead = NULL;
6271 pCard->ccbSendTail = NULL;
6272 AG_LOCAL_UNLOCK( &pCard->sendLock );
6274 AG_LOCAL_LOCK( &pCard->doneLock );
6275 pCard->ccbDoneHead = NULL;
6276 pCard->ccbDoneTail = NULL;
6277 AG_LOCAL_UNLOCK( &pCard->doneLock );
6279 // clear smp queues also
6280 AG_LOCAL_LOCK( &pCard->sendSMPLock );
6281 pCard->smpSendHead = NULL;
6282 pCard->smpSendTail = NULL;
6283 AG_LOCAL_UNLOCK( &pCard->sendSMPLock );
6285 AG_LOCAL_LOCK( &pCard->doneSMPLock );
6286 pCard->smpDoneHead = NULL;
6287 pCard->smpDoneTail = NULL;
6288 AG_LOCAL_UNLOCK( &pCard->doneSMPLock );
6290 // finished with all reset stuff, now start things back up
6291 tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE );
6292 pCard->flags |= AGTIAPI_SYS_INTR_ON;
6293 pCard->flags |= AGTIAPI_HAD_RESET;
6294 pCard->flags &= ~AGTIAPI_RESET; // ##
6295 agtiapi_StartIO( pCard );
6296 AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" );
6297 return AGTIAPI_SUCCESS;
6298 } // agtiapi_ResetCard
6301 /******************************************************************************
6302 agtiapi_ReleaseHBA()
6305 Releases all resources previously acquired to support
6306 a specific Host Adapter, including the I/O Address range,
6307 and unregisters the agtiapi Host Adapter.
6309 device_t dev (IN) - device pointer
6311 always return 0 - success
6313 ******************************************************************************/
6314 int agtiapi_ReleaseHBA( device_t dev )
6317 int thisCard = device_get_unit( dev ); // keeping get_unit call to once
6319 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
6320 struct ccb_setasync csa;
6321 struct agtiapi_softc *pCard;
6322 pCard = device_get_softc( dev );
6323 ag_card_info_t *pCardInfo = pCard->pCardInfo;
6324 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
6326 AG_GLOBAL_ARG(flags);
6328 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: start\n" );
6330 if (thisCardInst != pCardInfo)
6332 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p "
6336 panic( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p pCardInfo "
6344 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA card %p\n", pCard );
6345 pCard->flags |= AGTIAPI_SHUT_DOWN;
6349 if (pCard->flags & AGTIAPI_TIMER_ON)
6351 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6352 callout_drain( &pCard->OS_timer );
6353 callout_drain( &pCard->devRmTimer );
6354 callout_drain(&pCard->IO_timer);
6355 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6356 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: timer released\n" );
6359 #ifdef HIALEAH_ENCRYPTION
6360 //Release encryption table memory - Fix it
6361 //if(pCard->encrypt && (pCard->flags & AGTIAPI_INSTALLED))
6362 //agtiapi_CleanupEncryption(pCard);
6366 * Shutdown the channel so that chip gets frozen
6367 * and it does not do any more pci-bus accesses.
6369 if (pCard->flags & AGTIAPI_SYS_INTR_ON)
6371 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6372 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6373 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: card interrupt off\n" );
6375 if (pCard->flags & AGTIAPI_INSTALLED)
6377 tiCOMShutDown( &pCard->tiRoot );
6378 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: low layers shutdown\n" );
6382 * first release IRQ, so that we do not get any more interrupts
6385 if (pCard->flags & AGTIAPI_IRQ_REQUESTED)
6387 if (!agtiapi_intx_mode)
6390 for (i = 0; i< MAX_MSIX_NUM_VECTOR; i++)
6392 if (pCard->irq[i] != agNULL && pCard->rscID[i] != 0)
6394 bus_teardown_intr(dev, pCard->irq[i], pCard->intrcookie[i]);
6395 bus_release_resource( dev,
6401 pci_release_msi(dev);
6403 pCard->flags &= ~AGTIAPI_IRQ_REQUESTED;
6408 for (i = 0; i < MAX_MSIX_NUM_DPC; i++)
6409 tasklet_kill(&pCard->tasklet_dpc[i]);
6411 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: IRQ released\n");
6414 // release memory vs. alloc in agtiapi_alloc_ostimem; used in ostiAllocMemory
6415 if( pCard->osti_busaddr != 0 ) {
6416 bus_dmamap_unload( pCard->osti_dmat, pCard->osti_mapp );
6418 if( pCard->osti_mem != NULL ) {
6419 bus_dmamem_free( pCard->osti_dmat, pCard->osti_mem, pCard->osti_mapp );
6421 if( pCard->osti_dmat != NULL ) {
6422 bus_dma_tag_destroy( pCard->osti_dmat );
6425 /* unmap the mapped PCI memory */
6426 /* calls bus_release_resource( ,SYS_RES_MEMORY, ..) */
6427 agtiapi_ReleasePCIMem(thisCardInst);
6429 /* release all ccbs */
6430 if (pCard->ccbTotal)
6432 //calls bus_dmamap_destroy() for all pccbs
6433 agtiapi_ReleaseCCBs(pCard);
6434 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: CCB released\n");
6437 #ifdef HIALEAH_ENCRYPTION
6438 /*release encryption resources - Fix it*/
6441 /*Check that all IO's are completed */
6442 if(atomic_read (&outstanding_encrypted_io_count) > 0)
6444 printf("%s: WARNING: %d outstanding encrypted IOs !\n", __FUNCTION__, atomic_read(&outstanding_encrypted_io_count));
6446 //agtiapi_CleanupEncryptionPools(pCard);
6451 /* release device list */
6452 if( pCard->pDevList ) {
6453 free((caddr_t)pCard->pDevList, M_PMC_MDVT);
6454 pCard->pDevList = NULL;
6455 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: device list released\n");
6457 #ifdef LINUX_PERBI_SUPPORT // ## review use of PERBI
6458 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: WWN list %p \n", pCard->pWWNList );
6459 if( pCard->pWWNList ) {
6460 free( (caddr_t)pCard->pWWNList, M_PMC_MTGT );
6461 pCard->pWWNList = NULL;
6462 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: WWN list released\n");
6464 if( pCard->pSLRList ) {
6465 free( (caddr_t)pCard->pSLRList, M_PMC_MSLR );
6466 pCard->pSLRList = NULL;
6467 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: SAS Local Remote list released\n");
6471 if (pCard->pPortalData)
6473 free((caddr_t)pCard->pPortalData, M_PMC_MPRT);
6474 pCard->pPortalData = NULL;
6475 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: PortalData released\n");
6477 //calls contigfree() or free()
6478 agtiapi_MemFree(pCardInfo);
6479 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: low level resource released\n");
6481 #ifdef HOTPLUG_SUPPORT
6482 if (pCard->flags & AGTIAPI_PORT_INITIALIZED)
6484 // agtiapi_FreeDevWorkList(pCard);
6485 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: (HP dev) work resources released\n");
6490 * TBD, scsi_unregister may release wrong host data structure
6491 * which cause NULL pointer shows up.
6493 if (pCard->flags & AGTIAPI_SCSI_REGISTERED)
6495 pCard->flags &= ~AGTIAPI_SCSI_REGISTERED;
6498 #ifdef AGTIAPI_LOCAL_LOCK
6503 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
6505 for( i = 0; i < maxLocks; i++ )
6507 mtx_destroy(&pCard->STLock[i]);
6509 free(pCard->STLock, M_PMC_MSTL);
6510 pCard->STLock = NULL;
6517 /* reset agtiapi_1st_time if this is the only card */
6518 if (!ag_card_good && !agtiapi_1st_time)
6520 agtiapi_1st_time = 1;
6523 /* for tiSgl_t memeory */
6524 if (pCard->tisgl_busaddr != 0)
6526 bus_dmamap_unload(pCard->tisgl_dmat, pCard->tisgl_map);
6528 if (pCard->tisgl_mem != NULL)
6530 bus_dmamem_free(pCard->tisgl_dmat, pCard->tisgl_mem, pCard->tisgl_map);
6532 if (pCard->tisgl_dmat != NULL)
6534 bus_dma_tag_destroy(pCard->tisgl_dmat);
6537 if (pCard->buffer_dmat != agNULL)
6539 bus_dma_tag_destroy(pCard->buffer_dmat);
6542 if (pCard->sim != NULL)
6544 mtx_lock(&thisCardInst->pmIOLock);
6545 xpt_setup_ccb(&csa.ccb_h, pCard->path, 5);
6546 csa.ccb_h.func_code = XPT_SASYNC_CB;
6547 csa.event_enable = 0;
6548 csa.callback = agtiapi_async;
6549 csa.callback_arg = pCard;
6550 xpt_action((union ccb *)&csa);
6551 xpt_free_path(pCard->path);
6552 // if (pCard->ccbTotal == 0)
6553 if (pCard->ccbTotal <= thisCard)
6556 no link up so that simq has not been released.
6557 In order to remove cam, we call this.
6559 xpt_release_simq(pCard->sim, 1);
6561 xpt_bus_deregister(cam_sim_path(pCard->sim));
6562 cam_sim_free(pCard->sim, FALSE);
6563 mtx_unlock(&thisCardInst->pmIOLock);
6565 if (pCard->devq != NULL)
6567 cam_simq_free(pCard->devq);
6571 mtx_destroy( &thisCardInst->pmIOLock );
6572 mtx_destroy( &pCard->sendLock );
6573 mtx_destroy( &pCard->doneLock );
6574 mtx_destroy( &pCard->sendSMPLock );
6575 mtx_destroy( &pCard->doneSMPLock );
6576 mtx_destroy( &pCard->ccbLock );
6577 mtx_destroy( &pCard->devListLock );
6578 mtx_destroy( &pCard->OS_timer_lock );
6579 mtx_destroy( &pCard->devRmTimerLock );
6580 mtx_destroy( &pCard->memLock );
6581 mtx_destroy( &pCard->freezeLock );
6583 destroy_dev( pCard->my_cdev );
6584 memset((void *)pCardInfo, 0, sizeof(ag_card_info_t));
6589 // Called during system shutdown after sync
6590 static int agtiapi_shutdown( device_t dev )
6592 AGTIAPI_PRINTK( "agtiapi_shutdown\n" );
6596 static int agtiapi_suspend( device_t dev ) // Device suspend routine.
6598 AGTIAPI_PRINTK( "agtiapi_suspend\n" );
6602 static int agtiapi_resume( device_t dev ) // Device resume routine.
6604 AGTIAPI_PRINTK( "agtiapi_resume\n" );
6608 static device_method_t agtiapi_methods[] = { // Device interface
6609 DEVMETHOD( device_probe, agtiapi_probe ),
6610 DEVMETHOD( device_attach, agtiapi_attach ),
6611 DEVMETHOD( device_detach, agtiapi_ReleaseHBA ),
6612 DEVMETHOD( device_shutdown, agtiapi_shutdown ),
6613 DEVMETHOD( device_suspend, agtiapi_suspend ),
6614 DEVMETHOD( device_resume, agtiapi_resume ),
6618 static devclass_t pmspcv_devclass;
6620 static driver_t pmspcv_driver = {
6623 sizeof( struct agtiapi_softc )
6626 DRIVER_MODULE( pmspcv, pci, pmspcv_driver, pmspcv_devclass, 0, 0 );
6627 MODULE_DEPEND( pmspcv, cam, 1, 1, 1 );
6628 MODULE_DEPEND( pmspcv, pci, 1, 1, 1 );
6630 #include <dev/pms/freebsd/driver/common/lxosapi.c>
6631 #include <dev/pms/freebsd/driver/ini/src/osapi.c>
6632 #include <dev/pms/freebsd/driver/common/lxutil.c>
6633 #include <dev/pms/freebsd/driver/common/lxencrypt.c>