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