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%lx 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 /* Max supported I/O size, in bytes. */
1837 cpi->maxio = ulmin(1024 * 1024, maxphys);
1838 cpi->initiator_id = 255;
1839 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1840 strlcpy(cpi->hba_vid, "PMC", HBA_IDLEN);
1841 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1842 cpi->unit_number = cam_sim_unit(sim);
1843 cpi->bus_id = cam_sim_bus(sim);
1844 // rate is set when XPT_GET_TRAN_SETTINGS is processed
1845 cpi->base_transfer_speed = 150000;
1846 cpi->transport = XPORT_SAS;
1847 cpi->transport_version = 0;
1848 cpi->protocol = PROTO_SCSI;
1849 cpi->protocol_version = SCSI_REV_SPC3;
1850 cpi->ccb_h.status = CAM_REQ_CMP;
1853 case XPT_GET_TRAN_SETTINGS:
1855 struct ccb_trans_settings *cts;
1856 struct ccb_trans_settings_sas *sas;
1857 struct ccb_trans_settings_scsi *scsi;
1859 if ( pmcsc->flags & AGTIAPI_SHUT_DOWN )
1865 sas = &ccb->cts.xport_specific.sas;
1866 scsi = &cts->proto_specific.scsi;
1868 cts->protocol = PROTO_SCSI;
1869 cts->protocol_version = SCSI_REV_SPC3;
1870 cts->transport = XPORT_SAS;
1871 cts->transport_version = 0;
1873 sas->valid = CTS_SAS_VALID_SPEED;
1875 /* this sets the "MB/s transfers" */
1876 if (pmcsc != NULL && targetID >= 0 && targetID < maxTargets)
1878 if (pmcsc->pWWNList != NULL)
1880 TID = INDEX(pmcsc, targetID);
1881 if (TID < maxTargets)
1883 pDevHandle = pmcsc->pDevList[TID].pDevHandle;
1889 tiINIGetDeviceInfo( &pmcsc->tiRoot, pDevHandle, &devInfo );
1890 switch (devInfo.info.devType_S_Rate & 0xF)
1892 case 0x8: speed = 150000;
1894 case 0x9: speed = 300000;
1896 case 0xA: speed = 600000;
1898 case 0xB: speed = 1200000;
1900 default: speed = 150000;
1904 sas->bitrate = speed;
1905 scsi->valid = CTS_SCSI_VALID_TQ;
1906 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
1907 ccb->ccb_h.status = CAM_REQ_CMP;
1912 lRetVal = agtiapi_eh_HostReset( pmcsc, ccb ); // usually works first time
1913 if ( SUCCESS == lRetVal )
1915 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset success.\n" );
1919 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset failed.\n" );
1921 ccb->ccb_h.status = CAM_REQ_CMP;
1926 ccb->ccb_h.status = CAM_REQ_CMP;
1931 ccb->ccb_h.status = CAM_REQ_CMP;
1934 #if __FreeBSD_version >= 900026
1937 agtiapi_QueueSMP( pmcsc, ccb );
1940 #endif /* __FreeBSD_version >= 900026 */
1943 if(pmcsc->dev_scan == agFALSE)
1945 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1948 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
1950 AGTIAPI_PRINTK( "agtiapi_cam_action: shutdown, XPT_SCSI_IO 0x%x\n",
1952 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1957 AGTIAPI_IO( "agtiapi_cam_action: Zero XPT_SCSI_IO 0x%x, doing IOs\n",
1959 agtiapi_QueueCmnd_( pmcsc, ccb );
1964 case XPT_CALC_GEOMETRY:
1966 cam_calc_geometry(&ccb->ccg, 1);
1967 ccb->ccb_h.status = CAM_REQ_CMP;
1973 XPT_SET_TRAN_SETTINGS
1975 AGTIAPI_IO( "agtiapi_cam_action: default function code 0x%x\n",
1976 ccb->ccb_h.func_code );
1977 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1985 /******************************************************************************
1989 Get a ccb from free list or allocate a new one
1991 struct agtiapi_softc *pmcsc (IN) Pointer to HBA structure
1993 Pointer to a ccb structure, or NULL if not available
1995 ******************************************************************************/
1996 STATIC pccb_t agtiapi_GetCCB( struct agtiapi_softc *pmcsc )
2000 AGTIAPI_IO( "agtiapi_GetCCB: start\n" );
2002 AG_LOCAL_LOCK( &pmcsc->ccbLock );
2004 /* get the ccb from the head of the free list */
2005 if ((pccb = (pccb_t)pmcsc->ccbFreeList) != NULL)
2007 pmcsc->ccbFreeList = (caddr_t *)pccb->pccbNext;
2008 pccb->pccbNext = NULL;
2009 pccb->flags = ACTIVE;
2010 pccb->startTime = 0;
2012 AGTIAPI_IO( "agtiapi_GetCCB: re-allocated ccb %p\n", pccb );
2016 AGTIAPI_PRINTK( "agtiapi_GetCCB: kmalloc ERROR - no ccb allocated\n" );
2019 AG_LOCAL_UNLOCK( &pmcsc->ccbLock );
2023 /******************************************************************************
2024 agtiapi_QueueCmnd_()
2027 Calls for sending CCB and excuting on HBA.
2029 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2030 union ccb * ccb (IN) Pointer to CAM ccb data structure
2032 0 - Command is pending to execute
2033 1 - Command returned without further process
2035 ******************************************************************************/
2036 int agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb)
2038 struct ccb_scsiio *csio = &ccb->csio;
2039 pccb_t pccb = agNULL; // call dequeue
2040 int status = tiSuccess;
2041 U32 Channel = CMND_TO_CHANNEL(ccb);
2042 U32 TID = CMND_TO_TARGET(ccb);
2043 U32 LUN = CMND_TO_LUN(ccb);
2045 AGTIAPI_IO( "agtiapi_QueueCmnd_: start\n" );
2047 /* no support for CBD > 16 */
2048 if (csio->cdb_len > 16)
2050 AGTIAPI_PRINTK( "agtiapi_QueueCmnd_: unsupported CDB length %d\n",
2052 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2053 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2054 ccb->ccb_h.status |= CAM_REQ_INVALID;//CAM_REQ_CMP;
2058 if (TID < 0 || TID >= maxTargets)
2060 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: INVALID TID ERROR\n");
2061 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2062 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2063 ccb->ccb_h.status |= CAM_DEV_NOT_THERE;//CAM_REQ_CMP;
2068 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
2070 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n");
2074 TID = INDEX(pmcsc, TID);
2075 targ = &pmcsc->pDevList[TID];
2076 agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth);
2078 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2079 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2080 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2084 pccb->pmcsc = pmcsc;
2085 /* initialize Command Control Block (CCB) */
2086 pccb->targetId = TID;
2088 pccb->channel = Channel;
2089 pccb->ccb = ccb; /* for struct scsi_cmnd */
2090 pccb->senseLen = csio->sense_len;
2091 pccb->startTime = ticks;
2092 pccb->pSenseData = (caddr_t) &csio->sense_data;
2093 pccb->tiSuperScsiRequest.flags = 0;
2095 /* each channel is reserved for different addr modes */
2096 pccb->addrMode = agtiapi_AddrModes[Channel];
2098 status = agtiapi_PrepareSGList(pmcsc, pccb);
2099 if (status != tiSuccess)
2101 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: agtiapi_PrepareSGList failure\n");
2102 agtiapi_FreeCCB(pmcsc, pccb);
2103 if (status == tiReject)
2105 ccb->ccb_h.status = CAM_REQ_INVALID;
2109 ccb->ccb_h.status = CAM_REQ_CMP;
2117 /******************************************************************************
2123 const char *ptitle (IN) A string to be printed
2124 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2127 ******************************************************************************/
2128 STATIC void agtiapi_DumpCDB(const char *ptitle, ccb_t *pccb)
2131 struct ccb_scsiio *csio;
2137 printf( "agtiapi_DumpCDB: no pccb here \n" );
2138 panic("agtiapi_DumpCDB: pccb is NULL. called from %s\n", ptitle);
2144 printf( "agtiapi_DumpCDB: no ccb here \n" );
2145 panic( "agtiapi_DumpCDB: pccb %p ccb %p flags %d ccb NULL! "
2147 pccb, pccb->ccb, pccb->flags, ptitle );
2153 printf( "agtiapi_DumpCDB: no csio here \n" );
2154 panic( "agtiapi_DumpCDB: pccb%p ccb%p flags%d csio NULL! called from %s\n",
2155 pccb, pccb->ccb, pccb->flags, ptitle );
2158 len = MIN(64, csio->cdb_len);
2159 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2161 bcopy(csio->cdb_io.cdb_ptr, &cdb[0], len);
2165 bcopy(csio->cdb_io.cdb_bytes, &cdb[0], len);
2168 AGTIAPI_IO( "agtiapi_DumpCDB: pccb%p CDB0x%x csio->cdb_len %d"
2169 " len %d from %s\n",
2177 /******************************************************************************
2178 agtiapi_DoSoftReset()
2183 *data (IN) point to pmcsc (struct agtiapi_softc *)
2186 ******************************************************************************/
2187 int agtiapi_DoSoftReset (struct agtiapi_softc *pmcsc)
2190 unsigned long flags;
2192 pmcsc->flags |= AGTIAPI_SOFT_RESET;
2193 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
2194 ret = agtiapi_ResetCard( pmcsc, &flags );
2195 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
2197 if( ret != AGTIAPI_SUCCESS )
2203 /******************************************************************************
2204 agtiapi_CheckIOTimeout()
2207 Timeout function for SCSI IO or TM
2209 *data (IN) point to pCard (ag_card_t *)
2212 ******************************************************************************/
2213 STATIC void agtiapi_CheckIOTimeout(void *data)
2215 U32 status = AGTIAPI_SUCCESS;
2217 struct agtiapi_softc *pmcsc;
2220 pmcsc = (struct agtiapi_softc *)data;
2222 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Enter\n");
2224 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Active CCB %d\n", pmcsc->activeCCB);
2226 pccb = (pccb_t)pmcsc->ccbChainList;
2228 /* if link is down, do nothing */
2229 if ((pccb == NULL) || (pmcsc->activeCCB == 0))
2231 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: goto restart_timer\n");
2235 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
2236 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
2241 /* Walk thorugh the IO Chain linked list to find the pending io */
2242 /* Set the TM flag based on the pccb type, i.e SCSI IO or TM cmd */
2243 while (pccb_curr != NULL)
2245 /* start from 1st ccb in the chain */
2246 pccb_next = pccb_curr->pccbChainNext;
2247 if( (pccb_curr->flags == 0) || (pccb_curr->tiIORequest.tdData == NULL) ||
2248 (pccb_curr->startTime == 0) /* && (pccb->startTime == 0) */)
2250 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: move to next element\n");
2252 else if ( ( (ticks-pccb_curr->startTime) >= ag_timeout_secs ) &&
2253 !(pccb_curr->flags & TIMEDOUT) )
2255 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: pccb %p timed out, call TM "
2256 "function -- flags=%x startTime=%ld tdData = %p\n",
2257 pccb_curr, pccb_curr->flags, pccb->startTime,
2258 pccb_curr->tiIORequest.tdData );
2259 pccb_curr->flags |= TIMEDOUT;
2260 status = agtiapi_StartTM(pmcsc, pccb_curr);
2261 if (status == AGTIAPI_SUCCESS)
2263 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: TM Request sent with "
2269 #ifdef AGTIAPI_LOCAL_RESET
2270 /* abort request did not go through */
2271 AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Abort request failed\n");
2272 /* TODO: call Soft reset here */
2273 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout:in agtiapi_CheckIOTimeout() "
2274 "abort request did not go thru ==> soft reset#7, then "
2275 "restart timer\n" );
2276 agtiapi_DoSoftReset (pmcsc);
2281 pccb_curr = pccb_next;
2284 callout_reset(&pmcsc->IO_timer, 1*hz, agtiapi_CheckIOTimeout, pmcsc);
2287 AG_SPIN_UNLOCK_IRQ(agtiapi_host_lock, flags);
2291 /******************************************************************************
2295 DDI calls for aborting outstanding IO command
2297 struct scsi_cmnd *pccb (IN) Pointer to the command to be aborted
2298 unsigned long flags (IN/out) spinlock flags used in locking from
2301 AGTIAPI_SUCCESS - success
2303 ******************************************************************************/
2305 agtiapi_StartTM(struct agtiapi_softc *pCard, ccb_t *pccb)
2307 ccb_t *pTMccb = NULL;
2308 U32 status = AGTIAPI_SUCCESS;
2309 ag_device_t *pDevice = NULL;
2310 U32 TMstatus = tiSuccess;
2311 AGTIAPI_PRINTK( "agtiapi_StartTM: pccb %p, pccb->flags %x\n",
2312 pccb, pccb->flags );
2315 AGTIAPI_PRINTK("agtiapi_StartTM: %p not found\n",pccb);
2316 status = AGTIAPI_SUCCESS;
2319 if (!pccb->tiIORequest.tdData)
2321 /* should not be the case */
2322 AGTIAPI_PRINTK("agtiapi_StartTM: ccb %p flag 0x%x tid %d no tdData "
2323 "ERROR\n", pccb, pccb->flags, pccb->targetId);
2324 status = AGTIAPI_FAIL;
2328 /* If timedout CCB is TM_ABORT_TASK command, issue LocalAbort first to
2329 clear pending TM_ABORT_TASK */
2330 /* Else Device State will not be put back to Operational, (refer FW) */
2331 if (pccb->flags & TASK_MANAGEMENT)
2333 if (tiINIIOAbort(&pCard->tiRoot, &pccb->tiIORequest) != tiSuccess)
2335 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort Request for Abort_TASK "
2337 /* TODO: call Soft reset here */
2338 AGTIAPI_PRINTK( "agtiapi_StartTM: in agtiapi_StartTM() abort "
2339 "tiINIIOAbort() failed ==> soft reset#8\n" );
2340 agtiapi_DoSoftReset( pCard );
2344 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort for Abort_TASK TM "
2346 status = AGTIAPI_SUCCESS;
2352 if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
2354 AGTIAPI_PRINTK("agtiapi_StartTM: TM resource unavailable!\n");
2355 status = AGTIAPI_FAIL;
2358 pTMccb->pmcsc = pCard;
2359 pTMccb->targetId = pccb->targetId;
2360 pTMccb->devHandle = pccb->devHandle;
2361 if (pTMccb->targetId >= pCard->devDiscover)
2363 AGTIAPI_PRINTK("agtiapi_StartTM: Incorrect dev Id in TM!\n");
2364 status = AGTIAPI_FAIL;
2367 if (pTMccb->targetId < 0 || pTMccb->targetId >= maxTargets)
2369 return AGTIAPI_FAIL;
2371 if (INDEX(pCard, pTMccb->targetId) >= maxTargets)
2373 return AGTIAPI_FAIL;
2375 pDevice = &pCard->pDevList[INDEX(pCard, pTMccb->targetId)];
2376 if ((pDevice == NULL) || !(pDevice->flags & ACTIVE))
2378 return AGTIAPI_FAIL;
2381 /* save pending io to issue local abort at Task mgmt CB */
2382 pTMccb->pccbIO = pccb;
2383 AGTIAPI_PRINTK( "agtiapi_StartTM: pTMccb %p flag %x tid %d via TM "
2385 pTMccb, pTMccb->flags, pTMccb->targetId );
2386 pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
2387 pTMccb->flags |= TASK_MANAGEMENT;
2388 TMstatus = tiINITaskManagement(&pCard->tiRoot,
2391 &pccb->tiSuperScsiRequest.scsiCmnd.lun,
2393 &pTMccb->tiIORequest);
2394 if (TMstatus == tiSuccess)
2396 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request success ccb "
2399 pTMccb->startTime = ticks;
2400 status = AGTIAPI_SUCCESS;
2402 else if (TMstatus == tiIONoDevice)
2404 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request tiIONoDevice ccb "
2407 status = AGTIAPI_SUCCESS;
2411 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request failed ccb %p, "
2414 status = AGTIAPI_FAIL;
2415 agtiapi_FreeTMCCB(pCard, pTMccb);
2417 /* call TM_TARGET_RESET */
2422 AGTIAPI_PRINTK("agtiapi_StartTM: return %d flgs %x\n", status,
2423 (pccb) ? pccb->flags : -1);
2425 } /* agtiapi_StartTM */
2427 #if __FreeBSD_version > 901000
2428 /******************************************************************************
2429 agtiapi_PrepareSGList()
2432 This function prepares scatter-gather list for the given ccb
2434 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2435 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2441 ******************************************************************************/
2442 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2444 union ccb *ccb = pccb->ccb;
2445 struct ccb_scsiio *csio = &ccb->csio;
2446 struct ccb_hdr *ccbh = &ccb->ccb_h;
2447 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2449 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2450 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2452 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2454 switch((ccbh->flags & CAM_DATA_MASK))
2457 struct bus_dma_segment seg;
2458 case CAM_DATA_VADDR:
2459 /* Virtual address that needs to translated into one or more physical address ranges. */
2461 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2462 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2463 error = bus_dmamap_load( pmcsc->buffer_dmat,
2467 agtiapi_PrepareSGListCB,
2469 BUS_DMA_NOWAIT/* 0 */ );
2470 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2472 if (error == EINPROGRESS)
2474 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2475 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2476 xpt_freeze_simq(pmcsc->sim, 1);
2477 pmcsc->SimQFrozen = agTRUE;
2478 ccbh->status |= CAM_RELEASE_SIMQ;
2481 case CAM_DATA_PADDR:
2482 /* We have been given a pointer to single physical buffer. */
2483 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2484 //struct bus_dma_segment seg;
2485 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2487 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2488 seg.ds_len = csio->dxfer_len;
2489 // * 0xFF to be defined
2490 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2493 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2499 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2504 /******************************************************************************
2505 agtiapi_PrepareSGList()
2508 This function prepares scatter-gather list for the given ccb
2510 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2511 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2517 ******************************************************************************/
2518 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2520 union ccb *ccb = pccb->ccb;
2521 struct ccb_scsiio *csio = &ccb->csio;
2522 struct ccb_hdr *ccbh = &ccb->ccb_h;
2523 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2524 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2525 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2527 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2529 if ((ccbh->flags & CAM_SCATTER_VALID) == 0)
2531 /* We've been given a pointer to a single buffer. */
2532 if ((ccbh->flags & CAM_DATA_PHYS) == 0)
2534 /* Virtual address that needs to translated into one or more physical address ranges. */
2536 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2537 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2538 error = bus_dmamap_load( pmcsc->buffer_dmat,
2542 agtiapi_PrepareSGListCB,
2544 BUS_DMA_NOWAIT/* 0 */ );
2545 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2547 if (error == EINPROGRESS)
2549 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2550 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2551 xpt_freeze_simq(pmcsc->sim, 1);
2552 pmcsc->SimQFrozen = agTRUE;
2553 ccbh->status |= CAM_RELEASE_SIMQ;
2558 /* We have been given a pointer to single physical buffer. */
2559 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2560 struct bus_dma_segment seg;
2561 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2563 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2564 seg.ds_len = csio->dxfer_len;
2565 // * 0xFF to be defined
2566 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2572 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2578 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2584 /******************************************************************************
2585 agtiapi_PrepareSGListCB()
2588 Callback function for bus_dmamap_load()
2589 This fuctions sends IO to LL layer.
2591 void *arg (IN) Pointer to the HBA data structure
2592 bus_dma_segment_t *segs (IN) Pointer to dma segment
2593 int nsegs (IN) number of dma segment
2594 int error (IN) error
2597 ******************************************************************************/
2598 static void agtiapi_PrepareSGListCB( void *arg,
2599 bus_dma_segment_t *segs,
2604 union ccb *ccb = pccb->ccb;
2605 struct ccb_scsiio *csio = &ccb->csio;
2607 struct agtiapi_softc *pmcsc;
2608 tiIniScsiCmnd_t *pScsiCmnd;
2610 bus_dmasync_op_t op;
2613 int io_is_encryptable = 0;
2614 unsigned long long start_lba = 0;
2616 U32 TID = CMND_TO_TARGET(ccb);
2618 AGTIAPI_IO( "agtiapi_PrepareSGListCB: start, nsegs %d error 0x%x\n",
2620 pmcsc = pccb->pmcsc;
2622 if (error != tiSuccess)
2624 if (error == 0xAABBCCDD || error == 0xAAAAAAAA)
2630 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: error status 0x%x\n", error);
2631 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2632 agtiapi_FreeCCB(pmcsc, pccb);
2634 ccb->ccb_h.status = CAM_REQ_TOO_BIG;
2636 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2642 if (nsegs > AGTIAPI_MAX_DMA_SEGS)
2644 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: over the limit. nsegs %d"
2645 " AGTIAPI_MAX_DMA_SEGS %d\n",
2646 nsegs, AGTIAPI_MAX_DMA_SEGS );
2647 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2648 agtiapi_FreeCCB(pmcsc, pccb);
2649 ccb->ccb_h.status = CAM_REQ_TOO_BIG;
2655 /* fill in IO information */
2656 pccb->dataLen = csio->dxfer_len;
2658 /* start fill in sgl structure */
2659 if (nsegs == 1 && error == 0xAABBCCDD)
2662 /* A single physical buffer */
2663 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: nsegs is 1\n");
2664 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2665 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2666 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2667 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)segs->ds_addr;
2668 pccb->numSgElements = 1;
2670 else if (nsegs == 0 && error == 0xAAAAAAAA)
2672 /* no data transfer */
2673 AGTIAPI_IO( "agtiapi_PrepareSGListCB: no data transfer\n" );
2674 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2676 pccb->numSgElements = 0;
2680 /* virtual/logical buffer */
2683 pccb->dataLen = segs[0].ds_len;
2685 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2686 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2687 pccb->tiSuperScsiRequest.agSgl1.len = htole32(segs[0].ds_len);
2688 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2689 pccb->numSgElements = nsegs;
2696 for (i = 0; i < nsegs; i++)
2698 pccb->sgList[i].len = htole32(segs[i].ds_len);
2699 CPU_TO_LE32(pccb->sgList[i], segs[i].ds_addr);
2700 pccb->sgList[i].type = htole32(tiSgl);
2701 pccb->dataLen += segs[i].ds_len;
2704 pccb->numSgElements = nsegs;
2705 /* set up sgl buffer address */
2706 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, pccb->tisgl_busaddr);
2707 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSglList);
2708 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2709 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2710 pccb->numSgElements = nsegs;
2714 /* set data transfer direction */
2715 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2717 op = BUS_DMASYNC_PREWRITE;
2718 pccb->tiSuperScsiRequest.dataDirection = tiDirectionOut;
2722 op = BUS_DMASYNC_PREREAD;
2723 pccb->tiSuperScsiRequest.dataDirection = tiDirectionIn;
2726 pScsiCmnd = &pccb->tiSuperScsiRequest.scsiCmnd;
2728 pScsiCmnd->expDataLength = pccb->dataLen;
2730 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2732 bcopy(csio->cdb_io.cdb_ptr, &pScsiCmnd->cdb[0], csio->cdb_len);
2736 bcopy(csio->cdb_io.cdb_bytes, &pScsiCmnd->cdb[0],csio->cdb_len);
2739 CDB = &pScsiCmnd->cdb[0];
2743 case REQUEST_SENSE: /* requires different buffer */
2744 /* This code should not be excercised because SAS support auto sense
2745 For the completeness, vtophys() is still used here.
2747 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: QueueCmnd - REQUEST SENSE new\n");
2748 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->senseLen);
2749 phys_addr = vtophys(&csio->sense_data);
2750 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, phys_addr);
2751 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2752 pccb->dataLen = pccb->senseLen;
2753 pccb->numSgElements = 1;
2756 /* only using lun 0 for device type detection */
2757 pccb->flags |= AGTIAPI_INQUIRY;
2759 case TEST_UNIT_READY:
2763 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2769 start_lba = ((CDB[1] & 0x1f) << 16) |
2772 #ifdef HIALEAH_ENCRYPTION
2773 io_is_encryptable = 1;
2781 start_lba = (CDB[2] << 24) |
2785 #ifdef HIALEAH_ENCRYPTION
2786 io_is_encryptable = 1;
2792 start_lba = (CDB[2] << 24) |
2797 start_lba |= ((CDB[6] << 24) |
2801 #ifdef HIALEAH_ENCRYPTION
2802 io_is_encryptable = 1;
2809 /* fill device lun based one address mode */
2810 agtiapi_SetLunField(pccb);
2812 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
2814 pccb->ccbStatus = tiIOFailed;
2815 pccb->scsiStatus = tiDetailNoLogin;
2816 agtiapi_FreeCCB(pmcsc, pccb);
2817 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2822 if (INDEX(pmcsc, pccb->targetId) >= maxTargets)
2824 pccb->ccbStatus = tiIOFailed;
2825 pccb->scsiStatus = tiDetailNoLogin;
2826 agtiapi_FreeCCB(pmcsc, pccb);
2827 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2832 pDev = &pmcsc->pDevList[INDEX(pmcsc, pccb->targetId)];
2835 if ((pmcsc->flags & EDC_DATA) &&
2836 (pDev->flags & EDC_DATA))
2841 * Possible command supported -
2842 * READ_6, READ_10, READ_12, READ_16, READ_LONG, READ_BUFFER,
2843 * READ_DEFECT_DATA, etc.
2844 * WRITE_6, WRITE_10, WRITE_12, WRITE_16, WRITE_LONG, WRITE_LONG2,
2845 * WRITE_BUFFER, WRITE_VERIFY, WRITE_VERIFY_12, etc.
2847 * Do some data length adjustment and set chip operation instruction.
2855 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2856 #ifdef AGTIAPI_TEST_DIF
2857 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2859 pccb->flags |= EDC_DATA;
2861 #ifdef TEST_VERIFY_AND_FORWARD
2862 pccb->tiSuperScsiRequest.Dif.flags =
2863 DIF_VERIFY_FORWARD | DIF_UDT_REF_BLOCK_COUNT;
2864 if(pDev->sector_size == 520) {
2865 pScsiCmnd->expDataLength += (pccb->dataLen / 512) * 8;
2866 } else if(pDev->sector_size == 4104) {
2867 pScsiCmnd->expDataLength += (pccb->dataLen / 4096) * 8;
2870 #ifdef AGTIAPI_TEST_DIF
2871 pccb->tiSuperScsiRequest.Dif.flags =
2872 DIF_VERIFY_DELETE | DIF_UDT_REF_BLOCK_COUNT;
2875 #ifdef AGTIAPI_TEST_DIF
2876 switch(pDev->sector_size) {
2878 pccb->tiSuperScsiRequest.Dif.flags |=
2879 ( DIF_BLOCK_SIZE_520 << 16 );
2882 pccb->tiSuperScsiRequest.Dif.flags |=
2883 ( DIF_BLOCK_SIZE_4096 << 16 );
2886 pccb->tiSuperScsiRequest.Dif.flags |=
2887 ( DIF_BLOCK_SIZE_4160 << 16 );
2891 if(pCard->flags & EDC_DATA_CRC)
2892 pccb->tiSuperScsiRequest.Dif.flags |= DIF_CRC_VERIFICATION;
2894 /* Turn on upper 4 bits of UVM */
2895 pccb->tiSuperScsiRequest.Dif.flags |= 0x03c00000;
2898 #ifdef AGTIAPI_TEST_DPL
2899 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2900 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2901 cmnd->result = SCSI_HOST(DID_ERROR);
2904 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2906 #ifdef AGTIAPI_TEST_DIF
2908 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2909 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2911 /* Set LBA in UDT array */
2912 if(CDB[0] == READ_6) {
2913 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2914 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2915 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2916 pccb->tiSuperScsiRequest.Dif.udtArray[5] = 0;
2917 } else if(CDB[0] == READ_10 || CDB[0] == READ_12) {
2918 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2919 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2920 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2921 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2922 } else if(CDB[0] == READ_16) {
2923 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[9];
2924 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[8];
2925 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[7];
2926 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[6];
2927 /* Note: 32 bits lost */
2936 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2937 pccb->flags |= EDC_DATA;
2938 #ifdef AGTIAPI_TEST_DIF
2939 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2940 pccb->tiSuperScsiRequest.Dif.flags =
2941 DIF_INSERT | DIF_UDT_REF_BLOCK_COUNT;
2942 switch(pDev->sector_size) {
2944 pccb->tiSuperScsiRequest.Dif.flags |=
2945 (DIF_BLOCK_SIZE_520 << 16);
2948 pccb->tiSuperScsiRequest.Dif.flags |=
2949 ( DIF_BLOCK_SIZE_4096 << 16 );
2952 pccb->tiSuperScsiRequest.Dif.flags |=
2953 ( DIF_BLOCK_SIZE_4160 << 16 );
2957 /* Turn on upper 4 bits of UUM */
2958 pccb->tiSuperScsiRequest.Dif.flags |= 0xf0000000;
2960 #ifdef AGTIAPI_TEST_DPL
2961 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2962 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2963 cmnd->result = SCSI_HOST(DID_ERROR);
2966 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2968 #ifdef AGTIAPI_TEST_DIF
2970 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2971 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2973 /* Set LBA in UDT array */
2974 if(CDB[0] == WRITE_6) {
2975 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2976 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2977 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2978 } else if(CDB[0] == WRITE_10 || CDB[0] == WRITE_12) {
2979 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2980 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2981 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2982 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2983 } else if(CDB[0] == WRITE_16) {
2984 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2985 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2986 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2987 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2988 /* Note: 32 bits lost */
2994 #endif /* end of DIF */
2996 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
2998 switch(csio->tag_action)
3000 case MSG_HEAD_OF_Q_TAG:
3001 pScsiCmnd->taskAttribute = TASK_HEAD_OF_QUEUE;
3004 pScsiCmnd->taskAttribute = TASK_ACA;
3006 case MSG_ORDERED_Q_TAG:
3007 pScsiCmnd->taskAttribute = TASK_ORDERED;
3009 case MSG_SIMPLE_Q_TAG: /* fall through */
3011 pScsiCmnd->taskAttribute = TASK_SIMPLE;
3016 if (pccb->tiSuperScsiRequest.agSgl1.len != 0 && pccb->dataLen != 0)
3018 /* should be just before start IO */
3019 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
3023 * If assigned pDevHandle is not available
3024 * then there is no need to send it to StartIO()
3026 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
3028 pccb->ccbStatus = tiIOFailed;
3029 pccb->scsiStatus = tiDetailNoLogin;
3030 agtiapi_FreeCCB(pmcsc, pccb);
3031 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3036 TID = INDEX(pmcsc, pccb->targetId);
3037 if ((TID >= pmcsc->devDiscover) ||
3038 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle))
3041 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: not sending ccb devH %p,"
3042 " target %d tid %d/%d card %p ERROR pccb %p\n",
3043 pccb->devHandle, pccb->targetId, TID,
3044 pmcsc->devDiscover, pmcsc, pccb );
3046 pccb->ccbStatus = tiIOFailed;
3047 pccb->scsiStatus = tiDetailNoLogin;
3048 agtiapi_FreeCCB(pmcsc, pccb);
3049 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3054 AGTIAPI_IO( "agtiapi_PrepareSGListCB: send ccb pccb->devHandle %p, "
3055 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3056 pccb->devHandle, pccb->targetId, TID, pmcsc->devDiscover,
3058 #ifdef HIALEAH_ENCRYPTION
3059 if(pmcsc->encrypt && io_is_encryptable) {
3060 agtiapi_SetupEncryptedIO(pmcsc, pccb, start_lba);
3062 io_is_encryptable = 0;
3063 pccb->tiSuperScsiRequest.flags = 0;
3066 // put the request in send queue
3067 agtiapi_QueueCCB( pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3068 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb );
3069 agtiapi_StartIO(pmcsc);
3073 /******************************************************************************
3077 Send IO request down for processing.
3079 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3082 ******************************************************************************/
3083 STATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc )
3089 AGTIAPI_IO( "agtiapi_StartIO: start\n" );
3091 AG_LOCAL_LOCK( &pmcsc->sendLock );
3092 pccb = pmcsc->ccbSendHead;
3094 /* if link is down, do nothing */
3095 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3097 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3098 AGTIAPI_PRINTK( "agtiapi_StartIO: goto ext\n" );
3103 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3105 TID = INDEX(pmcsc, pccb->targetId);
3106 targ = &pmcsc->pDevList[TID];
3110 /* clear send queue */
3111 pmcsc->ccbSendHead = NULL;
3112 pmcsc->ccbSendTail = NULL;
3113 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3115 /* send all ccbs down */
3121 pccb_next = pccb->pccbNext;
3122 pccb->pccbNext = NULL;
3126 AGTIAPI_PRINTK( "agtiapi_StartIO: pccb->ccb is NULL ERROR!\n" );
3130 AG_IO_DUMPCCB( pccb );
3132 if (!pccb->devHandle)
3134 agtiapi_DumpCCB( pccb );
3135 AGTIAPI_PRINTK( "agtiapi_StartIO: ccb NULL device ERROR!\n" );
3139 AGTIAPI_IO( "agtiapi_StartIO: ccb %p retry %d\n", pccb, pccb->retryCount );
3142 if( !pccb->devHandle || !pccb->devHandle->osData || /* in rmmod case */
3143 !(((ag_device_t *)(pccb->devHandle->osData))->flags & ACTIVE))
3145 AGTIAPI_PRINTK( "agtiapi_StartIO: device %p not active! ERROR\n",
3147 if( pccb->devHandle ) {
3148 AGTIAPI_PRINTK( "agtiapi_StartIO: device not active detail"
3150 pccb->devHandle->osData );
3151 if( pccb->devHandle->osData ) {
3152 AGTIAPI_PRINTK( "agtiapi_StartIO: more device not active detail"
3153 " -- active flag:%d\n",
3155 (pccb->devHandle->osData))->flags & ACTIVE );
3158 pccb->ccbStatus = tiIOFailed;
3159 pccb->scsiStatus = tiDetailNoLogin;
3160 agtiapi_Done( pmcsc, pccb );
3167 status = agtiapi_FastIOTest( pmcsc, pccb );
3169 status = tiINISuperIOStart( &pmcsc->tiRoot,
3172 &pccb->tiSuperScsiRequest,
3173 (void *)&pccb->tdIOReqBody,
3174 tiInterruptContext );
3180 static int squelchCount = 0;
3181 if ( 200000 == squelchCount++ ) // squelch prints
3183 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart stat tiSuccess %p\n",
3185 squelchCount = 0; // reset count
3192 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiDeviceBusy %p\n",
3195 agtiapi_LogEvent( pmcsc,
3196 IOCTL_EVT_SEV_INFORMATIONAL,
3200 "tiINIIOStart tiDeviceBusy " );
3202 pccb->ccbStatus = tiIOFailed;
3203 pccb->scsiStatus = tiDeviceBusy;
3204 agtiapi_Done(pmcsc, pccb);
3208 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiBusy %p\n",
3211 agtiapi_LogEvent( pmcsc,
3212 IOCTL_EVT_SEV_INFORMATIONAL,
3216 "tiINIIOStart tiBusy " );
3219 pccb->ccbStatus = tiIOFailed;
3220 pccb->scsiStatus = tiBusy;
3221 agtiapi_Done(pmcsc, pccb);
3225 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiNoDevice %p "
3226 "ERROR\n", pccb->ccb );
3228 agtiapi_LogEvent( pmcsc,
3229 IOCTL_EVT_SEV_INFORMATIONAL,
3233 "tiINIIOStart invalid device handle " );
3236 /* return command back to OS due to no device available */
3237 ((ag_device_t *)(pccb->devHandle->osData))->flags &= ~ACTIVE;
3238 pccb->ccbStatus = tiIOFailed;
3239 pccb->scsiStatus = tiDetailNoLogin;
3240 agtiapi_Done(pmcsc, pccb);
3242 /* for short cable pull, we want IO retried - 3-18-2005 */
3243 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3244 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
3248 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3251 agtiapi_LogEvent(pmcsc,
3252 IOCTL_EVT_SEV_INFORMATIONAL,
3256 "tiINIIOStart tiError ");
3258 pccb->ccbStatus = tiIOFailed;
3259 pccb->scsiStatus = tiDetailOtherError;
3260 agtiapi_Done(pmcsc, pccb);
3263 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3266 agtiapi_LogEvent(pmcsc,
3267 IOCTL_EVT_SEV_ERROR,
3271 "tiINIIOStart unexpected status ");
3273 pccb->ccbStatus = tiIOFailed;
3274 pccb->scsiStatus = tiDetailOtherError;
3275 agtiapi_Done(pmcsc, pccb);
3281 /* some IO requests might have been completed */
3282 AG_GET_DONE_PCCB(pccb, pmcsc);
3286 /******************************************************************************
3290 Send SMP request down for processing.
3292 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3295 ******************************************************************************/
3296 STATIC void agtiapi_StartSMP(struct agtiapi_softc *pmcsc)
3300 AGTIAPI_PRINTK("agtiapi_StartSMP: start\n");
3302 AG_LOCAL_LOCK(&pmcsc->sendSMPLock);
3303 pccb = pmcsc->smpSendHead;
3305 /* if link is down, do nothing */
3306 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3308 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3309 AGTIAPI_PRINTK("agtiapi_StartSMP: goto ext\n");
3313 /* clear send queue */
3314 pmcsc->smpSendHead = NULL;
3315 pmcsc->smpSendTail = NULL;
3316 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3318 /* send all ccbs down */
3324 pccb_next = pccb->pccbNext;
3325 pccb->pccbNext = NULL;
3329 AGTIAPI_PRINTK("agtiapi_StartSMP: pccb->ccb is NULL ERROR!\n");
3334 if (!pccb->devHandle)
3336 AGTIAPI_PRINTK("agtiapi_StartSMP: ccb NULL device ERROR!\n");
3340 pccb->flags |= TAG_SMP; // mark as SMP for later tracking
3341 AGTIAPI_PRINTK( "agtiapi_StartSMP: ccb %p retry %d\n",
3342 pccb, pccb->retryCount );
3343 status = tiINISMPStart( &pmcsc->tiRoot,
3347 (void *)&pccb->tdIOReqBody,
3348 tiInterruptContext);
3355 AGTIAPI_PRINTK("agtiapi_StartSMP: tiINISMPStart status tiBusy %p\n",
3357 /* pending ccb back to send queue */
3358 agtiapi_QueueCCB(pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3359 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb);
3362 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3364 pccb->ccbStatus = tiSMPFailed;
3365 agtiapi_SMPDone(pmcsc, pccb);
3368 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3370 pccb->ccbStatus = tiSMPFailed;
3371 agtiapi_SMPDone(pmcsc, pccb);
3377 /* some SMP requests might have been completed */
3378 AG_GET_DONE_SMP_PCCB(pccb, pmcsc);
3383 #if __FreeBSD_version > 901000
3384 /******************************************************************************
3385 agtiapi_PrepareSMPSGList()
3388 This function prepares scatter-gather list for the given ccb
3390 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3391 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3397 ******************************************************************************/
3398 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3400 /* Pointer to CAM's ccb */
3401 union ccb *ccb = pccb->ccb;
3402 struct ccb_smpio *csmpio = &ccb->smpio;
3403 struct ccb_hdr *ccbh = &ccb->ccb_h;
3405 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3406 switch((ccbh->flags & CAM_DATA_MASK))
3408 case CAM_DATA_PADDR:
3409 case CAM_DATA_SG_PADDR:
3410 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address not supported\n");
3411 ccb->ccb_h.status = CAM_REQ_INVALID;
3417 * Currently we do not support Multiple SG list
3418 * return error for now
3420 if ( (csmpio->smp_request_sglist_cnt > 1)
3421 || (csmpio->smp_response_sglist_cnt > 1) )
3423 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list not supported\n");
3424 ccb->ccb_h.status = CAM_REQ_INVALID;
3429 if ( csmpio->smp_request_sglist_cnt != 0 )
3432 * Virtual address that needs to translated into
3433 * one or more physical address ranges.
3436 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3437 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3438 error = bus_dmamap_load( pmcsc->buffer_dmat,
3440 csmpio->smp_request,
3441 csmpio->smp_request_len,
3442 agtiapi_PrepareSMPSGListCB,
3444 BUS_DMA_NOWAIT /* 0 */ );
3446 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3448 if (error == EINPROGRESS)
3451 * So as to maintain ordering,
3452 * freeze the controller queue
3453 * until our mapping is
3456 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3457 xpt_freeze_simq( pmcsc->sim, 1 );
3458 pmcsc->SimQFrozen = agTRUE;
3459 ccbh->status |= CAM_RELEASE_SIMQ;
3462 if( csmpio->smp_response_sglist_cnt != 0 )
3465 * Virtual address that needs to translated into
3466 * one or more physical address ranges.
3469 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3470 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3471 error = bus_dmamap_load( pmcsc->buffer_dmat,
3473 csmpio->smp_response,
3474 csmpio->smp_response_len,
3475 agtiapi_PrepareSMPSGListCB,
3477 BUS_DMA_NOWAIT /* 0 */ );
3479 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3481 if ( error == EINPROGRESS )
3484 * So as to maintain ordering,
3485 * freeze the controller queue
3486 * until our mapping is
3489 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3490 xpt_freeze_simq( pmcsc->sim, 1 );
3491 pmcsc->SimQFrozen = agTRUE;
3492 ccbh->status |= CAM_RELEASE_SIMQ;
3498 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3499 (csmpio->smp_response_sglist_cnt == 0) )
3501 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3502 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3503 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3504 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3506 // 0xFF to be defined
3507 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3509 pccb->tiSMPFrame.flag = 0;
3516 /******************************************************************************
3517 agtiapi_PrepareSMPSGList()
3520 This function prepares scatter-gather list for the given ccb
3522 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3523 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3529 ******************************************************************************/
3530 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3532 /* Pointer to CAM's ccb */
3533 union ccb *ccb = pccb->ccb;
3534 struct ccb_smpio *csmpio = &ccb->smpio;
3535 struct ccb_hdr *ccbh = &ccb->ccb_h;
3537 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3539 if (ccbh->flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS))
3541 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address "
3542 "not supported\n" );
3543 ccb->ccb_h.status = CAM_REQ_INVALID;
3548 if (ccbh->flags & CAM_SCATTER_VALID)
3551 * Currently we do not support Multiple SG list
3552 * return error for now
3554 if ( (csmpio->smp_request_sglist_cnt > 1)
3555 || (csmpio->smp_response_sglist_cnt > 1) )
3557 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list "
3558 "not supported\n" );
3559 ccb->ccb_h.status = CAM_REQ_INVALID;
3563 if ( csmpio->smp_request_sglist_cnt != 0 )
3566 * Virtual address that needs to translated into
3567 * one or more physical address ranges.
3570 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3571 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3572 error = bus_dmamap_load( pmcsc->buffer_dmat,
3574 csmpio->smp_request,
3575 csmpio->smp_request_len,
3576 agtiapi_PrepareSMPSGListCB,
3578 BUS_DMA_NOWAIT /* 0 */ );
3580 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3582 if (error == EINPROGRESS)
3585 * So as to maintain ordering,
3586 * freeze the controller queue
3587 * until our mapping is
3590 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3591 xpt_freeze_simq( pmcsc->sim, 1 );
3592 pmcsc->SimQFrozen = agTRUE;
3593 ccbh->status |= CAM_RELEASE_SIMQ;
3596 if( csmpio->smp_response_sglist_cnt != 0 )
3599 * Virtual address that needs to translated into
3600 * one or more physical address ranges.
3603 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3604 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3605 error = bus_dmamap_load( pmcsc->buffer_dmat,
3607 csmpio->smp_response,
3608 csmpio->smp_response_len,
3609 agtiapi_PrepareSMPSGListCB,
3611 BUS_DMA_NOWAIT /* 0 */ );
3613 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3615 if ( error == EINPROGRESS )
3618 * So as to maintain ordering,
3619 * freeze the controller queue
3620 * until our mapping is
3623 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3624 xpt_freeze_simq( pmcsc->sim, 1 );
3625 pmcsc->SimQFrozen = agTRUE;
3626 ccbh->status |= CAM_RELEASE_SIMQ;
3632 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3633 (csmpio->smp_response_sglist_cnt == 0) )
3635 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3636 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3637 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3638 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3640 // 0xFF to be defined
3641 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3643 pccb->tiSMPFrame.flag = 0;
3650 /******************************************************************************
3651 agtiapi_PrepareSMPSGListCB()
3654 Callback function for bus_dmamap_load()
3655 This fuctions sends IO to LL layer.
3657 void *arg (IN) Pointer to the HBA data structure
3658 bus_dma_segment_t *segs (IN) Pointer to dma segment
3659 int nsegs (IN) number of dma segment
3660 int error (IN) error
3663 ******************************************************************************/
3664 static void agtiapi_PrepareSMPSGListCB( void *arg,
3665 bus_dma_segment_t *segs,
3670 union ccb *ccb = pccb->ccb;
3671 struct agtiapi_softc *pmcsc;
3672 U32 TID = CMND_TO_TARGET(ccb);
3674 tiDeviceHandle_t *tiExpDevHandle;
3675 tiPortalContext_t *tiExpPortalContext;
3676 ag_portal_info_t *tiExpPortalInfo;
3678 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: start, nsegs %d error 0x%x\n",
3680 pmcsc = pccb->pmcsc;
3682 if ( error != tiSuccess )
3684 if (error == 0xAABBCCDD)
3690 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: error status 0x%x\n",
3692 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3693 agtiapi_FreeCCB( pmcsc, pccb );
3695 ccb->ccb_h.status = CAM_REQ_TOO_BIG;
3697 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
3703 if ( nsegs > AGTIAPI_MAX_DMA_SEGS )
3705 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: over the limit. nsegs %d "
3706 "AGTIAPI_MAX_DMA_SEGS %d\n",
3707 nsegs, AGTIAPI_MAX_DMA_SEGS );
3708 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3709 agtiapi_FreeCCB( pmcsc, pccb );
3710 ccb->ccb_h.status = CAM_REQ_TOO_BIG;
3716 * If assigned pDevHandle is not available
3717 * then there is no need to send it to StartIO()
3719 /* TODO: Add check for deviceType */
3720 if ( pccb->targetId < 0 || pccb->targetId >= maxTargets )
3722 agtiapi_FreeCCB( pmcsc, pccb );
3723 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3728 TID = INDEX( pmcsc, pccb->targetId );
3729 if ( (TID >= pmcsc->devDiscover) ||
3730 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle) )
3732 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: not sending ccb devH %p, "
3733 "target %d tid %d/%d "
3734 "card %p ERROR pccb %p\n",
3741 agtiapi_FreeCCB( pmcsc, pccb );
3742 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3747 /* TODO: add indirect handling */
3748 /* set the flag correctly based on Indiret SMP request and response */
3750 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, "
3751 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3753 pccb->targetId, TID,
3756 tiExpDevHandle = pccb->devHandle;
3757 tiExpPortalInfo = pmcsc->pDevList[TID].pPortalInfo;
3758 tiExpPortalContext = &tiExpPortalInfo->tiPortalContext;
3759 /* Look for the expander associated with the ses device */
3760 status = tiINIGetExpander( &pmcsc->tiRoot,
3765 if ( status != tiSuccess )
3767 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: Error getting Expander "
3769 agtiapi_FreeCCB( pmcsc, pccb );
3770 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3776 /* this is expander device */
3777 pccb->devHandle = tiExpDevHandle;
3778 /* put the request in send queue */
3779 agtiapi_QueueCCB( pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3780 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb );
3782 agtiapi_StartSMP( pmcsc );
3788 /******************************************************************************
3792 Processing completed ccbs
3794 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3795 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3798 ******************************************************************************/
3799 STATIC void agtiapi_Done(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3801 pccb_t pccb_curr = pccb;
3804 tiIniScsiCmnd_t *cmnd;
3807 AGTIAPI_IO("agtiapi_Done: start\n");
3810 /* start from 1st ccb in the chain */
3811 pccb_next = pccb_curr->pccbNext;
3813 if (agtiapi_CheckError(pmcsc, pccb_curr) != 0)
3815 /* send command back and release the ccb */
3816 cmnd = &pccb_curr->tiSuperScsiRequest.scsiCmnd;
3818 if (cmnd->cdb[0] == RECEIVE_DIAGNOSTIC)
3820 AGTIAPI_PRINTK("agtiapi_Done: RECEIVE_DIAG pg %d id %d cmnd %p pccb "
3821 "%p\n", cmnd->cdb[2], pccb_curr->targetId, cmnd,
3825 CMND_DMA_UNMAP(pmcsc, ccb);
3827 /* send the request back to the CAM */
3828 ccb = pccb_curr->ccb;
3829 agtiapi_FreeCCB(pmcsc, pccb_curr);
3832 pccb_curr = pccb_next;
3837 /******************************************************************************
3841 Processing completed ccbs
3843 struct agtiapi_softc *pmcsc (IN) Ponter to HBA data structure
3844 ccb_t *pccb (IN) A pointer to the driver's own CCB, not
3848 ******************************************************************************/
3849 STATIC void agtiapi_SMPDone(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3851 pccb_t pccb_curr = pccb;
3856 AGTIAPI_PRINTK("agtiapi_SMPDone: start\n");
3860 /* start from 1st ccb in the chain */
3861 pccb_next = pccb_curr->pccbNext;
3863 if (agtiapi_CheckSMPError(pmcsc, pccb_curr) != 0)
3865 CMND_DMA_UNMAP(pmcsc, ccb);
3867 /* send the request back to the CAM */
3868 ccb = pccb_curr->ccb;
3869 agtiapi_FreeSMPCCB(pmcsc, pccb_curr);
3873 pccb_curr = pccb_next;
3876 AGTIAPI_PRINTK("agtiapi_SMPDone: Done\n");
3880 /******************************************************************************
3884 Utility function for dumping in hex
3886 const char *ptitle (IN) A string to be printed
3887 bit8 *pbuf (IN) A pointer to a buffer to be printed.
3888 int len (IN) The lengther of the buffer
3891 ******************************************************************************/
3892 void agtiapi_hexdump(const char *ptitle, bit8 *pbuf, int len)
3895 AGTIAPI_PRINTK("%s - hexdump(len=%d):\n", ptitle, (int)len);
3898 AGTIAPI_PRINTK("pbuf is NULL\n");
3901 for (i = 0; i < len; )
3905 AGTIAPI_PRINTK( " 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1],
3906 pbuf[i+2], pbuf[i+3] );
3911 AGTIAPI_PRINTK(" 0x%02x,", pbuf[i]);
3915 AGTIAPI_PRINTK("\n");
3919 /******************************************************************************
3920 agtiapi_CheckError()
3923 Processes status pertaining to the ccb -- whether it was
3924 completed successfully, aborted, or error encountered.
3926 ag_card_t *pCard (IN) Pointer to HBA data structure
3927 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
3929 0 - the command retry is required
3930 1 - the command process is completed
3933 ******************************************************************************/
3934 STATIC U32 agtiapi_CheckError(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3936 ag_device_t *pDevice;
3937 // union ccb * ccb = pccb->ccb;
3945 AGTIAPI_IO("agtiapi_CheckError: start\n");
3948 /* shouldn't be here but just in case we do */
3949 AGTIAPI_PRINTK("agtiapi_CheckError: CCB orphan = %p ERROR\n", pccb);
3950 agtiapi_FreeCCB(pmcsc, pccb);
3956 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3958 if (pmcsc->pWWNList != NULL)
3960 TID = INDEX(pmcsc, pccb->targetId);
3961 if (TID < maxTargets)
3963 pDevice = &pmcsc->pDevList[TID];
3964 if (pDevice != NULL)
3973 AGTIAPI_PRINTK("agtiapi_CheckError: pDevice == NULL\n");
3974 agtiapi_FreeCCB(pmcsc, pccb);
3979 ccb->csio.scsi_status = pccb->scsiStatus;
3981 if(pDevice->CCBCount > 0){
3982 atomic_subtract_int(&pDevice->CCBCount,1);
3984 AG_LOCAL_LOCK(&pmcsc->freezeLock);
3985 if(pmcsc->freezeSim == agTRUE)
3987 pmcsc->freezeSim = agFALSE;
3988 xpt_release_simq(pmcsc->sim, 1);
3990 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
3992 switch (pccb->ccbStatus)
3995 AGTIAPI_IO("agtiapi_CheckError: tiIOSuccess pccb %p\n", pccb);
3997 if (pccb->scsiStatus == SCSI_STATUS_OK)
3999 ccb->ccb_h.status = CAM_REQ_CMP;
4002 if (pccb->scsiStatus == SCSI_TASK_ABORTED)
4004 ccb->ccb_h.status = CAM_REQ_ABORTED;
4008 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
4010 if (ccb->csio.scsi_status == SCSI_CHECK_CONDITION)
4012 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
4018 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOOverRun pccb %p\n", pccb);
4019 /* resid is ignored for this condition */
4020 ccb->csio.resid = 0;
4021 ccb->ccb_h.status = CAM_DATA_RUN_ERR;
4024 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOUnderRun pccb %p\n", pccb);
4025 ccb->csio.resid = pccb->scsiStatus;
4026 ccb->ccb_h.status = CAM_REQ_CMP;
4027 ccb->csio.scsi_status = SCSI_STATUS_OK;
4031 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4032 pccb, pccb->scsiStatus, pccb->targetId );
4033 if (pccb->scsiStatus == tiDeviceBusy)
4035 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - tiDetailBusy\n",
4037 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
4038 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4039 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0)
4041 ccb->ccb_h.status |= CAM_DEV_QFRZN;
4042 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
4045 else if(pccb->scsiStatus == tiBusy)
4047 AG_LOCAL_LOCK(&pmcsc->freezeLock);
4048 if(pmcsc->freezeSim == agFALSE)
4050 pmcsc->freezeSim = agTRUE;
4051 xpt_freeze_simq(pmcsc->sim, 1);
4053 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
4054 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4055 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4057 else if (pccb->scsiStatus == tiDetailNoLogin)
4059 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4060 "tiDetailNoLogin ERROR\n", pccb );
4061 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
4063 else if (pccb->scsiStatus == tiDetailNotValid)
4065 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4066 "tiDetailNotValid ERROR\n", pccb );
4067 ccb->ccb_h.status = CAM_REQ_INVALID;
4069 else if (pccb->scsiStatus == tiDetailAbortLogin)
4071 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4072 "tiDetailAbortLogin ERROR\n", pccb );
4073 ccb->ccb_h.status = CAM_REQ_ABORTED;
4075 else if (pccb->scsiStatus == tiDetailAbortReset)
4077 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4078 "tiDetailAbortReset ERROR\n", pccb );
4079 ccb->ccb_h.status = CAM_REQ_ABORTED;
4081 else if (pccb->scsiStatus == tiDetailAborted)
4083 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4084 "tiDetailAborted ERROR\n", pccb );
4085 ccb->ccb_h.status = CAM_REQ_ABORTED;
4087 else if (pccb->scsiStatus == tiDetailOtherError)
4089 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4090 "tiDetailOtherError ERROR\n", pccb );
4091 ccb->ccb_h.status = CAM_REQ_ABORTED;
4095 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4096 pccb, pccb->scsiStatus, pccb->targetId );
4097 if (pccb->scsiStatus == tiDetailDifAppTagMismatch)
4099 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - "
4100 "tiDetailDifAppTagMismatch\n", pccb );
4101 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4103 else if (pccb->scsiStatus == tiDetailDifRefTagMismatch)
4105 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4106 "tiDetailDifRefTagMismatch\n", pccb );
4107 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4109 else if (pccb->scsiStatus == tiDetailDifCrcMismatch)
4111 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4112 "tiDetailDifCrcMismatch\n", pccb );
4113 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4116 #ifdef HIALEAH_ENCRYPTION
4117 case tiIOEncryptError:
4118 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4119 pccb, pccb->scsiStatus, pccb->targetId );
4120 if (pccb->scsiStatus == tiDetailDekKeyCacheMiss)
4122 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4123 "tiDetailDekKeyCacheMiss ERROR\n",
4124 __FUNCTION__, pccb );
4125 ccb->ccb_h.status = CAM_REQ_ABORTED;
4126 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4128 else if (pccb->scsiStatus == tiDetailDekIVMismatch)
4130 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4131 "tiDetailDekIVMismatch ERROR\n", __FUNCTION__, pccb );
4132 ccb->ccb_h.status = CAM_REQ_ABORTED;
4133 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4138 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOdefault %d id %d ERROR\n",
4139 pccb, pccb->ccbStatus, pccb->targetId );
4140 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4148 /******************************************************************************
4149 agtiapi_SMPCheckError()
4152 Processes status pertaining to the ccb -- whether it was
4153 completed successfully, aborted, or error encountered.
4155 ag_card_t *pCard (IN) Pointer to HBA data structure
4156 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
4158 0 - the command retry is required
4159 1 - the command process is completed
4162 ******************************************************************************/
4163 STATIC U32 agtiapi_CheckSMPError( struct agtiapi_softc *pmcsc, ccb_t *pccb )
4165 union ccb * ccb = pccb->ccb;
4167 AGTIAPI_PRINTK("agtiapi_CheckSMPError: start\n");
4171 /* shouldn't be here but just in case we do */
4172 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: CCB orphan = %p ERROR\n",
4174 agtiapi_FreeSMPCCB(pmcsc, pccb);
4178 switch (pccb->ccbStatus)
4181 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPSuccess pccb %p\n",
4184 ccb->ccb_h.status = CAM_REQ_CMP;
4187 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPFailed pccb %p\n",
4190 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4193 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: pccb %p tiSMPdefault %d "
4198 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4207 /******************************************************************************
4208 agtiapi_HandleEncryptedIOFailure():
4215 ******************************************************************************/
4216 void agtiapi_HandleEncryptedIOFailure(ag_device_t *pDev, ccb_t *pccb)
4219 AGTIAPI_PRINTK("agtiapi_HandleEncryptedIOFailure: start\n");
4223 /******************************************************************************
4229 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA structure
4230 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4234 ******************************************************************************/
4235 STATIC void agtiapi_Retry(struct agtiapi_softc *pmcsc, ccb_t *pccb)
4238 pccb->flags = ACTIVE | AGTIAPI_RETRY;
4239 pccb->ccbStatus = 0;
4240 pccb->scsiStatus = 0;
4241 pccb->startTime = ticks;
4243 AGTIAPI_PRINTK( "agtiapi_Retry: start\n" );
4244 AGTIAPI_PRINTK( "agtiapi_Retry: ccb %p retry %d flgs x%x\n", pccb,
4245 pccb->retryCount, pccb->flags );
4247 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
4248 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
4253 /******************************************************************************
4257 Dump CCB for debuging
4259 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4262 ******************************************************************************/
4263 STATIC void agtiapi_DumpCCB(ccb_t *pccb)
4265 AGTIAPI_PRINTK("agtiapi_DumpCCB: pccb %p, devHandle %p, tid %d, lun %d\n",
4270 AGTIAPI_PRINTK("flag 0x%x, add_mode 0x%x, ccbStatus 0x%x, scsiStatus 0x%x\n",
4275 AGTIAPI_PRINTK("scsi comand = 0x%x, numSgElements = %d\n",
4276 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4277 pccb->numSgElements);
4278 AGTIAPI_PRINTK("dataLen = 0x%x, sens_len = 0x%x\n",
4281 AGTIAPI_PRINTK("tiSuperScsiRequest:\n");
4282 AGTIAPI_PRINTK("scsiCmnd: expDataLength 0x%x, taskAttribute 0x%x\n",
4283 pccb->tiSuperScsiRequest.scsiCmnd.expDataLength,
4284 pccb->tiSuperScsiRequest.scsiCmnd.taskAttribute);
4285 AGTIAPI_PRINTK("cdb[0] = 0x%x, cdb[1] = 0x%x, cdb[2] = 0x%x, cdb[3] = 0x%x\n",
4286 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4287 pccb->tiSuperScsiRequest.scsiCmnd.cdb[1],
4288 pccb->tiSuperScsiRequest.scsiCmnd.cdb[2],
4289 pccb->tiSuperScsiRequest.scsiCmnd.cdb[3]);
4290 AGTIAPI_PRINTK("cdb[4] = 0x%x, cdb[5] = 0x%x, cdb[6] = 0x%x, cdb[7] = 0x%x\n",
4291 pccb->tiSuperScsiRequest.scsiCmnd.cdb[4],
4292 pccb->tiSuperScsiRequest.scsiCmnd.cdb[5],
4293 pccb->tiSuperScsiRequest.scsiCmnd.cdb[6],
4294 pccb->tiSuperScsiRequest.scsiCmnd.cdb[7]);
4295 AGTIAPI_PRINTK( "cdb[8] = 0x%x, cdb[9] = 0x%x, cdb[10] = 0x%x, "
4297 pccb->tiSuperScsiRequest.scsiCmnd.cdb[8],
4298 pccb->tiSuperScsiRequest.scsiCmnd.cdb[9],
4299 pccb->tiSuperScsiRequest.scsiCmnd.cdb[10],
4300 pccb->tiSuperScsiRequest.scsiCmnd.cdb[11] );
4301 AGTIAPI_PRINTK("agSgl1: upper 0x%x, lower 0x%x, len 0x%x, type %d\n",
4302 pccb->tiSuperScsiRequest.agSgl1.upper,
4303 pccb->tiSuperScsiRequest.agSgl1.lower,
4304 pccb->tiSuperScsiRequest.agSgl1.len,
4305 pccb->tiSuperScsiRequest.agSgl1.type);
4308 /******************************************************************************
4309 agtiapi_eh_HostReset()
4312 A new error handler of Host Reset command.
4314 scsi_cmnd *cmnd (IN) Pointer to a command to the HBA to be reset
4319 ******************************************************************************/
4320 int agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4322 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4327 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4328 return tiInvalidHandle;
4332 agtiapi_LogEvent( pmcsc,
4333 IOCTL_EVT_SEV_INFORMATIONAL,
4337 "agtiapi_eh_HostReset! " );
4340 return agtiapi_DoSoftReset( pmcsc );
4344 /******************************************************************************
4348 Put ccb in ccb queue at the tail
4350 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4351 pccb_t *phead (IN) Double pointer to ccb queue head
4352 pccb_t *ptail (IN) Double pointer to ccb queue tail
4353 ccb_t *pccb (IN) Poiner to a ccb to be queued
4356 Put the ccb to the tail of queue
4357 ******************************************************************************/
4358 STATIC void agtiapi_QueueCCB( struct agtiapi_softc *pmcsc,
4361 #ifdef AGTIAPI_LOCAL_LOCK
4366 AGTIAPI_IO( "agtiapi_QueueCCB: start\n" );
4367 AGTIAPI_IO( "agtiapi_QueueCCB: %p to %p\n", pccb, phead );
4368 if (phead == NULL || ptail == NULL)
4370 panic( "agtiapi_QueueCCB: phead %p ptail %p", phead, ptail );
4372 pccb->pccbNext = NULL;
4373 AG_LOCAL_LOCK( mutex );
4376 //WARN_ON(*ptail != NULL); /* critical, just get more logs */
4381 //WARN_ON(*ptail == NULL); /* critical, just get more logs */
4383 (*ptail)->pccbNext = pccb;
4386 AG_LOCAL_UNLOCK( mutex );
4391 /******************************************************************************
4402 ******************************************************************************/
4403 static int agtiapi_QueueSMP(struct agtiapi_softc *pmcsc, union ccb * ccb)
4405 pccb_t pccb = agNULL; /* call dequeue */
4406 int status = tiSuccess;
4407 int targetID = xpt_path_target_id(ccb->ccb_h.path);
4409 AGTIAPI_PRINTK("agtiapi_QueueSMP: start\n");
4412 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
4414 AGTIAPI_PRINTK("agtiapi_QueueSMP: GetCCB ERROR\n");
4415 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4419 pccb->pmcsc = pmcsc;
4421 /* initialize Command Control Block (CCB) */
4422 pccb->targetId = targetID;
4423 pccb->ccb = ccb; /* for struct scsi_cmnd */
4425 status = agtiapi_PrepareSMPSGList(pmcsc, pccb);
4427 if (status != tiSuccess)
4429 AGTIAPI_PRINTK("agtiapi_QueueSMP: agtiapi_PrepareSMPSGList failure\n");
4430 agtiapi_FreeCCB(pmcsc, pccb);
4431 if (status == tiReject)
4433 ccb->ccb_h.status = CAM_REQ_INVALID;
4437 ccb->ccb_h.status = CAM_REQ_CMP;
4446 /******************************************************************************
4447 agtiapi_SetLunField()
4450 Set LUN field based on different address mode
4452 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4455 ******************************************************************************/
4456 void agtiapi_SetLunField(ccb_t *pccb)
4460 pchar = (U08 *)&pccb->tiSuperScsiRequest.scsiCmnd.lun;
4462 // AGTIAPI_PRINTK("agtiapi_SetLunField: start\n");
4464 switch (pccb->addrMode)
4466 case AGTIAPI_PERIPHERAL:
4468 *pchar = (U08)pccb->lun;
4470 case AGTIAPI_VOLUME_SET:
4471 *pchar++ = (AGTIAPI_VOLUME_SET << AGTIAPI_ADDRMODE_SHIFT) |
4472 (U08)((pccb->lun >> 8) & 0x3F);
4473 *pchar = (U08)pccb->lun;
4475 case AGTIAPI_LUN_ADDR:
4476 *pchar++ = (AGTIAPI_LUN_ADDR << AGTIAPI_ADDRMODE_SHIFT) |
4478 *pchar = (U08)pccb->lun;
4486 /*****************************************************************************
4490 Free a ccb and put it back to ccbFreeList.
4492 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4493 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4497 *****************************************************************************/
4498 STATIC void agtiapi_FreeCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4500 union ccb *ccb = pccb->ccb;
4501 bus_dmasync_op_t op;
4503 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4504 AGTIAPI_IO( "agtiapi_FreeCCB: start %p\n", pccb );
4506 #ifdef AGTIAPI_TEST_EPL
4507 tiEncrypt_t *encrypt;
4510 agtiapi_DumpCDB( "agtiapi_FreeCCB", pccb );
4512 if (pccb->sgList != agNULL)
4514 AGTIAPI_IO( "agtiapi_FreeCCB: pccb->sgList is NOT null\n" );
4518 AGTIAPI_PRINTK( "agtiapi_FreeCCB: pccb->sgList is null\n" );
4521 /* set data transfer direction */
4522 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4524 op = BUS_DMASYNC_POSTWRITE;
4528 op = BUS_DMASYNC_POSTREAD;
4531 if (pccb->numSgElements == 0)
4534 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements zero\n" );
4536 else if (pccb->numSgElements == 1)
4538 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements is one\n" );
4539 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4540 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4541 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4545 AGTIAPI_PRINTK( "agtiapi_FreeCCB: numSgElements 2 or higher \n" );
4546 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4547 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4548 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4551 #ifdef AGTIAPI_TEST_DPL
4552 if (pccb->tiSuperScsiRequest.Dif.enableDIFPerLA == TRUE) {
4554 memset( (char *) pccb->dplPtr,
4556 MAX_DPL_REGIONS * sizeof(dplaRegion_t) );
4557 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = FALSE;
4558 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrLo = 0;
4559 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrHi = 0;
4563 #ifdef AGTIAPI_TEST_EPL
4564 encrypt = &pccb->tiSuperScsiRequest.Encrypt;
4565 if (encrypt->enableEncryptionPerLA == TRUE) {
4566 encrypt->enableEncryptionPerLA = FALSE;
4567 encrypt->EncryptionPerLAAddrLo = 0;
4568 encrypt->EncryptionPerLAAddrHi = 0;
4572 #ifdef ENABLE_SATA_DIF
4573 if (pccb->holePtr && pccb->dmaHandleHole)
4574 pci_free_consistent( pmcsc->pCardInfo->pPCIDev,
4577 pccb->dmaHandleHole );
4579 pccb->dmaHandleHole = 0;
4583 pccb->retryCount = 0;
4584 pccb->ccbStatus = 0;
4585 pccb->scsiStatus = 0;
4586 pccb->startTime = 0;
4587 pccb->dmaHandle = 0;
4588 pccb->numSgElements = 0;
4589 pccb->tiIORequest.tdData = 0;
4590 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4592 #ifdef HIALEAH_ENCRYPTION
4594 agtiapi_CleanupEncryptedIO(pmcsc, pccb);
4599 pccb->pccbIO = NULL;
4600 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4601 pmcsc->ccbFreeList = (caddr_t *)pccb;
4605 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4610 /******************************************************************************
4614 Flush all in processed ccbs.
4616 ag_card_t *pCard (IN) Pointer to HBA data structure
4617 U32 flag (IN) Flag to call back
4620 ******************************************************************************/
4621 STATIC void agtiapi_FlushCCBs( struct agtiapi_softc *pCard, U32 flag )
4626 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: enter \n" );
4627 for( pccb = (pccb_t)pCard->ccbChainList;
4629 pccb = pccb->pccbChainNext ) {
4630 if( pccb->flags == 0 )
4632 // printf( "agtiapi_FlushCCBs: nothing, continue \n" );
4636 if ( pccb->flags & ( TASK_MANAGEMENT | DEV_RESET ) )
4638 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeTMCCB \n" );
4639 agtiapi_FreeTMCCB( pCard, pccb );
4643 if ( pccb->flags & TAG_SMP )
4645 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeSMPCCB \n" );
4646 agtiapi_FreeSMPCCB( pCard, pccb );
4650 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeCCB \n" );
4651 agtiapi_FreeCCB( pCard, pccb );
4654 CMND_DMA_UNMAP( pCard, ccb );
4655 if( flag == AGTIAPI_CALLBACK ) {
4656 ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
4664 /*****************************************************************************
4665 agtiapi_FreeSMPCCB()
4668 Free a ccb and put it back to ccbFreeList.
4670 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4671 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4675 *****************************************************************************/
4676 STATIC void agtiapi_FreeSMPCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4678 union ccb *ccb = pccb->ccb;
4679 bus_dmasync_op_t op;
4681 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4682 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: start %p\n", pccb);
4684 /* set data transfer direction */
4685 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4687 op = BUS_DMASYNC_POSTWRITE;
4691 op = BUS_DMASYNC_POSTREAD;
4694 if (pccb->numSgElements == 0)
4697 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 0\n");
4699 else if (pccb->numSgElements == 1)
4701 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 1\n");
4702 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4703 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4704 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4708 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 2 or higher \n");
4709 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4710 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4711 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4714 /*dma api cleanning*/
4716 pccb->retryCount = 0;
4717 pccb->ccbStatus = 0;
4718 pccb->startTime = 0;
4719 pccb->dmaHandle = 0;
4720 pccb->numSgElements = 0;
4721 pccb->tiIORequest.tdData = 0;
4722 memset((void *)&pccb->tiSMPFrame, 0, AGSMP_INIT_XCHG_LEN);
4726 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4727 pmcsc->ccbFreeList = (caddr_t *)pccb;
4731 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4736 /*****************************************************************************
4740 Free a ccb and put it back to ccbFreeList.
4742 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4743 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4747 *****************************************************************************/
4748 STATIC void agtiapi_FreeTMCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4750 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4751 AGTIAPI_PRINTK("agtiapi_FreeTMCCB: start %p\n", pccb);
4753 pccb->retryCount = 0;
4754 pccb->ccbStatus = 0;
4755 pccb->scsiStatus = 0;
4756 pccb->startTime = 0;
4757 pccb->dmaHandle = 0;
4758 pccb->numSgElements = 0;
4759 pccb->tiIORequest.tdData = 0;
4760 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4763 pccb->pccbIO = NULL;
4764 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4765 pmcsc->ccbFreeList = (caddr_t *)pccb;
4767 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4770 /******************************************************************************
4771 agtiapi_CheckAllVectors():
4777 Currently, not used.
4778 ******************************************************************************/
4779 void agtiapi_CheckAllVectors( struct agtiapi_softc *pCard, bit32 context )
4781 #ifdef SPC_MSIX_INTR
4782 if (!agtiapi_intx_mode)
4786 for (i = 0; i < pCard->pCardInfo->maxInterruptVectors; i++)
4787 if (tiCOMInterruptHandler(&pCard->tiRoot, i) == agTRUE)
4788 tiCOMDelayedInterruptHandler(&pCard->tiRoot, i, 100, context);
4791 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4792 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4794 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4795 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4801 /******************************************************************************
4805 Check call back function returned event for process completion
4807 struct agtiapi_softc *pCard Pointer to card data structure
4808 U32 milisec (IN) Waiting time for expected event
4809 U32 flag (IN) Flag of the event to check
4810 U32 *pStatus (IN) Pointer to status of the card or port to check
4812 AGTIAPI_SUCCESS - event comes as expected
4813 AGTIAPI_FAIL - event not coming
4816 ******************************************************************************/
4817 agBOOLEAN agtiapi_CheckCB( struct agtiapi_softc *pCard,
4820 volatile U32 *pStatus )
4822 U32 msecsPerTick = pCard->pCardInfo->tiRscInfo.tiInitiatorResource.
4823 initiatorOption.usecsPerTick / 1000;
4824 S32 i = milisec/msecsPerTick;
4825 AG_GLOBAL_ARG( _flags );
4827 AGTIAPI_PRINTK( "agtiapi_CheckCB: start\n" );
4828 AGTIAPI_FLOW( "agtiapi_CheckCB: start\n" );
4834 if (*pStatus & TASK_MANAGEMENT)
4836 if (*pStatus & AGTIAPI_CB_DONE)
4838 if( flag == 0 || *pStatus & flag )
4839 return AGTIAPI_SUCCESS;
4841 return AGTIAPI_FAIL;
4844 else if (pCard->flags & AGTIAPI_CB_DONE)
4846 if( flag == 0 || *pStatus & flag )
4847 return AGTIAPI_SUCCESS;
4849 return AGTIAPI_FAIL;
4852 agtiapi_DelayMSec( msecsPerTick );
4854 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, _flags );
4855 tiCOMTimerTick( &pCard->tiRoot );
4857 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
4858 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, _flags );
4863 if( *pStatus & TASK_MANAGEMENT )
4864 *pStatus |= TASK_TIMEOUT;
4866 return AGTIAPI_FAIL;
4870 /******************************************************************************
4871 agtiapi_DiscoverTgt()
4874 Discover available devices
4876 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
4879 ******************************************************************************/
4880 STATIC void agtiapi_DiscoverTgt(struct agtiapi_softc *pCard)
4883 ag_portal_data_t *pPortalData;
4886 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: start\n");
4887 AGTIAPI_FLOW("agtiapi_DiscoverTgt\n");
4888 AGTIAPI_INIT("agtiapi_DiscoverTgt\n");
4890 pPortalData = pCard->pPortalData;
4891 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4893 pCard->flags &= ~AGTIAPI_CB_DONE;
4894 if (!(PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4896 if (pCard->flags & AGTIAPI_INIT_TIME)
4898 if (agtiapi_CheckCB(pCard, 5000, AGTIAPI_PORT_DISC_READY,
4899 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4901 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Port %p / %d not ready for "
4903 pPortalData, count );
4905 * There is no need to spend time on discovering device
4906 * if port is not ready to do so.
4915 AGTIAPI_FLOW( "agtiapi_DiscoverTgt: Portal %p DiscoverTargets starts\n",
4917 AGTIAPI_INIT_DELAY(1000);
4919 pCard->flags &= ~AGTIAPI_CB_DONE;
4920 if (tiINIDiscoverTargets(&pCard->tiRoot,
4921 &pPortalData->portalInfo.tiPortalContext,
4922 FORCE_PERSISTENT_ASSIGN_MASK)
4924 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: tiINIDiscoverTargets ERROR\n");
4927 * Should wait till discovery completion to start
4928 * next portal. However, lower layer have issue on
4929 * multi-portal case under Linux.
4933 pPortalData = pCard->pPortalData;
4934 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4936 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4938 if (agtiapi_CheckCB(pCard, 20000, AGTIAPI_DISC_COMPLETE,
4939 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4941 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE))
4942 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover complete, "
4945 PORTAL_STATUS(pPortalData) );
4947 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover is not "
4948 "completed, status 0x%x\n",
4949 pPortalData, PORTAL_STATUS(pPortalData) );
4952 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %d discover target "
4959 * Calling to get device handle should be done per portal based
4960 * and better right after discovery is done. However, lower iscsi
4961 * layer may not returns discovery complete in correct sequence or we
4962 * ran out time. We get device handle for all portals together
4963 * after discovery is done or timed out.
4965 pPortalData = pCard->pPortalData;
4966 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4969 * We try to get device handle no matter
4970 * if discovery is completed or not.
4972 if (PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)
4976 for (i = 0; i < AGTIAPI_GET_DEV_MAX; i++)
4978 if (agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 0, 0) != 0)
4980 agtiapi_DelayMSec(AGTIAPI_EXTRA_DELAY);
4983 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE) ||
4984 (pCard->tgtCount > 0))
4985 PORTAL_STATUS(pPortalData) |= ( AGTIAPI_DISC_DONE |
4986 AGTIAPI_PORT_LINK_UP );
4996 /******************************************************************************
5000 Prepares CCB including DMA map.
5002 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5003 ccb_hdr_t *hdr (IN) Pointer to the CCB header
5005 U32 max_ccb (IN) count
5009 ******************************************************************************/
5010 STATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard,
5024 AGTIAPI_PRINTK("agtiapi_PrepCCBs: start\n");
5025 offset = tid * AGTIAPI_CCB_PER_DEVICE;
5026 nsegs = AGTIAPI_NSEGS;
5027 sgl_sz = sizeof(tiSgl_t) * nsegs;
5028 AGTIAPI_PRINTK( "agtiapi_PrepCCBs: tid %d offset %d nsegs %d sizeof(tiSgl_t) "
5029 "%lu, max_ccb %d\n",
5036 ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
5037 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5039 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after cache line\n");
5041 memset((void *)hdr, 0, size);
5042 hdr->next = pCard->ccbAllocList;
5043 pCard->ccbAllocList = hdr;
5045 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after memset\n");
5047 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5049 for (i = 0; i < max_ccb; i++, pccb = (ccb_t*)((char*)pccb + ccb_sz))
5051 pccb->tiIORequest.osData = (void *)pccb;
5054 * Initially put all the ccbs on the free list
5055 * in addition to chainlist.
5056 * ccbChainList is a list of all available ccbs
5057 * (free/active everything)
5059 pccb->pccbChainNext = (pccb_t)pCard->ccbChainList;
5060 pccb->pccbNext = (pccb_t)pCard->ccbFreeList;
5062 pCard->ccbChainList = (caddr_t *)pccb;
5063 pCard->ccbFreeList = (caddr_t *)pccb;
5066 #ifdef AGTIAPI_ALIGN_CHECK
5068 AGTIAPI_PRINTK("pccb = %p\n", pccb);
5069 if (pccb->devHandle & 0x63)
5070 AGTIAPI_PRINTK("devHandle addr = %p\n", &pccb->devHandle);
5071 if (&pccb->lun & 0x63)
5072 AGTIAPI_PRINTK("lun addr = %p\n", &pccb->lun);
5073 if (&pccb->targetId & 0x63)
5074 AGTIAPI_PRINTK("tig addr = %p\n", &pccb->targetId);
5075 if (&pccb->ccbStatus & 0x63)
5076 AGTIAPI_PRINTK("ccbStatus addr = %p\n", &pccb->ccbStatus);
5077 if (&pccb->scsiStatus & 0x63)
5078 AGTIAPI_PRINTK("scsiStatus addr = %p\n", &pccb->scsiStatus);
5079 if (&pccb->dataLen & 0x63)
5080 AGTIAPI_PRINTK("dataLen addr = %p\n", &pccb->dataLen);
5081 if (&pccb->senseLen & 0x63)
5082 AGTIAPI_PRINTK("senseLen addr = %p\n", &pccb->senseLen);
5083 if (&pccb->numSgElements & 0x63)
5084 AGTIAPI_PRINTK("numSgElements addr = %p\n", &pccb->numSgElements);
5085 if (&pccb->retryCount & 0x63)
5086 AGTIAPI_PRINTK("retry cnt addr = %p\n", &pccb->retryCount);
5087 if (&pccb->flags & 0x63)
5088 AGTIAPI_PRINTK("flag addr = %p\n", &pccb->flags);
5089 if (&pccb->pSenseData & 0x63)
5090 AGTIAPI_PRINTK("senseData addr = %p\n", &pccb->pSenseData);
5091 if (&pccb->sgList[0] & 0x63)
5092 AGTIAPI_PRINTK("SgList 0 = %p\n", &pccb->sgList[0]);
5093 if (&pccb->pccbNext & 0x63)
5094 AGTIAPI_PRINTK("ccb next = %p\n", &pccb->pccbNext);
5095 if (&pccb->pccbChainNext & 0x63)
5096 AGTIAPI_PRINTK("ccbChainNext = %p\n", &pccb->pccbChainNext);
5097 if (&pccb->cmd & 0x63)
5098 AGTIAPI_PRINTK("command = %p\n", &pccb->cmd);
5099 if( &pccb->startTime & 0x63 )
5100 AGTIAPI_PRINTK( "startTime = %p\n", &pccb->startTime );
5101 if (&pccb->tiIORequest & 0x63)
5102 AGTIAPI_PRINTK("tiIOReq addr = %p\n", &pccb->tiIORequest);
5103 if (&pccb->tdIOReqBody & 0x63)
5104 AGTIAPI_PRINTK("tdIORequestBody addr = %p\n", &pccb->tdIOReqBody);
5105 if (&pccb->tiSuperScsiRequest & 0x63)
5106 AGTIAPI_PRINTK( "InitiatorExchange addr = %p\n",
5107 &pccb->tiSuperScsiRequest );
5109 if ( bus_dmamap_create( pCard->buffer_dmat, 0, &pccb->CCB_dmamap ) !=
5112 AGTIAPI_PRINTK("agtiapi_PrepCCBs: can't create dma\n");
5115 /* assigns tiSgl_t memory to pccb */
5116 pccb->sgList = (void*)((U64)pCard->tisgl_mem + ((i + offset) * sgl_sz));
5117 pccb->tisgl_busaddr = pCard->tisgl_busaddr + ((i + offset) * sgl_sz);
5119 pccb->pccbIO = NULL;
5120 pccb->startTime = 0;
5123 #ifdef AGTIAPI_ALIGN_CHECK
5124 AGTIAPI_PRINTK("ccb size = %d / %d\n", sizeof(ccb_t), ccb_sz);
5129 /******************************************************************************
5133 Create and initialize per card based CCB pool.
5135 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5136 int tgtCount (IN) Count
5138 Total number of ccb allocated
5140 ******************************************************************************/
5141 STATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid)
5144 U32 max_ccb, size, ccb_sz, hdr_sz;
5145 int no_allocs = 0, i;
5146 ccb_hdr_t *hdr = NULL;
5148 AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n");
5149 AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5150 AGTIAPI_FLOW("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5152 #ifndef HOTPLUG_SUPPORT
5153 if (pCard->tgtCount > AGSA_MAX_INBOUND_Q)
5156 if (tgtCount > AGSA_MAX_INBOUND_Q)
5157 tgtCount = AGSA_MAX_INBOUND_Q;
5160 max_ccb = tgtCount * AGTIAPI_CCB_PER_DEVICE;// / 4; // TBR
5161 ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
5162 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5163 size = ccb_sz * max_ccb + hdr_sz;
5165 for (i = 0; i < (1 << no_allocs); i++)
5167 hdr = (ccb_hdr_t*)malloc( size, M_PMC_MCCB, M_NOWAIT );
5170 panic( "agtiapi_InitCCBs: bug!!!\n" );
5174 agtiapi_PrepCCBs( pCard, hdr, size, max_ccb, tid );
5183 #ifdef LINUX_PERBI_SUPPORT
5184 /******************************************************************************
5185 agtiapi_GetWWNMappings()
5188 Get the mappings from target IDs to WWNs, if any.
5189 Store them in the WWN_list array, indexed by target ID.
5190 Leave the devListIndex field blank; this will be filled-in later.
5192 ag_card_t *pCard (IN) Pointer to HBA data structure
5193 ag_mapping_t *pMapList (IN) Pointer to mapped device list
5195 Note: The boot command line parameters are used to load the
5196 mapping information, which is contained in the system
5198 ******************************************************************************/
5199 STATIC void agtiapi_GetWWNMappings( struct agtiapi_softc *pCard,
5200 ag_mapping_t *pMapList )
5204 ag_tgt_map_t *pWWNList;
5205 ag_slr_map_t *pSLRList;
5206 ag_device_t *pDevList;
5209 panic( "agtiapi_GetWWNMappings: no pCard \n" );
5211 AGTIAPI_PRINTK( "agtiapi_GetWWNMappings: start\n" );
5213 pWWNList = pCard->pWWNList;
5214 pSLRList = pCard->pSLRList;
5215 pDevList = pCard->pDevList;
5216 pCard->numTgtHardMapped = 0;
5217 devDisc = pCard->devDiscover;
5219 pWWNList[devDisc-1].devListIndex = maxTargets;
5220 pSLRList[devDisc-1].localeNameLen = -2;
5221 pSLRList[devDisc-1].remoteNameLen = -2;
5222 pDevList[devDisc-1].targetId = maxTargets;
5225 * Get the mappings from holding area which contains
5226 * the input of the system file and store them
5227 * in the WWN_list array, indexed by target ID.
5229 for ( lIdx = 0; lIdx < devDisc - 1; lIdx++) {
5230 pWWNList[lIdx].flags = 0;
5231 pWWNList[lIdx].devListIndex = maxTargets;
5232 pSLRList[lIdx].localeNameLen = -1;
5233 pSLRList[lIdx].remoteNameLen = -1;
5236 // this is where we would propagate values fed to pMapList
5238 } /* agtiapi_GetWWNMappings */
5243 /******************************************************************************
5244 agtiapi_FindWWNListNext()
5246 finds first available new (unused) wwn list entry
5249 ag_tgt_map_t *pWWNList Pointer to head of wwn list
5250 int lstMax Number of entries in WWNList
5252 index into WWNList indicating available entry space;
5253 if available entry space is not found, return negative value
5254 ******************************************************************************/
5255 STATIC int agtiapi_FindWWNListNext( ag_tgt_map_t *pWWNList, int lstMax )
5259 for ( lLstIdx = 0; lLstIdx < lstMax; lLstIdx++ )
5261 if ( pWWNList[lLstIdx].devListIndex == lstMax &&
5262 pWWNList[lLstIdx].targetLen == 0 )
5264 AGTIAPI_PRINTK( "agtiapi_FindWWNListNext: %d %d %d %d v. %d\n",
5266 pWWNList[lLstIdx].devListIndex,
5267 pWWNList[lLstIdx].targetLen,
5268 pWWNList[lLstIdx].portId,
5277 /******************************************************************************
5278 agtiapi_GetDevHandle()
5281 Get device handle. Handles will be placed in the
5282 devlist array with same order as TargetList provided and
5283 will be mapped to a scsi target id and registered to OS later.
5285 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5286 ag_portal_info_t *pPortalInfo (IN) Pointer to the portal data structure
5287 U32 eType (IN) Port event
5288 U32 eStatus (IN) Port event status
5290 Number of device handle slot present
5292 The sequence of device handle will match the sequence of taregt list
5293 ******************************************************************************/
5294 STATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard,
5295 ag_portal_info_t *pPortalInfo,
5299 ag_device_t *pDevice;
5300 // tiDeviceHandle_t *agDev[pCard->devDiscover];
5301 tiDeviceHandle_t **agDev;
5302 int devIdx, szdv, devTotal, cmpsetRtn;
5303 int lDevIndex = 0, lRunScanFlag = FALSE;
5305 tiPortInfo_t portInfT;
5306 ag_device_t lTmpDevice;
5307 ag_tgt_map_t *pWWNList;
5308 ag_slr_map_t *pSLRList;
5313 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: start\n" );
5314 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: pCard->devDiscover %d / tgtCt %d\n",
5315 pCard->devDiscover, pCard->tgtCount );
5316 AGTIAPI_FLOW( "agtiapi_GetDevHandle: portalInfo %p\n", pPortalInfo );
5317 AGTIAPI_INIT_DELAY( 1000 );
5319 agDev = (tiDeviceHandle_t **) malloc( sizeof(tiDeviceHandle_t *) * pCard->devDiscover,
5320 M_PMC_MDEV, M_ZERO | M_NOWAIT);
5323 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc agDev[]\n" );
5327 lDevFlags = (int *) malloc( sizeof(int) * pCard->devDiscover,
5328 M_PMC_MFLG, M_ZERO | M_NOWAIT );
5329 if (lDevFlags == NULL)
5331 free((caddr_t)agDev, M_PMC_MDEV);
5332 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc lDevFlags[]\n" );
5336 pWWNList = pCard->pWWNList;
5337 pSLRList = pCard->pSLRList;
5339 memset( (void *)agDev, 0, sizeof(void *) * pCard->devDiscover );
5340 memset( lDevFlags, 0, sizeof(int) * pCard->devDiscover );
5342 // get device handles
5343 devTotal = tiINIGetDeviceHandles( &pCard->tiRoot,
5344 &pPortalInfo->tiPortalContext,
5345 (tiDeviceHandle_t **)agDev,
5346 pCard->devDiscover );
5348 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: portalInfo %p port id %d event %u "
5349 "status %u card %p pCard->devDiscover %d devTotal %d "
5350 "pPortalInfo->devTotal %d pPortalInfo->devPrev %d "
5351 "AGTIAPI_INIT_TIME %x\n",
5352 pPortalInfo, pPortalInfo->portID, eType, eStatus, pCard,
5353 pCard->devDiscover, devTotal, pPortalInfo->devTotal,
5354 pPortalInfo->devPrev,
5355 pCard->flags & AGTIAPI_INIT_TIME );
5357 // reset devTotal from any previous runs of this
5358 pPortalInfo->devPrev = devTotal;
5359 pPortalInfo->devTotal = devTotal;
5361 AG_LIST_LOCK( &pCard->devListLock );
5363 if ( tiCOMGetPortInfo( &pCard->tiRoot,
5364 &pPortalInfo->tiPortalContext,
5368 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: tiCOMGetPortInfo did not succeed. \n" );
5372 szdv = sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
5373 if (szdv > pCard->devDiscover)
5375 szdv = pCard->devDiscover;
5378 // reconstructing dev list via comparison of wwn
5380 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5382 if ( agDev[devIdx] != NULL )
5384 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n",
5385 // devIdx, agDev[devIdx] );
5387 // pack temp device structure for tiINIGetDeviceInfo call
5388 pDevice = &lTmpDevice;
5389 pDevice->devType = DIRECT_DEVICE;
5390 pDevice->pCard = (void *)pCard;
5391 pDevice->flags = ACTIVE;
5392 pDevice->pPortalInfo = pPortalInfo;
5393 pDevice->pDevHandle = agDev[devIdx];
5394 pDevice->qbusy = agFALSE;
5396 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: idx %d / %d : %p \n",
5397 // devIdx, pCard->devDiscover, agDev[devIdx] );
5399 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx],
5400 &pDevice->devInfo );
5402 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: wwn sizes %ld %d/%d ",
5403 // sizeof(pDevice->targetName),
5404 // pDevice->devInfo.osAddress1,
5405 // pDevice->devInfo.osAddress2 );
5408 wwnprintk( (unsigned char*)pDevice->targetName, pDevice->targetLen );
5410 for ( lDevIndex = 0; lDevIndex < szdv; lDevIndex++ ) // match w/ wwn list
5412 if ( (pCard->pDevList[lDevIndex].portalId == pPortalInfo->portID) &&
5413 pDevice->targetLen > 0 &&
5414 portInfT.localNameLen > 0 &&
5415 portInfT.remoteNameLen > 0 &&
5416 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen > 0 &&
5417 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen > 0 &&
5418 ( portInfT.localNameLen ==
5419 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen ) &&
5420 ( portInfT.remoteNameLen ==
5421 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen ) &&
5422 memcmp( pWWNList[lDevIndex].targetName, pDevice->targetName,
5423 pDevice->targetLen ) == 0 &&
5424 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].localeName,
5426 portInfT.localNameLen ) == 0 &&
5427 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteName,
5428 portInfT.remoteName,
5429 portInfT.remoteNameLen ) == 0 )
5431 AGTIAPI_PRINTK( " pWWNList match @ %d/%d/%d \n",
5432 lDevIndex, devIdx, pPortalInfo->portID );
5434 if ( (pCard->pDevList[lDevIndex].targetId == lDevIndex) &&
5435 ( pPortalInfo->pDevList[lDevIndex] ==
5436 &pCard->pDevList[lDevIndex] ) ) // active
5439 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: dev in use %d of %d/%d\n",
5440 lDevIndex, devTotal, pPortalInfo->portID );
5441 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev handle
5442 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5443 lReadRm = atomic_readandclear_32( &pWWNList[lDevIndex].devRemoved );
5444 if ( lReadRm ) // cleared timeout, now remove count for timer
5446 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: clear timer count for"
5448 lDevIndex, pPortalInfo->portID );
5449 atomic_subtract_16( &pCard->rmChkCt, 1 );
5450 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5453 callout_stop( &pCard->devRmTimer );
5459 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: goin fresh on %d of %d/%d\n",
5460 lDevIndex, // reactivate now
5461 devTotal, pPortalInfo->portID );
5463 // pDevice going fresh
5464 lRunScanFlag = TRUE; // scan and clear outstanding removals
5466 // pCard->tgtCount++; ##
5467 pDevice->targetId = lDevIndex;
5468 pDevice->portalId = pPortalInfo->portID;
5470 memcpy ( &pCard->pDevList[lDevIndex], pDevice, sizeof(lTmpDevice) );
5471 agDev[devIdx]->osData = (void *)&pCard->pDevList[lDevIndex];
5472 if ( agtiapi_InitCCBs( pCard, 1, pDevice->targetId ) == 0 )
5474 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: InitCCB "
5475 "tgtCnt %d ERROR!\n", pCard->tgtCount );
5476 AG_LIST_UNLOCK( &pCard->devListLock );
5477 free((caddr_t)lDevFlags, M_PMC_MFLG);
5478 free((caddr_t)agDev, M_PMC_MDEV);
5481 pPortalInfo->pDevList[lDevIndex] = &pCard->pDevList[lDevIndex]; // (ag_device_t *)
5482 if ( 0 == lDevFlags[devIdx] )
5484 pPortalInfo->devTotal++;
5485 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5486 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5490 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: odd dev handle "
5491 "status inspect %d %d %d\n",
5492 lDevFlags[devIdx], devIdx, lDevIndex );
5493 pPortalInfo->devTotal++;
5494 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5495 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5501 // end: match this wwn with previous wwn list
5503 // we have an agDev entry, but no pWWNList target for it
5504 if ( !(lDevFlags[devIdx] & DPMC_LEANFLAG_AGDEVUSED) )
5505 { // flag dev handle not accounted for yet
5506 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOWWNLIST;
5507 // later, get an empty pDevice and map this agDev.
5508 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: devIdx %d flags 0x%x, %d\n",
5509 // devIdx, lDevFlags[devIdx], (lDevFlags[devIdx] & 8) );
5514 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOAGDEVYT; // known empty agDev handle
5518 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: all WWN all the time, "
5519 // "devLstIdx/flags/(WWNL)portId ... \n" );
5520 // review device list for further action needed
5521 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5523 if ( lDevFlags[devIdx] & DPMC_LEANFLAG_NOWWNLIST ) // new target, register
5525 int lNextDyad; // find next available dyad entry
5527 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: register new target, "
5528 "devIdx %d -- %d \n", devIdx, pCard->devDiscover );
5529 lRunScanFlag = TRUE; // scan and clear outstanding removals
5530 for ( lNextDyad = 0; lNextDyad < pCard->devDiscover; lNextDyad++ )
5532 if ( pSLRList[lNextDyad].localeNameLen < 0 &&
5533 pSLRList[lNextDyad].remoteNameLen < 0 )
5537 if ( lNextDyad == pCard->devDiscover )
5539 printf( "agtiapi_GetDevHandle: failed to find available SAS LR\n" );
5540 AG_LIST_UNLOCK( &pCard->devListLock );
5541 free( (caddr_t)lDevFlags, M_PMC_MFLG );
5542 free( (caddr_t)agDev, M_PMC_MDEV );
5545 // index of new entry
5546 lDevIndex = agtiapi_FindWWNListNext( pWWNList, pCard->devDiscover );
5547 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: listIdx new target %d of %d/%d\n",
5548 lDevIndex, devTotal, pPortalInfo->portID );
5549 if ( 0 > lDevIndex )
5551 printf( "agtiapi_GetDevHandle: WARNING -- WWNList exhausted.\n" );
5555 pDevice = &pCard->pDevList[lDevIndex];
5557 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], &pDevice->devInfo );
5559 agtiapi_InitCCBs( pCard, 1, lDevIndex );
5561 pDevice->pCard = (void *)pCard;
5562 pDevice->devType = DIRECT_DEVICE;
5564 // begin to populate new WWNList entry
5565 memcpy( pWWNList[lDevIndex].targetName, pDevice->targetName, pDevice->targetLen );
5566 pWWNList[lDevIndex].targetLen = pDevice->targetLen;
5568 pWWNList[lDevIndex].flags = SOFT_MAPPED;
5569 pWWNList[lDevIndex].portId = pPortalInfo->portID;
5570 pWWNList[lDevIndex].devListIndex = lDevIndex;
5571 pWWNList[lDevIndex].sasLrIdx = lNextDyad;
5573 pSLRList[lNextDyad].localeNameLen = portInfT.localNameLen;
5574 pSLRList[lNextDyad].remoteNameLen = portInfT.remoteNameLen;
5575 memcpy( pSLRList[lNextDyad].localeName, portInfT.localName, portInfT.localNameLen );
5576 memcpy( pSLRList[lNextDyad].remoteName, portInfT.remoteName, portInfT.remoteNameLen );
5577 // end of populating new WWNList entry
5579 pDevice->targetId = lDevIndex;
5581 pDevice->flags = ACTIVE;
5582 pDevice->CCBCount = 0;
5583 pDevice->pDevHandle = agDev[devIdx];
5584 agDev[devIdx]->osData = (void*)pDevice;
5586 pDevice->pPortalInfo = pPortalInfo;
5587 pDevice->portalId = pPortalInfo->portID;
5588 pPortalInfo->pDevList[lDevIndex] = (void*)pDevice;
5589 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // mark pDevice slot used
5592 if ( (pCard->pDevList[devIdx].portalId == pPortalInfo->portID) &&
5593 !(lDevFlags[devIdx] & DPMC_LEANFLAG_PDEVSUSED) ) // pDevice not used
5595 pDevice = &pCard->pDevList[devIdx];
5596 //pDevice->flags &= ~ACTIVE;
5597 if ( ( pDevice->pDevHandle != NULL ||
5598 pPortalInfo->pDevList[devIdx] != NULL ) )
5600 atomic_add_16( &pCard->rmChkCt, 1 ); // show count of lost device
5602 if (FALSE == lRunScanFlag)
5605 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: targ dropped out %d of %d/%d\n",
5606 devIdx, devTotal, pPortalInfo->portID );
5607 // if ( 0 == pWWNList[devIdx].devRemoved ) '.devRemoved = 5;
5608 cmpsetRtn = atomic_cmpset_32( &pWWNList[devIdx].devRemoved, 0, 5 );
5609 if ( 0 == cmpsetRtn )
5611 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: target %d timer already set\n",
5616 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5619 // else ... scan coming soon enough anyway, ignore timer for dropout
5622 } // end of for ( devIdx = 0; ...
5624 AG_LIST_UNLOCK( &pCard->devListLock );
5626 free((caddr_t)lDevFlags, M_PMC_MFLG);
5627 free((caddr_t)agDev, M_PMC_MDEV);
5629 if ( TRUE == lRunScanFlag )
5630 agtiapi_clrRmScan( pCard );
5633 } // end agtiapi_GetDevHandle
5635 /******************************************************************************
5641 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5644 ******************************************************************************/
5645 static void agtiapi_scan(struct agtiapi_softc *pmcsc)
5650 AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo);
5652 bus = cam_sim_path(pmcsc->sim);
5654 tid = CAM_TARGET_WILDCARD;
5655 lun = CAM_LUN_WILDCARD;
5657 mtx_lock(&(pmcsc->pCardInfo->pmIOLock));
5658 ccb = xpt_alloc_ccb_nowait();
5661 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5664 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
5665 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
5667 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5672 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5673 pmcsc->dev_scan = agTRUE;
5678 /******************************************************************************
5679 agtiapi_DeQueueCCB()
5682 Remove a ccb from a queue
5684 struct agtiapi_softc *pCard (IN) Pointer to the card structure
5685 pccb_t *phead (IN) Pointer to a head of ccb queue
5686 ccb_t *pccd (IN) Pointer to the ccb to be processed
5688 AGTIAPI_SUCCESS - the ccb is removed from queue
5689 AGTIAPI_FAIL - the ccb is not found from queue
5691 ******************************************************************************/
5693 agtiapi_DeQueueCCB(struct agtiapi_softc *pCard, pccb_t *phead, pccb_t *ptail,
5694 #ifdef AGTIAPI_LOCAL_LOCK
5700 U32 status = AGTIAPI_FAIL;
5702 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5704 if (pccb == NULL || *phead == NULL)
5706 return AGTIAPI_FAIL;
5709 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5710 AG_LOCAL_LOCK(lock);
5714 *phead = (*phead)->pccbNext;
5720 pccb->pccbNext = NULL;
5721 status = AGTIAPI_SUCCESS;
5726 while (pccb_curr->pccbNext != NULL)
5728 if (pccb_curr->pccbNext == pccb)
5730 pccb_curr->pccbNext = pccb->pccbNext;
5731 pccb->pccbNext = NULL;
5737 pccb->pccbNext = NULL;
5738 status = AGTIAPI_SUCCESS;
5741 pccb_curr = pccb_curr->pccbNext;
5744 AG_LOCAL_UNLOCK(lock);
5750 STATIC void wwnprintk( unsigned char *name, int len )
5754 for (i = 0; i < len; i++, name++)
5755 AGTIAPI_PRINTK("%02x", *name);
5756 AGTIAPI_PRINTK("\n");
5759 * SAS and SATA behind expander has 8 byte long unique address.
5760 * However, direct connect SATA device use 512 byte unique device id.
5761 * SPC uses remoteName to indicate length of ID and remoteAddress for the
5762 * address of memory that holding ID.
5764 STATIC int wwncpy( ag_device_t *pDevice )
5768 if (sizeof(pDevice->targetName) >= pDevice->devInfo.osAddress1 +
5769 pDevice->devInfo.osAddress2)
5771 memcpy(pDevice->targetName,
5772 pDevice->devInfo.remoteName,
5773 pDevice->devInfo.osAddress1);
5774 memcpy(pDevice->targetName + pDevice->devInfo.osAddress1,
5775 pDevice->devInfo.remoteAddress,
5776 pDevice->devInfo.osAddress2);
5777 pDevice->targetLen = pDevice->devInfo.osAddress1 +
5778 pDevice->devInfo.osAddress2;
5779 rc = pDevice->targetLen;
5783 AGTIAPI_PRINTK("WWN wrong size: %d + %d ERROR\n",
5784 pDevice->devInfo.osAddress1, pDevice->devInfo.osAddress2);
5791 /******************************************************************************
5792 agtiapi_ReleaseCCBs()
5795 Free all allocated CCB memories for the Host Adapter.
5797 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5800 ******************************************************************************/
5801 STATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard )
5808 AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" );
5810 #if ( defined AGTIAPI_TEST_DPL || defined AGTIAPI_TEST_EPL )
5814 #ifdef AGTIAPI_TEST_DPL
5815 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5816 pccb = pccb->pccbChainNext)
5818 if(pccb->dplPtr && pccb->dplDma)
5819 pci_pool_free(pCard->dpl_ctx_pool, pccb->dplPtr, pccb->dplDma);
5823 #ifdef AGTIAPI_TEST_EPL
5824 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5825 pccb = pccb->pccbChainNext)
5827 if(pccb->epl_ptr && pccb->epl_dma_ptr)
5829 pCard->epl_ctx_pool,
5836 while ((hdr = pCard->ccbAllocList) != NULL)
5838 pCard->ccbAllocList = hdr->next;
5839 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5840 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5841 if (pCard->buffer_dmat != NULL && pccb->CCB_dmamap != NULL)
5843 bus_dmamap_destroy(pCard->buffer_dmat, pccb->CCB_dmamap);
5845 free(hdr, M_PMC_MCCB);
5847 pCard->ccbAllocList = NULL;
5853 /******************************************************************************
5857 Timer tick for tisa common layer
5859 void *data (IN) Pointer to the HBA data structure
5862 ******************************************************************************/
5863 STATIC void agtiapi_TITimer( void *data )
5867 struct agtiapi_softc *pCard;
5869 pCard = (struct agtiapi_softc *)data;
5871 // AGTIAPI_PRINTK("agtiapi_TITimer: start\n");
5872 AG_GLOBAL_ARG( flags );
5874 next_tick = pCard->pCardInfo->tiRscInfo.tiLoLevelResource.
5875 loLevelOption.usecsPerTick / USEC_PER_TICK;
5877 if( next_tick == 0 ) /* no timer required */
5879 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
5880 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5882 tiCOMTimerTick( &pCard->tiRoot ); /* tisa common layer timer tick */
5884 //add for polling mode
5886 if( agtiapi_polling_mode )
5887 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
5889 callout_reset( &pCard->OS_timer, next_tick, agtiapi_TITimer, pCard );
5891 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
5895 /******************************************************************************
5899 Clears device list entries scheduled for timeout and calls scan
5901 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5902 ******************************************************************************/
5903 STATIC void agtiapi_clrRmScan( struct agtiapi_softc *pCard )
5905 ag_tgt_map_t *pWWNList;
5906 ag_portal_info_t *pPortalInfo;
5907 ag_portal_data_t *pPortalData;
5912 pWWNList = pCard->pWWNList;
5914 AGTIAPI_PRINTK( "agtiapi_clrRmScan: start\n" );
5916 AG_LIST_LOCK( &pCard->devListLock );
5918 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5920 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5923 break; // trim to who cares
5926 lReadRm = atomic_readandclear_32( &pWWNList[lIdx].devRemoved );
5929 pCard->pDevList[lIdx].flags &= ~ACTIVE;
5930 pCard->pDevList[lIdx].pDevHandle = NULL;
5932 pPortalData = &pCard->pPortalData[pWWNList[lIdx].portId];
5933 pPortalInfo = &pPortalData->portalInfo;
5934 pPortalInfo->pDevList[lIdx] = NULL;
5935 AGTIAPI_PRINTK( "agtiapi_clrRmScan: cleared dev %d at port %d\n",
5936 lIdx, pWWNList[lIdx].portId );
5937 atomic_subtract_16( &pCard->rmChkCt, 1 );
5940 AG_LIST_UNLOCK( &pCard->devListLock );
5942 agtiapi_scan( pCard );
5946 /******************************************************************************
5947 agtiapi_devRmCheck()
5950 Timer tick to check for timeout on missing targets
5951 Removes device list entry when timeout is reached
5953 void *data (IN) Pointer to the HBA data structure
5954 ******************************************************************************/
5955 STATIC void agtiapi_devRmCheck( void *data )
5957 struct agtiapi_softc *pCard;
5958 ag_tgt_map_t *pWWNList;
5959 int lIdx, cmpsetRtn, lRunScanFlag = FALSE;
5963 pCard = ( struct agtiapi_softc * )data;
5966 if ( callout_pending( &pCard->devRmTimer ) ) // callout was reset
5970 if ( !callout_active( &pCard->devRmTimer ) ) // callout was stopped
5974 callout_deactivate( &pCard->devRmTimer );
5976 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5978 return; // implicit timer clear
5981 pWWNList = pCard->pWWNList;
5983 AG_LIST_LOCK( &pCard->devListLock );
5984 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5987 if ( callout_pending(&pCard->devRmTimer) == FALSE )
5989 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5993 AG_LIST_UNLOCK( &pCard->devListLock );
5997 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5999 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
6002 break; // if handled somewhere else, get out
6005 lReadRm = atomic_load_acq_32( &pWWNList[lIdx].devRemoved );
6008 if ( 1 == lReadRm ) // timed out
6009 { // no decrement of devRemoved as way to leave a clrRmScan marker
6010 lRunScanFlag = TRUE; // other devRemoved values are about to get wiped
6011 break; // ... so bail out
6015 AGTIAPI_PRINTK( "agtiapi_devRmCheck: counting down dev %d @ %d; %d\n",
6016 lIdx, lReadRm, lReadCt );
6017 cmpsetRtn = atomic_cmpset_32( &pWWNList[lIdx].devRemoved,
6020 if ( 0 == cmpsetRtn )
6022 printf( "agtiapi_devRmCheck: %d decrement already handled\n",
6028 AG_LIST_UNLOCK( &pCard->devListLock );
6030 if ( TRUE == lRunScanFlag )
6031 agtiapi_clrRmScan( pCard );
6035 AG_LIST_UNLOCK( &pCard->devListLock );
6042 static void agtiapi_cam_poll( struct cam_sim *asim )
6047 /*****************************************************************************
6051 Hard or soft reset on the controller and resend any
6052 outstanding requests if needed.
6054 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
6055 unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
6057 AGTIAPI_SUCCESS - reset successful
6058 AGTIAPI_FAIL - reset failed
6060 *****************************************************************************/
6061 U32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags )
6063 ag_device_t *pDevice;
6067 ag_portal_info_t *pPortalInfo;
6068 ag_portal_data_t *pPortalData;
6072 if( pCard->flags & AGTIAPI_RESET ) {
6073 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" );
6074 return AGTIAPI_FAIL;
6077 AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n",
6078 pCard->resetCount );
6080 agtiapi_LogEvent( pCard,
6081 IOCTL_EVT_SEV_INFORMATIONAL,
6085 "Reset initiator time = %d!",
6086 pCard->resetCount + 1 );
6089 pCard->flags |= AGTIAPI_RESET;
6090 pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS);
6091 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6092 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6094 agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK );
6096 for ( lIdx = 1; 3 >= lIdx; lIdx++ ) // we try reset up to 3 times
6098 if( pCard->flags & AGTIAPI_SOFT_RESET )
6100 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" );
6101 tiCOMReset( &pCard->tiRoot, tiSoftReset );
6105 AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" );
6108 lFlagVal = AGTIAPI_RESET_SUCCESS;
6109 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6110 ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags );
6111 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags );
6113 if( ret == AGTIAPI_FAIL )
6115 AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, "
6125 if ( AGTIAPI_FAIL == ret )
6127 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n",
6132 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n",
6136 if( AGTIAPI_FAIL == ret )
6138 printf( "agtiapi_ResetCard: reset ERROR\n" );
6139 pCard->flags &= ~AGTIAPI_INSTALLED;
6140 return AGTIAPI_FAIL;
6143 pCard->flags &= ~AGTIAPI_SOFT_RESET;
6145 // disable all devices
6146 pDevice = pCard->pDevList;
6147 for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ )
6149 /* if ( pDevice->flags & ACTIVE )
6151 printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx );
6153 pDevice->flags &= ~ACTIVE;
6156 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6157 if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess )
6158 printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" );
6160 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" );
6162 if( !pCard->pDevList ) { // try to get a little sanity here
6163 AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n",
6165 return AGTIAPI_FAIL;
6168 AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n",
6169 pCard->tgtCount, pCard->portCount );
6170 pCard->tgtCount = 0;
6174 pCard->flags &= ~AGTIAPI_CB_DONE;
6176 pPortalData = pCard->pPortalData;
6178 for( count = 0; count < pCard->portCount; count++ ) {
6179 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6180 pPortalInfo = &pPortalData->portalInfo;
6181 pPortalInfo->portStatus = 0;
6182 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
6183 AGTIAPI_PORT_DISC_READY |
6185 AGTIAPI_DISC_COMPLETE );
6188 sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
6189 if (szdv > pCard->devDiscover)
6191 szdv = pCard->devDiscover;
6194 for( lIdx = 0, loop = 0;
6195 lIdx < szdv && loop < pPortalInfo->devTotal;
6198 pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx];
6202 pDevice->pDevHandle = 0; // mark for availability in pCard->pDevList[]
6203 // don't erase more as the device is scheduled for removal on DPC
6205 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n",
6206 pDevice, pPortalInfo->pDevList, lIdx );
6207 pPortalInfo->devTotal = pPortalInfo->devPrev = 0;
6210 for( lIdx = 0; lIdx < maxTargets; lIdx++ )
6211 { // we reconstruct dev list later in get dev handle
6212 pPortalInfo->pDevList[lIdx] = NULL;
6215 for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ )
6217 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data "
6220 pPortalInfo->portID,
6221 &pPortalInfo->tiPortalContext );
6223 if( tiCOMPortStart( &pCard->tiRoot,
6224 pPortalInfo->portID,
6225 &pPortalInfo->tiPortalContext,
6229 printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n",
6230 pPortalInfo->portID );
6234 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n",
6235 pPortalInfo->portID );
6239 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6240 tiCOMGetPortInfo( &pCard->tiRoot,
6241 &pPortalInfo->tiPortalContext,
6242 &pPortalInfo->tiPortInfo );
6245 // ## fail case: pCard->flags &= ~AGTIAPI_INSTALLED;
6248 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags);
6250 if( !(pCard->flags & AGTIAPI_INSTALLED) ) // driver not installed !
6252 printf( "agtiapi_ResetCard: error, driver not intstalled? "
6253 "!AGTIAPI_INSTALLED \n" );
6254 return AGTIAPI_FAIL;
6257 AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount );
6260 agtiapi_LogEvent( pCard,
6261 IOCTL_EVT_SEV_INFORMATIONAL,
6265 "Reset initiator total device = %d!",
6268 pCard->resetCount++;
6270 AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" );
6271 // clear send & done queue
6272 AG_LOCAL_LOCK( &pCard->sendLock );
6273 pCard->ccbSendHead = NULL;
6274 pCard->ccbSendTail = NULL;
6275 AG_LOCAL_UNLOCK( &pCard->sendLock );
6277 AG_LOCAL_LOCK( &pCard->doneLock );
6278 pCard->ccbDoneHead = NULL;
6279 pCard->ccbDoneTail = NULL;
6280 AG_LOCAL_UNLOCK( &pCard->doneLock );
6282 // clear smp queues also
6283 AG_LOCAL_LOCK( &pCard->sendSMPLock );
6284 pCard->smpSendHead = NULL;
6285 pCard->smpSendTail = NULL;
6286 AG_LOCAL_UNLOCK( &pCard->sendSMPLock );
6288 AG_LOCAL_LOCK( &pCard->doneSMPLock );
6289 pCard->smpDoneHead = NULL;
6290 pCard->smpDoneTail = NULL;
6291 AG_LOCAL_UNLOCK( &pCard->doneSMPLock );
6293 // finished with all reset stuff, now start things back up
6294 tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE );
6295 pCard->flags |= AGTIAPI_SYS_INTR_ON;
6296 pCard->flags |= AGTIAPI_HAD_RESET;
6297 pCard->flags &= ~AGTIAPI_RESET; // ##
6298 agtiapi_StartIO( pCard );
6299 AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" );
6300 return AGTIAPI_SUCCESS;
6301 } // agtiapi_ResetCard
6304 /******************************************************************************
6305 agtiapi_ReleaseHBA()
6308 Releases all resources previously acquired to support
6309 a specific Host Adapter, including the I/O Address range,
6310 and unregisters the agtiapi Host Adapter.
6312 device_t dev (IN) - device pointer
6314 always return 0 - success
6316 ******************************************************************************/
6317 int agtiapi_ReleaseHBA( device_t dev )
6320 int thisCard = device_get_unit( dev ); // keeping get_unit call to once
6322 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
6323 struct ccb_setasync csa;
6324 struct agtiapi_softc *pCard;
6325 pCard = device_get_softc( dev );
6326 ag_card_info_t *pCardInfo = pCard->pCardInfo;
6327 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
6329 AG_GLOBAL_ARG(flags);
6331 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: start\n" );
6333 if (thisCardInst != pCardInfo)
6335 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p "
6339 panic( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p pCardInfo "
6347 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA card %p\n", pCard );
6348 pCard->flags |= AGTIAPI_SHUT_DOWN;
6352 if (pCard->flags & AGTIAPI_TIMER_ON)
6354 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6355 callout_drain( &pCard->OS_timer );
6356 callout_drain( &pCard->devRmTimer );
6357 callout_drain(&pCard->IO_timer);
6358 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6359 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: timer released\n" );
6362 #ifdef HIALEAH_ENCRYPTION
6363 //Release encryption table memory - Fix it
6364 //if(pCard->encrypt && (pCard->flags & AGTIAPI_INSTALLED))
6365 //agtiapi_CleanupEncryption(pCard);
6369 * Shutdown the channel so that chip gets frozen
6370 * and it does not do any more pci-bus accesses.
6372 if (pCard->flags & AGTIAPI_SYS_INTR_ON)
6374 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6375 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6376 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: card interrupt off\n" );
6378 if (pCard->flags & AGTIAPI_INSTALLED)
6380 tiCOMShutDown( &pCard->tiRoot );
6381 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: low layers shutdown\n" );
6385 * first release IRQ, so that we do not get any more interrupts
6388 if (pCard->flags & AGTIAPI_IRQ_REQUESTED)
6390 if (!agtiapi_intx_mode)
6393 for (i = 0; i< MAX_MSIX_NUM_VECTOR; i++)
6395 if (pCard->irq[i] != agNULL && pCard->rscID[i] != 0)
6397 bus_teardown_intr(dev, pCard->irq[i], pCard->intrcookie[i]);
6398 bus_release_resource( dev,
6404 pci_release_msi(dev);
6406 pCard->flags &= ~AGTIAPI_IRQ_REQUESTED;
6411 for (i = 0; i < MAX_MSIX_NUM_DPC; i++)
6412 tasklet_kill(&pCard->tasklet_dpc[i]);
6414 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: IRQ released\n");
6417 // release memory vs. alloc in agtiapi_alloc_ostimem; used in ostiAllocMemory
6418 if( pCard->osti_busaddr != 0 ) {
6419 bus_dmamap_unload( pCard->osti_dmat, pCard->osti_mapp );
6421 if( pCard->osti_mem != NULL ) {
6422 bus_dmamem_free( pCard->osti_dmat, pCard->osti_mem, pCard->osti_mapp );
6424 if( pCard->osti_dmat != NULL ) {
6425 bus_dma_tag_destroy( pCard->osti_dmat );
6428 /* unmap the mapped PCI memory */
6429 /* calls bus_release_resource( ,SYS_RES_MEMORY, ..) */
6430 agtiapi_ReleasePCIMem(thisCardInst);
6432 /* release all ccbs */
6433 if (pCard->ccbTotal)
6435 //calls bus_dmamap_destroy() for all pccbs
6436 agtiapi_ReleaseCCBs(pCard);
6437 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: CCB released\n");
6440 #ifdef HIALEAH_ENCRYPTION
6441 /*release encryption resources - Fix it*/
6444 /*Check that all IO's are completed */
6445 if(atomic_read (&outstanding_encrypted_io_count) > 0)
6447 printf("%s: WARNING: %d outstanding encrypted IOs !\n", __FUNCTION__, atomic_read(&outstanding_encrypted_io_count));
6449 //agtiapi_CleanupEncryptionPools(pCard);
6454 /* release device list */
6455 if( pCard->pDevList ) {
6456 free((caddr_t)pCard->pDevList, M_PMC_MDVT);
6457 pCard->pDevList = NULL;
6458 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: device list released\n");
6460 #ifdef LINUX_PERBI_SUPPORT // ## review use of PERBI
6461 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: WWN list %p \n", pCard->pWWNList );
6462 if( pCard->pWWNList ) {
6463 free( (caddr_t)pCard->pWWNList, M_PMC_MTGT );
6464 pCard->pWWNList = NULL;
6465 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: WWN list released\n");
6467 if( pCard->pSLRList ) {
6468 free( (caddr_t)pCard->pSLRList, M_PMC_MSLR );
6469 pCard->pSLRList = NULL;
6470 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: SAS Local Remote list released\n");
6474 if (pCard->pPortalData)
6476 free((caddr_t)pCard->pPortalData, M_PMC_MPRT);
6477 pCard->pPortalData = NULL;
6478 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: PortalData released\n");
6480 //calls contigfree() or free()
6481 agtiapi_MemFree(pCardInfo);
6482 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: low level resource released\n");
6484 #ifdef HOTPLUG_SUPPORT
6485 if (pCard->flags & AGTIAPI_PORT_INITIALIZED)
6487 // agtiapi_FreeDevWorkList(pCard);
6488 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: (HP dev) work resources released\n");
6493 * TBD, scsi_unregister may release wrong host data structure
6494 * which cause NULL pointer shows up.
6496 if (pCard->flags & AGTIAPI_SCSI_REGISTERED)
6498 pCard->flags &= ~AGTIAPI_SCSI_REGISTERED;
6501 #ifdef AGTIAPI_LOCAL_LOCK
6506 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
6508 for( i = 0; i < maxLocks; i++ )
6510 mtx_destroy(&pCard->STLock[i]);
6512 free(pCard->STLock, M_PMC_MSTL);
6513 pCard->STLock = NULL;
6520 /* reset agtiapi_1st_time if this is the only card */
6521 if (!ag_card_good && !agtiapi_1st_time)
6523 agtiapi_1st_time = 1;
6526 /* for tiSgl_t memeory */
6527 if (pCard->tisgl_busaddr != 0)
6529 bus_dmamap_unload(pCard->tisgl_dmat, pCard->tisgl_map);
6531 if (pCard->tisgl_mem != NULL)
6533 bus_dmamem_free(pCard->tisgl_dmat, pCard->tisgl_mem, pCard->tisgl_map);
6535 if (pCard->tisgl_dmat != NULL)
6537 bus_dma_tag_destroy(pCard->tisgl_dmat);
6540 if (pCard->buffer_dmat != agNULL)
6542 bus_dma_tag_destroy(pCard->buffer_dmat);
6545 if (pCard->sim != NULL)
6547 mtx_lock(&thisCardInst->pmIOLock);
6548 xpt_setup_ccb(&csa.ccb_h, pCard->path, 5);
6549 csa.ccb_h.func_code = XPT_SASYNC_CB;
6550 csa.event_enable = 0;
6551 csa.callback = agtiapi_async;
6552 csa.callback_arg = pCard;
6553 xpt_action((union ccb *)&csa);
6554 xpt_free_path(pCard->path);
6555 // if (pCard->ccbTotal == 0)
6556 if (pCard->ccbTotal <= thisCard)
6559 no link up so that simq has not been released.
6560 In order to remove cam, we call this.
6562 xpt_release_simq(pCard->sim, 1);
6564 xpt_bus_deregister(cam_sim_path(pCard->sim));
6565 cam_sim_free(pCard->sim, FALSE);
6566 mtx_unlock(&thisCardInst->pmIOLock);
6568 if (pCard->devq != NULL)
6570 cam_simq_free(pCard->devq);
6574 mtx_destroy( &thisCardInst->pmIOLock );
6575 mtx_destroy( &pCard->sendLock );
6576 mtx_destroy( &pCard->doneLock );
6577 mtx_destroy( &pCard->sendSMPLock );
6578 mtx_destroy( &pCard->doneSMPLock );
6579 mtx_destroy( &pCard->ccbLock );
6580 mtx_destroy( &pCard->devListLock );
6581 mtx_destroy( &pCard->OS_timer_lock );
6582 mtx_destroy( &pCard->devRmTimerLock );
6583 mtx_destroy( &pCard->memLock );
6584 mtx_destroy( &pCard->freezeLock );
6586 destroy_dev( pCard->my_cdev );
6587 memset((void *)pCardInfo, 0, sizeof(ag_card_info_t));
6592 // Called during system shutdown after sync
6593 static int agtiapi_shutdown( device_t dev )
6595 AGTIAPI_PRINTK( "agtiapi_shutdown\n" );
6599 static int agtiapi_suspend( device_t dev ) // Device suspend routine.
6601 AGTIAPI_PRINTK( "agtiapi_suspend\n" );
6605 static int agtiapi_resume( device_t dev ) // Device resume routine.
6607 AGTIAPI_PRINTK( "agtiapi_resume\n" );
6611 static device_method_t agtiapi_methods[] = { // Device interface
6612 DEVMETHOD( device_probe, agtiapi_probe ),
6613 DEVMETHOD( device_attach, agtiapi_attach ),
6614 DEVMETHOD( device_detach, agtiapi_ReleaseHBA ),
6615 DEVMETHOD( device_shutdown, agtiapi_shutdown ),
6616 DEVMETHOD( device_suspend, agtiapi_suspend ),
6617 DEVMETHOD( device_resume, agtiapi_resume ),
6621 static devclass_t pmspcv_devclass;
6623 static driver_t pmspcv_driver = {
6626 sizeof( struct agtiapi_softc )
6629 DRIVER_MODULE( pmspcv, pci, pmspcv_driver, pmspcv_devclass, 0, 0 );
6630 MODULE_DEPEND( pmspcv, cam, 1, 1, 1 );
6631 MODULE_DEPEND( pmspcv, pci, 1, 1, 1 );
6633 #include <dev/pms/freebsd/driver/common/lxosapi.c>
6634 #include <dev/pms/freebsd/driver/ini/src/osapi.c>
6635 #include <dev/pms/freebsd/driver/common/lxutil.c>
6636 #include <dev/pms/freebsd/driver/common/lxencrypt.c>