Import 2.3.18pre1
[davej-history.git] / drivers / scsi / megaraid.c
blob62400530496a45ebe4f436d98ae3c345cba76acd
1 /*===================================================================
3 * Linux MegaRAID device driver
5 * Copyright 1998 American Megatrends Inc.
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.
12 * Version : 1.04
14 * Description: Linux device driver for AMI MegaRAID controller
16 * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 490
18 * History:
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.
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.
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.
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>
44 * Merged with 2.1.131 source tree.
45 * 12 Dec 98 K. Baranowski <kgb@knm.org.pl>
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.
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
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
72 * Version 0.96:
73 * 762 fully supported.
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.
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
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.
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().
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
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.
114 * BUGS:
115 * Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
116 * fails to detect the controller as a pci device on the system.
118 * Timeout period for upper scsi layer, i.e. SD_TIMEOUT in
119 * /drivers/scsi/sd.c, is too short for this controller. SD_TIMEOUT
120 * value must be increased to (30 * HZ) otherwise false timeouts
121 * will occur in the upper layer.
123 *===================================================================*/
125 #define CRLFSTR "\n"
126 #define IOCTL_CMD_NEW 0x81
128 #define MEGARAID_VERSION "v1.04 (August 16, 1999)"
130 #include <linux/version.h>
132 #ifdef MODULE
133 #include <linux/modversions.h>
134 #include <linux/module.h>
136 #if LINUX_VERSION_CODE >= 0x20100
137 char kernel_version[] = UTS_RELEASE;
139 MODULE_AUTHOR ("American Megatrends Inc.");
140 MODULE_DESCRIPTION ("AMI MegaRAID driver");
141 #endif
142 #endif
144 #include <linux/types.h>
145 #include <linux/errno.h>
146 #include <linux/kernel.h>
147 #include <linux/sched.h>
148 #include <linux/malloc.h>
149 #include <linux/ioport.h>
150 #include <linux/fcntl.h>
151 #include <linux/delay.h>
152 #include <linux/pci.h>
153 #include <linux/proc_fs.h>
154 #include <linux/blk.h>
155 #include <linux/wait.h>
156 #include <linux/tqueue.h>
157 #include <linux/interrupt.h>
159 #include <linux/stat.h>
160 #if LINUX_VERSION_CODE < 0x20100
161 #include <linux/bios32.h>
162 #else
163 #include <linux/spinlock.h>
164 #endif
166 #include <asm/io.h>
167 #include <asm/irq.h>
168 #include <asm/uaccess.h>
170 #include "sd.h"
171 #include "scsi.h"
172 #include "hosts.h"
174 #include "megaraid.h"
176 /*================================================================
178 * #Defines
180 *================================================================
183 #if LINUX_VERSION_CODE < 0x020100
184 #define ioremap vremap
185 #define iounmap vfree
187 /* simulate spin locks */
188 typedef struct {
189 volatile char lock;
190 } spinlock_t;
192 #define spin_lock_init(x) { (x)->lock = 0;}
193 #define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\
194 (x)->lock=1; save_flags(flags);\
195 cli();}
196 #define spin_unlock_irqrestore(x,flags) { (x)->lock=0; restore_flags(flags);}
198 #endif
200 #if LINUX_VERSION_CODE >= 0x020100
201 #define queue_task_irq(a,b) queue_task(a,b)
202 #define queue_task_irq_off(a,b) queue_task(a,b)
203 #endif
205 #define MAX_SERBUF 160
206 #define COM_BASE 0x2f8
208 #define ENQUEUE(obj,type,list,next) \
209 { type **node; long cpuflag; \
210 spin_lock_irqsave(&mega_lock,cpuflag);\
211 for(node=&(list); *node; node=(type **)&(*node)->##next); \
212 (*node) = obj; \
213 (*node)->##next = NULL; \
214 spin_unlock_irqrestore(&mega_lock,cpuflag);\
217 /* a non-locking version (if we already have the lock) */
218 #define ENQUEUE_NL(obj,type,list,next) \
219 { type **node; \
220 for(node=&(list); *node; node=(type **)&(*node)->##next); \
221 (*node) = obj; \
222 (*node)->##next = NULL; \
225 #define DEQUEUE(obj,type,list,next) \
226 { long cpuflag; \
227 spin_lock_irqsave(&mega_lock,cpuflag);\
228 if ((obj=list) != NULL) {\
229 list = (type *)(list)->##next; \
231 spin_unlock_irqrestore(&mega_lock,cpuflag);\
234 u32 RDINDOOR (mega_host_config * megaCfg)
236 return readl (megaCfg->base + 0x20);
239 void WRINDOOR (mega_host_config * megaCfg, u32 value)
241 writel (value, megaCfg->base + 0x20);
244 u32 RDOUTDOOR (mega_host_config * megaCfg)
246 return readl (megaCfg->base + 0x2C);
249 void WROUTDOOR (mega_host_config * megaCfg, u32 value)
251 writel (value, megaCfg->base + 0x2C);
254 /*================================================================
256 * Function prototypes
258 *================================================================
260 static int megaIssueCmd (mega_host_config * megaCfg,
261 u_char * mboxData,
262 mega_scb * scb,
263 int intr);
264 static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
265 u32 * buffer, u32 * length);
267 static int mega_busyWaitMbox(mega_host_config *);
268 static void mega_runpendq (mega_host_config *);
269 static void mega_rundoneq (void);
270 static void mega_cmd_done (mega_host_config *, mega_scb *, int);
271 static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt);
272 static inline void freeSgList(mega_host_config *megaCfg);
273 static void mega_Convert8ldTo40ld( mega_RAIDINQ *inquiry,
274 mega_Enquiry3 *enquiry3,
275 megaRaidProductInfo *productInfo );
277 /* set SERDEBUG to 1 to enable serial debugging */
278 #define SERDEBUG 0
279 #if SERDEBUG
280 static void ser_init (void);
281 static void ser_puts (char *str);
282 static void ser_putc (char c);
283 static int ser_printk (const char *fmt,...);
284 #endif
286 /*================================================================
288 * Global variables
290 *================================================================
293 /* Use "megaraid=skipXX" as LILO option to prohibit driver from scanning
294 XX scsi id on each channel. Used for Madrona motherboard, where SAF_TE
295 processor id cannot be scanned */
296 static char *megaraid;
297 #if LINUX_VERSION_CODE > 0x20100
298 #ifdef MODULE
299 MODULE_PARM(megaraid, "s");
300 #endif
301 #endif
302 static int skip_id;
304 static int numCtlrs = 0;
305 static mega_host_config *megaCtlrs[FC_MAX_CHANNELS] = {0};
307 #if DEBUG
308 static u32 maxCmdTime = 0;
309 #endif
311 static mega_scb *pLastScb = NULL;
313 /* Queue of pending/completed SCBs */
314 static Scsi_Cmnd *qCompleted = NULL;
316 #if SERDEBUG
317 volatile static spinlock_t serial_lock;
318 #endif
319 volatile static spinlock_t mega_lock;
321 struct proc_dir_entry proc_scsi_megaraid =
323 PROC_SCSI_MEGARAID, 8, "megaraid",
324 S_IFDIR | S_IRUGO | S_IXUGO, 2
327 #if SERDEBUG
328 static char strbuf[MAX_SERBUF + 1];
330 static void ser_init ()
332 unsigned port = COM_BASE;
334 outb (0x80, port + 3);
335 outb (0, port + 1);
336 /* 9600 Baud, if 19200: outb(6,port) */
337 outb (12, port);
338 outb (3, port + 3);
339 outb (0, port + 1);
342 static void ser_puts (char *str)
344 char *ptr;
346 ser_init ();
347 for (ptr = str; *ptr; ++ptr)
348 ser_putc (*ptr);
351 static void ser_putc (char c)
353 unsigned port = COM_BASE;
355 while ((inb (port + 5) & 0x20) == 0);
356 outb (c, port);
357 if (c == 0x0a) {
358 while ((inb (port + 5) & 0x20) == 0);
359 outb (0x0d, port);
363 static int ser_printk (const char *fmt,...)
365 va_list args;
366 int i;
367 long flags;
369 spin_lock_irqsave(&serial_lock,flags);
370 va_start (args, fmt);
371 i = vsprintf (strbuf, fmt, args);
372 ser_puts (strbuf);
373 va_end (args);
374 spin_unlock_irqrestore(&serial_lock,flags);
376 return i;
379 #define TRACE(a) { ser_printk a;}
381 #else
382 #define TRACE(A)
383 #endif
385 void callDone (Scsi_Cmnd * SCpnt)
387 if (SCpnt->result) {
388 TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number,
389 SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun,
390 SCpnt->result));
392 SCpnt->scsi_done (SCpnt);
395 /*-------------------------------------------------------------------------
397 * Local functions
399 *-------------------------------------------------------------------------*/
401 /*=======================
402 * Free a SCB structure
403 *=======================
405 static void freeSCB (mega_host_config *megaCfg, mega_scb * pScb)
407 mega_scb **ppScb;
409 /* Unlink from pending queue */
410 for(ppScb=&megaCfg->qPending; *ppScb; ppScb=&(*ppScb)->next) {
411 if (*ppScb == pScb) {
412 *ppScb = pScb->next;
413 break;
417 /* Link back into list */
418 pScb->state = SCB_FREE;
419 pScb->SCpnt = NULL;
421 pScb->next = megaCfg->qFree;
422 megaCfg->qFree = pScb;
425 /*===========================
426 * Allocate a SCB structure
427 *===========================
429 static mega_scb * allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
431 mega_scb *pScb;
433 /* Unlink command from Free List */
434 if ((pScb = megaCfg->qFree) != NULL) {
435 megaCfg->qFree = pScb->next;
437 pScb->isrcount = jiffies;
438 pScb->next = NULL;
439 pScb->state = SCB_ACTIVE;
440 pScb->SCpnt = SCpnt;
442 return pScb;
445 printk (KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");
447 return NULL;
450 /*================================================
451 * Initialize SCB structures
452 *================================================
454 static int initSCB (mega_host_config * megaCfg)
456 int idx;
458 megaCfg->qFree = NULL;
459 for (idx = megaCfg->max_cmds-1; idx >= 0; idx--) {
460 megaCfg->scbList[idx].idx = idx;
461 megaCfg->scbList[idx].sgList = kmalloc(sizeof(mega_sglist) * MAX_SGLIST,
462 GFP_ATOMIC | GFP_DMA);
463 if (megaCfg->scbList[idx].sgList == NULL) {
464 printk(KERN_WARNING "Can't allocate sglist for id %d\n",idx);
465 freeSgList(megaCfg);
466 return -1;
469 if (idx < MAX_COMMANDS) {
470 /* Link to free list */
471 freeSCB(megaCfg, &megaCfg->scbList[idx]);
474 return 0;
477 /* Run through the list of completed requests */
478 static void mega_rundoneq ()
480 Scsi_Cmnd *SCpnt;
482 while (1) {
483 DEQUEUE (SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
484 if (SCpnt == NULL)
485 return;
487 /* Callback */
488 callDone (SCpnt);
493 Runs through the list of pending requests
494 Assumes that mega_lock spin_lock has been acquired.
496 static void mega_runpendq(mega_host_config *megaCfg)
498 mega_scb *pScb;
500 /* Issue any pending commands to the card */
501 for(pScb=megaCfg->qPending; pScb; pScb=pScb->next) {
502 if (pScb->state == SCB_ACTIVE) {
503 megaIssueCmd(megaCfg, pScb->mboxData, pScb, 1);
508 /* Add command to the list of completed requests */
509 static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb,
510 int status)
512 int islogical;
513 Scsi_Cmnd *SCpnt;
514 mega_passthru *pthru;
515 mega_mailbox *mbox;
517 if (pScb == NULL) {
518 TRACE(("NULL pScb in mega_cmd_done!"));
519 printk("NULL pScb in mega_cmd_done!");
522 SCpnt = pScb->SCpnt;
523 /*freeSCB(megaCfg, pScb);*/ /*delay this to the end of this func.*/
524 pthru = &pScb->pthru;
525 mbox = (mega_mailbox *) &pScb->mboxData;
527 if (SCpnt == NULL) {
528 TRACE(("NULL SCpnt in mega_cmd_done!"));
529 TRACE(("pScb->idx = ",pScb->idx));
530 TRACE(("pScb->state = ",pScb->state));
531 TRACE(("pScb->state = ",pScb->state));
532 printk("Problem...!\n");
533 while(1);
536 islogical = (SCpnt->channel == megaCfg->host->max_channel);
538 if (SCpnt->cmnd[0] == INQUIRY &&
539 ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
540 !islogical) {
541 status = 0xF0;
544 /* clear result; otherwise, success returns corrupt value */
545 SCpnt->result = 0;
547 if ((SCpnt->cmnd[0] & 0x80) ) {/* i.e. ioctl cmd such as 0x80, 0x81 of megamgr*/
548 switch (status) {
549 case 0xF0:
550 case 0xF4:
551 SCpnt->result=(DID_BAD_TARGET<<16)|status;
552 break;
553 default:
554 SCpnt->result|=status;
555 }/*end of switch*/
557 else{
558 /* Convert MegaRAID status to Linux error code */
559 switch (status) {
560 case 0x00: /* SUCCESS , i.e. SCSI_STATUS_GOOD*/
561 SCpnt->result |= (DID_OK << 16);
562 break;
563 case 0x02: /* ERROR_ABORTED, i.e. SCSI_STATUS_CHECK_CONDITION */
564 /*set sense_buffer and result fields*/
565 if( mbox->cmd==MEGA_MBOXCMD_PASSTHRU ){
566 memcpy( SCpnt->sense_buffer , pthru->reqsensearea, 14);
567 SCpnt->result = (DRIVER_SENSE<<24)|(DID_ERROR << 16)|status;
569 else{
570 SCpnt->sense_buffer[0]=0x70;
571 SCpnt->sense_buffer[2]=ABORTED_COMMAND;
572 SCpnt->result |= (CHECK_CONDITION << 1);
574 break;
575 case 0x08: /* ERR_DEST_DRIVE_FAILED, i.e. SCSI_STATUS_BUSY */
576 SCpnt->result |= (DID_BUS_BUSY << 16)|status;
577 break;
578 default:
579 SCpnt->result |= (DID_BAD_TARGET << 16)|status;
580 break;
583 if ( SCpnt->cmnd[0]!=IOCTL_CMD_NEW )
584 /* not IOCTL_CMD_NEW SCB, freeSCB()*/
585 /* For IOCTL_CMD_NEW SCB, delay freeSCB() in megaraid_queue()
586 * after copy data back to user space*/
587 freeSCB(megaCfg, pScb);
589 /* Add Scsi_Command to end of completed queue */
590 ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
593 /*-------------------------------------------------------------------
595 * Build a SCB from a Scsi_Cmnd
597 * Returns a SCB pointer, or NULL
598 * If NULL is returned, the scsi_done function MUST have been called
600 *-------------------------------------------------------------------*/
601 static mega_scb * mega_build_cmd (mega_host_config * megaCfg,
602 Scsi_Cmnd * SCpnt)
604 mega_scb *pScb;
605 mega_mailbox *mbox;
606 mega_passthru *pthru;
607 long seg;
608 char islogical;
609 char lun = SCpnt->lun;
611 if ((SCpnt->cmnd[0] == 0x80) || (SCpnt->cmnd[0] == IOCTL_CMD_NEW) ) /* ioctl */
612 return mega_ioctl (megaCfg, SCpnt);
614 islogical = (SCpnt->channel == megaCfg->host->max_channel);
616 if (!islogical && lun != 0) {
617 SCpnt->result = (DID_BAD_TARGET << 16);
618 callDone (SCpnt);
619 return NULL;
622 if (!islogical && SCpnt->target == skip_id) {
623 SCpnt->result = (DID_BAD_TARGET << 16);
624 callDone (SCpnt);
625 return NULL;
628 if ( islogical ) {
629 lun = (SCpnt->target * 8) + lun;
630 #if 1
631 if ( lun > FC_MAX_LOGICAL_DRIVES ){
632 SCpnt->result = (DID_BAD_TARGET << 16);
633 callDone (SCpnt);
634 return NULL;
636 #endif
638 /*-----------------------------------------------------
640 * Logical drive commands
642 *-----------------------------------------------------*/
643 if (islogical) {
644 switch (SCpnt->cmnd[0]) {
645 case TEST_UNIT_READY:
646 memset (SCpnt->request_buffer, 0, SCpnt->request_bufflen);
647 SCpnt->result = (DID_OK << 16);
648 callDone (SCpnt);
649 return NULL;
651 case MODE_SENSE:
652 memset (SCpnt->request_buffer, 0, SCpnt->cmnd[4]);
653 SCpnt->result = (DID_OK << 16);
654 callDone (SCpnt);
655 return NULL;
657 case READ_CAPACITY:
658 case INQUIRY:
659 /* Allocate a SCB and initialize passthru */
660 if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
661 SCpnt->result = (DID_ERROR << 16);
662 callDone (SCpnt);
663 return NULL;
665 pthru = &pScb->pthru;
666 mbox = (mega_mailbox *) & pScb->mboxData;
668 memset (mbox, 0, sizeof (pScb->mboxData));
669 memset (pthru, 0, sizeof (mega_passthru));
670 pthru->timeout = 0;
671 pthru->ars = 1;
672 pthru->reqsenselen = 14;
673 pthru->islogical = 1;
674 pthru->logdrv = lun;
675 pthru->cdblen = SCpnt->cmd_len;
676 pthru->dataxferaddr = virt_to_bus (SCpnt->request_buffer);
677 pthru->dataxferlen = SCpnt->request_bufflen;
678 memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
680 /* Initialize mailbox area */
681 mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
682 mbox->xferaddr = virt_to_bus (pthru);
684 return pScb;
686 case READ_6:
687 case WRITE_6:
688 case READ_10:
689 case WRITE_10:
690 /* Allocate a SCB and initialize mailbox */
691 if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
692 SCpnt->result = (DID_ERROR << 16);
693 callDone (SCpnt);
694 return NULL;
696 mbox = (mega_mailbox *) & pScb->mboxData;
698 memset (mbox, 0, sizeof (pScb->mboxData));
699 mbox->logdrv = lun;
700 mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ?
701 MEGA_MBOXCMD_LREAD : MEGA_MBOXCMD_LWRITE;
703 /* 6-byte */
704 if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) {
705 mbox->numsectors =
706 (u32) SCpnt->cmnd[4];
707 mbox->lba =
708 ((u32) SCpnt->cmnd[1] << 16) |
709 ((u32) SCpnt->cmnd[2] << 8) |
710 (u32) SCpnt->cmnd[3];
711 mbox->lba &= 0x1FFFFF;
714 /* 10-byte */
715 if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) {
716 mbox->numsectors =
717 (u32) SCpnt->cmnd[8] |
718 ((u32) SCpnt->cmnd[7] << 8);
719 mbox->lba =
720 ((u32) SCpnt->cmnd[2] << 24) |
721 ((u32) SCpnt->cmnd[3] << 16) |
722 ((u32) SCpnt->cmnd[4] << 8) |
723 (u32) SCpnt->cmnd[5];
726 /* Calculate Scatter-Gather info */
727 mbox->numsgelements = build_sglist (megaCfg, pScb,
728 (u32 *) & mbox->xferaddr,
729 (u32 *) & seg);
731 return pScb;
733 default:
734 SCpnt->result = (DID_BAD_TARGET << 16);
735 callDone (SCpnt);
736 return NULL;
739 /*-----------------------------------------------------
741 * Passthru drive commands
743 *-----------------------------------------------------*/
744 else {
745 /* Allocate a SCB and initialize passthru */
746 if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
747 SCpnt->result = (DID_ERROR << 16);
748 callDone (SCpnt);
749 return NULL;
751 pthru = &pScb->pthru;
752 mbox = (mega_mailbox *) pScb->mboxData;
754 memset (mbox, 0, sizeof (pScb->mboxData));
755 memset (pthru, 0, sizeof (mega_passthru));
756 pthru->timeout = 2; /*set adapter timeout value to 10 min. for tape drive*/
757 /* 0=6sec/1=60sec/2=10min/3=3hrs */
758 pthru->ars = 1;
759 pthru->reqsenselen = 14;
760 pthru->islogical = 0;
761 pthru->channel = (megaCfg->flag & BOARD_40LD) ? 0 : SCpnt->channel;
762 pthru->target = (megaCfg->flag & BOARD_40LD) ? /*BOARD_40LD*/
763 (SCpnt->channel<<4)|SCpnt->target : SCpnt->target;
764 pthru->cdblen = SCpnt->cmd_len;
765 memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
767 pthru->numsgelements = build_sglist (megaCfg, pScb,
768 (u32 *) & pthru->dataxferaddr,
769 (u32 *) & pthru->dataxferlen);
771 /* Initialize mailbox */
772 mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
773 mbox->xferaddr = virt_to_bus (pthru);
775 return pScb;
777 return NULL;
780 /*--------------------------------------------------------------------
781 * build RAID commands for controller, passed down through ioctl()
782 *--------------------------------------------------------------------*/
783 static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
785 mega_scb *pScb;
786 mega_ioctl_mbox *mbox;
787 mega_mailbox *mailbox;
788 mega_passthru *pthru;
789 u8 *mboxdata;
790 long seg;
791 unsigned char *data = (unsigned char *)SCpnt->request_buffer;
792 int i;
794 if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
795 SCpnt->result = (DID_ERROR << 16);
796 callDone (SCpnt);
797 return NULL;
800 #if 0
801 printk("\nBUF: ");
802 for (i=0;i<18;i++) {
803 printk(" %x",data[i]);
805 printk("......\n");
806 #endif
808 mboxdata = (u8 *) & pScb->mboxData;
809 mbox = (mega_ioctl_mbox *) & pScb->mboxData;
810 mailbox = (mega_mailbox *) & pScb->mboxData;
811 memset (mailbox, 0, sizeof (pScb->mboxData));
813 if (data[0] == 0x03) { /* passthrough command */
814 unsigned char cdblen = data[2];
815 pthru = &pScb->pthru;
816 memset (pthru, 0, sizeof (mega_passthru));
817 pthru->islogical = (data[cdblen+3] & 0x80) ? 1:0;
818 pthru->timeout = data[cdblen+3] & 0x07;
819 pthru->reqsenselen = 14;
820 pthru->ars = (data[cdblen+3] & 0x08) ? 1:0;
821 pthru->logdrv = data[cdblen+4];
822 pthru->channel = data[cdblen+5];
823 pthru->target = data[cdblen+6];
824 pthru->cdblen = cdblen;
825 memcpy (pthru->cdb, &data[3], cdblen);
827 mailbox->cmd = MEGA_MBOXCMD_PASSTHRU;
828 mailbox->xferaddr = virt_to_bus (pthru);
830 pthru->numsgelements = build_sglist (megaCfg, pScb,
831 (u32 *) & pthru->dataxferaddr,
832 (u32 *) & pthru->dataxferlen);
834 for (i=0;i<(SCpnt->request_bufflen-cdblen-7);i++) {
835 data[i] = data[i+cdblen+7];
838 return pScb;
840 /* else normal (nonpassthru) command */
842 if (SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
843 /* use external data area for large xfers */
844 /* If cmnd[0] is set to IOCTL_CMD_NEW then *
845 * cmnd[4..7] = external user buffer *
846 * cmnd[8..11] = length of buffer *
847 * */
848 char *kern_area;
849 char *user_area = *((char **)&SCpnt->cmnd[4]);
850 u32 xfer_size = *((u32 *)&SCpnt->cmnd[8]);
851 if (verify_area(VERIFY_READ, user_area, xfer_size)) {
852 printk("megaraid: Got bad user address.\n");
853 SCpnt->result = (DID_ERROR << 16);
854 callDone (SCpnt);
855 return NULL;
857 kern_area = kmalloc(xfer_size, GFP_ATOMIC | GFP_DMA);
858 if (kern_area == NULL) {
859 printk("megaraid: Couldn't allocate kernel mem.\n");
860 SCpnt->result = (DID_ERROR << 16);
861 callDone (SCpnt);
862 return NULL;
864 copy_from_user(kern_area,user_area,xfer_size);
865 pScb->kern_area = kern_area;
868 mbox->cmd = data[0];
869 mbox->channel = data[1];
870 mbox->param = data[2];
871 mbox->pad[0] = data[3];
872 mbox->logdrv = data[4];
874 if(SCpnt->cmnd[0] == IOCTL_CMD_NEW) {
875 if(data[0]==DCMD_FC_CMD){ /*i.e. 0xA1, then override some mbox data */
876 *(mboxdata+0) = data[0]; /*mailbox byte 0: DCMD_FC_CMD*/
877 *(mboxdata+2) = data[2]; /*sub command*/
878 *(mboxdata+3) = 0; /*number of elements in SG list*/
879 mbox->xferaddr /*i.e. mboxdata byte 0x8 to 0xb*/
880 = virt_to_bus(pScb->kern_area);
882 else{
883 mbox->xferaddr = virt_to_bus(pScb->kern_area);
884 mbox->numsgelements = 0;
887 else {
889 mbox->numsgelements = build_sglist (megaCfg, pScb,
890 (u32 *) & mbox->xferaddr,
891 (u32 *) & seg);
893 for (i=0;i<(SCpnt->request_bufflen-6);i++) {
894 data[i] = data[i+6];
898 return (pScb);
901 #if DEBUG
902 static void showMbox(mega_scb *pScb)
904 mega_mailbox *mbox;
906 if (pScb == NULL) return;
908 mbox = (mega_mailbox *)pScb->mboxData;
909 printk("%u cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n",
910 pScb->SCpnt->pid,
911 mbox->cmd, mbox->cmdid, mbox->numsectors,
912 mbox->lba, mbox->xferaddr, mbox->logdrv,
913 mbox->numsgelements);
915 #endif
917 /*--------------------------------------------------------------------
918 * Interrupt service routine
919 *--------------------------------------------------------------------*/
920 static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
922 mega_host_config *megaCfg;
923 u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE];
924 u32 dword;
925 mega_mailbox *mbox;
926 mega_scb *pScb;
927 long flags;
928 int qCnt, qStatus;
930 megaCfg = (mega_host_config *) devp;
931 mbox = (mega_mailbox *)tmpBox;
933 #if LINUX_VERSION_CODE >= 0x20100
934 spin_lock_irqsave (&io_request_lock, flags);
935 #endif
937 while (megaCfg->host->irq == irq) {
939 spin_lock_irqsave (&mega_lock, flags);
941 if (megaCfg->flag & IN_ISR) {
942 TRACE (("ISR called reentrantly!!\n"));
945 megaCfg->flag |= IN_ISR;
947 if (mega_busyWaitMbox(megaCfg)) {
948 printk(KERN_WARNING "Error: mailbox busy in isr!\n");
952 /* Check if a valid interrupt is pending */
953 if (megaCfg->flag & BOARD_QUARTZ) {
954 dword = RDOUTDOOR (megaCfg);
955 if (dword != 0x10001234) {
956 /* Spurious interrupt */
957 megaCfg->flag &= ~IN_ISR;
958 spin_unlock_irqrestore (&mega_lock, flags);
959 break;
961 WROUTDOOR (megaCfg, dword);
963 /* Copy to temp location */
964 memcpy(tmpBox, (mega_mailbox *)megaCfg->mbox, MAILBOX_SIZE);
966 /* Acknowledge interrupt */
967 WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
968 while (RDINDOOR (megaCfg) & 0x02);
970 else {
971 byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
972 if ((byte & VALID_INTR_BYTE) == 0) {
973 /* Spurious interrupt */
974 megaCfg->flag &= ~IN_ISR;
975 spin_unlock_irqrestore (&mega_lock, flags);
976 break;
978 WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
980 /* Copy to temp location */
981 memcpy(tmpBox, (mega_mailbox *)megaCfg->mbox, MAILBOX_SIZE);
983 /* Acknowledge interrupt */
984 CLEAR_INTR (megaCfg->host->io_port);
987 qCnt = mbox->numstatus;
988 qStatus = mbox->status;
990 for (idx = 0; idx < qCnt; idx++) {
991 sIdx = mbox->completed[idx];
992 if (sIdx > 0) {
993 pScb = &megaCfg->scbList[sIdx - 1];
995 /* ASSERT(pScb->state == SCB_ISSUED); */
997 #if DEBUG
998 if (((jiffies) - pScb->isrcount) > maxCmdTime) {
999 maxCmdTime = (jiffies) - pScb->isrcount;
1000 printk("cmd time = %u\n", maxCmdTime);
1002 #endif
1004 if (pScb->state == SCB_ABORTED) {
1005 printk("Received aborted SCB! %u\n", (int)((jiffies)-pScb->isrcount));
1008 if (*(pScb->SCpnt->cmnd)==IOCTL_CMD_NEW)
1009 { /* external user buffer */
1010 up(&pScb->sem);
1012 /* Mark command as completed */
1013 mega_cmd_done(megaCfg, pScb, qStatus);
1018 spin_unlock_irqrestore (&mega_lock, flags);
1020 megaCfg->flag &= ~IN_ISR;
1022 mega_rundoneq();
1024 /* Loop through any pending requests */
1025 spin_lock_irqsave(&mega_lock, flags);
1026 mega_runpendq(megaCfg);
1027 spin_unlock_irqrestore(&mega_lock,flags);
1031 #if LINUX_VERSION_CODE >= 0x20100
1032 spin_unlock_irqrestore (&io_request_lock, flags);
1033 #endif
1036 /*==================================================*/
1037 /* Wait until the controller's mailbox is available */
1038 /*==================================================*/
1039 static int mega_busyWaitMbox (mega_host_config * megaCfg)
1041 mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
1042 long counter;
1044 for (counter = 0; counter < 10000; counter++) {
1045 if (!mbox->busy) {
1046 return 0;
1048 udelay (100);
1049 barrier();
1051 return -1; /* give up after 1 second */
1054 /*=====================================================
1055 * Post a command to the card
1057 * Arguments:
1058 * mega_host_config *megaCfg - Controller structure
1059 * u_char *mboxData - Mailbox area, 16 bytes
1060 * mega_scb *pScb - SCB posting (or NULL if N/A)
1061 * int intr - if 1, interrupt, 0 is blocking
1062 * Return Value: (added on 7/26 for 40ld/64bit)
1063 * -1: the command was not actually issued out
1064 * othercases:
1065 * intr==0, return ScsiStatus, i.e. mbox->status
1066 * intr==1, return 0
1067 *=====================================================
1069 static int megaIssueCmd (mega_host_config * megaCfg,
1070 u_char * mboxData,
1071 mega_scb * pScb,
1072 int intr)
1074 mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
1075 u_char byte;
1076 u32 cmdDone;
1077 Scsi_Cmnd *SCpnt;
1078 u32 phys_mbox;
1079 u8 retval=-1;
1081 mboxData[0x1] = (pScb ? pScb->idx + 1: 0x0); /* Set cmdid */
1082 mboxData[0xF] = 1; /* Set busy */
1084 phys_mbox = virt_to_bus (megaCfg->mbox);
1086 #if 0
1087 if (intr && mbox->busy) {
1088 return 0;
1090 #endif
1092 #if DEBUG
1093 showMbox(pScb);
1094 #endif
1096 /* Wait until mailbox is free */
1097 while (mega_busyWaitMbox (megaCfg)) {
1098 printk("Blocked mailbox......!!\n");
1099 udelay(1000);
1101 #if DEBUG
1102 showMbox(pLastScb);
1103 #endif
1105 /* Abort command */
1106 if (pScb == NULL) {
1107 printk("NULL pScb in megaIssue\n");
1108 TRACE(("NULL pScb in megaIssue\n"));
1110 SCpnt = pScb->SCpnt;
1111 freeSCB(megaCfg, pScb);
1113 SCpnt->result = (DID_ABORT << 16);
1114 callDone(SCpnt);
1115 return -1;
1118 pLastScb = pScb;
1120 /* Copy mailbox data into host structure */
1121 megaCfg->mbox64->xferSegment = 0;
1122 memcpy (mbox, mboxData, 16);
1124 /* Kick IO */
1125 if (intr) {
1127 /* Issue interrupt (non-blocking) command */
1128 if (megaCfg->flag & BOARD_QUARTZ) {
1129 mbox->mraid_poll = 0;
1130 mbox->mraid_ack = 0;
1131 WRINDOOR (megaCfg, phys_mbox | 0x1);
1133 else {
1134 ENABLE_INTR (megaCfg->host->io_port);
1135 ISSUE_COMMAND (megaCfg->host->io_port);
1137 pScb->state = SCB_ISSUED;
1139 retval=0;
1141 else { /* Issue non-ISR (blocking) command */
1142 disable_irq(megaCfg->host->irq);
1143 if (megaCfg->flag & BOARD_QUARTZ) {
1144 mbox->mraid_poll = 0;
1145 mbox->mraid_ack = 0;
1146 WRINDOOR (megaCfg, phys_mbox | 0x1);
1148 while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
1149 WROUTDOOR (megaCfg, cmdDone);
1151 if (pScb) {
1152 mega_cmd_done (megaCfg, pScb, mbox->status);
1153 mega_rundoneq ();
1156 WRINDOOR (megaCfg, phys_mbox | 0x2);
1157 while (RDINDOOR (megaCfg) & 0x2);
1160 else {
1161 DISABLE_INTR (megaCfg->host->io_port);
1162 ISSUE_COMMAND (megaCfg->host->io_port);
1164 while (!((byte = READ_PORT (megaCfg->host->io_port, INTR_PORT)) & INTR_VALID));
1165 WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
1168 ENABLE_INTR (megaCfg->host->io_port);
1169 CLEAR_INTR (megaCfg->host->io_port);
1171 if (pScb) {
1172 mega_cmd_done (megaCfg, pScb, mbox->status);
1173 mega_rundoneq ();
1175 else {
1176 TRACE (("Error: NULL pScb!\n"));
1180 enable_irq(megaCfg->host->irq);
1181 retval=mbox->status;
1183 while (mega_busyWaitMbox (megaCfg)) {
1184 printk("Blocked mailbox on exit......!\n");
1185 udelay(1000);
1188 return retval;
1191 /*-------------------------------------------------------------------
1192 * Copies data to SGLIST
1193 *-------------------------------------------------------------------*/
1194 static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
1195 u32 * buffer, u32 * length)
1197 struct scatterlist *sgList;
1198 int idx;
1200 /* Scatter-gather not used */
1201 if (scb->SCpnt->use_sg == 0) {
1202 *buffer = virt_to_bus (scb->SCpnt->request_buffer);
1203 *length = (u32) scb->SCpnt->request_bufflen;
1204 return 0;
1207 sgList = (struct scatterlist *) scb->SCpnt->request_buffer;
1208 if (scb->SCpnt->use_sg == 1) {
1209 *buffer = virt_to_bus (sgList[0].address);
1210 *length = (u32) sgList[0].length;
1211 return 0;
1214 /* Copy Scatter-Gather list info into controller structure */
1215 for (idx = 0; idx < scb->SCpnt->use_sg; idx++) {
1216 scb->sgList[idx].address = virt_to_bus (sgList[idx].address);
1217 scb->sgList[idx].length = (u32) sgList[idx].length;
1220 /* Reset pointer and length fields */
1221 *buffer = virt_to_bus (scb->sgList);
1222 *length = 0;
1224 /* Return count of SG requests */
1225 return scb->SCpnt->use_sg;
1228 /*--------------------------------------------------------------------
1229 * Initializes the adress of the controller's mailbox register
1230 * The mailbox register is used to issue commands to the card.
1231 * Format of the mailbox area:
1232 * 00 01 command
1233 * 01 01 command id
1234 * 02 02 # of sectors
1235 * 04 04 logical bus address
1236 * 08 04 physical buffer address
1237 * 0C 01 logical drive #
1238 * 0D 01 length of scatter/gather list
1239 * 0E 01 reserved
1240 * 0F 01 mailbox busy
1241 * 10 01 numstatus byte
1242 * 11 01 status byte
1243 *--------------------------------------------------------------------*/
1244 static int mega_register_mailbox (mega_host_config * megaCfg, u32 paddr)
1246 /* align on 16-byte boundry */
1247 megaCfg->mbox = &megaCfg->mailbox64.mailbox;
1248 megaCfg->mbox = (mega_mailbox *) ((((u32) megaCfg->mbox) + 16) & 0xfffffff0);
1249 megaCfg->mbox64 = (mega_mailbox64 *) (megaCfg->mbox - 4);
1250 paddr = (paddr + 4 + 16) & 0xfffffff0;
1252 /* Register mailbox area with the firmware */
1253 if (megaCfg->flag & BOARD_QUARTZ) {
1255 else {
1256 WRITE_PORT (megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF);
1257 WRITE_PORT (megaCfg->host->io_port, MBOX_PORT1, (paddr >> 8) & 0xFF);
1258 WRITE_PORT (megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF);
1259 WRITE_PORT (megaCfg->host->io_port, MBOX_PORT3, (paddr >> 24) & 0xFF);
1260 WRITE_PORT (megaCfg->host->io_port, ENABLE_MBOX_REGION, ENABLE_MBOX_BYTE);
1262 CLEAR_INTR (megaCfg->host->io_port);
1263 ENABLE_INTR (megaCfg->host->io_port);
1265 return 0;
1269 /*---------------------------------------------------------------------------
1270 * mega_Convert8ldTo40ld() -- takes all info in AdapterInquiry structure and
1271 * puts it into ProductInfo and Enquiry3 structures for later use
1272 *---------------------------------------------------------------------------*/
1273 static void mega_Convert8ldTo40ld( mega_RAIDINQ *inquiry,
1274 mega_Enquiry3 *enquiry3,
1275 megaRaidProductInfo *productInfo )
1277 int i;
1279 productInfo->MaxConcCmds = inquiry->AdpInfo.MaxConcCmds;
1280 enquiry3->rbldRate = inquiry->AdpInfo.RbldRate;
1281 productInfo->SCSIChanPresent = inquiry->AdpInfo.ChanPresent;
1282 for (i=0;i<4;i++) {
1283 productInfo->FwVer[i] = inquiry->AdpInfo.FwVer[i];
1284 productInfo->BiosVer[i] = inquiry->AdpInfo.BiosVer[i];
1286 enquiry3->cacheFlushInterval = inquiry->AdpInfo.CacheFlushInterval;
1287 productInfo->DramSize = inquiry->AdpInfo.DramSize;
1289 enquiry3->numLDrv = inquiry->LogdrvInfo.NumLDrv;
1290 for (i=0;i<MAX_LOGICAL_DRIVES;i++) {
1291 enquiry3->lDrvSize[i] = inquiry->LogdrvInfo.LDrvSize[i];
1292 enquiry3->lDrvProp[i] = inquiry->LogdrvInfo.LDrvProp[i];
1293 enquiry3->lDrvState[i] = inquiry->LogdrvInfo.LDrvState[i];
1296 for (i=0;i<(MAX_PHYSICAL_DRIVES);i++) {
1297 enquiry3->pDrvState[i] = inquiry->PhysdrvInfo.PDrvState[i];
1302 /*-------------------------------------------------------------------
1303 * Issue an adapter info query to the controller
1304 *-------------------------------------------------------------------*/
1305 static int mega_i_query_adapter (mega_host_config * megaCfg)
1307 mega_Enquiry3 *enquiry3Pnt;
1308 mega_mailbox *mbox;
1309 u_char mboxData[16];
1310 u32 paddr;
1311 u8 retval;
1313 spin_lock_init (&mega_lock);
1315 /* Initialize adapter inquiry mailbox*/
1316 paddr = virt_to_bus (megaCfg->mega_buffer);
1317 mbox = (mega_mailbox *) mboxData;
1319 memset ((void *) megaCfg->mega_buffer, 0, sizeof (megaCfg->mega_buffer));
1320 memset (mbox, 0, 16);
1323 * Try to issue Enquiry3 command
1324 * if not suceeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
1325 * update enquiry3 structure
1327 mbox->xferaddr = virt_to_bus ( (void*) megaCfg->mega_buffer);
1328 /* Initialize mailbox databuffer addr */
1329 enquiry3Pnt = (mega_Enquiry3 *) megaCfg->mega_buffer;
1330 /* point mega_Enguiry3 to the data buf */
1332 mboxData[0]=FC_NEW_CONFIG ; /* i.e. mbox->cmd=0xA1 */
1333 mboxData[2]=NC_SUBOP_ENQUIRY3; /* i.e. 0x0F */
1334 mboxData[3]=ENQ3_GET_SOLICITED_FULL; /* i.e. 0x02 */
1336 /* Issue a blocking command to the card */
1337 if ( (retval=megaIssueCmd(megaCfg, mboxData, NULL, 0)) != 0 )
1338 { /* the adapter does not support 40ld*/
1340 mega_RAIDINQ adapterInquiryData;
1341 mega_RAIDINQ *adapterInquiryPnt = &adapterInquiryData;
1343 mbox->xferaddr = virt_to_bus ( (void*) adapterInquiryPnt);
1345 mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ; /*issue old 0x05 command to adapter*/
1346 /* Issue a blocking command to the card */;
1347 retval=megaIssueCmd (megaCfg, mboxData, NULL, 0);
1349 /*update Enquiry3 and ProductInfo structures with mega_RAIDINQ structure*/
1350 mega_Convert8ldTo40ld( adapterInquiryPnt,
1351 enquiry3Pnt,
1352 (megaRaidProductInfo * ) &megaCfg->productInfo );
1355 else{ /* adapter supports 40ld */
1356 megaCfg->flag |= BOARD_40LD;
1358 /*get productInfo, which is static information and will be unchanged*/
1359 mbox->xferaddr = virt_to_bus ( (void*) &megaCfg->productInfo );
1361 mboxData[0]=FC_NEW_CONFIG ; /* i.e. mbox->cmd=0xA1 */
1362 mboxData[2]=NC_SUBOP_PRODUCT_INFO; /* i.e. 0x0E */
1364 if( (retval=megaIssueCmd(megaCfg, mboxData, NULL, 0)) != 0 )
1365 printk("ami:Product_info (0x0E) cmd failed with error: %d\n", retval);
1369 megaCfg->host->max_channel = megaCfg->productInfo.SCSIChanPresent;
1370 megaCfg->host->max_id = 16; /* max targets per channel */
1371 /*(megaCfg->flag & BOARD_40LD)?FC_MAX_TARGETS_PER_CHANNEL:MAX_TARGET+1;*/
1372 megaCfg->host->max_lun = /* max lun */
1373 (megaCfg->flag & BOARD_40LD) ? FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;
1375 megaCfg->numldrv = enquiry3Pnt->numLDrv;
1376 megaCfg->max_cmds = megaCfg->productInfo.MaxConcCmds;
1378 #if 0
1379 int i;
1380 printk (KERN_DEBUG "---- Logical drive info from enquiry3 struct----\n");
1381 for (i = 0; i < megaCfg->numldrv; i++) {
1382 printk ("%d: size: %d prop: %x state: %x\n", i,
1383 enquiry3Pnt->lDrvSize[i],
1384 enquiry3Pnt->lDrvProp[i],
1385 enquiry3Pnt->lDrvState[i]);
1388 printk (KERN_DEBUG "---- Physical drive info ----\n");
1389 for (i = 0; i < FC_MAX_PHYSICAL_DEVICES; i++) {
1390 if (i && !(i % 8))
1391 printk ("\n");
1392 printk ("%d: %x ", i, enquiry3Pnt->pDrvState[i]);
1394 printk ("\n");
1395 #endif
1397 #ifdef HP /* use HP firmware and bios version encoding */
1398 sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
1399 megaCfg->productInfo.FwVer[2],
1400 megaCfg->productInfo.FwVer[1] >> 8,
1401 megaCfg->productInfo.FwVer[1] & 0x0f,
1402 megaCfg->productInfo.FwVer[2] >> 8,
1403 megaCfg->productInfo.FwVer[2] & 0x0f);
1404 sprintf (megaCfg->biosVer, "%c%d%d.%d%d",
1405 megaCfg->productInfo.BiosVer[2],
1406 megaCfg->productInfo.BiosVer[1] >> 8,
1407 megaCfg->productInfo.BiosVer[1] & 0x0f,
1408 megaCfg->productInfo.BiosVer[2] >> 8,
1409 megaCfg->productInfo.BiosVer[2] & 0x0f);
1410 #else
1411 memcpy (megaCfg->fwVer, (void *)megaCfg->productInfo.FwVer, 4);
1412 megaCfg->fwVer[4] = 0;
1414 memcpy (megaCfg->biosVer, (void *)megaCfg->productInfo.BiosVer, 4);
1415 megaCfg->biosVer[4] = 0;
1416 #endif
1418 printk ("megaraid: [%s:%s] detected %d logical drives" CRLFSTR,
1419 megaCfg->fwVer,
1420 megaCfg->biosVer,
1421 megaCfg->numldrv);
1423 return 0;
1426 /*-------------------------------------------------------------------------
1428 * Driver interface functions
1430 *-------------------------------------------------------------------------*/
1432 /*----------------------------------------------------------
1433 * Returns data to be displayed in /proc/scsi/megaraid/X
1434 *----------------------------------------------------------*/
1435 int megaraid_proc_info (char *buffer, char **start, off_t offset,
1436 int length, int host_no, int inout)
1438 *start = buffer;
1439 return 0;
1442 int findCard (Scsi_Host_Template * pHostTmpl,
1443 u16 pciVendor, u16 pciDev,
1444 long flag)
1446 mega_host_config *megaCfg;
1447 struct Scsi_Host *host;
1448 u_char pciBus, pciDevFun, megaIrq;
1449 u32 megaBase;
1450 u16 pciIdx = 0;
1451 u16 numFound = 0;
1453 #if LINUX_VERSION_CODE < 0x20100
1454 while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
1456 #if 0
1457 } /* keep auto-indenters happy */
1458 #endif
1459 #else
1461 struct pci_dev *pdev = pci_devices;
1463 while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) {
1464 pciBus = pdev->bus->number;
1465 pciDevFun = pdev->devfn;
1466 #endif
1467 if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
1468 u16 magic;
1469 pcibios_read_config_word (pciBus, pciDevFun,
1470 PCI_CONF_AMISIG,
1471 &magic);
1472 if (magic != AMI_SIGNATURE) {
1473 pciIdx++;
1474 continue; /* not an AMI board */
1477 printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:func %d\n",
1478 pciVendor,
1479 pciDev,
1480 pciIdx, pciBus,
1481 PCI_SLOT (pciDevFun),
1482 PCI_FUNC (pciDevFun));
1484 /* Read the base port and IRQ from PCI */
1485 megaBase = pdev->resource[0].start;
1486 megaIrq = pdev->irq;
1487 pciIdx++;
1489 if (flag & BOARD_QUARTZ) {
1491 megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
1492 megaBase = (long) ioremap (megaBase, 128);
1494 else {
1495 megaBase &= PCI_BASE_ADDRESS_IO_MASK;
1496 megaBase += 0x10;
1499 /* Initialize SCSI Host structure */
1500 host = scsi_register (pHostTmpl, sizeof (mega_host_config));
1501 megaCfg = (mega_host_config *) host->hostdata;
1502 memset (megaCfg, 0, sizeof (mega_host_config));
1504 printk ("scsi%d : Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR,
1505 host->host_no, (u_int) megaBase, megaIrq);
1507 /* Copy resource info into structure */
1508 megaCfg->qPending = NULL;
1509 megaCfg->qFree = NULL;
1510 megaCfg->flag = flag;
1511 megaCfg->host = host;
1512 megaCfg->base = megaBase;
1513 megaCfg->host->irq = megaIrq;
1514 megaCfg->host->io_port = megaBase;
1515 megaCfg->host->n_io_port = 16;
1516 megaCfg->host->unique_id = (pciBus << 8) | pciDevFun;
1517 megaCtlrs[numCtlrs++] = megaCfg;
1518 if (flag != BOARD_QUARTZ) {
1519 /* Request our IO Range */
1520 if (check_region (megaBase, 16)) {
1521 printk (KERN_WARNING "megaraid: Couldn't register I/O range!" CRLFSTR);
1522 scsi_unregister (host);
1523 continue;
1525 request_region (megaBase, 16, "megaraid");
1528 /* Request our IRQ */
1529 if (request_irq (megaIrq, megaraid_isr, SA_SHIRQ,
1530 "megaraid", megaCfg)) {
1531 printk (KERN_WARNING "megaraid: Couldn't register IRQ %d!" CRLFSTR,
1532 megaIrq);
1533 scsi_unregister (host);
1534 continue;
1537 mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox64));
1538 mega_i_query_adapter (megaCfg);
1540 /* Initialize SCBs */
1541 if (initSCB (megaCfg)) {
1542 scsi_unregister (host);
1543 continue;
1546 numFound++;
1548 return numFound;
1551 /*---------------------------------------------------------
1552 * Detects if a megaraid controller exists in this system
1553 *---------------------------------------------------------*/
1554 int megaraid_detect (Scsi_Host_Template * pHostTmpl)
1556 int count = 0;
1558 pHostTmpl->proc_dir = &proc_scsi_megaraid;
1560 #if LINUX_VERSION_CODE < 0x20100
1561 if (!pcibios_present ()) {
1562 printk (KERN_WARNING "megaraid: PCI bios not present." CRLFSTR);
1563 return 0;
1565 #endif
1566 skip_id = -1;
1567 if (megaraid && !strncmp(megaraid,"skip",strlen("skip"))) {
1568 if (megaraid[4] != '\0') {
1569 skip_id = megaraid[4] - '0';
1570 if (megaraid[5] != '\0') {
1571 skip_id = (skip_id * 10) + (megaraid[5] - '0');
1574 skip_id = (skip_id > 15) ? -1 : skip_id;
1577 printk ("megaraid: " MEGARAID_VERSION CRLFSTR);
1579 count += findCard (pHostTmpl, 0x101E, 0x9010, 0);
1580 count += findCard (pHostTmpl, 0x101E, 0x9060, 0);
1581 count += findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
1583 return count;
1586 /*---------------------------------------------------------------------
1587 * Release the controller's resources
1588 *---------------------------------------------------------------------*/
1589 int megaraid_release (struct Scsi_Host *pSHost)
1591 mega_host_config *megaCfg;
1592 mega_mailbox *mbox;
1593 u_char mboxData[16];
1595 megaCfg = (mega_host_config *) pSHost->hostdata;
1596 mbox = (mega_mailbox *) mboxData;
1598 /* Flush cache to disk */
1599 memset (mbox, 0, 16);
1600 mboxData[0] = 0xA;
1602 free_irq (megaCfg->host->irq, megaCfg);/* Must be freed first, otherwise
1603 extra interrupt is generated */
1605 /* Issue a blocking (interrupts disabled) command to the card */
1606 megaIssueCmd (megaCfg, mboxData, NULL, 0);
1608 /* Free our resources */
1609 if (megaCfg->flag & BOARD_QUARTZ) {
1610 iounmap ((void *) megaCfg->base);
1612 else {
1613 release_region (megaCfg->host->io_port, 16);
1616 freeSgList(megaCfg);
1617 scsi_unregister (pSHost);
1619 return 0;
1622 static inline void freeSgList(mega_host_config *megaCfg)
1624 int i;
1626 for (i = 0; i < megaCfg->max_cmds; i++) {
1627 if (megaCfg->scbList[i].sgList)
1628 kfree (megaCfg->scbList[i].sgList); /* free sgList */
1632 /*----------------------------------------------
1633 * Get information about the card/driver
1634 *----------------------------------------------*/
1635 const char * megaraid_info (struct Scsi_Host *pSHost)
1637 static char buffer[512];
1638 mega_host_config *megaCfg;
1640 megaCfg = (mega_host_config *) pSHost->hostdata;
1642 sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans %d luns",
1643 megaCfg->fwVer,
1644 megaCfg->productInfo.MaxConcCmds,
1645 megaCfg->host->max_id,
1646 megaCfg->host->max_channel,
1647 megaCfg->host->max_lun);
1648 return buffer;
1651 /*-----------------------------------------------------------------
1652 * Perform a SCSI command
1653 * Mailbox area:
1654 * 00 01 command
1655 * 01 01 command id
1656 * 02 02 # of sectors
1657 * 04 04 logical bus address
1658 * 08 04 physical buffer address
1659 * 0C 01 logical drive #
1660 * 0D 01 length of scatter/gather list
1661 * 0E 01 reserved
1662 * 0F 01 mailbox busy
1663 * 10 01 numstatus byte
1664 * 11 01 status byte
1665 *-----------------------------------------------------------------*/
1666 int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
1668 mega_host_config *megaCfg;
1669 mega_scb *pScb;
1670 long flags;
1672 spin_lock_irqsave(&mega_lock,flags);
1674 megaCfg = (mega_host_config *) SCpnt->host->hostdata;
1676 if (!(megaCfg->flag & (1L << SCpnt->channel))) {
1677 if (SCpnt->channel < SCpnt->host->max_channel)
1678 printk (/*KERN_INFO*/ "scsi%d: scanning channel %c for devices.\n",
1679 megaCfg->host->host_no,
1680 SCpnt->channel + '1');
1681 else
1682 printk(/*KERN_INFO*/ "scsi%d: scanning virtual channel for logical drives.\n", megaCfg->host->host_no);
1684 megaCfg->flag |= (1L << SCpnt->channel);
1687 SCpnt->scsi_done = pktComp;
1689 /* If driver in abort or reset.. cancel this command */
1690 if (megaCfg->flag & IN_ABORT) {
1691 SCpnt->result = (DID_ABORT << 16);
1692 ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
1694 spin_unlock_irqrestore(&mega_lock,flags);
1695 return 0;
1697 else if (megaCfg->flag & IN_RESET) {
1698 SCpnt->result = (DID_RESET << 16);
1699 ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
1701 spin_unlock_irqrestore(&mega_lock,flags);
1702 return 0;
1705 /* Allocate and build a SCB request */
1706 if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
1707 /*build SCpnt for IOCTL_CMD_NEW cmd in mega_ioctl()*/
1708 /* Add SCB to the head of the pending queue */
1709 ENQUEUE_NL (pScb, mega_scb, megaCfg->qPending, next);
1711 /* Issue any pending command to the card if not in ISR */
1712 if (!(megaCfg->flag & IN_ISR)) {
1713 mega_runpendq(megaCfg);
1715 else {
1716 printk("IRQ pend...\n");
1719 if ( SCpnt->cmnd[0]==IOCTL_CMD_NEW )
1720 { /* user data from external user buffer */
1721 char *user_area;
1722 u32 xfer_size;
1724 init_MUTEX_LOCKED(&pScb->sem);
1725 down(&pScb->sem);
1727 user_area = *((char **)&pScb->SCpnt->cmnd[4]);
1728 xfer_size = *((u32 *)&pScb->SCpnt->cmnd[8]);
1730 copy_to_user(user_area,pScb->kern_area,xfer_size);
1732 kfree(pScb->kern_area);
1734 freeSCB(megaCfg, pScb);
1739 spin_unlock_irqrestore(&mega_lock,flags);
1741 return 0;
1744 /*----------------------------------------------------------------------
1745 * Issue a blocking command to the controller
1746 *----------------------------------------------------------------------*/
1747 volatile static int internal_done_flag = 0;
1748 volatile static int internal_done_errcode = 0;
1749 static DECLARE_WAIT_QUEUE_HEAD(internal_wait);
1751 static void internal_done (Scsi_Cmnd * SCpnt)
1753 internal_done_errcode = SCpnt->result;
1754 internal_done_flag++;
1755 wake_up(&internal_wait);
1758 /* shouldn't be used, but included for completeness */
1760 int megaraid_command (Scsi_Cmnd * SCpnt)
1762 internal_done_flag = 0;
1764 /* Queue command, and wait until it has completed */
1765 megaraid_queue (SCpnt, internal_done);
1767 while (!internal_done_flag) {
1768 interruptible_sleep_on(&internal_wait);
1771 return internal_done_errcode;
1774 /*---------------------------------------------------------------------
1775 * Abort a previous SCSI request
1776 *---------------------------------------------------------------------*/
1777 int megaraid_abort (Scsi_Cmnd * SCpnt)
1779 mega_host_config *megaCfg;
1780 int rc, idx;
1781 long flags;
1782 mega_scb *pScb;
1784 rc = SCSI_ABORT_SUCCESS;
1786 spin_lock_irqsave (&mega_lock, flags);
1788 megaCfg = (mega_host_config *) SCpnt->host->hostdata;
1790 megaCfg->flag |= IN_ABORT;
1792 for(pScb=megaCfg->qPending; pScb; pScb=pScb->next) {
1793 if (pScb->SCpnt == SCpnt) {
1794 /* Found an aborting command */
1795 #if DEBUG
1796 showMbox(pScb);
1797 #endif
1799 printk("Abort: %d %u\n",
1800 SCpnt->timeout_per_command,
1801 (uint)((jiffies) - pScb->isrcount));
1803 switch(pScb->state) {
1804 case SCB_ABORTED: /* Already aborted */
1805 rc = SCSI_ABORT_SNOOZE;
1806 break;
1807 case SCB_ISSUED: /* Waiting on ISR result */
1808 rc = SCSI_ABORT_PENDING;
1809 pScb->state = SCB_ABORTED;
1810 break;
1815 #if 0
1816 TRACE (("ABORT!!! %.08lx %.02x <%d.%d.%d>\n",
1817 SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
1818 SCpnt->lun));
1819 for(pScb=megaCfg->qPending; pScb; pScb=pScb->next) {
1820 if (pScb->SCpnt == SCpnt) {
1821 ser_printk("** %d<%x> %c\n", pScb->SCpnt->pid, pScb->idx+1,
1822 pScb->state == SCB_ACTIVE ? 'A' : 'I');
1823 #if DEBUG
1824 showMbox(pScb);
1825 #endif
1828 #endif
1831 * Walk list of SCBs for any that are still outstanding
1833 for (idx = 0; idx < megaCfg->max_cmds; idx++) {
1834 if (megaCfg->scbList[idx].state != SCB_FREE) {
1835 if (megaCfg->scbList[idx].SCpnt == SCpnt) {
1836 freeSCB (megaCfg, &megaCfg->scbList[idx]);
1838 SCpnt->result = (DID_ABORT << 16) | (SUGGEST_RETRY << 24);
1839 ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
1844 megaCfg->flag &= ~IN_ABORT;
1846 spin_unlock_irqrestore (&mega_lock, flags);
1848 mega_rundoneq();
1850 return rc;
1853 /*---------------------------------------------------------------------
1854 * Reset a previous SCSI request
1855 *---------------------------------------------------------------------*/
1856 int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
1858 mega_host_config *megaCfg;
1859 int idx;
1860 long flags;
1862 spin_lock_irqsave (&mega_lock, flags);
1864 megaCfg = (mega_host_config *) SCpnt->host->hostdata;
1866 megaCfg->flag |= IN_RESET;
1868 TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n",
1869 SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
1870 SCpnt->lun));
1873 * Walk list of SCBs for any that are still outstanding
1875 for (idx = 0; idx < megaCfg->max_cmds; idx++) {
1876 if (megaCfg->scbList[idx].state != SCB_FREE) {
1877 SCpnt = megaCfg->scbList[idx].SCpnt;
1878 if (SCpnt != NULL) {
1879 freeSCB (megaCfg, &megaCfg->scbList[idx]);
1880 SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
1881 ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
1886 megaCfg->flag &= ~IN_RESET;
1888 spin_unlock_irqrestore (&mega_lock, flags);
1890 mega_rundoneq();
1891 return SCSI_RESET_PUNT;
1894 /*-------------------------------------------------------------
1895 * Return the disk geometry for a particular disk
1896 * Input:
1897 * Disk *disk - Disk geometry
1898 * kdev_t dev - Device node
1899 * int *geom - Returns geometry fields
1900 * geom[0] = heads
1901 * geom[1] = sectors
1902 * geom[2] = cylinders
1903 *-------------------------------------------------------------*/
1904 int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom)
1906 int heads, sectors, cylinders;
1907 mega_host_config *megaCfg;
1909 /* Get pointer to host config structure */
1910 megaCfg = (mega_host_config *) disk->device->host->hostdata;
1912 /* Default heads (64) & sectors (32) */
1913 heads = 64;
1914 sectors = 32;
1915 cylinders = disk->capacity / (heads * sectors);
1917 /* Handle extended translation size for logical drives > 1Gb */
1918 if (disk->capacity >= 0x200000) {
1919 heads = 255;
1920 sectors = 63;
1921 cylinders = disk->capacity / (heads * sectors);
1924 /* return result */
1925 geom[0] = heads;
1926 geom[1] = sectors;
1927 geom[2] = cylinders;
1929 return 0;
1932 #ifdef MODULE
1933 Scsi_Host_Template driver_template = MEGARAID;
1935 #include "scsi_module.c"
1936 #endif