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