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