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