~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/scsi/megaraid.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*===================================================================
  2  *
  3  *                    Linux MegaRAID device driver
  4  *
  5  * Copyright 1999 American Megatrends Inc.
  6  *
  7  *              This program is free software; you can redistribute it and/or
  8  *              modify it under the terms of the GNU General Public License
  9  *              as published by the Free Software Foundation; either version
 10  *              2 of the License, or (at your option) any later version.
 11  *
 12  * Version : 1.07b
 13  * 
 14  * Description: Linux device driver for AMI MegaRAID controller
 15  *
 16  * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 490
 17  * 
 18  * History:
 19  *
 20  * Version 0.90:
 21  *     Original source contributed by Dell; integrated it into the kernel and
 22  *     cleaned up some things.  Added support for 438/466 controllers.
 23  *
 24  * Version 0.91:
 25  *     Aligned mailbox area on 16-byte boundry.
 26  *     Added schedule() at the end to properly clean up.
 27  *     Made improvements for conformity to linux driver standards.
 28  *
 29  * Version 0.92:
 30  *     Added support for 2.1 kernels.
 31  *         Reads from pci_dev struct, so it's not dependent on pcibios.
 32  *         Added some missing virt_to_bus() translations.
 33  *     Added support for SMP.
 34  *         Changed global cli()'s to spinlocks for 2.1, and simulated
 35  *          spinlocks for 2.0.
 36  *     Removed setting of SA_INTERRUPT flag when requesting Irq.
 37  *
 38  * Version 0.92ac:
 39  *     Small changes to the comments/formatting. Plus a couple of
 40  *      added notes. Returned to the authors. No actual code changes
 41  *      save printk levels.
 42  *     8 Oct 98        Alan Cox <alan.cox@linux.org>
 43  *
 44  *     Merged with 2.1.131 source tree.
 45  *     12 Dec 98       K. Baranowski <kgb@knm.org.pl>                          
 46  *
 47  * Version 0.93:
 48  *     Added support for vendor specific ioctl commands (0x80+xxh)
 49  *     Changed some fields in MEGARAID struct to better values.
 50  *     Added signature check for Rp controllers under 2.0 kernels
 51  *     Changed busy-wait loop to be time-based
 52  *     Fixed SMP race condition in isr
 53  *     Added kfree (sgList) on release
 54  *     Added #include linux/version.h to megaraid.h for hosts.h
 55  *     Changed max_id to represent max logical drives instead of targets.
 56  *
 57  * Version 0.94:
 58  *     Got rid of some excess locking/unlocking
 59  *     Fixed slight memory corruption problem while memcpy'ing into mailbox
 60  *     Changed logical drives to be reported as luns rather than targets
 61  *     Changed max_id to 16 since it is now max targets/chan again.
 62  *     Improved ioctl interface for upcoming megamgr
 63  *
 64  * Version 0.95:
 65  *     Fixed problem of queueing multiple commands to adapter;
 66  *       still has some strange problems on some setups, so still
 67  *       defaults to single.  To enable parallel commands change
 68  *       #define MULTI_IO in megaraid.h
 69  *     Changed kmalloc allocation to be done in beginning.
 70  *     Got rid of C++ style comments
 71  *
 72  * Version 0.96:
 73  *     762 fully supported.
 74  *
 75  * Version 0.97:
 76  *     Changed megaraid_command to use wait_queue.
 77  *     Fixed bug of undesirably detecting HP onboard controllers which
 78  *       are disabled.
 79  *     
 80  * Version 1.00:
 81  *     Checks to see if an irq ocurred while in isr, and runs through
 82  *       routine again.
 83  *     Copies mailbox to temp area before processing in isr
 84  *     Added barrier() in busy wait to fix volatility bug
 85  *     Uses separate list for freed Scbs, keeps track of cmd state
 86  *     Put spinlocks around entire queue function for now...
 87  *     Full multi-io commands working stablely without previous problems
 88  *     Added skipXX LILO option for Madrona motherboard support
 89  *
 90  * Version 1.01:
 91  *     Fixed bug in mega_cmd_done() for megamgr control commands,
 92  *       the host_byte in the result code from the scsi request to 
 93  *       scsi midlayer is set to DID_BAD_TARGET when adapter's 
 94  *       returned codes are 0xF0 and 0xF4.  
 95  *
 96  * Version 1.02:
 97  *     Fixed the tape drive bug by extending the adapter timeout value
 98  *       for passthrough command to 60 seconds in mega_build_cmd(). 
 99  *
100  * Version 1.03:
101  *    Fixed Madrona support.
102  *    Changed the adapter timeout value from 60 sec in 1.02 to 10 min
103  *      for bigger and slower tape drive.
104  *    Added driver version printout at driver loadup time
105  *
106  * Version 1.04
107  *    Added code for 40 ld FW support. 
108  *    Added new ioctl command 0x81 to support NEW_READ/WRITE_CONFIG with
109  *      data area greater than 4 KB, which is the upper bound for data
110  *      tranfer through scsi_ioctl interface.
111  *    The addtional 32 bit field for 64bit address in the newly defined
112  *      mailbox64 structure is set to 0 at this point.
113  *
114  * Version 1.05
115  *    Changed the queing implementation for handling SCBs and completed
116  *      commands.
117  *    Added spinlocks in the interrupt service routine to enable the dirver
118  *      function in the SMP environment.
119  *    Fixed the problem of unnecessary aborts in the abort entry point, which
120  *      also enables the driver to handle large amount of I/O requests for
121  *      long duration of time.
122  *
123  * Version 1.07
124  *    Removed the usage of uaccess.h file for kernel versions less than
125  *    2.0.36, as this file is not present in those versions.
126  *
127  * Version 1.07b
128  *    The MegaRAID 466 cards with 3.00 firmware lockup and seem to very
129  *    occasionally hang. We check such cards and report them. You can
130  *    get firmware upgrades to flash the board to 3.10 for free.
131  *
132  * BUGS:
133  *     Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
134  *     fails to detect the controller as a pci device on the system.
135  *
136  *     Timeout period for upper scsi layer, i.e. SD_TIMEOUT in
137  *     /drivers/scsi/sd.c, is too short for this controller. SD_TIMEOUT
138  *     value must be increased to (30 * HZ) otherwise false timeouts 
139  *     will occur in the upper layer.
140  *
141  *===================================================================*/
142 
143 #define CRLFSTR "\n"
144 #define IOCTL_CMD_NEW  0x81
145 
146 #define MEGARAID_VERSION "v107 (December 22, 1999)"
147 
148 
149 #include <linux/version.h>
150 
151 #ifdef MODULE
152 #include <linux/module.h>
153 
154 char kernel_version[] = UTS_RELEASE;
155 
156 MODULE_AUTHOR ("American Megatrends Inc.");
157 MODULE_DESCRIPTION ("AMI MegaRAID driver");
158 #endif
159 
160 #include <linux/init.h>
161 #include <linux/types.h>
162 #include <linux/errno.h>
163 #include <linux/kernel.h>
164 #include <linux/ioport.h>
165 #include <linux/fcntl.h>
166 #include <linux/delay.h>
167 #include <linux/pci.h>
168 #include <linux/proc_fs.h>
169 #include <linux/blk.h>
170 #include <linux/wait.h>
171 #include <linux/tqueue.h>
172 #include <linux/interrupt.h>
173 
174 #include <linux/stat.h>
175 #include <linux/spinlock.h>
176 
177 #include <asm/io.h>
178 #include <asm/irq.h>
179 #if LINUX_VERSION_CODE > 0x020024
180 #include <asm/uaccess.h>
181 #endif
182 
183 #include "sd.h"
184 #include "scsi.h"
185 #include "hosts.h"
186 
187 #include "megaraid.h"
188 
189 /*================================================================
190  *
191  *                          #Defines
192  *
193  *================================================================
194  */
195 
196 #define MAX_SERBUF 160
197 #define COM_BASE 0x2f8
198 
199 
200 u32 RDINDOOR (mega_host_config * megaCfg)
201 {
202   return readl (megaCfg->base + 0x20);
203 }
204 
205 void WRINDOOR (mega_host_config * megaCfg, u32 value)
206 {
207   writel (value, megaCfg->base + 0x20);
208 }
209 
210 u32 RDOUTDOOR (mega_host_config * megaCfg)
211 {
212   return readl (megaCfg->base + 0x2C);
213 }
214 
215 void WROUTDOOR (mega_host_config * megaCfg, u32 value)
216 {
217   writel (value, megaCfg->base + 0x2C);
218 }
219 
220 /*================================================================
221  *
222  *                    Function prototypes
223  *
224  *================================================================
225  */
226 static int __init megaraid_setup(char *);
227 
228 static int megaIssueCmd (mega_host_config * megaCfg,
229                          u_char * mboxData,
230                          mega_scb * scb,
231                          int intr);
232 static int mega_build_sglist (mega_host_config * megaCfg, mega_scb * scb,
233                          u32 * buffer, u32 * length);
234 
235 static int mega_busyWaitMbox(mega_host_config *);
236 static void mega_runpendq (mega_host_config *);
237 static void mega_rundoneq (mega_host_config *);
238 static void mega_cmd_done (mega_host_config *, mega_scb *, int);
239 static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt);
240 static inline void mega_freeSgList(mega_host_config *megaCfg);
241 static void mega_Convert8ldTo40ld(  mega_RAIDINQ  *inquiry,
242                                     mega_Enquiry3 *enquiry3,
243                                     megaRaidProductInfo *productInfo );
244 
245 
246 #include <linux/smp.h>
247 
248 
249 #define cpuid smp_processor_id()
250 #define DRIVER_LOCK_T
251 #define DRIVER_LOCK_INIT(p)
252 #define DRIVER_LOCK(p)
253 #define DRIVER_UNLOCK(p)
254 #define IO_LOCK_T unsigned long io_flags = 0;
255 #define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
256 #define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
257 
258 /* set SERDEBUG to 1 to enable serial debugging */
259 #define SERDEBUG 0
260 #if SERDEBUG
261 static void ser_init (void);
262 static void ser_puts (char *str);
263 static void ser_putc (char c);
264 static int ser_printk (const char *fmt,...);
265 #endif
266 
267 /*================================================================
268  *
269  *                    Global variables
270  *
271  *================================================================
272  */
273 
274 /*  Use "megaraid=skipXX" as LILO option to prohibit driver from scanning
275     XX scsi id on each channel.  Used for Madrona motherboard, where SAF_TE
276     processor id cannot be scanned */
277 #ifdef MODULE
278 static char *megaraid = NULL;
279 MODULE_PARM(megaraid, "s");
280 #endif
281 static int skip_id;
282 
283 static int numCtlrs = 0;
284 static mega_host_config *megaCtlrs[FC_MAX_CHANNELS] = {0};
285 
286 #if DEBUG
287 static u32 maxCmdTime = 0;
288 #endif
289 
290 static mega_scb *pLastScb = NULL;
291 
292 
293 #if SERDEBUG
294 static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
295 #endif
296 
297 #if SERDEBUG
298 static char strbuf[MAX_SERBUF + 1];
299 
300 static void ser_init ()
301 {
302   unsigned port = COM_BASE;
303 
304   outb (0x80, port + 3);
305   outb (0, port + 1);
306   /* 9600 Baud, if 19200: outb(6,port) */
307   outb (12, port);
308   outb (3, port + 3);
309   outb (0, port + 1);
310 }
311 
312 static void ser_puts (char *str)
313 {
314   char *ptr;
315 
316   ser_init ();
317   for (ptr = str; *ptr; ++ptr)
318     ser_putc (*ptr);
319 }
320 
321 static void ser_putc (char c)
322 {
323   unsigned port = COM_BASE;
324 
325   while ((inb (port + 5) & 0x20) == 0);
326   outb (c, port);
327   if (c == 0x0a) {
328     while ((inb (port + 5) & 0x20) == 0);
329     outb (0x0d, port);
330   }
331 }
332 
333 static int ser_printk (const char *fmt,...)
334 {
335   va_list args;
336   int i;
337   long flags;
338 
339   spin_lock_irqsave(&serial_lock,flags);
340   va_start (args, fmt);
341   i = vsprintf (strbuf, fmt, args);
342   ser_puts (strbuf);
343   va_end (args);
344   spin_unlock_irqrestore(&serial_lock,flags);
345 
346   return i;
347 }
348 
349 #define TRACE(a)    { ser_printk a;}
350 
351 #else
352 #define TRACE(A)
353 #endif
354 
355 static void callDone (Scsi_Cmnd * SCpnt)
356 {
357   if (SCpnt->result) {
358     TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number,
359             SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun,
360             SCpnt->result));
361   }
362   SCpnt->scsi_done (SCpnt);
363 }
364 
365 /*-------------------------------------------------------------------------
366  *
367  *                      Local functions
368  *
369  *-------------------------------------------------------------------------*/
370 
371 /*=======================
372  * Free a SCB structure
373  *=======================
374  */
375 static void mega_freeSCB (mega_host_config *megaCfg, mega_scb * pScb)
376 {
377 
378   mega_scb *pScbtmp;
379 
380   if ((pScb == NULL) || (pScb->idx >= 0xFE)) {
381     return ;
382   }
383 
384   /* Unlink from pending queue */
385 
386   if(pScb == megaCfg->qPendingH) {
387     if(megaCfg->qPendingH == megaCfg->qPendingT ) 
388       megaCfg->qPendingH = megaCfg->qPendingT = NULL;
389     else {
390       megaCfg->qPendingH = megaCfg->qPendingH->next;
391     }
392     megaCfg->qPcnt--;
393   }
394   else {
395     for(pScbtmp=megaCfg->qPendingH; pScbtmp; pScbtmp=pScbtmp->next) {
396       if (pScbtmp->next == pScb) {
397         pScbtmp->next = pScb->next;
398         if(pScb == megaCfg->qPendingT) {
399           megaCfg->qPendingT = pScbtmp;
400         }
401         megaCfg->qPcnt--;
402         break;
403     }
404   }
405   }
406 
407   /* Link back into free list */
408   pScb->state = SCB_FREE;
409   pScb->SCpnt = NULL;
410 
411   if(megaCfg->qFreeH == (mega_scb *) NULL ) {
412     megaCfg->qFreeH = megaCfg->qFreeT = pScb;
413   }
414   else {
415     megaCfg->qFreeT->next  = pScb;
416     megaCfg->qFreeT = pScb;
417   }
418   megaCfg->qFreeT->next = NULL;
419   megaCfg->qFcnt++;
420 
421 }
422 
423 /*===========================
424  * Allocate a SCB structure
425  *===========================
426  */
427 static mega_scb * mega_allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
428 {
429   mega_scb *pScb;
430 
431   /* Unlink command from Free List */
432   if ((pScb = megaCfg->qFreeH) != NULL) {
433     megaCfg->qFreeH = pScb->next;
434     megaCfg->qFcnt--;
435     
436     pScb->isrcount = jiffies;
437     pScb->next  = NULL;
438     pScb->state = SCB_ACTIVE;
439     pScb->SCpnt = SCpnt;
440 
441     return pScb;
442   }
443 
444   printk (KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");
445 
446   return NULL;
447 }
448 
449 /*================================================
450  * Initialize SCB structures
451  *================================================
452  */
453 static int mega_initSCB (mega_host_config * megaCfg)
454 {
455   int idx;
456 
457   megaCfg->qFreeH = NULL;
458   megaCfg->qFcnt = 0;
459 #if DEBUG
460 if(megaCfg->max_cmds >= MAX_COMMANDS) {
461 printk("megaraid:ctlr max cmds = %x : MAX_CMDS = %x", megaCfg->max_cmds, MAX_COMMANDS);
462 }
463 #endif
464 
465   for (idx = megaCfg->max_cmds-1; idx >= 0; idx--) {
466     megaCfg->scbList[idx].idx    = idx;
467     megaCfg->scbList[idx].sgList = kmalloc(sizeof(mega_sglist) * MAX_SGLIST,
468                                            GFP_ATOMIC | GFP_DMA);
469     if (megaCfg->scbList[idx].sgList == NULL) {
470       printk(KERN_WARNING "Can't allocate sglist for id %d\n",idx);
471       mega_freeSgList(megaCfg);
472       return -1;
473     }
474     
475     if (idx < MAX_COMMANDS) {
476       /* Link to free list */
477       mega_freeSCB(megaCfg, &megaCfg->scbList[idx]);
478     }
479   }
480   return 0;
481 }
482 
483 /* Run through the list of completed requests */
484 static void mega_rundoneq (mega_host_config *megaCfg)
485 {
486   Scsi_Cmnd *SCpnt;
487 
488   while ((SCpnt = megaCfg->qCompletedH) != NULL) {
489     megaCfg->qCompletedH = (Scsi_Cmnd *)SCpnt->host_scribble;
490     megaCfg->qCcnt--;
491 
492     SCpnt->host_scribble = (unsigned char *) NULL ; // XC : sep 14
493     /* Callback */
494     callDone (SCpnt);
495   }
496   megaCfg->qCompletedH = megaCfg->qCompletedT = NULL;
497 }
498 
499 /*
500  * Runs through the list of pending requests
501  * Assumes that mega_lock spin_lock has been acquired.
502  */
503 static void mega_runpendq(mega_host_config *megaCfg)
504 {
505   mega_scb *pScb;
506 
507   /* Issue any pending commands to the card */
508   for(pScb=megaCfg->qPendingH; pScb; pScb=pScb->next) {
509     if (pScb->state == SCB_ACTIVE) {
510       if(megaIssueCmd(megaCfg, pScb->mboxData, pScb, 1))
511         return;
512     }
513   }
514 }
515 
516 /* Add command to the list of completed requests */
517 static void
518 mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, 
519                            int status)
520 {
521   int islogical;
522   Scsi_Cmnd *SCpnt;
523   mega_passthru *pthru;
524   mega_mailbox *mbox;
525 
526   if (pScb == NULL) {
527         TRACE(("NULL pScb in mega_cmd_done!"));
528         printk("NULL pScb in mega_cmd_done!");
529   }
530 
531   SCpnt = pScb->SCpnt;
532   pthru = &pScb->pthru;
533   mbox = (mega_mailbox *) &pScb->mboxData;
534 
535   if (SCpnt == NULL) {
536         TRACE(("NULL SCpnt in mega_cmd_done!"));
537         TRACE(("pScb->idx = ",pScb->idx));
538         TRACE(("pScb->state = ",pScb->state));
539         TRACE(("pScb->state = ",pScb->state));
540         printk("megaraid:Problem...!\n");
541         while(1);
542   }
543 
544   islogical = (SCpnt->channel == megaCfg->host->max_channel);
545 
546   if (SCpnt->cmnd[0] == INQUIRY &&
547       ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
548       !islogical) {
549     status = 0xF0;
550   }
551 
552 /* clear result; otherwise, success returns corrupt value */ 
553  SCpnt->result = 0;  
554 
555 if ((SCpnt->cmnd[0] & 0x80) ) {/* i.e. ioctl cmd such as 0x80, 0x81 of megamgr*/
556     switch (status) {
557       case 0xF0:
558       case 0xF4:
559         SCpnt->result=(DID_BAD_TARGET<<16)|status;
560         break;
561       default:
562         SCpnt->result|=status;
563    }/*end of switch*/
564 }
565 else{
566   /* Convert MegaRAID status to Linux error code */
567   switch (status) {
568   case 0x00: /* SUCCESS , i.e. SCSI_STATUS_GOOD*/
569     SCpnt->result |= (DID_OK << 16);
570     break;
571   case 0x02: /* ERROR_ABORTED, i.e. SCSI_STATUS_CHECK_CONDITION */
572         /*set sense_buffer and result fields*/
573        if( mbox->cmd==MEGA_MBOXCMD_PASSTHRU ){
574           memcpy( SCpnt->sense_buffer , pthru->reqsensearea, 14);
575           SCpnt->result = (DRIVER_SENSE<<24)|(DID_ERROR << 16)|status; 
576        }
577        else{
578           SCpnt->sense_buffer[0]=0x70;
579           SCpnt->sense_buffer[2]=ABORTED_COMMAND;
580           SCpnt->result |= (CHECK_CONDITION << 1);
581        }
582     break;
583   case 0x08:  /* ERR_DEST_DRIVE_FAILED, i.e. SCSI_STATUS_BUSY */
584     SCpnt->result |= (DID_BUS_BUSY << 16)|status;
585     break;
586   default: 
587     SCpnt->result |= (DID_BAD_TARGET << 16)|status;
588     break;
589   }
590  }
591   if ( SCpnt->cmnd[0]!=IOCTL_CMD_NEW ) 
592   /* not IOCTL_CMD_NEW SCB, freeSCB()*/
593   /* For IOCTL_CMD_NEW SCB, delay freeSCB() in megaraid_queue()
594    * after copy data back to user space*/
595      mega_freeSCB(megaCfg, pScb);
596 
597   /* Add Scsi_Command to end of completed queue */
598     if( megaCfg->qCompletedH == NULL ) {
599       megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
600     }
601     else {
602       megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
603       megaCfg->qCompletedT = SCpnt;
604    }
605    megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
606    megaCfg->qCcnt++;
607 }
608 
609 /*-------------------------------------------------------------------
610  *
611  *                 Build a SCB from a Scsi_Cmnd
612  *
613  * Returns a SCB pointer, or NULL
614  * If NULL is returned, the scsi_done function MUST have been called
615  *
616  *-------------------------------------------------------------------*/
617 static mega_scb * mega_build_cmd (mega_host_config * megaCfg, 
618                                   Scsi_Cmnd * SCpnt)
619 {
620   mega_scb *pScb;
621   mega_mailbox *mbox;
622   mega_passthru *pthru;
623   long seg;
624   char islogical;
625   char lun = SCpnt->lun;
626 
627   if ((SCpnt->cmnd[0] == 0x80)  || (SCpnt->cmnd[0] == IOCTL_CMD_NEW) )  /* ioctl */
628     return mega_ioctl (megaCfg, SCpnt);
629  
630   islogical = (SCpnt->channel == megaCfg->host->max_channel);
631 
632   if (!islogical && lun != 0) {
633     SCpnt->result = (DID_BAD_TARGET << 16);
634     callDone (SCpnt);
635     return NULL;
636   }
637 
638   if (!islogical && SCpnt->target == skip_id) {
639         SCpnt->result = (DID_BAD_TARGET << 16);
640         callDone (SCpnt);
641         return NULL;
642   }
643 
644   if ( islogical ) {
645         lun = (SCpnt->target * 8) + lun;
646         if ( lun > FC_MAX_LOGICAL_DRIVES ){
647             SCpnt->result = (DID_BAD_TARGET << 16);
648             callDone (SCpnt);
649             return NULL;
650         }
651   }
652   /*-----------------------------------------------------
653    *
654    *               Logical drive commands
655    *
656    *-----------------------------------------------------*/
657   if (islogical) {
658     switch (SCpnt->cmnd[0]) {
659     case TEST_UNIT_READY:
660       memset (SCpnt->request_buffer, 0, SCpnt->request_bufflen);
661       SCpnt->result = (DID_OK << 16);
662       callDone (SCpnt);
663       return NULL;
664 
665     case MODE_SENSE:
666       memset (SCpnt->request_buffer, 0, SCpnt->cmnd[4]);
667       SCpnt->result = (DID_OK << 16);
668       callDone (SCpnt);
669       return NULL;
670 
671     case READ_CAPACITY:
672     case INQUIRY:
673       /* Allocate a SCB and initialize passthru */
674       if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
675         SCpnt->result = (DID_ERROR << 16);
676         callDone (SCpnt);
677         return NULL;
678       }
679       pthru = &pScb->pthru;
680       mbox = (mega_mailbox *) & pScb->mboxData;
681 
682       memset (mbox, 0, sizeof (pScb->mboxData));
683       memset (pthru, 0, sizeof (mega_passthru));
684       pthru->timeout = 0;
685       pthru->ars = 1;
686       pthru->reqsenselen = 14;
687       pthru->islogical = 1;
688       pthru->logdrv = lun;
689       pthru->cdblen = SCpnt->cmd_len;
690       pthru->dataxferaddr = virt_to_bus (SCpnt->request_buffer);
691       pthru->dataxferlen = SCpnt->request_bufflen;
692       memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
693 
694       /* Initialize mailbox area */
695       mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
696       mbox->xferaddr = virt_to_bus (pthru);
697 
698       return pScb;
699 
700     case READ_6:
701     case WRITE_6:
702     case READ_10:
703     case WRITE_10:
704       /* Allocate a SCB and initialize mailbox */
705       if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
706         SCpnt->result = (DID_ERROR << 16);
707         callDone (SCpnt);
708         return NULL;
709       }
710       mbox = (mega_mailbox *) & pScb->mboxData;
711 
712       memset (mbox, 0, sizeof (pScb->mboxData));
713       mbox->logdrv = lun;
714       mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ?
715         MEGA_MBOXCMD_LREAD : MEGA_MBOXCMD_LWRITE;
716 
717       /* 6-byte */
718       if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) {
719         mbox->numsectors =
720           (u32) SCpnt->cmnd[4];
721         mbox->lba =
722           ((u32) SCpnt->cmnd[1] << 16) |
723           ((u32) SCpnt->cmnd[2] << 8) |
724           (u32) SCpnt->cmnd[3];
725         mbox->lba &= 0x1FFFFF;
726       }
727 
728       /* 10-byte */
729       if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) {
730         mbox->numsectors =
731           (u32) SCpnt->cmnd[8] |
732           ((u32) SCpnt->cmnd[7] << 8);
733         mbox->lba =
734           ((u32) SCpnt->cmnd[2] << 24) |
735           ((u32) SCpnt->cmnd[3] << 16) |
736           ((u32) SCpnt->cmnd[4] << 8) |
737           (u32) SCpnt->cmnd[5];
738       }
739 
740       /* Calculate Scatter-Gather info */
741       mbox->numsgelements = mega_build_sglist (megaCfg, pScb,
742                                           (u32 *) & mbox->xferaddr,
743                                           (u32 *) & seg);
744 
745       return pScb;
746 
747     default:
748       SCpnt->result = (DID_BAD_TARGET << 16);
749       callDone (SCpnt);
750       return NULL;
751     }
752   }
753   /*-----------------------------------------------------
754    *
755    *               Passthru drive commands
756    *
757    *-----------------------------------------------------*/
758   else {
759     /* Allocate a SCB and initialize passthru */
760     if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
761       SCpnt->result = (DID_ERROR << 16);
762       callDone (SCpnt);
763       return NULL;
764     }
765     pthru = &pScb->pthru;
766     mbox = (mega_mailbox *) pScb->mboxData;
767 
768     memset (mbox, 0, sizeof (pScb->mboxData));
769     memset (pthru, 0, sizeof (mega_passthru));
770     pthru->timeout = 2; /*set adapter timeout value to 10 min. for tape drive*/
771                         /* 0=6sec/1=60sec/2=10min/3=3hrs */
772     pthru->ars = 1;
773     pthru->reqsenselen = 14;
774     pthru->islogical = 0;
775     pthru->channel = (megaCfg->flag & BOARD_40LD) ? 0 : SCpnt->channel;
776     pthru->target = (megaCfg->flag & BOARD_40LD) ? /*BOARD_40LD*/
777                      (SCpnt->channel<<4)|SCpnt->target : SCpnt->target;
778     pthru->cdblen = SCpnt->cmd_len;
779     memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
780 
781     pthru->numsgelements = mega_build_sglist (megaCfg, pScb,
782                                          (u32 *) & pthru->dataxferaddr,
783                                          (u32 *) & pthru->dataxferlen);
784 
785     /* Initialize mailbox */
786     mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
787     mbox->xferaddr = virt_to_bus (pthru);
788 
789     return pScb;
790   }
791   return NULL;
792 }
793 
794 /*--------------------------------------------------------------------
795  * build RAID commands for controller, passed down through ioctl()
796  *--------------------------------------------------------------------*/
797 static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
798 {
799   mega_scb *pScb;
800   mega_ioctl_mbox *mbox;
801   mega_mailbox *mailbox;
802   mega_passthru *pthru;
803   u8 *mboxdata;
804   long seg;
805   unsigned char *data = (unsigned char *)SCpnt->request_buffer;
806   int i;
807 
808   if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
809     SCpnt->result = (DID_ERROR << 16);
810     callDone (SCpnt);
811     return NULL;
812   }
813 
814   mboxdata = (u8 *) & pScb->mboxData;
815   mbox = (mega_ioctl_mbox *) & pScb->mboxData;
816   mailbox = (mega_mailbox *) & pScb->mboxData;
817   memset (mailbox, 0, sizeof (pScb->mboxData));
818 
819   if (data[0] == 0x03) {        /* passthrough command */
820     unsigned char cdblen = data[2];
821     pthru = &pScb->pthru;
822     memset (pthru, 0, sizeof (mega_passthru));
823     pthru->islogical = (data[cdblen+3] & 0x80) ? 1:0;
824     pthru->timeout = data[cdblen+3] & 0x07;
825     pthru->reqsenselen = 14;
826     pthru->ars = (data[cdblen+3] & 0x08) ? 1:0;
827     pthru->logdrv = data[cdblen+4];
828     pthru->channel = data[cdblen+5];
829     pthru->target = data[cdblen+6];
830     pthru->cdblen = cdblen;
831     memcpy (pthru->cdb, &data[3], cdblen);
832 
833     mailbox->cmd = MEGA_MBOXCMD_PASSTHRU;
834     mailbox->xferaddr = virt_to_bus (pthru);
835 
836     pthru->numsgelements = mega_build_sglist (megaCfg, pScb,
837                                          (u32 *) & pthru->dataxferaddr,
838                                          (u32 *) & pthru->dataxferlen);
839 
840     for (i=0;i<(SCpnt->request_bufflen-cdblen-7);i++) {
841        data[i] = data[i+cdblen+7];
842     }
843 
844     return pScb;
845   }
846   /* else normal (nonpassthru) command */
847 
848 #if LINUX_VERSION_CODE > 0x020024
849 /*
850  * usage of the function copy from user is used in case of data more than
851  * 4KB.  This is used only with adapters which supports more than 8 logical
852  * drives.  This feature is disabled on kernels earlier or same as 2.0.36
853  * as the uaccess.h file is not available with those kernels.
854  */
855 
856   if (SCpnt->cmnd[0] == IOCTL_CMD_NEW) { 
857             /* use external data area for large xfers  */
858      /* If cmnd[0] is set to IOCTL_CMD_NEW then *
859       *   cmnd[4..7] = external user buffer     *
860       *   cmnd[8..11] = length of buffer        *
861       *                                         */
862       char *kern_area;
863       char *user_area = *((char **)&SCpnt->cmnd[4]);
864       u32 xfer_size = *((u32 *)&SCpnt->cmnd[8]);
865       if (verify_area(VERIFY_READ, user_area, xfer_size)) {
866           printk("megaraid: Got bad user address.\n");
867           SCpnt->result = (DID_ERROR << 16);
868           callDone (SCpnt);
869           return NULL;
870       }
871       kern_area = kmalloc(xfer_size, GFP_ATOMIC | GFP_DMA);
872       if (kern_area == NULL) {
873           printk("megaraid: Couldn't allocate kernel mem.\n");
874           SCpnt->result = (DID_ERROR << 16);
875           callDone (SCpnt);
876           return NULL;
877       }
878       copy_from_user(kern_area,user_area,xfer_size);
879       pScb->kern_area = kern_area;
880   }
881 #endif
882 
883   mbox->cmd = data[0];
884   mbox->channel = data[1];
885   mbox->param = data[2];
886   mbox->pad[0] = data[3];
887   mbox->logdrv = data[4];
888 
889   if(SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
890       if(data[0]==DCMD_FC_CMD){ /*i.e. 0xA1, then override some mbox data */
891           *(mboxdata+0) = data[0]; /*mailbox byte 0: DCMD_FC_CMD*/
892           *(mboxdata+2) = data[2]; /*sub command*/
893           *(mboxdata+3) = 0;       /*number of elements in SG list*/
894           mbox->xferaddr           /*i.e. mboxdata byte 0x8 to 0xb*/
895                         = virt_to_bus(pScb->kern_area);
896       }
897       else{
898          mbox->xferaddr = virt_to_bus(pScb->kern_area);
899          mbox->numsgelements = 0;
900       }
901   } 
902   else {
903 
904       mbox->numsgelements = mega_build_sglist (megaCfg, pScb,
905                                       (u32 *) & mbox->xferaddr,
906                                       (u32 *) & seg);
907 
908       for (i=0;i<(SCpnt->request_bufflen-6);i++) {
909           data[i] = data[i+6];
910       }
911   }
912 
913   return (pScb);
914 }
915 
916 #if DEBUG
917 static void showMbox(mega_scb *pScb)
918 {
919   mega_mailbox *mbox;
920 
921   if (pScb == NULL) return;
922 
923   mbox = (mega_mailbox *)pScb->mboxData;
924   printk("%u cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n",
925          pScb->SCpnt->pid, 
926          mbox->cmd, mbox->cmdid, mbox->numsectors,
927          mbox->lba, mbox->xferaddr, mbox->logdrv,
928          mbox->numsgelements);
929 }
930 #endif
931 
932 #if DEBUG
933 static unsigned int cum_time = 0;
934 static unsigned int cum_time_cnt = 0;
935 #endif
936 
937 /*--------------------------------------------------------------------
938  * Interrupt service routine
939  *--------------------------------------------------------------------*/
940 static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
941 {
942 #if LINUX_VERSION_CODE >= 0x20100
943   IO_LOCK_T
944 #endif
945   mega_host_config    *megaCfg;
946   u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE];
947   u32 dword=0;
948   mega_mailbox *mbox;
949   mega_scb *pScb;
950   u_char qCnt, qStatus;
951   u_char            completed[MAX_FIRMWARE_STATUS];
952   Scsi_Cmnd *SCpnt;
953 
954   megaCfg = (mega_host_config *) devp;
955   mbox = (mega_mailbox *)tmpBox;
956 
957   if (megaCfg->host->irq == irq) {
958     if (megaCfg->flag & IN_ISR) {
959       printk(KERN_ERR "ISR called reentrantly!!\n");
960     }
961 
962     megaCfg->flag |= IN_ISR;
963 
964     if (mega_busyWaitMbox(megaCfg)) {
965         printk(KERN_WARNING "Error: mailbox busy in isr!\n");
966     }
967 
968     /* Check if a valid interrupt is pending */
969     if (megaCfg->flag & BOARD_QUARTZ) {
970       dword = RDOUTDOOR (megaCfg);
971       if (dword != 0x10001234) {
972         /* Spurious interrupt */
973         megaCfg->flag &= ~IN_ISR;
974         return;
975       }
976     }
977     else {
978       byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
979       if ((byte & VALID_INTR_BYTE) == 0) {
980         /* Spurious interrupt */
981         megaCfg->flag &= ~IN_ISR;
982         return;
983       }
984       WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
985     }
986 
987     for(idx=0;idx<MAX_FIRMWARE_STATUS;idx++ ) completed[idx] = 0;
988 
989     IO_LOCK;
990 
991     qCnt = 0xff;
992     while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) 
993       ;
994 
995     qStatus = 0xff;
996     while ((qStatus = megaCfg->mbox->status) == 0xFF)
997       ;
998 
999     /* Get list of completed requests */
1000     for (idx = 0; idx<qCnt; idx++) {
1001       while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) {
1002         printk("p");
1003       }
1004       completed[idx] = sIdx;
1005       sIdx = 0xFF;
1006     }
1007 
1008     if (megaCfg->flag & BOARD_QUARTZ) {
1009       WROUTDOOR (megaCfg, dword);
1010       /* Acknowledge interrupt */
1011       WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
1012       while (RDINDOOR (megaCfg) & 0x02);
1013     }
1014     else {
1015       CLEAR_INTR (megaCfg->host->io_port);
1016     }
1017 
1018 #if DEBUG
1019     if(qCnt >= MAX_FIRMWARE_STATUS) {
1020       printk("megaraid_isr: cmplt=%d ", qCnt);
1021     }
1022 #endif
1023 
1024     for (idx = 0; idx < qCnt; idx++) {
1025       sIdx = completed[idx];
1026       if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) {
1027         pScb = &megaCfg->scbList[sIdx - 1];
1028 
1029         /* ASSERT(pScb->state == SCB_ISSUED); */
1030 
1031 #if DEBUG
1032         if (((jiffies) - pScb->isrcount) > maxCmdTime) {
1033           maxCmdTime = (jiffies) - pScb->isrcount;
1034           printk("megaraid_isr : cmd time = %u\n", maxCmdTime);
1035         }
1036 #endif
1037 /*
1038  * Assuming that the scsi command, for which an abort request was received
1039  * earlier has completed.
1040  */
1041         if (pScb->state == SCB_ABORTED) {
1042           SCpnt = pScb->SCpnt;
1043         }
1044         if (pScb->state == SCB_RESET) {
1045           SCpnt = pScb->SCpnt;
1046           mega_freeSCB (megaCfg, pScb);
1047           SCpnt->result = (DID_RESET << 16) ;
1048           if( megaCfg->qCompletedH == NULL ) {
1049             megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
1050           }
1051           else {
1052             megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
1053             megaCfg->qCompletedT = SCpnt;
1054           }
1055           megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
1056           megaCfg->qCcnt++;
1057           continue;
1058         }
1059 
1060         if (*(pScb->SCpnt->cmnd)==IOCTL_CMD_NEW) 
1061         {    /* external user buffer */
1062            up(&pScb->sem);
1063         }
1064         /* Mark command as completed */
1065         mega_cmd_done(megaCfg, pScb, qStatus);
1066 
1067       }
1068       else {
1069         printk(KERN_ERR "megaraid: wrong cmd id completed from firmware:id=%x\n",sIdx);
1070       }
1071     }
1072 
1073     mega_rundoneq(megaCfg);
1074 
1075     megaCfg->flag &= ~IN_ISR;
1076 
1077     /* Loop through any pending requests */
1078     mega_runpendq(megaCfg);
1079 #if LINUX_VERSION_CODE >= 0x20100
1080     IO_UNLOCK;
1081 #endif
1082 
1083   }
1084 }
1085 
1086 /*==================================================*/
1087 /* Wait until the controller's mailbox is available */
1088 /*==================================================*/
1089 static int mega_busyWaitMbox (mega_host_config * megaCfg)
1090 {
1091   mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
1092   long counter;
1093 
1094   for (counter = 0; counter < 10000; counter++) {
1095     if (!mbox->busy) {
1096       return 0;
1097     }
1098     udelay (100);
1099     barrier();
1100   }
1101   return -1;                    /* give up after 1 second */
1102 }
1103 
1104 /*=====================================================
1105  * Post a command to the card
1106  *
1107  * Arguments:
1108  *   mega_host_config *megaCfg - Controller structure
1109  *   u_char *mboxData - Mailbox area, 16 bytes
1110  *   mega_scb *pScb   - SCB posting (or NULL if N/A)
1111  *   int intr         - if 1, interrupt, 0 is blocking
1112  * Return Value: (added on 7/26 for 40ld/64bit)
1113  *   -1: the command was not actually issued out
1114  *   othercases:
1115  *     intr==0, return ScsiStatus, i.e. mbox->status
1116  *     intr==1, return 0 
1117  *=====================================================
1118  */
1119 static int megaIssueCmd (mega_host_config * megaCfg,
1120               u_char * mboxData,
1121               mega_scb * pScb,
1122               int intr)
1123 {
1124   mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
1125   u_char byte;
1126   u32 cmdDone;
1127   u32 phys_mbox;
1128   u8 retval=-1;
1129 
1130   mboxData[0x1] = (pScb ? pScb->idx + 1: 0x0);   /* Set cmdid */
1131   mboxData[0xF] = 1;            /* Set busy */
1132 
1133   phys_mbox = virt_to_bus (megaCfg->mbox);
1134 
1135 #if DEBUG
1136   showMbox(pScb);
1137 #endif
1138 
1139   /* Wait until mailbox is free */
1140   if (mega_busyWaitMbox (megaCfg)) {
1141     printk("Blocked mailbox......!!\n");
1142     udelay(1000);
1143 
1144 #if DEBUG
1145     showMbox(pLastScb);
1146 #endif
1147     
1148     /* Abort command */
1149     if (pScb == NULL) {
1150         TRACE(("NULL pScb in megaIssue\n"));
1151         printk("NULL pScb in megaIssue\n");
1152     }
1153     mega_cmd_done (megaCfg, pScb, 0x08);
1154     return -1;
1155   }
1156 
1157   pLastScb = pScb;
1158 
1159   /* Copy mailbox data into host structure */
1160   megaCfg->mbox64->xferSegment = 0;
1161   memcpy (mbox, mboxData, 16);
1162 
1163   /* Kick IO */
1164   if (intr) {
1165 
1166     /* Issue interrupt (non-blocking) command */
1167     if (megaCfg->flag & BOARD_QUARTZ) {
1168        mbox->mraid_poll = 0;
1169       mbox->mraid_ack = 0;
1170       WRINDOOR (megaCfg, phys_mbox | 0x1);
1171     }
1172     else {
1173       ENABLE_INTR (megaCfg->host->io_port);
1174       ISSUE_COMMAND (megaCfg->host->io_port);
1175     }
1176     pScb->state = SCB_ISSUED;
1177 
1178     retval=0;
1179   }
1180   else {                        /* Issue non-ISR (blocking) command */
1181     disable_irq(megaCfg->host->irq);
1182     if (megaCfg->flag & BOARD_QUARTZ) {
1183       mbox->mraid_poll = 0;
1184       mbox->mraid_ack = 0;
1185       WRINDOOR (megaCfg, phys_mbox | 0x1);
1186 
1187       while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
1188       WROUTDOOR (megaCfg, cmdDone);
1189 
1190       if (pScb) {
1191         mega_cmd_done (megaCfg, pScb, mbox->status);
1192       }
1193 
1194       WRINDOOR (megaCfg, phys_mbox | 0x2);
1195       while (RDINDOOR (megaCfg) & 0x2);
1196 
1197     }
1198     else {
1199       DISABLE_INTR (megaCfg->host->io_port);
1200       ISSUE_COMMAND (megaCfg->host->io_port);
1201 
1202       while (!((byte = READ_PORT (megaCfg->host->io_port, INTR_PORT)) & INTR_VALID));
1203       WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
1204 
1205       ENABLE_INTR (megaCfg->host->io_port);
1206       CLEAR_INTR (megaCfg->host->io_port);
1207 
1208       if (pScb) {
1209         mega_cmd_done (megaCfg, pScb, mbox->status);
1210       }
1211       else {
1212         TRACE (("Error: NULL pScb!\n"));
1213       }
1214     }
1215     enable_irq(megaCfg->host->irq);
1216     retval=mbox->status;
1217   }
1218 #if DEBUG
1219   while (mega_busyWaitMbox (megaCfg)) {
1220     printk("Blocked mailbox on exit......!\n");
1221     udelay(1000);
1222   }
1223 #endif
1224 
1225   return retval;
1226 }
1227 
1228 /*-------------------------------------------------------------------
1229  * Copies data to SGLIST
1230  *-------------------------------------------------------------------*/
1231 static int mega_build_sglist (mega_host_config * megaCfg, mega_scb * scb,
1232               u32 * buffer, u32 * length)
1233 {
1234   struct scatterlist *sgList;
1235   int idx;
1236 
1237   /* Scatter-gather not used */
1238   if (scb->SCpnt->use_sg == 0) {
1239     *buffer = virt_to_bus (scb->SCpnt->request_buffer);
1240     *length = (u32) scb->SCpnt->request_bufflen;
1241     return 0;
1242   }
1243 
1244   sgList = (struct scatterlist *) scb->SCpnt->request_buffer;
1245   if (scb->SCpnt->use_sg == 1) {
1246     *buffer = virt_to_bus (sgList[0].address);
1247     *length = (u32) sgList[0].length;
1248     return 0;
1249   }
1250 
1251   /* Copy Scatter-Gather list info into controller structure */
1252   for (idx = 0; idx < scb->SCpnt->use_sg; idx++) {
1253     scb->sgList[idx].address = virt_to_bus (sgList[idx].address);
1254     scb->sgList[idx].length = (u32) sgList[idx].length;
1255   }
1256 
1257   /* Reset pointer and length fields */
1258   *buffer = virt_to_bus (scb->sgList);
1259   *length = 0;
1260 
1261   /* Return count of SG requests */
1262   return scb->SCpnt->use_sg;
1263 }
1264 
1265 /*--------------------------------------------------------------------
1266  * Initializes the adress of the controller's mailbox register
1267  *  The mailbox register is used to issue commands to the card.
1268  *  Format of the mailbox area:
1269  *   00 01 command
1270  *   01 01 command id
1271  *   02 02 # of sectors
1272  *   04 04 logical bus address
1273  *   08 04 physical buffer address
1274  *   0C 01 logical drive #
1275  *   0D 01 length of scatter/gather list
1276  *   0E 01 reserved
1277  *   0F 01 mailbox busy
1278  *   10 01 numstatus byte
1279  *   11 01 status byte
1280  *--------------------------------------------------------------------*/
1281 static int mega_register_mailbox (mega_host_config * megaCfg, u32 paddr)
1282 {
1283   /* align on 16-byte boundry */
1284   megaCfg->mbox = &megaCfg->mailbox64.mailbox;
1285   megaCfg->mbox = (mega_mailbox *) ((((u32) megaCfg->mbox) + 16) & 0xfffffff0);
1286   megaCfg->mbox64 = (mega_mailbox64 *) (megaCfg->mbox - 4);
1287   paddr = (paddr + 4 + 16) & 0xfffffff0;
1288 
1289   /* Register mailbox area with the firmware */
1290   if (!(megaCfg->flag & BOARD_QUARTZ)) {
1291     WRITE_PORT (megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF);
1292     WRITE_PORT (megaCfg->host->io_port, MBOX_PORT1, (paddr >> 8) & 0xFF);
1293     WRITE_PORT (megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF);
1294     WRITE_PORT (megaCfg->host->io_port, MBOX_PORT3, (paddr >> 24) & 0xFF);
1295     WRITE_PORT (megaCfg->host->io_port, ENABLE_MBOX_REGION, ENABLE_MBOX_BYTE);
1296 
1297     CLEAR_INTR (megaCfg->host->io_port);
1298     ENABLE_INTR (megaCfg->host->io_port);
1299   }
1300   return 0;
1301 }
1302 
1303 
1304 /*---------------------------------------------------------------------------
1305  * mega_Convert8ldTo40ld() -- takes all info in AdapterInquiry structure and
1306  * puts it into ProductInfo and Enquiry3 structures for later use
1307  *---------------------------------------------------------------------------*/
1308 static void mega_Convert8ldTo40ld(  mega_RAIDINQ  *inquiry,
1309                                     mega_Enquiry3 *enquiry3,
1310                                     megaRaidProductInfo *productInfo )
1311 {
1312         int i;
1313 
1314         productInfo->MaxConcCmds = inquiry->AdpInfo.MaxConcCmds;
1315         enquiry3->rbldRate = inquiry->AdpInfo.RbldRate;
1316         productInfo->SCSIChanPresent = inquiry->AdpInfo.ChanPresent;
1317         for (i=0;i<4;i++) {
1318                 productInfo->FwVer[i] = inquiry->AdpInfo.FwVer[i];
1319                 productInfo->BiosVer[i] = inquiry->AdpInfo.BiosVer[i];
1320         }
1321         enquiry3->cacheFlushInterval = inquiry->AdpInfo.CacheFlushInterval;
1322         productInfo->DramSize = inquiry->AdpInfo.DramSize;
1323 
1324         enquiry3->numLDrv = inquiry->LogdrvInfo.NumLDrv;
1325         for (i=0;i<MAX_LOGICAL_DRIVES;i++) {
1326                 enquiry3->lDrvSize[i] = inquiry->LogdrvInfo.LDrvSize[i];
1327                 enquiry3->lDrvProp[i] = inquiry->LogdrvInfo.LDrvProp[i];
1328                 enquiry3->lDrvState[i] = inquiry->LogdrvInfo.LDrvState[i];
1329         }
1330 
1331         for (i=0;i<(MAX_PHYSICAL_DRIVES);i++) {
1332                 enquiry3->pDrvState[i] = inquiry->PhysdrvInfo.PDrvState[i];
1333         }
1334 }
1335 
1336 
1337 /*-------------------------------------------------------------------
1338  * Issue an adapter info query to the controller
1339  *-------------------------------------------------------------------*/
1340 static int mega_i_query_adapter (mega_host_config * megaCfg)
1341 {
1342   mega_Enquiry3 *enquiry3Pnt;
1343   mega_mailbox *mbox;
1344   u_char mboxData[16];
1345   u32 paddr;
1346   u8 retval;
1347 
1348   /* Initialize adapter inquiry mailbox*/
1349   paddr = virt_to_bus (megaCfg->mega_buffer);
1350   mbox = (mega_mailbox *) mboxData;
1351 
1352   memset ((void *) megaCfg->mega_buffer, 0, sizeof (megaCfg->mega_buffer));
1353   memset (mbox, 0, 16);
1354 
1355 /*
1356  * Try to issue Enquiry3 command 
1357  * if not suceeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and 
1358  * update enquiry3 structure
1359  */
1360   mbox->xferaddr = virt_to_bus ( (void*) megaCfg->mega_buffer); 
1361              /* Initialize mailbox databuffer addr */
1362   enquiry3Pnt = (mega_Enquiry3 *) megaCfg->mega_buffer; 
1363              /* point mega_Enguiry3 to the data buf */
1364 
1365   mboxData[0]=FC_NEW_CONFIG ;          /* i.e. mbox->cmd=0xA1 */
1366   mboxData[2]=NC_SUBOP_ENQUIRY3;       /* i.e. 0x0F */
1367   mboxData[3]=ENQ3_GET_SOLICITED_FULL; /* i.e. 0x02 */
1368 
1369   /* Issue a blocking command to the card */
1370   if ( (retval=megaIssueCmd(megaCfg, mboxData, NULL, 0)) != 0 )
1371   {  /* the adapter does not support 40ld*/
1372 
1373      mega_RAIDINQ adapterInquiryData;
1374      mega_RAIDINQ *adapterInquiryPnt = &adapterInquiryData;
1375 
1376      mbox->xferaddr = virt_to_bus ( (void*) adapterInquiryPnt);
1377 
1378      mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ;  /*issue old 0x05 command to adapter*/
1379      /* Issue a blocking command to the card */;
1380      retval=megaIssueCmd (megaCfg, mboxData, NULL, 0);
1381 
1382      /*update Enquiry3 and ProductInfo structures with mega_RAIDINQ structure*/
1383      mega_Convert8ldTo40ld(  adapterInquiryPnt, 
1384                              enquiry3Pnt, 
1385                              (megaRaidProductInfo * ) &megaCfg->productInfo );
1386 
1387   }
1388   else{ /* adapter supports 40ld */
1389     megaCfg->flag |= BOARD_40LD;
1390 
1391     /*get productInfo, which is static information and will be unchanged*/
1392     mbox->xferaddr = virt_to_bus ( (void*) &megaCfg->productInfo );
1393 
1394     mboxData[0]=FC_NEW_CONFIG ;         /* i.e. mbox->cmd=0xA1 */
1395     mboxData[2]=NC_SUBOP_PRODUCT_INFO;  /* i.e. 0x0E */
1396    
1397     if( (retval=megaIssueCmd(megaCfg, mboxData, NULL, 0)) != 0  ) 
1398         printk("ami:Product_info (0x0E) cmd failed with error: %d\n", retval);
1399 
1400   }
1401 
1402   megaCfg->host->max_channel = megaCfg->productInfo.SCSIChanPresent;
1403   megaCfg->host->max_id = 16;              /* max targets per channel */
1404     /*(megaCfg->flag & BOARD_40LD)?FC_MAX_TARGETS_PER_CHANNEL:MAX_TARGET+1;*/ 
1405   megaCfg->host->max_lun =              /* max lun */
1406     (megaCfg->flag & BOARD_40LD) ? FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES; 
1407   megaCfg->host->cmd_per_lun = MAX_CMD_PER_LUN;
1408 
1409   megaCfg->numldrv = enquiry3Pnt->numLDrv;
1410   megaCfg->max_cmds = megaCfg->productInfo.MaxConcCmds;
1411   if(megaCfg->max_cmds > MAX_COMMANDS) megaCfg->max_cmds = MAX_COMMANDS - 1;
1412 
1413   megaCfg->host->can_queue   = megaCfg->max_cmds;
1414 
1415   if (megaCfg->host->can_queue >= MAX_COMMANDS) {
1416     megaCfg->host->can_queue = MAX_COMMANDS-1;
1417   }
1418 
1419 #ifdef HP                       /* use HP firmware and bios version encoding */
1420   sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
1421            megaCfg->productInfo.FwVer[2],
1422            megaCfg->productInfo.FwVer[1] >> 8,
1423            megaCfg->productInfo.FwVer[1] & 0x0f,
1424            megaCfg->productInfo.FwVer[2] >> 8,
1425            megaCfg->productInfo.FwVer[2] & 0x0f);
1426   sprintf (megaCfg->biosVer, "%c%d%d.%d%d",
1427            megaCfg->productInfo.BiosVer[2],
1428            megaCfg->productInfo.BiosVer[1] >> 8,
1429            megaCfg->productInfo.BiosVer[1] & 0x0f,
1430            megaCfg->productInfo.BiosVer[2] >> 8,
1431            megaCfg->productInfo.BiosVer[2] & 0x0f);
1432 #else
1433         memcpy (megaCfg->fwVer, (void *)megaCfg->productInfo.FwVer, 4);
1434         megaCfg->fwVer[4] = 0;
1435 
1436         memcpy (megaCfg->biosVer, (void *)megaCfg->productInfo.BiosVer, 4);
1437         megaCfg->biosVer[4] = 0;
1438 #endif
1439 
1440         printk ("megaraid: [%s:%s] detected %d logical drives" CRLFSTR,
1441                 megaCfg->fwVer,
1442                 megaCfg->biosVer,
1443                 megaCfg->numldrv);
1444 
1445         return 0;
1446 }
1447 
1448 /*-------------------------------------------------------------------------
1449  *
1450  *                      Driver interface functions
1451  *
1452  *-------------------------------------------------------------------------*/
1453 
1454 /*----------------------------------------------------------
1455  * Returns data to be displayed in /proc/scsi/megaraid/X
1456  *----------------------------------------------------------*/
1457 int megaraid_proc_info (char *buffer, char **start, off_t offset,
1458                     int length, int host_no, int inout)
1459 {
1460   *start = buffer;
1461   return 0;
1462 }
1463 
1464 int mega_findCard (Scsi_Host_Template * pHostTmpl,
1465           u16 pciVendor, u16 pciDev,
1466           long flag)
1467 {
1468   mega_host_config *megaCfg;
1469   struct Scsi_Host *host;
1470   u_char megaIrq;
1471   u32 megaBase;
1472   u16 numFound = 0;
1473 
1474   struct pci_dev *pdev = NULL;
1475   
1476   while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) {
1477     if (pci_enable_device(pdev))
1478         continue;
1479     if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
1480       u16 magic;
1481       pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
1482       if ((magic != AMI_SIGNATURE) && (magic != AMI_SIGNATURE_471))
1483         continue;               /* not an AMI board */
1484     }
1485     printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x: in %s\n",
1486             pciVendor,
1487             pciDev,
1488             pdev->slot_name);
1489 
1490     /* Read the base port and IRQ from PCI */
1491     megaBase = pci_resource_start (pdev, 0);
1492     megaIrq  = pdev->irq;
1493 
1494     if (flag & BOARD_QUARTZ)
1495       megaBase = (long) ioremap (megaBase, 128);
1496     else
1497       megaBase += 0x10;
1498 
1499     /* Initialize SCSI Host structure */
1500     host = scsi_register (pHostTmpl, sizeof (mega_host_config));
1501     if(host == NULL)
1502         continue;
1503     megaCfg = (mega_host_config *) host->hostdata;
1504     memset (megaCfg, 0, sizeof (mega_host_config));
1505 
1506     printk ("scsi%d : Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR,
1507             host->host_no, (u_int) megaBase, megaIrq);
1508 
1509     /* Copy resource info into structure */
1510     megaCfg->qCompletedH = NULL;
1511     megaCfg->qCompletedT = NULL;
1512     megaCfg->qPendingH = NULL;
1513     megaCfg->qPendingT = NULL;
1514     megaCfg->qFreeH    = NULL;
1515     megaCfg->qFreeT    = NULL;
1516     megaCfg->qFcnt = 0;
1517     megaCfg->qPcnt = 0;
1518     megaCfg->qCcnt = 0;
1519     megaCfg->flag = flag;
1520     megaCfg->host = host;
1521     megaCfg->base = megaBase;
1522     megaCfg->host->irq = megaIrq;
1523     megaCfg->host->io_port = megaBase;
1524     megaCfg->host->n_io_port = 16;
1525     megaCfg->host->unique_id = (pdev->bus->number << 8) | pdev->devfn;
1526     megaCtlrs[numCtlrs++] = megaCfg; 
1527     if (flag != BOARD_QUARTZ) {
1528       /* Request our IO Range */
1529       if (request_region (megaBase, 16, "megaraid")) {
1530         printk (KERN_WARNING "megaraid: Couldn't register I/O range!" CRLFSTR);
1531         scsi_unregister (host);
1532         continue;
1533       }
1534     }
1535 
1536     /* Request our IRQ */
1537     if (request_irq (megaIrq, megaraid_isr, SA_SHIRQ,
1538                      "megaraid", megaCfg)) {
1539       printk (KERN_WARNING "megaraid: Couldn't register IRQ %d!" CRLFSTR,
1540               megaIrq);
1541       scsi_unregister (host);
1542       continue;
1543     }
1544 
1545     mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox64));
1546     mega_i_query_adapter (megaCfg);
1547    
1548     if (flag == BOARD_QUARTZ) {
1549       /* Check to see if this is a Dell PERC RAID controller model 466 */
1550       u16 subsysid, subsysvid;
1551 #if LINUX_VERSION_CODE < 0x20100
1552       pcibios_read_config_word (pciBus, pciDevFun,
1553                                 PCI_SUBSYSTEM_VENDOR_ID,
1554                                 &subsysvid);
1555       pcibios_read_config_word (pciBus, pciDevFun,
1556                                 PCI_SUBSYSTEM_ID,
1557                                 &subsysid);
1558 #else
1559       pci_read_config_word (pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
1560       pci_read_config_word (pdev, PCI_SUBSYSTEM_ID, &subsysid);
1561 #endif
1562       if ( (subsysid == 0x1111) && (subsysvid == 0x1111) &&
1563            (!strcmp(megaCfg->fwVer,"3.00") || !strcmp(megaCfg->fwVer,"3.01"))) {
1564         printk(KERN_WARNING
1565 "megaraid: Your card is a Dell PERC 2/SC RAID controller with firmware\n"
1566 "megaraid: 3.00 or 3.01.  This driver is known to have corruption issues\n"
1567 "megaraid: with those firmware versions on this specific card.  In order\n"
1568 "megaraid: to protect your data, please upgrade your firmware to version\n"
1569 "megaraid: 3.10 or later, available from the Dell Technical Support web\n"
1570 "megaraid: site at\n"
1571 "http://support.dell.com/us/en/filelib/download/index.asp?fileid=2940\n");
1572         megaraid_release (host);
1573 #ifdef MODULE   
1574         continue;
1575 #else
1576         while(1) schedule_timeout(1 * HZ);
1577 #endif  
1578       }
1579     }
1580 
1581     /* Initialize SCBs */
1582     if (mega_initSCB (megaCfg)) {
1583       megaraid_release (host);
1584       continue;
1585     }
1586 
1587     numFound++;
1588   }
1589   return numFound;
1590 }
1591 
1592 /*---------------------------------------------------------
1593  * Detects if a megaraid controller exists in this system
1594  *---------------------------------------------------------*/
1595 int megaraid_detect (Scsi_Host_Template * pHostTmpl)
1596 {
1597   int count = 0;
1598 
1599 #ifdef MODULE
1600   if (megaraid)
1601       megaraid_setup(megaraid);
1602 #endif
1603 
1604   pHostTmpl->proc_name = "megaraid";
1605 
1606   printk ("megaraid: " MEGARAID_VERSION CRLFSTR);
1607 
1608   count += mega_findCard (pHostTmpl, 0x101E, 0x9010, 0);
1609   count += mega_findCard (pHostTmpl, 0x101E, 0x9060, 0);
1610   count += mega_findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
1611 
1612   return count;
1613 }
1614 
1615 /*---------------------------------------------------------------------
1616  * Release the controller's resources
1617  *---------------------------------------------------------------------*/
1618 int megaraid_release (struct Scsi_Host *pSHost)
1619 {
1620   mega_host_config *megaCfg;
1621   mega_mailbox *mbox;
1622   u_char mboxData[16];
1623 
1624   megaCfg = (mega_host_config *) pSHost->hostdata;
1625   mbox = (mega_mailbox *) mboxData;
1626 
1627   /* Flush cache to disk */
1628   memset (mbox, 0, 16);
1629   mboxData[0] = 0xA;
1630 
1631   free_irq (megaCfg->host->irq, megaCfg);/* Must be freed first, otherwise
1632                                            extra interrupt is generated */
1633 
1634   /* Issue a blocking (interrupts disabled) command to the card */
1635   megaIssueCmd (megaCfg, mboxData, NULL, 0);
1636 
1637   /* Free our resources */
1638   if (megaCfg->flag & BOARD_QUARTZ) {
1639     iounmap ((void *) megaCfg->base);
1640   }
1641   else {
1642     release_region (megaCfg->host->io_port, 16);
1643   }
1644 
1645   mega_freeSgList(megaCfg);
1646   scsi_unregister (pSHost);
1647 
1648   return 0;
1649 }
1650 
1651 static inline void mega_freeSgList(mega_host_config *megaCfg)
1652 {
1653   int i;
1654 
1655   for (i = 0; i < megaCfg->max_cmds; i++) {
1656     if (megaCfg->scbList[i].sgList)
1657       kfree (megaCfg->scbList[i].sgList);       /* free sgList */
1658   }
1659 }
1660 
1661 /*----------------------------------------------
1662  * Get information about the card/driver 
1663  *----------------------------------------------*/
1664 const char * megaraid_info (struct Scsi_Host *pSHost)
1665 {
1666   static char buffer[512];
1667   mega_host_config *megaCfg;
1668 
1669   megaCfg = (mega_host_config *) pSHost->hostdata;
1670 
1671   sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans %d luns",
1672            megaCfg->fwVer,
1673            megaCfg->productInfo.MaxConcCmds,
1674            megaCfg->host->max_id,
1675            megaCfg->host->max_channel,
1676            megaCfg->host->max_lun);
1677   return buffer;
1678 }
1679 
1680 /*-----------------------------------------------------------------
1681  * Perform a SCSI command
1682  * Mailbox area:
1683  *   00 01 command
1684  *   01 01 command id
1685  *   02 02 # of sectors
1686  *   04 04 logical bus address
1687  *   08 04 physical buffer address
1688  *   0C 01 logical drive #
1689  *   0D 01 length of scatter/gather list
1690  *   0E 01 reserved
1691  *   0F 01 mailbox busy
1692  *   10 01 numstatus byte
1693  *   11 01 status byte 
1694  *-----------------------------------------------------------------*/
1695 int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
1696 {
1697   DRIVER_LOCK_T
1698   mega_host_config *megaCfg;
1699   mega_scb *pScb;
1700 
1701   megaCfg = (mega_host_config *) SCpnt->host->hostdata;
1702   DRIVER_LOCK(megaCfg);
1703 
1704   if (!(megaCfg->flag & (1L << SCpnt->channel))) {
1705     if (SCpnt->channel < SCpnt->host->max_channel)
1706        printk (/*KERN_INFO*/ "scsi%d: scanning channel %c for devices.\n",
1707             megaCfg->host->host_no,
1708             SCpnt->channel + '1');
1709     else
1710        printk(/*KERN_INFO*/ "scsi%d: scanning virtual channel for logical drives.\n", megaCfg->host->host_no);
1711        
1712     megaCfg->flag |= (1L << SCpnt->channel);
1713   }
1714 
1715   SCpnt->scsi_done = pktComp;
1716 
1717   /* If driver in abort or reset.. cancel this command */
1718   if (megaCfg->flag & IN_ABORT) {
1719     SCpnt->result = (DID_ABORT << 16);
1720     /* Add Scsi_Command to end of completed queue */
1721     if( megaCfg->qCompletedH == NULL ) {
1722       megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
1723     }
1724     else {
1725       megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
1726       megaCfg->qCompletedT = SCpnt;
1727     }
1728     megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
1729     megaCfg->qCcnt++;
1730 
1731     DRIVER_UNLOCK(megaCfg);
1732     return 0;
1733   }
1734   else if (megaCfg->flag & IN_RESET) {
1735     SCpnt->result = (DID_RESET << 16);
1736     /* Add Scsi_Command to end of completed queue */
1737     if( megaCfg->qCompletedH == NULL ) {
1738       megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
1739     }
1740     else {
1741       megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
1742       megaCfg->qCompletedT = SCpnt;
1743     }
1744     megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
1745     megaCfg->qCcnt++;
1746 
1747     DRIVER_UNLOCK(megaCfg);
1748     return 0;
1749   }
1750 
1751   megaCfg->flag |= IN_QUEUE;
1752   /* Allocate and build a SCB request */
1753   if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
1754               /*build SCpnt for IOCTL_CMD_NEW cmd in mega_ioctl()*/
1755     /* Add SCB to the head of the pending queue */
1756     /* Add SCB to the head of the pending queue */
1757     if( megaCfg->qPendingH == NULL ) {
1758       megaCfg->qPendingH = megaCfg->qPendingT = pScb;
1759     }
1760     else {
1761       megaCfg->qPendingT->next = pScb;
1762       megaCfg->qPendingT = pScb;
1763     }
1764     megaCfg->qPendingT->next = NULL;
1765     megaCfg->qPcnt++;
1766 
1767       mega_runpendq(megaCfg);
1768 
1769 #if LINUX_VERSION_CODE > 0x020024
1770     if ( SCpnt->cmnd[0]==IOCTL_CMD_NEW )
1771     {  /* user data from external user buffer */
1772           char *user_area;
1773           u32  xfer_size;
1774 
1775           init_MUTEX_LOCKED(&pScb->sem);
1776           down(&pScb->sem);
1777 
1778           user_area = *((char **)&pScb->SCpnt->cmnd[4]);
1779           xfer_size = *((u32 *)&pScb->SCpnt->cmnd[8]);
1780 
1781           copy_to_user(user_area,pScb->kern_area,xfer_size);
1782 
1783           kfree(pScb->kern_area);
1784 
1785           mega_freeSCB(megaCfg, pScb);
1786     }
1787 #endif
1788   }
1789 
1790   megaCfg->flag &= ~IN_QUEUE;
1791   DRIVER_UNLOCK(megaCfg);
1792 
1793   return 0;
1794 }
1795 
1796 /*----------------------------------------------------------------------
1797  * Issue a blocking command to the controller
1798  *----------------------------------------------------------------------*/
1799 volatile static int internal_done_flag = 0;
1800 volatile static int internal_done_errcode = 0;
1801 static DECLARE_WAIT_QUEUE_HEAD(internal_wait);
1802 
1803 static void internal_done (Scsi_Cmnd * SCpnt)
1804 {
1805   internal_done_errcode = SCpnt->result;
1806   internal_done_flag++;
1807   wake_up(&internal_wait);
1808 }
1809 
1810 /* shouldn't be used, but included for completeness */
1811 
1812 int megaraid_command (Scsi_Cmnd * SCpnt)
1813 {
1814   internal_done_flag = 0;
1815 
1816   /* Queue command, and wait until it has completed */
1817   megaraid_queue (SCpnt, internal_done);
1818 
1819   while (!internal_done_flag) {
1820         interruptible_sleep_on(&internal_wait);
1821   }
1822 
1823   return internal_done_errcode;
1824 }
1825 
1826 /*---------------------------------------------------------------------
1827  * Abort a previous SCSI request
1828  *---------------------------------------------------------------------*/
1829 int
1830 megaraid_abort (Scsi_Cmnd * SCpnt)
1831 {
1832   mega_host_config *megaCfg;
1833   int   rc; //, idx;
1834   mega_scb *pScb;
1835 
1836   rc = SCSI_ABORT_NOT_RUNNING;
1837 
1838   megaCfg = (mega_host_config *) SCpnt->host->hostdata;
1839 
1840   megaCfg->flag |= IN_ABORT;
1841 
1842   for(pScb=megaCfg->qPendingH; pScb; pScb=pScb->next) {
1843     if (pScb->SCpnt == SCpnt) {
1844       /* Found an aborting command */
1845 #if DEBUG
1846       showMbox(pScb);
1847 #endif
1848 
1849 /*
1850  * If the command is queued to be issued to the firmware, abort the scsi cmd,
1851  * If the command is already aborted in a previous call to the _abort entry
1852  *  point, return SCSI_ABORT_SNOOZE, suggesting a reset.
1853  * If the command is issued to the firmware, which might complete after
1854  *  some time, we will mark the scb as aborted, and return to the mid layer, 
1855  *  that abort could not be done.
1856  *  In the ISR, when this command actually completes, we will perform a normal
1857  *  completion.
1858  *
1859  * Oct 27, 1999
1860  */
1861 
1862       switch(pScb->state) {
1863       case SCB_ABORTED: /* Already aborted */
1864         rc = SCSI_ABORT_SNOOZE;
1865         break;
1866       case SCB_ISSUED: /* Waiting on ISR result */
1867         rc = SCSI_ABORT_NOT_RUNNING;
1868         pScb->state = SCB_ABORTED;
1869         break;
1870       case SCB_ACTIVE: /* still on the pending queue */
1871         mega_freeSCB (megaCfg, pScb);
1872         SCpnt->result = (DID_ABORT << 16) ;
1873         if( megaCfg->qCompletedH == NULL ) {
1874           megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
1875         }
1876         else {
1877           megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
1878           megaCfg->qCompletedT = SCpnt;
1879         }
1880         megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
1881         megaCfg->qCcnt++;
1882         rc = SCSI_ABORT_SUCCESS;
1883         break;
1884       default:
1885         printk("megaraid_abort: unknown command state!!\n");
1886         rc = SCSI_ABORT_NOT_RUNNING;
1887         break;
1888       }
1889       break;
1890     }
1891   }
1892 
1893   megaCfg->flag &= ~IN_ABORT;
1894 
1895 #if DEBUG
1896 if(megaCfg->flag & IN_QUEUE)  printk("ma:flag is in queue\n");
1897 if(megaCfg->qCompletedH == NULL) printk("ma:qchead == null\n");
1898 #endif
1899   
1900 /*
1901  * This is required here to complete any completed requests to be communicated
1902  * over to the mid layer.
1903  * Calling just mega_rundoneq() did not work.
1904  */
1905 if(megaCfg->qCompletedH) {
1906   SCpnt = megaCfg->qCompletedH;
1907   megaCfg->qCompletedH = (Scsi_Cmnd *)SCpnt->host_scribble;
1908   megaCfg->qCcnt--;
1909 
1910   SCpnt->host_scribble = (unsigned char *) NULL ;
1911   /* Callback */
1912   callDone (SCpnt);
1913 }
1914   mega_rundoneq(megaCfg);
1915 
1916   return rc;
1917 }
1918 
1919 /*---------------------------------------------------------------------
1920  * Reset a previous SCSI request
1921  *---------------------------------------------------------------------*/
1922 int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
1923 {
1924   mega_host_config *megaCfg;
1925   int idx;
1926   int rc;
1927   mega_scb *pScb;
1928 
1929   rc = SCSI_RESET_NOT_RUNNING;
1930   megaCfg = (mega_host_config *) SCpnt->host->hostdata;
1931 
1932   megaCfg->flag |= IN_RESET;
1933 
1934   printk ("megaraid_RESET: %.08lx cmd=%.02x <c=%d.t=%d.l=%d>, flag = %x\n",
1935         SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
1936           SCpnt->lun, rstflags);
1937 
1938   TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n",
1939         SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
1940           SCpnt->lun));
1941 
1942   /*
1943    * Walk list of SCBs for any that are still outstanding
1944    */
1945   for (idx = 0; idx < megaCfg->max_cmds; idx++) {
1946     if (megaCfg->scbList[idx].state != SCB_FREE) {
1947       SCpnt = megaCfg->scbList[idx].SCpnt;
1948       pScb = &megaCfg->scbList[idx];
1949       if (SCpnt != NULL) {
1950         pScb->state = SCB_RESET;
1951         break;
1952       }
1953     }
1954   }
1955 
1956   megaCfg->flag &= ~IN_RESET;
1957 
1958   mega_rundoneq(megaCfg);
1959   return rc;
1960 }
1961 
1962 /*-------------------------------------------------------------
1963  * Return the disk geometry for a particular disk
1964  * Input:
1965  *   Disk *disk - Disk geometry
1966  *   kdev_t dev - Device node
1967  *   int *geom  - Returns geometry fields
1968  *     geom[0] = heads
1969  *     geom[1] = sectors
1970  *     geom[2] = cylinders
1971  *-------------------------------------------------------------*/
1972 int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom)
1973 {
1974   int heads, sectors, cylinders;
1975   mega_host_config *megaCfg;
1976 
1977   /* Get pointer to host config structure */
1978   megaCfg = (mega_host_config *) disk->device->host->hostdata;
1979 
1980   /* Default heads (64) & sectors (32) */
1981   heads = 64;
1982   sectors = 32;
1983   cylinders = disk->capacity / (heads * sectors);
1984 
1985   /* Handle extended translation size for logical drives > 1Gb */
1986   if (disk->capacity >= 0x200000) {
1987     heads = 255;
1988     sectors = 63;
1989     cylinders = disk->capacity / (heads * sectors);
1990   }
1991 
1992   /* return result */
1993   geom[0] = heads;
1994   geom[1] = sectors;
1995   geom[2] = cylinders;
1996 
1997   return 0;
1998 }
1999 
2000 static int __init megaraid_setup(char *str)
2001 {
2002   skip_id = -1;
2003   if (str && !strncmp(str, "skip", strlen("skip"))) {
2004       if (str[4] != '\0') {
2005           skip_id = str[4] - '';
2006           if (str[5] != '\0') {
2007               skip_id = (skip_id * 10) + (str[5] - '');
2008           }
2009       }
2010       skip_id = (skip_id > 15) ? -1 : skip_id;
2011   }
2012   return 1;
2013 }
2014 
2015 __setup("megaraid=", megaraid_setup);
2016 
2017 static Scsi_Host_Template driver_template = MEGARAID;
2018 
2019 #include "scsi_module.c"
2020 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.