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