From: Alan Cox Date: Fri, 23 Nov 2007 20:19:33 +0000 (-0500) Subject: Import 2.2.12pre8 X-Git-Tag: 2.2.12pre8 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=8df602ce44f388c290f56a7d7b8e47b9557e20b7;p=history.git Import 2.2.12pre8 --- diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 0707cacf2cb0..0efe43182e95 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -4704,8 +4704,8 @@ CONFIG_SCSI_AM53C974 AMI MegaRAID support CONFIG_SCSI_MEGARAID - This driver supports the AMI MegaRAID 428 and 438 (and maybe 466) - SCSI host adapters. + This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490 + and 467 SCSI host adapters. If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -9936,6 +9936,15 @@ CONFIG_SOUND_ES1371_GAMEPORT Leave the default 200 unless you have a joystick not attached to your sound card. +ESS Solo1 based PCI sound cards (eg. SC1938) +CONFIG_SOUND_ESSSOLO1 + Say Y or M if you have a PCI sound card utilizing the ESS Technology + Solo1 chip. To find out if your sound card uses a + Solo1 chip without removing your computer's cover, use + lspci -n and look for the PCI ID 125D:1969. This driver + differs slightly from OSS/Free, so PLEASE READ + Documentation/sound/solo1. + S3 SonicVibes based PCI sound cards CONFIG_SOUND_SONICVIBES Say Y or M if you have a PCI sound card utilizing the S3 diff --git a/Documentation/sound/solo1 b/Documentation/sound/solo1 new file mode 100644 index 000000000000..1c0a641b01c4 --- /dev/null +++ b/Documentation/sound/solo1 @@ -0,0 +1,48 @@ +ALaw/uLaw sample formats +------------------------ + +This driver does not support the ALaw/uLaw sample formats. +ALaw is the default mode when opening a sound device +using OSS/Free. The reason for the lack of support is +that the hardware does not support these formats, and adding +conversion routines to the kernel would lead to very ugly +code in the presence of the mmap interface to the driver. +And since xquake uses mmap, mmap is considered important :-) +and no sane application uses ALaw/uLaw these days anyway. +In short, playing a Sun .au file as follows: + +cat my_file.au > /dev/dsp + +does not work. Instead, you may use the play script from +Chris Bagwell's sox-12.14 package (or later, available from the URL +below) to play many different audio file formats. +The script automatically determines the audio format +and does do audio conversions if necessary. +http://home.sprynet.com/sprynet/cbagwell/projects.html + + +Blocking vs. nonblocking IO +--------------------------- + +Unlike OSS/Free this driver honours the O_NONBLOCK file flag +not only during open, but also during read and write. +This is an effort to make the sound driver interface more +regular. Timidity has problems with this; a patch +is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html. +(Timidity patched will also run on OSS/Free). + + +MIDI UART +--------- + +The driver supports a simple MIDI UART interface, with +no ioctl's supported. + + +MIDI synthesizer +---------------- + +The card has an OPL compatible FM synthesizer. + +Thomas Sailer +sailer@ife.ee.ethz.ch diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index a2e4db1c6819..2c22c0c4bfd2 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -59,7 +59,7 @@ EXPORT_SYMBOL(_writew); EXPORT_SYMBOL(_writel); EXPORT_SYMBOL(_memcpy_fromio); EXPORT_SYMBOL(_memcpy_toio); -EXPORT_SYMBOL(_memset_io); +EXPORT_SYMBOL(_memset_c_io); EXPORT_SYMBOL(insb); EXPORT_SYMBOL(insw); EXPORT_SYMBOL(insl); diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in index e5c31c787e25..7f6e73a2fbdb 100644 --- a/drivers/scsi/Config.in +++ b/drivers/scsi/Config.in @@ -34,9 +34,6 @@ dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI dep_tristate 'AMI MegaRAID support' CONFIG_SCSI_MEGARAID $CONFIG_SCSI -if [ "$CONFIG_SCSI_MEGARAID" != "n" ]; then - bool ' Concurrent IO commands on MegaRAID' CONFIG_MEGARAID_MULTI_IO -fi dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC $CONFIG_SCSI if [ "$CONFIG_SCSI_BUSLOGIC" != "n" ]; then diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 23ffc897094d..5ccf0c8be8b6 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -9,14 +9,12 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Version : 1.01 + * Version : 1.04 * * Description: Linux device driver for AMI MegaRAID controller * - * Supported controllers: MegaRAID 418, 428, 438, 466, 762 + * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 490 * - * Maintainer: Jeff L Jones - * Xi Shine Chen * History: * * Version 0.90: @@ -93,18 +91,41 @@ * Fixed bug in mega_cmd_done() for megamgr control commands, * the host_byte in the result code from the scsi request to * scsi midlayer is set to DID_BAD_TARGET when adapter's - * returned codes are 0xF0 and oxF4. + * returned codes are 0xF0 and 0xF4. + * + * Version 1.02: + * Fixed the tape drive bug by extending the adapter timeout value + * for passthrough command to 60 seconds in mega_build_cmd(). + * + * Version 1.03: + * Fixed Madrona support. + * Changed the adapter timeout value from 60 sec in 1.02 to 10 min + * for bigger and slower tape drive. + * Added driver version printout at driver loadup time + * + * Version 1.04 + * Added code for 40 ld FW support. + * Added new ioctl command 0x81 to support NEW_READ/WRITE_CONFIG with + * data area greater than 4 KB, which is the upper bound for data + * tranfer through scsi_ioctl interface. + * The addtional 32 bit field for 64bit address in the newly defined + * mailbox64 structure is set to 0 at this point. * * BUGS: * Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that * fails to detect the controller as a pci device on the system. * - * Timeout period for mid scsi layer is too short for - * this controller. Must be increased or Aborts will occur. + * Timeout period for upper scsi layer, i.e. SD_TIMEOUT in + * /drivers/scsi/sd.c, is too short for this controller. SD_TIMEOUT + * value must be increased to (30 * HZ) otherwise false timeouts + * will occur in the upper layer. * *===================================================================*/ #define CRLFSTR "\n" +#define IOCTL_CMD_NEW 0x81 + +#define MEGARAID_VERSION "v1.04 (August 16, 1999)" #include #include @@ -148,6 +169,7 @@ MODULE_DESCRIPTION ("AMI MegaRAID driver"); #include #include +#include #include "sd.h" #include "scsi.h" @@ -213,22 +235,22 @@ typedef struct { spin_unlock_irqrestore(&mega_lock,cpuflag);\ }; -u_long RDINDOOR (mega_host_config * megaCfg) +u32 RDINDOOR (mega_host_config * megaCfg) { return readl (megaCfg->base + 0x20); } -void WRINDOOR (mega_host_config * megaCfg, u_long value) +void WRINDOOR (mega_host_config * megaCfg, u32 value) { writel (value, megaCfg->base + 0x20); } -u_long RDOUTDOOR (mega_host_config * megaCfg) +u32 RDOUTDOOR (mega_host_config * megaCfg) { return readl (megaCfg->base + 0x2C); } -void WROUTDOOR (mega_host_config * megaCfg, u_long value) +void WROUTDOOR (mega_host_config * megaCfg, u32 value) { writel (value, megaCfg->base + 0x2C); } @@ -244,7 +266,7 @@ static int megaIssueCmd (mega_host_config * megaCfg, mega_scb * scb, int intr); static int build_sglist (mega_host_config * megaCfg, mega_scb * scb, - u_long * buffer, u_long * length); + u32 * buffer, u32 * length); static int mega_busyWaitMbox(mega_host_config *); static void mega_runpendq (mega_host_config *); @@ -252,6 +274,9 @@ static void mega_rundoneq (void); static void mega_cmd_done (mega_host_config *, mega_scb *, int); static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt); static inline void freeSgList(mega_host_config *megaCfg); +static void mega_Convert8ldTo40ld( mega_RAIDINQ *inquiry, + mega_Enquiry3 *enquiry3, + megaRaidProductInfo *productInfo ); /* set SERDEBUG to 1 to enable serial debugging */ #define SERDEBUG 0 @@ -269,9 +294,9 @@ static int ser_printk (const char *fmt,...); *================================================================ */ -/* Use "megaraid=skipXX" to prohibit driver from scanning XX scsi id - on each channel. Used for Madrona motherboard, where SAF_TE - processor id cannot be scanned */ +/* Use "megaraid=skipXX" as LILO option to prohibit driver from scanning + XX scsi id on each channel. Used for Madrona motherboard, where SAF_TE + processor id cannot be scanned */ static char *megaraid; #if LINUX_VERSION_CODE > 0x20100 #ifdef MODULE @@ -281,10 +306,10 @@ MODULE_PARM(megaraid, "s"); static int skip_id; static int numCtlrs = 0; -static mega_host_config *megaCtlrs[12] = {0}; +static mega_host_config *megaCtlrs[FC_MAX_CHANNELS] = {0}; #if DEBUG -static u_long maxCmdTime = 0; +static u32 maxCmdTime = 0; #endif static mega_scb *pLastScb = NULL; @@ -512,8 +537,8 @@ static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, while(1); } - islogical = (SCpnt->channel == megaCfg->host->max_channel && - SCpnt->target == 0); + islogical = (SCpnt->channel == megaCfg->host->max_channel); + if (SCpnt->cmnd[0] == INQUIRY && ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) && !islogical) { @@ -523,8 +548,7 @@ static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, /* clear result; otherwise, success returns corrupt value */ SCpnt->result = 0; -if (SCpnt->cmnd[0] & 0x80) /* ioctl from megamgr */{ - /*printk(KERN_WARNING "***megamgr cmnd status= %x h\n ", status); */ +if ((SCpnt->cmnd[0] & 0x80) ) {/* i.e. ioctl cmd such as 0x80, 0x81 of megamgr*/ switch (status) { case 0xF0: case 0xF4: @@ -556,11 +580,15 @@ else{ SCpnt->result |= (DID_BUS_BUSY << 16)|status; break; default: - SCpnt->result |= (DID_BAD_TARGET << 16); + SCpnt->result |= (DID_BAD_TARGET << 16)|status; break; } } - freeSCB(megaCfg, pScb); + if ( SCpnt->cmnd[0]!=IOCTL_CMD_NEW ) + /* not IOCTL_CMD_NEW SCB, freeSCB()*/ + /* For IOCTL_CMD_NEW SCB, delay freeSCB() in megaraid_queue() + * after copy data back to user space*/ + freeSCB(megaCfg, pScb); /* Add Scsi_Command to end of completed queue */ ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble); @@ -582,18 +610,14 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg, mega_passthru *pthru; long seg; char islogical; + char lun = SCpnt->lun; - if (SCpnt == NULL) { - printk("NULL SCpnt in mega_build_cmd!\n"); - while(1); - } - - if (SCpnt->cmnd[0] & 0x80) /* ioctl from megamgr */ + if ((SCpnt->cmnd[0] == 0x80) || (SCpnt->cmnd[0] == IOCTL_CMD_NEW) ) /* ioctl */ return mega_ioctl (megaCfg, SCpnt); + + islogical = (SCpnt->channel == megaCfg->host->max_channel); - islogical = (SCpnt->channel == megaCfg->host->max_channel && SCpnt->target == 0); - - if (!islogical && SCpnt->lun != 0) { + if (!islogical && lun != 0) { SCpnt->result = (DID_BAD_TARGET << 16); callDone (SCpnt); return NULL; @@ -605,6 +629,16 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg, return NULL; } + if ( islogical ) { + lun = (SCpnt->target * 8) + lun; +#if 1 + if ( lun > FC_MAX_LOGICAL_DRIVES ){ + SCpnt->result = (DID_BAD_TARGET << 16); + callDone (SCpnt); + return NULL; + } +#endif + } /*----------------------------------------------------- * * Logical drive commands @@ -641,7 +675,7 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg, pthru->ars = 1; pthru->reqsenselen = 14; pthru->islogical = 1; - pthru->logdrv = SCpnt->lun; + pthru->logdrv = lun; pthru->cdblen = SCpnt->cmd_len; pthru->dataxferaddr = virt_to_bus (SCpnt->request_buffer); pthru->dataxferlen = SCpnt->request_bufflen; @@ -666,37 +700,37 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg, mbox = (mega_mailbox *) & pScb->mboxData; memset (mbox, 0, sizeof (pScb->mboxData)); - mbox->logdrv = SCpnt->lun; + mbox->logdrv = lun; mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ? MEGA_MBOXCMD_LREAD : MEGA_MBOXCMD_LWRITE; /* 6-byte */ if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) { mbox->numsectors = - (u_long) SCpnt->cmnd[4]; + (u32) SCpnt->cmnd[4]; mbox->lba = - ((u_long) SCpnt->cmnd[1] << 16) | - ((u_long) SCpnt->cmnd[2] << 8) | - (u_long) SCpnt->cmnd[3]; + ((u32) SCpnt->cmnd[1] << 16) | + ((u32) SCpnt->cmnd[2] << 8) | + (u32) SCpnt->cmnd[3]; mbox->lba &= 0x1FFFFF; } /* 10-byte */ if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) { mbox->numsectors = - (u_long) SCpnt->cmnd[8] | - ((u_long) SCpnt->cmnd[7] << 8); + (u32) SCpnt->cmnd[8] | + ((u32) SCpnt->cmnd[7] << 8); mbox->lba = - ((u_long) SCpnt->cmnd[2] << 24) | - ((u_long) SCpnt->cmnd[3] << 16) | - ((u_long) SCpnt->cmnd[4] << 8) | - (u_long) SCpnt->cmnd[5]; + ((u32) SCpnt->cmnd[2] << 24) | + ((u32) SCpnt->cmnd[3] << 16) | + ((u32) SCpnt->cmnd[4] << 8) | + (u32) SCpnt->cmnd[5]; } /* Calculate Scatter-Gather info */ mbox->numsgelements = build_sglist (megaCfg, pScb, - (u_long *) & mbox->xferaddr, - (u_long *) & seg); + (u32 *) & mbox->xferaddr, + (u32 *) & seg); return pScb; @@ -723,18 +757,20 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg, memset (mbox, 0, sizeof (pScb->mboxData)); memset (pthru, 0, sizeof (mega_passthru)); - pthru->timeout = 0; + pthru->timeout = 2; /*set adapter timeout value to 10 min. for tape drive*/ + /* 0=6sec/1=60sec/2=10min/3=3hrs */ pthru->ars = 1; pthru->reqsenselen = 14; pthru->islogical = 0; - pthru->channel = SCpnt->channel; - pthru->target = SCpnt->target; + pthru->channel = (megaCfg->flag & BOARD_40LD) ? 0 : SCpnt->channel; + pthru->target = (megaCfg->flag & BOARD_40LD) ? /*BOARD_40LD*/ + (SCpnt->channel<<4)|SCpnt->target : SCpnt->target; pthru->cdblen = SCpnt->cmd_len; memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len); pthru->numsgelements = build_sglist (megaCfg, pScb, - (u_long *) & pthru->dataxferaddr, - (u_long *) & pthru->dataxferlen); + (u32 *) & pthru->dataxferaddr, + (u32 *) & pthru->dataxferlen); /* Initialize mailbox */ mbox->cmd = MEGA_MBOXCMD_PASSTHRU; @@ -754,6 +790,7 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt) mega_ioctl_mbox *mbox; mega_mailbox *mailbox; mega_passthru *pthru; + u8 *mboxdata; long seg; unsigned char *data = (unsigned char *)SCpnt->request_buffer; int i; @@ -772,6 +809,7 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt) printk("......\n"); #endif + mboxdata = (u8 *) & pScb->mboxData; mbox = (mega_ioctl_mbox *) & pScb->mboxData; mailbox = (mega_mailbox *) & pScb->mboxData; memset (mailbox, 0, sizeof (pScb->mboxData)); @@ -793,10 +831,9 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt) mailbox->cmd = MEGA_MBOXCMD_PASSTHRU; mailbox->xferaddr = virt_to_bus (pthru); - pthru->numsgelements = build_sglist (megaCfg, pScb, - (u_long *) & pthru->dataxferaddr, - (u_long *) & pthru->dataxferlen); + (u32 *) & pthru->dataxferaddr, + (u32 *) & pthru->dataxferlen); for (i=0;i<(SCpnt->request_bufflen-cdblen-7);i++) { data[i] = data[i+cdblen+7]; @@ -806,18 +843,60 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt) } /* else normal (nonpassthru) command */ + if (SCpnt->cmnd[0] == IOCTL_CMD_NEW) { + /* use external data area for large xfers */ + /* If cmnd[0] is set to IOCTL_CMD_NEW then * + * cmnd[4..7] = external user buffer * + * cmnd[8..11] = length of buffer * + * */ + char *kern_area; + char *user_area = *((char **)&SCpnt->cmnd[4]); + u32 xfer_size = *((u32 *)&SCpnt->cmnd[8]); + if (verify_area(VERIFY_READ, user_area, xfer_size)) { + printk("megaraid: Got bad user address.\n"); + SCpnt->result = (DID_ERROR << 16); + callDone (SCpnt); + return NULL; + } + kern_area = kmalloc(xfer_size, GFP_ATOMIC | GFP_DMA); + if (kern_area == NULL) { + printk("megaraid: Couldn't allocate kernel mem.\n"); + SCpnt->result = (DID_ERROR << 16); + callDone (SCpnt); + return NULL; + } + copy_from_user(kern_area,user_area,xfer_size); + pScb->kern_area = kern_area; + } + mbox->cmd = data[0]; mbox->channel = data[1]; mbox->param = data[2]; mbox->pad[0] = data[3]; mbox->logdrv = data[4]; - mbox->numsgelements = build_sglist (megaCfg, pScb, - (u_long *) & mbox->xferaddr, - (u_long *) & seg); + if(SCpnt->cmnd[0] == IOCTL_CMD_NEW) { + if(data[0]==DCMD_FC_CMD){ /*i.e. 0xA1, then override some mbox data */ + *(mboxdata+0) = data[0]; /*mailbox byte 0: DCMD_FC_CMD*/ + *(mboxdata+2) = data[2]; /*sub command*/ + *(mboxdata+3) = 0; /*number of elements in SG list*/ + mbox->xferaddr /*i.e. mboxdata byte 0x8 to 0xb*/ + = virt_to_bus(pScb->kern_area); + } + else{ + mbox->xferaddr = virt_to_bus(pScb->kern_area); + mbox->numsgelements = 0; + } + } + else { - for (i=0;i<(SCpnt->request_bufflen-6);i++) { - data[i] = data[i+6]; + mbox->numsgelements = build_sglist (megaCfg, pScb, + (u32 *) & mbox->xferaddr, + (u32 *) & seg); + + for (i=0;i<(SCpnt->request_bufflen-6);i++) { + data[i] = data[i+6]; + } } return (pScb); @@ -846,7 +925,7 @@ static void megaraid_isr (int irq, void *devp, struct pt_regs *regs) { mega_host_config *megaCfg; u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE]; - u_long dword; + u32 dword; mega_mailbox *mbox; mega_scb *pScb; long flags; @@ -930,8 +1009,13 @@ static void megaraid_isr (int irq, void *devp, struct pt_regs *regs) printk("Received aborted SCB! %u\n", (int)((jiffies)-pScb->isrcount)); } + if (*(pScb->SCpnt->cmnd)==IOCTL_CMD_NEW) + { /* external user buffer */ + up(&pScb->sem); + } /* Mark command as completed */ mega_cmd_done(megaCfg, pScb, qStatus); + } } @@ -945,6 +1029,7 @@ static void megaraid_isr (int irq, void *devp, struct pt_regs *regs) spin_lock_irqsave(&mega_lock, flags); mega_runpendq(megaCfg); spin_unlock_irqrestore(&mega_lock,flags); + } #if LINUX_VERSION_CODE >= 0x20100 @@ -978,6 +1063,11 @@ static int mega_busyWaitMbox (mega_host_config * megaCfg) * u_char *mboxData - Mailbox area, 16 bytes * mega_scb *pScb - SCB posting (or NULL if N/A) * int intr - if 1, interrupt, 0 is blocking + * Return Value: (added on 7/26 for 40ld/64bit) + * -1: the command was not actually issued out + * othercases: + * intr==0, return ScsiStatus, i.e. mbox->status + * intr==1, return 0 *===================================================== */ static int megaIssueCmd (mega_host_config * megaCfg, @@ -987,12 +1077,16 @@ static int megaIssueCmd (mega_host_config * megaCfg, { mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox; u_char byte; - u_long cmdDone; + u32 cmdDone; Scsi_Cmnd *SCpnt; + u32 phys_mbox; + u8 retval=-1; mboxData[0x1] = (pScb ? pScb->idx + 1: 0x0); /* Set cmdid */ mboxData[0xF] = 1; /* Set busy */ + phys_mbox = virt_to_bus (megaCfg->mbox); + #if 0 if (intr && mbox->busy) { return 0; @@ -1005,7 +1099,7 @@ static int megaIssueCmd (mega_host_config * megaCfg, /* Wait until mailbox is free */ while (mega_busyWaitMbox (megaCfg)) { - printk("Blocked mailbox!!\n"); + printk("Blocked mailbox......!!\n"); udelay(1000); #if DEBUG @@ -1022,12 +1116,13 @@ static int megaIssueCmd (mega_host_config * megaCfg, SCpnt->result = (DID_ABORT << 16); callDone(SCpnt); - return 0; + return -1; } pLastScb = pScb; /* Copy mailbox data into host structure */ + megaCfg->mbox64->xferSegment = 0; memcpy (mbox, mboxData, 16); /* Kick IO */ @@ -1037,20 +1132,22 @@ static int megaIssueCmd (mega_host_config * megaCfg, if (megaCfg->flag & BOARD_QUARTZ) { mbox->mraid_poll = 0; mbox->mraid_ack = 0; - WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1); + WRINDOOR (megaCfg, phys_mbox | 0x1); } else { ENABLE_INTR (megaCfg->host->io_port); ISSUE_COMMAND (megaCfg->host->io_port); } pScb->state = SCB_ISSUED; + + retval=0; } else { /* Issue non-ISR (blocking) command */ disable_irq(megaCfg->host->irq); if (megaCfg->flag & BOARD_QUARTZ) { mbox->mraid_poll = 0; mbox->mraid_ack = 0; - WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1); + WRINDOOR (megaCfg, phys_mbox | 0x1); while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234); WROUTDOOR (megaCfg, cmdDone); @@ -1060,7 +1157,7 @@ static int megaIssueCmd (mega_host_config * megaCfg, mega_rundoneq (); } - WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2); + WRINDOOR (megaCfg, phys_mbox | 0x2); while (RDINDOOR (megaCfg) & 0x2); } @@ -1085,20 +1182,21 @@ static int megaIssueCmd (mega_host_config * megaCfg, } enable_irq(megaCfg->host->irq); + retval=mbox->status; } while (mega_busyWaitMbox (megaCfg)) { - printk("Blocked mailbox on exit!\n"); + printk("Blocked mailbox on exit......!\n"); udelay(1000); } - return 0; + return retval; } /*------------------------------------------------------------------- * Copies data to SGLIST *-------------------------------------------------------------------*/ static int build_sglist (mega_host_config * megaCfg, mega_scb * scb, - u_long * buffer, u_long * length) + u32 * buffer, u32 * length) { struct scatterlist *sgList; int idx; @@ -1106,21 +1204,21 @@ static int build_sglist (mega_host_config * megaCfg, mega_scb * scb, /* Scatter-gather not used */ if (scb->SCpnt->use_sg == 0) { *buffer = virt_to_bus (scb->SCpnt->request_buffer); - *length = (u_long) scb->SCpnt->request_bufflen; + *length = (u32) scb->SCpnt->request_bufflen; return 0; } sgList = (struct scatterlist *) scb->SCpnt->request_buffer; if (scb->SCpnt->use_sg == 1) { *buffer = virt_to_bus (sgList[0].address); - *length = (u_long) sgList[0].length; + *length = (u32) sgList[0].length; return 0; } /* Copy Scatter-Gather list info into controller structure */ for (idx = 0; idx < scb->SCpnt->use_sg; idx++) { scb->sgList[idx].address = virt_to_bus (sgList[idx].address); - scb->sgList[idx].length = (u_long) sgList[idx].length; + scb->sgList[idx].length = (u32) sgList[idx].length; } /* Reset pointer and length fields */ @@ -1147,12 +1245,13 @@ static int build_sglist (mega_host_config * megaCfg, mega_scb * scb, * 10 01 numstatus byte * 11 01 status byte *--------------------------------------------------------------------*/ -static int mega_register_mailbox (mega_host_config * megaCfg, u_long paddr) +static int mega_register_mailbox (mega_host_config * megaCfg, u32 paddr) { /* align on 16-byte boundry */ - megaCfg->mbox = &megaCfg->mailbox; - megaCfg->mbox = (mega_mailbox *) ((((ulong) megaCfg->mbox) + 16) & 0xfffffff0); - paddr = (paddr + 16) & 0xfffffff0; + megaCfg->mbox = &megaCfg->mailbox64.mailbox; + megaCfg->mbox = (mega_mailbox *) ((((u32) megaCfg->mbox) + 16) & 0xfffffff0); + megaCfg->mbox64 = (mega_mailbox64 *) (megaCfg->mbox - 4); + paddr = (paddr + 4 + 16) & 0xfffffff0; /* Register mailbox area with the firmware */ if (megaCfg->flag & BOARD_QUARTZ) { @@ -1170,83 +1269,161 @@ static int mega_register_mailbox (mega_host_config * megaCfg, u_long paddr) return 0; } + +/*--------------------------------------------------------------------------- + * mega_Convert8ldTo40ld() -- takes all info in AdapterInquiry structure and + * puts it into ProductInfo and Enquiry3 structures for later use + *---------------------------------------------------------------------------*/ +static void mega_Convert8ldTo40ld( mega_RAIDINQ *inquiry, + mega_Enquiry3 *enquiry3, + megaRaidProductInfo *productInfo ) +{ + int i; + + productInfo->MaxConcCmds = inquiry->AdpInfo.MaxConcCmds; + enquiry3->rbldRate = inquiry->AdpInfo.RbldRate; + productInfo->SCSIChanPresent = inquiry->AdpInfo.ChanPresent; + for (i=0;i<4;i++) { + productInfo->FwVer[i] = inquiry->AdpInfo.FwVer[i]; + productInfo->BiosVer[i] = inquiry->AdpInfo.BiosVer[i]; + } + enquiry3->cacheFlushInterval = inquiry->AdpInfo.CacheFlushInterval; + productInfo->DramSize = inquiry->AdpInfo.DramSize; + + enquiry3->numLDrv = inquiry->LogdrvInfo.NumLDrv; + for (i=0;ilDrvSize[i] = inquiry->LogdrvInfo.LDrvSize[i]; + enquiry3->lDrvProp[i] = inquiry->LogdrvInfo.LDrvProp[i]; + enquiry3->lDrvState[i] = inquiry->LogdrvInfo.LDrvState[i]; + } + + for (i=0;i<(MAX_PHYSICAL_DRIVES);i++) { + enquiry3->pDrvState[i] = inquiry->PhysdrvInfo.PDrvState[i]; + } +} + + /*------------------------------------------------------------------- * Issue an adapter info query to the controller *-------------------------------------------------------------------*/ static int mega_i_query_adapter (mega_host_config * megaCfg) { - mega_RAIDINQ *adapterInfo; + mega_Enquiry3 *enquiry3Pnt; mega_mailbox *mbox; u_char mboxData[16]; - u_long paddr; + u32 paddr; + u8 retval; spin_lock_init (&mega_lock); - /* Initialize adapter inquiry */ + /* Initialize adapter inquiry mailbox*/ paddr = virt_to_bus (megaCfg->mega_buffer); mbox = (mega_mailbox *) mboxData; memset ((void *) megaCfg->mega_buffer, 0, sizeof (megaCfg->mega_buffer)); memset (mbox, 0, 16); - /* Initialize mailbox registers */ - mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ; - mbox->xferaddr = paddr; +/* + * Try to issue Enquiry3 command + * if not suceeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and + * update enquiry3 structure + */ + mbox->xferaddr = virt_to_bus ( (void*) megaCfg->mega_buffer); + /* Initialize mailbox databuffer addr */ + enquiry3Pnt = (mega_Enquiry3 *) megaCfg->mega_buffer; + /* point mega_Enguiry3 to the data buf */ + + mboxData[0]=FC_NEW_CONFIG ; /* i.e. mbox->cmd=0xA1 */ + mboxData[2]=NC_SUBOP_ENQUIRY3; /* i.e. 0x0F */ + mboxData[3]=ENQ3_GET_SOLICITED_FULL; /* i.e. 0x02 */ /* Issue a blocking command to the card */ - megaIssueCmd (megaCfg, mboxData, NULL, 0); + if ( (retval=megaIssueCmd(megaCfg, mboxData, NULL, 0)) != 0 ) + { /* the adapter does not support 40ld*/ - /* Initialize host/local structures with Adapter info */ - adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer; - megaCfg->host->max_channel = adapterInfo->AdpInfo.ChanPresent; -/* megaCfg->host->max_id = adapterInfo->AdpInfo.MaxTargPerChan; */ - megaCfg->host->max_id = 16; /* max targets/chan */ - megaCfg->numldrv = adapterInfo->LogdrvInfo.NumLDrv; + mega_RAIDINQ adapterInquiryData; + mega_RAIDINQ *adapterInquiryPnt = &adapterInquiryData; -#if 0 - printk ("KERN_DEBUG ---- Logical drive info ----\n"); + mbox->xferaddr = virt_to_bus ( (void*) adapterInquiryPnt); + + mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ; /*issue old 0x05 command to adapter*/ + /* Issue a blocking command to the card */; + retval=megaIssueCmd (megaCfg, mboxData, NULL, 0); + + /*update Enquiry3 and ProductInfo structures with mega_RAIDINQ structure*/ + mega_Convert8ldTo40ld( adapterInquiryPnt, + enquiry3Pnt, + (megaRaidProductInfo * ) &megaCfg->productInfo ); + + } + else{ /* adapter supports 40ld */ + megaCfg->flag |= BOARD_40LD; + + /*get productInfo, which is static information and will be unchanged*/ + mbox->xferaddr = virt_to_bus ( (void*) &megaCfg->productInfo ); + + mboxData[0]=FC_NEW_CONFIG ; /* i.e. mbox->cmd=0xA1 */ + mboxData[2]=NC_SUBOP_PRODUCT_INFO; /* i.e. 0x0E */ + + if( (retval=megaIssueCmd(megaCfg, mboxData, NULL, 0)) != 0 ) + printk("ami:Product_info (0x0E) cmd failed with error: %d\n", retval); + + } + + megaCfg->host->max_channel = megaCfg->productInfo.SCSIChanPresent; + megaCfg->host->max_id = 16; /* max targets per channel */ + /*(megaCfg->flag & BOARD_40LD)?FC_MAX_TARGETS_PER_CHANNEL:MAX_TARGET+1;*/ + megaCfg->host->max_lun = /* max lun */ + (megaCfg->flag & BOARD_40LD) ? FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES; + + megaCfg->numldrv = enquiry3Pnt->numLDrv; + megaCfg->max_cmds = megaCfg->productInfo.MaxConcCmds; + +#if 0 + int i; + printk (KERN_DEBUG "---- Logical drive info from enquiry3 struct----\n"); for (i = 0; i < megaCfg->numldrv; i++) { - printk ("%d: size: %ld prop: %x state: %x\n", i, - adapterInfo->LogdrvInfo.LDrvSize[i], - adapterInfo->LogdrvInfo.LDrvProp[i], - adapterInfo->LogdrvInfo.LDrvState[i]); + printk ("%d: size: %d prop: %x state: %x\n", i, + enquiry3Pnt->lDrvSize[i], + enquiry3Pnt->lDrvProp[i], + enquiry3Pnt->lDrvState[i]); } + printk (KERN_DEBUG "---- Physical drive info ----\n"); - for (i = 0; i < MAX_PHYSICAL_DRIVES; i++) { + for (i = 0; i < FC_MAX_PHYSICAL_DEVICES; i++) { if (i && !(i % 8)) printk ("\n"); - printk ("%d: %x ", i, adapterInfo->PhysdrvInfo.PDrvState[i]); + printk ("%d: %x ", i, enquiry3Pnt->pDrvState[i]); } printk ("\n"); #endif - megaCfg->max_cmds = adapterInfo->AdpInfo.MaxConcCmds; - #ifdef HP /* use HP firmware and bios version encoding */ sprintf (megaCfg->fwVer, "%c%d%d.%d%d", - adapterInfo->AdpInfo.FwVer[2], - adapterInfo->AdpInfo.FwVer[1] >> 8, - adapterInfo->AdpInfo.FwVer[1] & 0x0f, - adapterInfo->AdpInfo.FwVer[2] >> 8, - adapterInfo->AdpInfo.FwVer[2] & 0x0f); + megaCfg->productInfo.FwVer[2], + megaCfg->productInfo.FwVer[1] >> 8, + megaCfg->productInfo.FwVer[1] & 0x0f, + megaCfg->productInfo.FwVer[2] >> 8, + megaCfg->productInfo.FwVer[2] & 0x0f); sprintf (megaCfg->biosVer, "%c%d%d.%d%d", - adapterInfo->AdpInfo.BiosVer[2], - adapterInfo->AdpInfo.BiosVer[1] >> 8, - adapterInfo->AdpInfo.BiosVer[1] & 0x0f, - adapterInfo->AdpInfo.BiosVer[2] >> 8, - adapterInfo->AdpInfo.BiosVer[2] & 0x0f); + megaCfg->productInfo.BiosVer[2], + megaCfg->productInfo.BiosVer[1] >> 8, + megaCfg->productInfo.BiosVer[1] & 0x0f, + megaCfg->productInfo.BiosVer[2] >> 8, + megaCfg->productInfo.BiosVer[2] & 0x0f); #else - memcpy (megaCfg->fwVer, adapterInfo->AdpInfo.FwVer, 4); + memcpy (megaCfg->fwVer, megaCfg->productInfo.FwVer, 4); megaCfg->fwVer[4] = 0; - memcpy (megaCfg->biosVer, adapterInfo->AdpInfo.BiosVer, 4); + memcpy (megaCfg->biosVer, megaCfg->productInfo.BiosVer, 4); megaCfg->biosVer[4] = 0; #endif - printk (KERN_INFO "megaraid: [%s:%s] detected %d logical drives" CRLFSTR, - megaCfg->fwVer, + printk ("megaraid: [%s:%s] detected %d logical drives" CRLFSTR, + megaCfg->fwVer, megaCfg->biosVer, megaCfg->numldrv); + return 0; } @@ -1267,15 +1444,15 @@ int megaraid_proc_info (char *buffer, char **start, off_t offset, } int findCard (Scsi_Host_Template * pHostTmpl, - u_short pciVendor, u_short pciDev, + u16 pciVendor, u16 pciDev, long flag) { mega_host_config *megaCfg; struct Scsi_Host *host; u_char pciBus, pciDevFun, megaIrq; - u_long megaBase; - u_short jdx,pciIdx = 0; - u_short numFound = 0; + u32 megaBase; + u16 pciIdx = 0; + u16 numFound = 0; #if LINUX_VERSION_CODE < 0x20100 while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) { @@ -1291,8 +1468,8 @@ int findCard (Scsi_Host_Template * pHostTmpl, pciBus = pdev->bus->number; pciDevFun = pdev->devfn; #endif - if (flag & BOARD_QUARTZ) { - u_short magic; + if ((flag & BOARD_QUARTZ) && (skip_id == -1)) { + u16 magic; pcibios_read_config_word (pciBus, pciDevFun, PCI_CONF_AMISIG, &magic); @@ -1301,7 +1478,7 @@ int findCard (Scsi_Host_Template * pHostTmpl, continue; /* not an AMI board */ } } - printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:fun %d\n", + printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:func %d\n", pciVendor, pciDev, pciIdx, pciBus, @@ -1323,6 +1500,7 @@ int findCard (Scsi_Host_Template * pHostTmpl, pciIdx++; if (flag & BOARD_QUARTZ) { + megaBase &= PCI_BASE_ADDRESS_MEM_MASK; megaBase = (long) ioremap (megaBase, 128); } @@ -1336,7 +1514,7 @@ int findCard (Scsi_Host_Template * pHostTmpl, megaCfg = (mega_host_config *) host->hostdata; memset (megaCfg, 0, sizeof (mega_host_config)); - printk (" scsi%d: Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR, + printk ("scsi%d : Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR, host->host_no, (u_int) megaBase, megaIrq); /* Copy resource info into structure */ @@ -1349,8 +1527,7 @@ int findCard (Scsi_Host_Template * pHostTmpl, megaCfg->host->io_port = megaBase; megaCfg->host->n_io_port = 16; megaCfg->host->unique_id = (pciBus << 8) | pciDevFun; - megaCtlrs[numCtlrs++] = megaCfg; - + megaCtlrs[numCtlrs++] = megaCfg; if (flag != BOARD_QUARTZ) { /* Request our IO Range */ if (check_region (megaBase, 16)) { @@ -1370,14 +1547,9 @@ int findCard (Scsi_Host_Template * pHostTmpl, continue; } - mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox)); + mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox64)); mega_i_query_adapter (megaCfg); - for(jdx=0; jdxnReads[jdx] = 0; - megaCfg->nWrites[jdx] = 0; - } - /* Initialize SCBs */ if (initSCB (megaCfg)) { scsi_unregister (host); @@ -1415,6 +1587,8 @@ int megaraid_detect (Scsi_Host_Template * pHostTmpl) skip_id = (skip_id > 15) ? -1 : skip_id; } + printk ("megaraid: " MEGARAID_VERSION CRLFSTR); + count += findCard (pHostTmpl, 0x101E, 0x9010, 0); count += findCard (pHostTmpl, 0x101E, 0x9060, 0); count += findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ); @@ -1475,16 +1649,15 @@ const char * megaraid_info (struct Scsi_Host *pSHost) { static char buffer[512]; mega_host_config *megaCfg; - mega_RAIDINQ *adapterInfo; megaCfg = (mega_host_config *) pSHost->hostdata; - adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer; - sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans", + sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans %d luns", megaCfg->fwVer, - adapterInfo->AdpInfo.MaxConcCmds, + megaCfg->productInfo.MaxConcCmds, megaCfg->host->max_id, - megaCfg->host->max_channel); + megaCfg->host->max_channel, + megaCfg->host->max_lun); return buffer; } @@ -1514,9 +1687,13 @@ int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *)) megaCfg = (mega_host_config *) SCpnt->host->hostdata; if (!(megaCfg->flag & (1L << SCpnt->channel))) { - printk (KERN_INFO "scsi%d: scanning channel %c for devices.\n", + if (SCpnt->channel < SCpnt->host->max_channel) + printk (/*KERN_INFO*/ "scsi%d: scanning channel %c for devices.\n", megaCfg->host->host_no, - SCpnt->channel + 'A'); + SCpnt->channel + '1'); + else + printk(/*KERN_INFO*/ "scsi%d: scanning virtual channel for logical drives.\n", megaCfg->host->host_no); + megaCfg->flag |= (1L << SCpnt->channel); } @@ -1540,6 +1717,7 @@ int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *)) /* Allocate and build a SCB request */ if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) { + /*build SCpnt for IOCTL_CMD_NEW cmd in mega_ioctl()*/ /* Add SCB to the head of the pending queue */ ENQUEUE_NL (pScb, mega_scb, megaCfg->qPending, next); @@ -1550,6 +1728,25 @@ int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *)) else { printk("IRQ pend...\n"); } + + if ( SCpnt->cmnd[0]==IOCTL_CMD_NEW ) + { /* user data from external user buffer */ + char *user_area; + u32 xfer_size; + + pScb->sem=MUTEX_LOCKED; + down(&pScb->sem); + + user_area = *((char **)&pScb->SCpnt->cmnd[4]); + xfer_size = *((u32 *)&pScb->SCpnt->cmnd[8]); + + copy_to_user(user_area,pScb->kern_area,xfer_size); + + kfree(pScb->kern_area); + + freeSCB(megaCfg, pScb); + } + } spin_unlock_irqrestore(&mega_lock,flags); @@ -1750,3 +1947,4 @@ Scsi_Host_Template driver_template = MEGARAID; #include "scsi_module.c" #endif + diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 1e328a155822..83fe02785b47 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -9,6 +9,7 @@ #define IN_ABORT 0x40000000L #define IN_RESET 0x20000000L #define BOARD_QUARTZ 0x08000000L +#define BOARD_40LD 0x04000000L #define SCB_FREE 0x0 #define SCB_ACTIVE 0x1 @@ -147,32 +148,333 @@ } #endif + +/*********************************************************************** + * Structure Declarations for the Firmware supporting 40 Logical Drives + * and 256 Physical Drives. + ***********************************************************************/ + +#define FC_MAX_LOGICAL_DRIVES 40 +#define FC_MAX_LOG_DEVICES FC_MAX_LOGICAL_DRIVES +#define FC_MAX_SPAN_DEPTH 8 +#define FC_MAX_ROW_SIZE 32 + +#define FC_MAX_CHANNELS 16 +#define FC_MAX_TARGETS_PER_CHANNEL 16 +#define FC_MAX_PHYSICAL_DEVICES 256 + +#define FC_NEW_CONFIG 0xA1 +#define DCMD_FC_CMD 0xA1 + #define NC_SUBOP_PRODUCT_INFO 0x0E + #define NC_SUBOP_ENQUIRY3 0x0F + #define ENQ3_GET_SOLICITED_NOTIFY_ONLY 0x01 + #define ENQ3_GET_SOLICITED_FULL 0x02 + #define ENQ3_GET_UNSOLICITED 0x03 + + +/******************************************** + * PRODUCT_INFO Strucure + ********************************************/ + +#define SIG_40LOG_32STR_8SPN 0x00282008 + +/* + * Utilities declare this strcture size as 1024 bytes. So more fields can + * be added in future. + */ + +struct MRaidProductInfo +{ + u32 DataSize; /* current size in bytes (not including resvd) */ + u32 ConfigSignature; + /* Current value is 0x00282008 + * 0x28=MAX_LOGICAL_DRIVES, + * 0x20=Number of stripes and + * 0x08=Number of spans */ + u8 FwVer[16]; /* printable ASCI string */ + u8 BiosVer[16]; /* printable ASCI string */ + u8 ProductName[80]; /* printable ASCI string */ + + u8 MaxConcCmds; /* Max. concurrent commands supported */ + u8 SCSIChanPresent; /* Number of SCSI Channels detected */ + u8 FCLoopPresent; /* Number of Fibre Loops detected */ + u8 memType; /* EDO, FPM, SDRAM etc */ + + u32 signature; + u16 DramSize; /* In terms of MB */ + u16 subSystemID; + + u16 subSystemVendorID; + u8 numNotifyCounters; + u8 pad1k[889]; /* 135 + 889 resvd = 1024 total size */ +}__attribute__((packed)); +typedef struct MRaidProductInfo megaRaidProductInfo; + +/******************************************** + * Standard ENQUIRY Strucure + ********************************************/ +struct FC_ADP_INFO +{ + u8 MaxConcCmds; /* Max. concurrent commands supported. */ + u8 RbldRate; /* Rebuild Rate. Varies from 0%-100% */ + u8 MaxTargPerChan; /* Max. Targets supported per chan. */ + u8 ChanPresent; /* No. of Chans present on this adapter. */ + u8 FwVer[4]; /* Firmware version. */ + u16 AgeOfFlash; /* No. of times FW has been downloaded. */ + u8 ChipSetValue; /* Contents of 0xC0000832 */ + u8 DramSize; /* In terms of MB */ + u8 CacheFlushInterval; /* In terms of Seconds */ + u8 BiosVersion[4]; + u8 BoardType; + u8 sense_alert; + u8 write_config_count; /* Increase with evry configuration change */ + u8 drive_inserted_count; /* Increase with every drive inserted */ + u8 inserted_drive; /* Channel: Id of inserted drive */ + u8 battery_status; + /* + BIT 0 : battery module missing + BIT 1 : VBAD + BIT 2 : temp high + BIT 3 : battery pack missing + BIT 4,5 : 00 - charge complete + 01 - fast charge in prog + 10 - fast charge fail + 11 - undefined + BIt 6 : counter > 1000 + Bit 7 : undefined + */ + u8 dec_fault_bus_info; /* was resvd */ +}__attribute__((packed)); + +struct FC_LDRV_INFO +{ + u8 NumLDrv; /* No. of Log. Drvs configured. */ + u8 recon_state[FC_MAX_LOGICAL_DRIVES/8]; + /* bit field for State of reconstruct */ + u16 LDrvOpStatus[FC_MAX_LOGICAL_DRIVES/8]; + /* bit field Status of Long Operations. */ + + u32 LDrvSize[FC_MAX_LOGICAL_DRIVES]; /* Size of each log. Drv. */ + u8 LDrvProp[FC_MAX_LOGICAL_DRIVES]; + u8 LDrvState[FC_MAX_LOGICAL_DRIVES]; /* State of Logical Drives. */ +}__attribute__((packed)); + +#define PREVSTAT_MASK 0xf0 +#define CURRSTAT_MASK 0x0f + +struct FC_PDRV_INFO +{ + u8 PDrvState[FC_MAX_PHYSICAL_DEVICES]; /* State of Phys Drvs. */ +}__attribute__((packed)); + + +struct FC_AdapterInq +{ + struct FC_ADP_INFO AdpInfo; + struct FC_LDRV_INFO LogdrvInfo; + struct FC_PDRV_INFO PhysdrvInfo; +}__attribute__((packed)); + + +typedef struct FC_AdapterInq mega_RAIDINQ_FC; + +/******************************************** + * NOTIFICATION Strucure + ********************************************/ + +#define MAX_NOTIFY_SIZE 0x80 +#define CUR_NOTIFY_SIZE sizeof(struct MegaRAID_Notify) + +/* + * Utilities declare this strcture size as ?? bytes. So more fields can + * be added in future. + */ +struct MegaRAID_Notify +{ + u32 globalCounter; /* Any change increments this counter */ + + u8 paramCounter; /* Indicates any params changed */ + u8 paramId; /* Param modified - defined below */ + u16 paramVal; /* New val of last param modified */ + + u8 writeConfigCounter; /* write config occurred */ + u8 writeConfigRsvd[3]; + + u8 ldrvOpCounter; /* Indicates ldrv op started/completed */ + u8 ldrvOpId; /* ldrv num */ + u8 ldrvOpCmd; /* ldrv operation - defined below */ + u8 ldrvOpStatus; /* status of the operation */ + + u8 ldrvStateCounter; /* Indicates change of ldrv state */ + u8 ldrvStateId; /* ldrv num */ + u8 ldrvStateNew; /* New state */ + u8 ldrvStateOld; /* old state */ + + u8 pdrvStateCounter; /* Indicates change of ldrv state */ + u8 pdrvStateId; /* pdrv id */ + u8 pdrvStateNew; /* New state */ + u8 pdrvStateOld; /* old state */ + + u8 pdrvFmtCounter; /* Indicates pdrv format started/over */ + u8 pdrvFmtId; /* pdrv id */ + u8 pdrvFmtVal; /* format started/over */ + u8 pdrvFmtRsvd; + + u8 targXferCounter; /* Indicates SCSI-2 Xfer rate change */ + u8 targXferId; /* pdrv Id */ + u8 targXferVal; /* new Xfer params of last pdrv */ + u8 targXferRsvd; + + u8 fcLoopIdChgCounter; /* Indicates loopid changed */ + u8 fcLoopIdPdrvId; /* pdrv id */ + u8 fcLoopId0; /* loopid on fc loop 0 */ + u8 fcLoopId1; /* loopid on fc loop 1 */ + + u8 fcLoopStateCounter; /* Indicates loop state changed */ + u8 fcLoopState0; /* state of fc loop 0 */ + u8 fcLoopState1; /* state of fc loop 1 */ + u8 fcLoopStateRsvd; +}__attribute__((packed)); + + +/******************************************** + * PARAM IDs in Notify struct + ********************************************/ +#define PARAM_RBLD_RATE 0x01 + /*-------------------------------------- + * Param val = + * byte 0: new rbld rate + *--------------------------------------*/ +#define PARAM_CACHE_FLUSH_INTERVAL 0x02 + /*-------------------------------------- + * Param val = + * byte 0: new cache flush interval + *--------------------------------------*/ +#define PARAM_SENSE_ALERT 0x03 + /*-------------------------------------- + * Param val = + * byte 0: last pdrv id causing chkcond + *--------------------------------------*/ +#define PARAM_DRIVE_INSERTED 0x04 + /*-------------------------------------- + * Param val = + * byte 0: last pdrv id inserted + *--------------------------------------*/ +#define PARAM_BATTERY_STATUS 0x05 + /*-------------------------------------- + * Param val = + * byte 0: battery status + *--------------------------------------*/ + +/******************************************** + * Ldrv operation cmd in Notify struct + ********************************************/ +#define LDRV_CMD_CHKCONSISTANCY 0x01 +#define LDRV_CMD_INITIALIZE 0x02 +#define LDRV_CMD_RECONSTRUCTION 0x03 + +/******************************************** + * Ldrv operation status in Notify struct + ********************************************/ +#define LDRV_OP_SUCCESS 0x00 +#define LDRV_OP_FAILED 0x01 +#define LDRV_OP_ABORTED 0x02 +#define LDRV_OP_CORRECTED 0x03 +#define LDRV_OP_STARTED 0x04 + + +/******************************************** + * Raid Logical drive states. + ********************************************/ +#define RDRV_OFFLINE 0 +#define RDRV_DEGRADED 1 +#define RDRV_OPTIMAL 2 +#define RDRV_DELETED 3 + +/******************************************* + * Physical drive states. + *******************************************/ +#define PDRV_UNCNF 0 +#define PDRV_ONLINE 3 +#define PDRV_FAILED 4 +#define PDRV_RBLD 5 +/* #define PDRV_HOTSPARE 6 */ + +/******************************************* + * Formal val in Notify struct + *******************************************/ +#define PDRV_FMT_START 0x01 +#define PDRV_FMT_OVER 0x02 + +/******************************************** + * FC Loop State in Notify Struct + ********************************************/ +#define ENQ_FCLOOP_FAILED 0 +#define ENQ_FCLOOP_ACTIVE 1 +#define ENQ_FCLOOP_TRANSIENT 2 + +/******************************************** + * ENQUIRY3 Strucure + ********************************************/ +/* + * Utilities declare this strcture size as 1024 bytes. So more fields can + * be added in future. + */ +struct MegaRAID_Enquiry3 +{ + u32 dataSize; /* current size in bytes (not including resvd) */ + + struct MegaRAID_Notify notify; + + u8 notifyRsvd[MAX_NOTIFY_SIZE - CUR_NOTIFY_SIZE]; + + u8 rbldRate; /* Rebuild rate (0% - 100%) */ + u8 cacheFlushInterval; /* In terms of Seconds */ + u8 senseAlert; + u8 driveInsertedCount; /* drive insertion count */ + + u8 batteryStatus; + u8 numLDrv; /* No. of Log Drives configured */ + u8 reconState[FC_MAX_LOGICAL_DRIVES/8]; /* State of reconstruct */ + u16 lDrvOpStatus[FC_MAX_LOGICAL_DRIVES/8]; /* log. Drv Status */ + + u32 lDrvSize[FC_MAX_LOGICAL_DRIVES]; /* Size of each log. Drv */ + u8 lDrvProp[FC_MAX_LOGICAL_DRIVES]; + u8 lDrvState[FC_MAX_LOGICAL_DRIVES]; /* State of Logical Drives */ + u8 pDrvState[FC_MAX_PHYSICAL_DEVICES]; /* State of Phys. Drvs. */ + u16 physDrvFormat[FC_MAX_PHYSICAL_DEVICES/16]; + + u8 targXfer[80]; /* phys device transfer rate */ + u8 pad1k[263]; /* 761 + 263reserved = 1024 bytes total size */ +}__attribute__((packed)); +typedef struct MegaRAID_Enquiry3 mega_Enquiry3; + /* 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]; + u8 MaxConcCmds; + u8 RbldRate; + u8 MaxTargPerChan; + u8 ChanPresent; + u8 FwVer[4]; + u16 AgeOfFlash; + u8 ChipSetValue; + u8 DramSize; + u8 CacheFlushInterval; + u8 BiosVer[4]; + u8 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]; + u8 NumLDrv; + u8 resvd[3]; + u32 LDrvSize[MAX_LOGICAL_DRIVES]; + u8 LDrvProp[MAX_LOGICAL_DRIVES]; + u8 LDrvState[MAX_LOGICAL_DRIVES]; } mega_LDRV_INFO; typedef struct _mega_PDRV_INFO { - u_char PDrvState[MAX_PHYSICAL_DRIVES]; - u_char resvd; + u8 PDrvState[MAX_PHYSICAL_DRIVES]; + u8 resvd; } mega_PDRV_INFO; // RAID inquiry: Mailbox command 0x5 @@ -184,65 +486,70 @@ typedef struct _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; + u8 timeout:3; /* 0=6sec/1=60sec/2=10min/3=3hrs */ + u8 ars:1; + u8 reserved:3; + u8 islogical:1; + u8 logdrv; /* if islogical == 1 */ + u8 channel; /* if islogical == 0 */ + u8 target; /* if islogical == 0 */ + u8 queuetag; /* unused */ + u8 queueaction; /* unused */ + u8 cdb[MAX_CDB_LEN]; + u8 cdblen; + u8 reqsenselen; + u8 reqsensearea[MAX_REQ_SENSE_LEN]; + u8 numsgelements; + u8 scsistatus; + u32 dataxferaddr; + u32 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]; + /* 0x0 */ u8 cmd; + /* 0x1 */ u8 cmdid; + /* 0x2 */ u16 numsectors; + /* 0x4 */ u32 lba; + /* 0x8 */ u32 xferaddr; + /* 0xC */ u8 logdrv; + /* 0xD */ u8 numsgelements; + /* 0xE */ u8 resvd; + /* 0xF */ u8 busy; + /* 0x10 */ u8 numstatus; + /* 0x11 */ u8 status; + /* 0x12 */ u8 completed[46]; + u8 mraid_poll; + u8 mraid_ack; + u8 pad[16]; } mega_mailbox; +typedef struct { + u32 xferSegment; /* for 64-bit controllers */ + mega_mailbox mailbox; +} mega_mailbox64; + 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]; + /* 0x0 */ u8 cmd; + /* 0x1 */ u8 cmdid; + /* 0x2 */ u8 channel; + /* 0x3 */ u8 param; + /* 0x4 */ u8 pad[4]; + /* 0x8 */ u32 xferaddr; + /* 0xC */ u8 logdrv; + /* 0xD */ u8 numsgelements; + /* 0xE */ u8 resvd; + /* 0xF */ u8 busy; + /* 0x10 */ u8 numstatus; + /* 0x11 */ u8 status; + /* 0x12 */ u8 completed[46]; + u8 mraid_poll; + u8 mraid_ack; + u8 malign[16]; } mega_ioctl_mbox; typedef struct _mega_sglist { - u_long address; - u_long length; + u32 address; + u32 length; } mega_sglist; /* Queued command data */ @@ -250,39 +557,51 @@ typedef struct _mega_scb mega_scb; struct _mega_scb { int idx; - u_long state; - u_long isrcount; - u_char mboxData[16]; + u32 state; + u32 isrcount; + u8 mboxData[16]; mega_passthru pthru; Scsi_Cmnd *SCpnt; mega_sglist *sgList; + char *kern_area; /* Only used for large ioctl xfers */ + struct wait_queue *ioctl_wait; + struct semaphore sem; mega_scb *next; }; /* Per-controller data */ typedef struct _mega_host_config { - u_char numldrv; - u_long flag; - u_long base; + u8 numldrv; + u32 flag; + u32 base; mega_scb *qFree; mega_scb *qPending; - u_long nReads[MAX_LOGICAL_DRIVES]; - u_long nWrites[MAX_LOGICAL_DRIVES]; + u32 nReads[FC_MAX_LOGICAL_DRIVES]; + u32 nWrites[FC_MAX_LOGICAL_DRIVES]; /* Host adapter parameters */ - u_char fwVer[7]; - u_char biosVer[7]; + u8 fwVer[7]; + u8 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]; + volatile mega_mailbox64 *mbox64; /* ptr to beginning of 64-bit mailbox */ + volatile mega_mailbox *mbox; /* ptr to beginning of standard mailbox */ + volatile mega_mailbox64 mailbox64; +#if 0 + volatile union { + u8 generic_buffer[2 * 1024L]; + mega_RAIDINQ adapterInfoData; + mega_Enquiry3 enquiry3Data; + }mega_buffer; +#else + volatile u8 mega_buffer[2*1024L]; +#endif + volatile megaRaidProductInfo productInfo; - u_char max_cmds; + u8 max_cmds; mega_scb scbList[MAX_COMMANDS]; } mega_host_config; diff --git a/include/net/ip_masq.h b/include/net/ip_masq.h index e3fcf6523112..8788eb27e162 100644 --- a/include/net/ip_masq.h +++ b/include/net/ip_masq.h @@ -74,6 +74,7 @@ struct ip_vs_dest; #ifdef __KERNEL__ +#define IP_MASQ_NTABLES 3 #define IP_MASQ_TAB_SIZE 256 /* diff --git a/net/ipv4/ip_masq.c b/net/ipv4/ip_masq.c index 7c1902488847..69b31496c813 100644 --- a/net/ipv4/ip_masq.c +++ b/net/ipv4/ip_masq.c @@ -599,8 +599,6 @@ EXPORT_SYMBOL(ip_masq_d_table); * 1 for extra modules support (daddr) */ -#define IP_MASQ_NTABLES 3 - struct list_head ip_masq_m_table[IP_MASQ_TAB_SIZE]; struct list_head ip_masq_s_table[IP_MASQ_TAB_SIZE]; struct list_head ip_masq_d_table[IP_MASQ_TAB_SIZE]; diff --git a/net/ipv4/ip_vs.c b/net/ipv4/ip_vs.c index efee35a9442e..9e4973d45c92 100644 --- a/net/ipv4/ip_vs.c +++ b/net/ipv4/ip_vs.c @@ -42,6 +42,7 @@ #include #include +#include #include #ifdef CONFIG_KMOD @@ -229,12 +230,12 @@ int ip_vs_hash(struct ip_masq *ms) hash = ip_vs_hash_key(ms->protocol, ms->daddr, ms->dport); /* - * Note: because ip_masq_put sets masq expire if its refcnt==2, - * we have to increase counter two times, otherwise the - * masq won't expire. + * Note: because ip_masq_put sets masq expire if its + * refcnt==IP_MASQ_NTABLES, we have to increase + * counter IP_MASQ_NTABLES times, otherwise the masq + * won't expire. */ - atomic_inc(&ms->refcnt); - atomic_inc(&ms->refcnt); + atomic_add(IP_MASQ_NTABLES, &ms->refcnt); list_add(&ms->m_list, &ip_vs_table[hash]); ms->flags |= IP_MASQ_F_HASHED; @@ -250,7 +251,6 @@ int ip_vs_hash(struct ip_masq *ms) int ip_vs_unhash(struct ip_masq *ms) { unsigned int hash; - struct ip_masq ** ms_p; if (!(ms->flags & IP_MASQ_F_HASHED)) { IP_VS_ERR("ip_vs_unhash(): request for unhash flagged, called from %p\n", @@ -262,11 +262,10 @@ int ip_vs_unhash(struct ip_masq *ms) */ hash = ip_vs_hash_key(ms->protocol, ms->daddr, ms->dport); /* - * Note: since we increase refcnt twice while hashing, - * we have to decrease it twice while unhashing. + * Note: since we increase refcnt while hashing, + * we have to decrease it while unhashing. */ - atomic_dec(&ms->refcnt); - atomic_dec(&ms->refcnt); + atomic_sub(IP_MASQ_NTABLES, &ms->refcnt); list_del(&ms->m_list); ms->flags &= ~IP_MASQ_F_HASHED; return 1; @@ -284,7 +283,7 @@ int ip_vs_unhash(struct ip_masq *ms) struct ip_masq * ip_vs_in_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port) { unsigned hash; - struct ip_masq *ms = NULL; + struct ip_masq *ms; struct list_head *l, *e; hash = ip_vs_hash_key(protocol, s_addr, s_port); @@ -301,6 +300,7 @@ struct ip_masq * ip_vs_in_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_ goto out; } } + ms = NULL; out: return ms; @@ -317,7 +317,7 @@ struct ip_masq * ip_vs_in_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_ struct ip_masq * ip_vs_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port) { unsigned hash; - struct ip_masq *ms = NULL; + struct ip_masq *ms; struct list_head *l, *e; /* @@ -338,6 +338,7 @@ struct ip_masq * ip_vs_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d } } + ms = NULL; out: return ms; @@ -1289,7 +1290,7 @@ __initfunc(int ip_vs_init(void)) #ifdef CONFIG_IP_MASQUERADE_VS_WLC ip_vs_wlc_init(); #endif -#ifdef CONFIG_IP_MASQUERADE_VS_WLC +#ifdef CONFIG_IP_MASQUERADE_VS_PCC ip_vs_pcc_init(); #endif return 0; diff --git a/sound/solo1 b/sound/solo1 new file mode 100644 index 000000000000..1c0a641b01c4 --- /dev/null +++ b/sound/solo1 @@ -0,0 +1,48 @@ +ALaw/uLaw sample formats +------------------------ + +This driver does not support the ALaw/uLaw sample formats. +ALaw is the default mode when opening a sound device +using OSS/Free. The reason for the lack of support is +that the hardware does not support these formats, and adding +conversion routines to the kernel would lead to very ugly +code in the presence of the mmap interface to the driver. +And since xquake uses mmap, mmap is considered important :-) +and no sane application uses ALaw/uLaw these days anyway. +In short, playing a Sun .au file as follows: + +cat my_file.au > /dev/dsp + +does not work. Instead, you may use the play script from +Chris Bagwell's sox-12.14 package (or later, available from the URL +below) to play many different audio file formats. +The script automatically determines the audio format +and does do audio conversions if necessary. +http://home.sprynet.com/sprynet/cbagwell/projects.html + + +Blocking vs. nonblocking IO +--------------------------- + +Unlike OSS/Free this driver honours the O_NONBLOCK file flag +not only during open, but also during read and write. +This is an effort to make the sound driver interface more +regular. Timidity has problems with this; a patch +is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html. +(Timidity patched will also run on OSS/Free). + + +MIDI UART +--------- + +The driver supports a simple MIDI UART interface, with +no ioctl's supported. + + +MIDI synthesizer +---------------- + +The card has an OPL compatible FM synthesizer. + +Thomas Sailer +sailer@ife.ee.ethz.ch