#ifndef __MEGARAID_H__ #define __MEGARAID_H__ #ifndef LINUX_VERSION_CODE #include #endif #define IN_ISR 0x80000000L #define IN_ABORT 0x40000000L #define IN_RESET 0x20000000L #define BOARD_QUARTZ 0x08000000L #define SCB_FREE 0x0 #define SCB_ACTIVE 0x1 #define SCB_WAITQ 0x2 #define SCB_ISSUED 0x3 #define SCB_COMPLETE 0x4 #define SCB_ABORTED 0x5 #define SCB_RESET 0x6 #define MEGA_CMD_TIMEOUT 10 #define MAX_SGLIST 17 #define MAX_COMMANDS 250 #define MAX_CMD_PER_LUN 63 #define MAX_LOGICAL_DRIVES 8 #define MAX_CHANNEL 5 #define MAX_TARGET 15 #define MAX_PHYSICAL_DRIVES MAX_CHANNEL*MAX_TARGET #define INQUIRY_DATA_SIZE 0x24 #define MAX_CDB_LEN 0x0A #define MAX_REQ_SENSE_LEN 0x20 #define INTR_VALID 0x40 /* Mailbox commands */ #define MEGA_MBOXCMD_LREAD 0x01 #define MEGA_MBOXCMD_LWRITE 0x02 #define MEGA_MBOXCMD_PASSTHRU 0x03 #define MEGA_MBOXCMD_ADAPTERINQ 0x05 /* Offsets into Mailbox */ #define COMMAND_PORT 0x00 #define COMMAND_ID_PORT 0x01 #define SG_LIST_PORT0 0x08 #define SG_LIST_PORT1 0x09 #define SG_LIST_PORT2 0x0a #define SG_LIST_PORT3 0x0b #define SG_ELEMENT_PORT 0x0d #define NO_FIRED_PORT 0x0f /* I/O Port offsets */ #define I_CMD_PORT 0x00 #define I_ACK_PORT 0x00 #define I_TOGGLE_PORT 0x01 #define INTR_PORT 0x0a #define MAILBOX_SIZE (sizeof(mega_mailbox)-16) #define MBOX_BUSY_PORT 0x00 #define MBOX_PORT0 0x04 #define MBOX_PORT1 0x05 #define MBOX_PORT2 0x06 #define MBOX_PORT3 0x07 #define ENABLE_MBOX_REGION 0x0B /* I/O Port Values */ #define ISSUE_BYTE 0x10 #define ACK_BYTE 0x08 #define ENABLE_INTR_BYTE 0xc0 #define DISABLE_INTR_BYTE 0x00 #define VALID_INTR_BYTE 0x40 #define MBOX_BUSY_BYTE 0x10 #define ENABLE_MBOX_BYTE 0x00 /* Setup some port macros here */ #define WRITE_MAILBOX(base,offset,value) *(base+offset)=value #define READ_MAILBOX(base,offset) *(base+offset) #define WRITE_PORT(base,offset,value) outb_p(value,base+offset) #define READ_PORT(base,offset) inb_p(base+offset) #define ISSUE_COMMAND(base) WRITE_PORT(base,I_CMD_PORT,ISSUE_BYTE) #define CLEAR_INTR(base) WRITE_PORT(base,I_ACK_PORT,ACK_BYTE) #define ENABLE_INTR(base) WRITE_PORT(base,I_TOGGLE_PORT,ENABLE_INTR_BYTE) #define DISABLE_INTR(base) WRITE_PORT(base,I_TOGGLE_PORT,DISABLE_INTR_BYTE) /* Define AMI's PCI codes */ #undef PCI_VENDOR_ID_AMI #undef PCI_DEVICE_ID_AMI_MEGARAID #ifndef PCI_VENDOR_ID_AMI #define PCI_VENDOR_ID_AMI 0x101E #define PCI_DEVICE_ID_AMI_MEGARAID 0x9010 #endif #define PCI_CONF_BASE_ADDR_OFFSET 0x10 #define PCI_CONF_IRQ_OFFSET 0x3c #define PCI_CONF_AMISIG 0xa0 #define AMI_SIGNATURE 0x3344 #if LINUX_VERSION_CODE < 0x20100 #define MEGARAID \ { NULL, /* Next */\ NULL, /* Usage Count Pointer */\ NULL, /* /proc Directory Entry */\ megaraid_proc_info, /* /proc Info Function */\ "MegaRAID", /* Driver Name */\ megaraid_detect, /* Detect Host Adapter */\ megaraid_release, /* Release Host Adapter */\ megaraid_info, /* Driver Info Function */\ megaraid_command, /* Command Function */\ megaraid_queue, /* Queue Command Function */\ megaraid_abort, /* Abort Command Function */\ megaraid_reset, /* Reset Command Function */\ NULL, /* Slave Attach Function */\ megaraid_biosparam, /* Disk BIOS Parameters */\ MAX_COMMANDS, /* # of cmds that can be\ outstanding at any time */\ 7, /* HBA Target ID */\ MAX_SGLIST, /* Scatter/Gather Table Size */\ MAX_CMD_PER_LUN, /* SCSI Commands per LUN */\ 0, /* Present */\ 0, /* Default Unchecked ISA DMA */\ ENABLE_CLUSTERING } /* Enable Clustering */ #else #define MEGARAID \ {\ name: "MegaRAID", /* Driver Name */\ proc_info: megaraid_proc_info, /* /proc driver info */\ detect: megaraid_detect, /* Detect Host Adapter */\ release: megaraid_release, /* Release Host Adapter */\ info: megaraid_info, /* Driver Info Function */\ command: megaraid_command, /* Command Function */\ queuecommand: megaraid_queue, /* Queue Command Function */\ abort: megaraid_abort, /* Abort Command Function */\ reset: megaraid_reset, /* Reset Command Function */\ bios_param: megaraid_biosparam, /* Disk BIOS Parameters */\ can_queue: MAX_COMMANDS, /* Can Queue */\ this_id: 7, /* HBA Target ID */\ sg_tablesize: MAX_SGLIST, /* Scatter/Gather Table Size */\ cmd_per_lun: MAX_CMD_PER_LUN, /* SCSI Commands per LUN */\ present: 0, /* Present */\ unchecked_isa_dma:0, /* Default Unchecked ISA DMA */\ use_clustering: ENABLE_CLUSTERING /* Enable Clustering */\ } #endif /* Structures */ typedef struct _mega_ADP_INFO { u_char MaxConcCmds; u_char RbldRate; u_char MaxTargPerChan; u_char ChanPresent; u_char FwVer[4]; u_short AgeOfFlash; u_char ChipSet; u_char DRAMSize; u_char CacheFlushInterval; u_char BiosVer[4]; u_char resvd[7]; } mega_ADP_INFO; typedef struct _mega_LDRV_INFO { u_char NumLDrv; u_char resvd[3]; u_long LDrvSize[MAX_LOGICAL_DRIVES]; u_char LDrvProp[MAX_LOGICAL_DRIVES]; u_char LDrvState[MAX_LOGICAL_DRIVES]; } mega_LDRV_INFO; typedef struct _mega_PDRV_INFO { u_char PDrvState[MAX_PHYSICAL_DRIVES]; u_char resvd; } mega_PDRV_INFO; // RAID inquiry: Mailbox command 0x5 typedef struct _mega_RAIDINQ { mega_ADP_INFO AdpInfo; mega_LDRV_INFO LogdrvInfo; mega_PDRV_INFO PhysdrvInfo; } mega_RAIDINQ; // Passthrough command: Mailbox command 0x3 typedef struct mega_passthru { u_char timeout:3; /* 0=6sec/1=60sec/2=10min/3=3hrs */ u_char ars:1; u_char reserved:3; u_char islogical:1; u_char logdrv; /* if islogical == 1 */ u_char channel; /* if islogical == 0 */ u_char target; /* if islogical == 0 */ u_char queuetag; /* unused */ u_char queueaction; /* unused */ u_char cdb[MAX_CDB_LEN]; u_char cdblen; u_char reqsenselen; u_char reqsensearea[MAX_REQ_SENSE_LEN]; u_char numsgelements; u_char scsistatus; u_long dataxferaddr; u_long dataxferlen; } mega_passthru; typedef struct _mega_mailbox { /* 0x0 */ u_char cmd; /* 0x1 */ u_char cmdid; /* 0x2 */ u_short numsectors; /* 0x4 */ u_long lba; /* 0x8 */ u_long xferaddr; /* 0xC */ u_char logdrv; /* 0xD */ u_char numsgelements; /* 0xE */ u_char resvd; /* 0xF */ u_char busy; /* 0x10 */ u_char numstatus; /* 0x11 */ u_char status; /* 0x12 */ u_char completed[46]; u_char mraid_poll; u_char mraid_ack; u_char pad[16]; } mega_mailbox; typedef struct _mega_ioctl_mbox { /* 0x0 */ u_char cmd; /* 0x1 */ u_char cmdid; /* 0x2 */ u_char channel; /* 0x3 */ u_char param; /* 0x4 */ u_char pad[4]; /* 0x8 */ u_long xferaddr; /* 0xC */ u_char logdrv; /* 0xD */ u_char numsgelements; /* 0xE */ u_char resvd; /* 0xF */ u_char busy; /* 0x10 */ u_char numstatus; /* 0x11 */ u_char status; /* 0x12 */ u_char completed[46]; u_char mraid_poll; u_char mraid_ack; u_char malign[16]; } mega_ioctl_mbox; typedef struct _mega_sglist { u_long address; u_long length; } mega_sglist; /* Queued command data */ typedef struct _mega_scb mega_scb; struct _mega_scb { int idx; u_long state; u_long isrcount; u_char mboxData[16]; mega_passthru pthru; Scsi_Cmnd *SCpnt; mega_sglist *sgList; mega_scb *next; }; /* Per-controller data */ typedef struct _mega_host_config { u_char numldrv; u_long flag; u_long base; mega_scb *qFree; mega_scb *qPending; u_long nReads[MAX_LOGICAL_DRIVES]; u_long nWrites[MAX_LOGICAL_DRIVES]; /* Host adapter parameters */ u_char fwVer[7]; u_char biosVer[7]; struct Scsi_Host *host; /* The following must be DMA-able!! */ volatile mega_mailbox *mbox; volatile mega_mailbox mailbox; volatile u_char mega_buffer[2 * 1024L]; u_char max_cmds; mega_scb scbList[MAX_COMMANDS]; } mega_host_config; extern struct proc_dir_entry proc_scsi_megaraid; const char *megaraid_info(struct Scsi_Host *); int megaraid_detect(Scsi_Host_Template *); int megaraid_release(struct Scsi_Host *); int megaraid_command(Scsi_Cmnd *); int megaraid_abort(Scsi_Cmnd *); int megaraid_reset(Scsi_Cmnd *, unsigned int); int megaraid_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); int megaraid_biosparam(Disk *, kdev_t, int *); int megaraid_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); #endif