Merge ../linux-2.6
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>
Mon, 28 Aug 2006 02:59:59 +0000 (21:59 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Mon, 28 Aug 2006 02:59:59 +0000 (21:59 -0500)
1  2 
drivers/message/fusion/mptfc.c
drivers/scsi/hptiop.c
drivers/scsi/libata-eh.c
drivers/scsi/megaraid/megaraid_mbox.c
include/linux/pci_ids.h

@@@ -162,13 -162,7 +162,13 @@@ static struct fc_function_template mptf
        .show_starget_port_id = 1,
        .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
        .show_rport_dev_loss_tmo = 1,
 -
 +      .show_host_supported_speeds = 1,
 +      .show_host_maxframe_size = 1,
 +      .show_host_speed = 1,
 +      .show_host_fabric_name = 1,
 +      .show_host_port_type = 1,
 +      .show_host_port_state = 1,
 +      .show_host_symbolic_name = 1,
  };
  
  static void
@@@ -675,7 -669,10 +675,10 @@@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, 
                         * if still doing discovery,
                         * hang loose a while until finished
                         */
-                       if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
+                       if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
+                           (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
+                            (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
+                             == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
                                if (count-- > 0) {
                                        msleep(100);
                                        goto try_again;
@@@ -842,95 -839,33 +845,95 @@@ mptfc_SetFcPortPage1_defaults(MPT_ADAPT
  static void
  mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
  {
 -      unsigned class = 0, cos = 0;
 +      unsigned        class = 0;
 +      unsigned        cos = 0;
 +      unsigned        speed;
 +      unsigned        port_type;
 +      unsigned        port_state;
 +      FCPortPage0_t   *pp0;
 +      struct Scsi_Host *sh;
 +      char            *sn;
  
        /* don't know what to do as only one scsi (fc) host was allocated */
        if (portnum != 0)
                return;
  
 -      class = ioc->fc_port_page0[portnum].SupportedServiceClass;
 +      pp0 = &ioc->fc_port_page0[portnum];
 +      sh = ioc->sh;
 +
 +      sn = fc_host_symbolic_name(sh);
 +      snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
 +          ioc->prod_name,
 +          MPT_FW_REV_MAGIC_ID_STRING,
 +          ioc->facts.FWVersion.Word);
 +
 +      fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
 +
 +      fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
 +
 +      fc_host_node_name(sh) =
 +              (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
 +
 +      fc_host_port_name(sh) =
 +              (u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
 +
 +      fc_host_port_id(sh) = pp0->PortIdentifier;
 +
 +      class = pp0->SupportedServiceClass;
        if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
                cos |= FC_COS_CLASS1;
        if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
                cos |= FC_COS_CLASS2;
        if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
                cos |= FC_COS_CLASS3;
 +      fc_host_supported_classes(sh) = cos;
 +
 +      if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
 +              speed = FC_PORTSPEED_1GBIT;
 +      else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
 +              speed = FC_PORTSPEED_2GBIT;
 +      else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
 +              speed = FC_PORTSPEED_4GBIT;
 +      else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
 +              speed = FC_PORTSPEED_10GBIT;
 +      else
 +              speed = FC_PORTSPEED_UNKNOWN;
 +      fc_host_speed(sh) = speed;
 +
 +      speed = 0;
 +      if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
 +              speed |= FC_PORTSPEED_1GBIT;
 +      if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
 +              speed |= FC_PORTSPEED_2GBIT;
 +      if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
 +              speed |= FC_PORTSPEED_4GBIT;
 +      if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
 +              speed |= FC_PORTSPEED_10GBIT;
 +      fc_host_supported_speeds(sh) = speed;
 +
 +      port_state = FC_PORTSTATE_UNKNOWN;
 +      if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
 +              port_state = FC_PORTSTATE_ONLINE;
 +      else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
 +              port_state = FC_PORTSTATE_LINKDOWN;
 +      fc_host_port_state(sh) = port_state;
 +
 +      port_type = FC_PORTTYPE_UNKNOWN;
 +      if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
 +              port_type = FC_PORTTYPE_PTP;
 +      else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
 +              port_type = FC_PORTTYPE_LPORT;
 +      else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
 +              port_type = FC_PORTTYPE_NLPORT;
 +      else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
 +              port_type = FC_PORTTYPE_NPORT;
 +      fc_host_port_type(sh) = port_type;
 +
 +      fc_host_fabric_name(sh) =
 +          (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
 +              (u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
 +              (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
  
 -      fc_host_node_name(ioc->sh) =
 -              (u64)ioc->fc_port_page0[portnum].WWNN.High << 32
 -                  | (u64)ioc->fc_port_page0[portnum].WWNN.Low;
 -
 -      fc_host_port_name(ioc->sh) =
 -              (u64)ioc->fc_port_page0[portnum].WWPN.High << 32
 -                  | (u64)ioc->fc_port_page0[portnum].WWPN.Low;
 -
 -      fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
 -
 -      fc_host_supported_classes(ioc->sh) = cos;
 -
 -      fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
  }
  
  static void
@@@ -963,59 -898,45 +966,45 @@@ mptfc_rescan_devices(void *arg
  {
        MPT_ADAPTER             *ioc = (MPT_ADAPTER *)arg;
        int                     ii;
-       int                     work_to_do;
        u64                     pn;
-       unsigned long           flags;
        struct mptfc_rport_info *ri;
  
-       do {
-               /* start by tagging all ports as missing */
-               list_for_each_entry(ri, &ioc->fc_rports, list) {
-                       if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
-                               ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
-                       }
+       /* start by tagging all ports as missing */
+       list_for_each_entry(ri, &ioc->fc_rports, list) {
+               if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
+                       ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
                }
+       }
  
-               /*
-                * now rescan devices known to adapter,
-                * will reregister existing rports
-                */
-               for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
-                       (void) mptfc_GetFcPortPage0(ioc, ii);
-                       mptfc_init_host_attr(ioc,ii);   /* refresh */
-                       mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
-               }
+       /*
+        * now rescan devices known to adapter,
+        * will reregister existing rports
+        */
+       for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
+               (void) mptfc_GetFcPortPage0(ioc, ii);
+               mptfc_init_host_attr(ioc, ii);  /* refresh */
+               mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
+       }
  
-               /* delete devices still missing */
-               list_for_each_entry(ri, &ioc->fc_rports, list) {
-                       /* if newly missing, delete it */
-                       if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
+       /* delete devices still missing */
+       list_for_each_entry(ri, &ioc->fc_rports, list) {
+               /* if newly missing, delete it */
+               if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
  
-                               ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
-                                              MPT_RPORT_INFO_FLAGS_MISSING);
-                               fc_remote_port_delete(ri->rport);       /* won't sleep */
-                               ri->rport = NULL;
+                       ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
+                                      MPT_RPORT_INFO_FLAGS_MISSING);
+                       fc_remote_port_delete(ri->rport);       /* won't sleep */
+                       ri->rport = NULL;
  
-                               pn = (u64)ri->pg0.WWPN.High << 32 |
-                                    (u64)ri->pg0.WWPN.Low;
-                               dfcprintk ((MYIOC_s_INFO_FMT
-                                       "mptfc_rescan.%d: %llx deleted\n",
-                                       ioc->name,
-                                       ioc->sh->host_no,
-                                       (unsigned long long)pn));
-                       }
+                       pn = (u64)ri->pg0.WWPN.High << 32 |
+                            (u64)ri->pg0.WWPN.Low;
+                       dfcprintk ((MYIOC_s_INFO_FMT
+                               "mptfc_rescan.%d: %llx deleted\n",
+                               ioc->name,
+                               ioc->sh->host_no,
+                               (unsigned long long)pn));
                }
-               /*
-                * allow multiple passes as target state
-                * might have changed during scan
-                */
-               spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
-               if (ioc->fc_rescan_work_count > 2)      /* only need one more */
-                       ioc->fc_rescan_work_count = 2;
-               work_to_do = --ioc->fc_rescan_work_count;
-               spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
-       } while (work_to_do);
+       }
  }
  
  static int
@@@ -1227,7 -1148,6 +1216,6 @@@ mptfc_probe(struct pci_dev *pdev, cons
         *      by doing it via the workqueue, some locking is eliminated
         */
  
-       ioc->fc_rescan_work_count = 1;
        queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
        flush_workqueue(ioc->fc_rescan_work_q);
  
@@@ -1270,10 -1190,8 +1258,8 @@@ mptfc_event_process(MPT_ADAPTER *ioc, E
        case MPI_EVENT_RESCAN:
                spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
                if (ioc->fc_rescan_work_q) {
-                       if (ioc->fc_rescan_work_count++ == 0) {
-                               queue_work(ioc->fc_rescan_work_q,
-                                          &ioc->fc_rescan_work);
-                       }
+                       queue_work(ioc->fc_rescan_work_q,
+                                  &ioc->fc_rescan_work);
                }
                spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
                break;
@@@ -1316,10 -1234,8 +1302,8 @@@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int r
                mptfc_SetFcPortPage1_defaults(ioc);
                spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
                if (ioc->fc_rescan_work_q) {
-                       if (ioc->fc_rescan_work_count++ == 0) {
-                               queue_work(ioc->fc_rescan_work_q,
-                                          &ioc->fc_rescan_work);
-                       }
+                       queue_work(ioc->fc_rescan_work_q,
+                                  &ioc->fc_rescan_work);
                }
                spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
        }
diff --combined drivers/scsi/hptiop.c
@@@ -15,6 -15,7 +15,6 @@@
   *
   * For more information, visit http://www.highpoint-tech.com
   */
 -#include <linux/config.h>
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/string.h>
@@@ -44,10 -45,6 +44,6 @@@ static char driver_name[] = "hptiop"
  static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver";
  static const char driver_ver[] = "v1.0 (060426)";
  
- static DEFINE_SPINLOCK(hptiop_hba_list_lock);
- static LIST_HEAD(hptiop_hba_list);
- static int hptiop_cdev_major = -1;
  static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag);
  static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag);
  static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg);
@@@ -576,7 -573,7 +572,7 @@@ static int hptiop_reset_hba(struct hpti
        if (atomic_xchg(&hba->resetting, 1) == 0) {
                atomic_inc(&hba->reset_count);
                writel(IOPMU_INBOUND_MSG0_RESET,
-                               &hba->iop->outbound_msgaddr0);
+                               &hba->iop->inbound_msgaddr0);
                hptiop_pci_posting_flush(hba->iop);
        }
  
@@@ -619,532 -616,11 +615,11 @@@ static int hptiop_adjust_disk_queue_dep
        return queue_depth;
  }
  
- struct hptiop_getinfo {
-       char __user *buffer;
-       loff_t buflength;
-       loff_t bufoffset;
-       loff_t buffillen;
-       loff_t filpos;
- };
- static void hptiop_copy_mem_info(struct hptiop_getinfo *pinfo,
-                                       char *data, int datalen)
- {
-       if (pinfo->filpos < pinfo->bufoffset) {
-               if (pinfo->filpos + datalen <= pinfo->bufoffset) {
-                       pinfo->filpos += datalen;
-                       return;
-               } else {
-                       data += (pinfo->bufoffset - pinfo->filpos);
-                       datalen  -= (pinfo->bufoffset - pinfo->filpos);
-                       pinfo->filpos = pinfo->bufoffset;
-               }
-       }
-       pinfo->filpos += datalen;
-       if (pinfo->buffillen == pinfo->buflength)
-               return;
-       if (pinfo->buflength - pinfo->buffillen < datalen)
-               datalen = pinfo->buflength - pinfo->buffillen;
-       if (copy_to_user(pinfo->buffer + pinfo->buffillen, data, datalen))
-               return;
-       pinfo->buffillen += datalen;
- }
- static int hptiop_copy_info(struct hptiop_getinfo *pinfo, char *fmt, ...)
- {
-       va_list args;
-       char buf[128];
-       int len;
-       va_start(args, fmt);
-       len = vsnprintf(buf, sizeof(buf), fmt, args);
-       va_end(args);
-       hptiop_copy_mem_info(pinfo, buf, len);
-       return len;
- }
- static void hptiop_ioctl_done(struct hpt_ioctl_k *arg)
- {
-       arg->done = NULL;
-       wake_up(&arg->hba->ioctl_wq);
- }
- static void hptiop_do_ioctl(struct hpt_ioctl_k *arg)
- {
-       struct hptiop_hba *hba = arg->hba;
-       u32 val;
-       struct hpt_iop_request_ioctl_command __iomem *req;
-       int ioctl_retry = 0;
-       dprintk("scsi%d: hptiop_do_ioctl\n", hba->host->host_no);
-       /*
-        * check (in + out) buff size from application.
-        * outbuf must be dword aligned.
-        */
-       if (((arg->inbuf_size + 3) & ~3) + arg->outbuf_size >
-                       hba->max_request_size
-                               - sizeof(struct hpt_iop_request_header)
-                               - 4 * sizeof(u32)) {
-               dprintk("scsi%d: ioctl buf size (%d/%d) is too large\n",
-                               hba->host->host_no,
-                               arg->inbuf_size, arg->outbuf_size);
-               arg->result = HPT_IOCTL_RESULT_FAILED;
-               return;
-       }
- retry:
-       spin_lock_irq(hba->host->host_lock);
-       val = readl(&hba->iop->inbound_queue);
-       if (val == IOPMU_QUEUE_EMPTY) {
-               spin_unlock_irq(hba->host->host_lock);
-               dprintk("scsi%d: no free req for ioctl\n", hba->host->host_no);
-               arg->result = -1;
-               return;
-       }
-       req = (struct hpt_iop_request_ioctl_command __iomem *)
-                       ((unsigned long)hba->iop + val);
-       writel(HPT_CTL_CODE_LINUX_TO_IOP(arg->ioctl_code),
-                       &req->ioctl_code);
-       writel(arg->inbuf_size, &req->inbuf_size);
-       writel(arg->outbuf_size, &req->outbuf_size);
-       /*
-        * use the buffer on the IOP local memory first, then copy it
-        * back to host.
-        * the caller's request buffer shoudl be little-endian.
-        */
-       if (arg->inbuf_size)
-               memcpy_toio(req->buf, arg->inbuf, arg->inbuf_size);
-       /* correct the controller ID for IOP */
-       if ((arg->ioctl_code == HPT_IOCTL_GET_CHANNEL_INFO ||
-               arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO_V2 ||
-               arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO)
-               && arg->inbuf_size >= sizeof(u32))
-               writel(0, req->buf);
-       writel(IOP_REQUEST_TYPE_IOCTL_COMMAND, &req->header.type);
-       writel(0, &req->header.flags);
-       writel(offsetof(struct hpt_iop_request_ioctl_command, buf)
-                       + arg->inbuf_size, &req->header.size);
-       writel((u32)(unsigned long)arg, &req->header.context);
-       writel(BITS_PER_LONG > 32 ? (u32)((unsigned long)arg>>32) : 0,
-                       &req->header.context_hi32);
-       writel(IOP_RESULT_PENDING, &req->header.result);
-       arg->result = HPT_IOCTL_RESULT_FAILED;
-       arg->done = hptiop_ioctl_done;
-       writel(val, &hba->iop->inbound_queue);
-       hptiop_pci_posting_flush(hba->iop);
-       spin_unlock_irq(hba->host->host_lock);
-       wait_event_timeout(hba->ioctl_wq, arg->done == NULL, 60 * HZ);
-       if (arg->done != NULL) {
-               hptiop_reset_hba(hba);
-               if (ioctl_retry++ < 3)
-                       goto retry;
-       }
-       dprintk("hpt_iop_ioctl %x result %d\n",
-                       arg->ioctl_code, arg->result);
- }
- static int __hpt_do_ioctl(struct hptiop_hba *hba, u32 code, void *inbuf,
-                       u32 insize, void *outbuf, u32 outsize)
- {
-       struct hpt_ioctl_k arg;
-       arg.hba = hba;
-       arg.ioctl_code = code;
-       arg.inbuf = inbuf;
-       arg.outbuf = outbuf;
-       arg.inbuf_size = insize;
-       arg.outbuf_size = outsize;
-       arg.bytes_returned = NULL;
-       hptiop_do_ioctl(&arg);
-       return arg.result;
- }
- static inline int hpt_id_valid(__le32 id)
- {
-       return id != 0 && id != cpu_to_le32(0xffffffff);
- }
- static int hptiop_get_controller_info(struct hptiop_hba *hba,
-                                       struct hpt_controller_info *pinfo)
- {
-       int id = 0;
-       return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CONTROLLER_INFO,
-               &id, sizeof(int), pinfo, sizeof(*pinfo));
- }
- static int hptiop_get_channel_info(struct hptiop_hba *hba, int bus,
-                                       struct hpt_channel_info *pinfo)
- {
-       u32 ids[2];
-       ids[0] = 0;
-       ids[1] = bus;
-       return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CHANNEL_INFO,
-                               ids, sizeof(ids), pinfo, sizeof(*pinfo));
- }
- static int hptiop_get_logical_devices(struct hptiop_hba *hba,
-                                       __le32 *pids, int maxcount)
- {
-       int i;
-       u32 count = maxcount - 1;
-       if (__hpt_do_ioctl(hba, HPT_IOCTL_GET_LOGICAL_DEVICES,
-                       &count, sizeof(u32),
-                       pids, sizeof(u32) * maxcount))
-               return -1;
-       maxcount = le32_to_cpu(pids[0]);
-       for (i = 0; i < maxcount; i++)
-               pids[i] = pids[i+1];
-       return maxcount;
- }
- static int hptiop_get_device_info_v3(struct hptiop_hba *hba, __le32 id,
-                               struct hpt_logical_device_info_v3 *pinfo)
- {
-       return __hpt_do_ioctl(hba, HPT_IOCTL_GET_DEVICE_INFO_V3,
-                               &id, sizeof(u32),
-                               pinfo, sizeof(*pinfo));
- }
- static const char *get_array_status(struct hpt_logical_device_info_v3 *devinfo)
- {
-       static char s[64];
-       u32 flags = le32_to_cpu(devinfo->u.array.flags);
-       u32 trans_prog = le32_to_cpu(devinfo->u.array.transforming_progress);
-       u32 reb_prog = le32_to_cpu(devinfo->u.array.rebuilding_progress);
-       if (flags & ARRAY_FLAG_DISABLED)
-               return "Disabled";
-       else if (flags & ARRAY_FLAG_TRANSFORMING)
-               sprintf(s, "Expanding/Migrating %d.%d%%%s%s",
-                       trans_prog / 100,
-                       trans_prog % 100,
-                       (flags & (ARRAY_FLAG_NEEDBUILDING|ARRAY_FLAG_BROKEN))?
-                                       ", Critical" : "",
-                       ((flags & ARRAY_FLAG_NEEDINITIALIZING) &&
-                        !(flags & ARRAY_FLAG_REBUILDING) &&
-                        !(flags & ARRAY_FLAG_INITIALIZING))?
-                                       ", Unintialized" : "");
-       else if ((flags & ARRAY_FLAG_BROKEN) &&
-                               devinfo->u.array.array_type != AT_RAID6)
-               return "Critical";
-       else if (flags & ARRAY_FLAG_REBUILDING)
-               sprintf(s,
-                       (flags & ARRAY_FLAG_NEEDINITIALIZING)?
-                               "%sBackground initializing %d.%d%%" :
-                                       "%sRebuilding %d.%d%%",
-                       (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
-                       reb_prog / 100,
-                       reb_prog % 100);
-       else if (flags & ARRAY_FLAG_VERIFYING)
-               sprintf(s, "%sVerifying %d.%d%%",
-                       (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
-                       reb_prog / 100,
-                       reb_prog % 100);
-       else if (flags & ARRAY_FLAG_INITIALIZING)
-               sprintf(s, "%sForground initializing %d.%d%%",
-                       (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
-                       reb_prog / 100,
-                       reb_prog % 100);
-       else if (flags & ARRAY_FLAG_NEEDTRANSFORM)
-               sprintf(s,"%s%s%s", "Need Expanding/Migrating",
-                       (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
-                       ((flags & ARRAY_FLAG_NEEDINITIALIZING) &&
-                        !(flags & ARRAY_FLAG_REBUILDING) &&
-                        !(flags & ARRAY_FLAG_INITIALIZING))?
-                               ", Unintialized" : "");
-       else if (flags & ARRAY_FLAG_NEEDINITIALIZING &&
-               !(flags & ARRAY_FLAG_REBUILDING) &&
-               !(flags & ARRAY_FLAG_INITIALIZING))
-               sprintf(s,"%sUninitialized",
-                       (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "");
-       else if ((flags & ARRAY_FLAG_NEEDBUILDING) ||
-                       (flags & ARRAY_FLAG_BROKEN))
-               return "Critical";
-       else
-               return "Normal";
-       return s;
- }
- static void hptiop_dump_devinfo(struct hptiop_hba *hba,
-                       struct hptiop_getinfo *pinfo, __le32 id, int indent)
- {
-       struct hpt_logical_device_info_v3 devinfo;
-       int i;
-       u64 capacity;
-       for (i = 0; i < indent; i++)
-               hptiop_copy_info(pinfo, "\t");
-       if (hptiop_get_device_info_v3(hba, id, &devinfo)) {
-               hptiop_copy_info(pinfo, "unknown\n");
-               return;
-       }
-       switch (devinfo.type) {
-       case LDT_DEVICE: {
-               struct hd_driveid *driveid;
-               u32 flags = le32_to_cpu(devinfo.u.device.flags);
-               driveid = (struct hd_driveid *)devinfo.u.device.ident;
-               /* model[] is 40 chars long, but we just want 20 chars here */
-               driveid->model[20] = 0;
-               if (indent)
-                       if (flags & DEVICE_FLAG_DISABLED)
-                               hptiop_copy_info(pinfo,"Missing\n");
-                       else
-                               hptiop_copy_info(pinfo, "CH%d %s\n",
-                                       devinfo.u.device.path_id + 1,
-                                       driveid->model);
-               else {
-                       capacity = le64_to_cpu(devinfo.capacity) * 512;
-                       do_div(capacity, 1000000);
-                       hptiop_copy_info(pinfo,
-                               "CH%d %s, %lluMB, %s %s%s%s%s\n",
-                               devinfo.u.device.path_id + 1,
-                               driveid->model,
-                               capacity,
-                               (flags & DEVICE_FLAG_DISABLED)?
-                                       "Disabled" : "Normal",
-                               devinfo.u.device.read_ahead_enabled?
-                                               "[RA]" : "",
-                               devinfo.u.device.write_cache_enabled?
-                                               "[WC]" : "",
-                               devinfo.u.device.TCQ_enabled?
-                                               "[TCQ]" : "",
-                               devinfo.u.device.NCQ_enabled?
-                                               "[NCQ]" : ""
-                       );
-               }
-               break;
-       }
-       case LDT_ARRAY:
-               if (devinfo.target_id != INVALID_TARGET_ID)
-                       hptiop_copy_info(pinfo, "[DISK %d_%d] ",
-                                       devinfo.vbus_id, devinfo.target_id);
-               capacity = le64_to_cpu(devinfo.capacity) * 512;
-               do_div(capacity, 1000000);
-               hptiop_copy_info(pinfo, "%s (%s), %lluMB, %s\n",
-                       devinfo.u.array.name,
-                       devinfo.u.array.array_type==AT_RAID0? "RAID0" :
-                               devinfo.u.array.array_type==AT_RAID1? "RAID1" :
-                               devinfo.u.array.array_type==AT_RAID5? "RAID5" :
-                               devinfo.u.array.array_type==AT_RAID6? "RAID6" :
-                               devinfo.u.array.array_type==AT_JBOD? "JBOD" :
-                                       "unknown",
-                       capacity,
-                       get_array_status(&devinfo));
-               for (i = 0; i < devinfo.u.array.ndisk; i++) {
-                       if (hpt_id_valid(devinfo.u.array.members[i])) {
-                               if (cpu_to_le16(1<<i) &
-                                       devinfo.u.array.critical_members)
-                                       hptiop_copy_info(pinfo, "\t*");
-                               hptiop_dump_devinfo(hba, pinfo,
-                                       devinfo.u.array.members[i], indent+1);
-                       }
-                       else
-                               hptiop_copy_info(pinfo, "\tMissing\n");
-               }
-               if (id == devinfo.u.array.transform_source) {
-                       hptiop_copy_info(pinfo, "\tExpanding/Migrating to:\n");
-                       hptiop_dump_devinfo(hba, pinfo,
-                               devinfo.u.array.transform_target, indent+1);
-               }
-               break;
-       }
- }
  static ssize_t hptiop_show_version(struct class_device *class_dev, char *buf)
  {
        return snprintf(buf, PAGE_SIZE, "%s\n", driver_ver);
  }
  
- static ssize_t hptiop_cdev_read(struct file *filp, char __user *buf,
-                               size_t count, loff_t *ppos)
- {
-       struct hptiop_hba *hba = filp->private_data;
-       struct hptiop_getinfo info;
-       int i, j, ndev;
-       struct hpt_controller_info con_info;
-       struct hpt_channel_info chan_info;
-       __le32 ids[32];
-       info.buffer     = buf;
-       info.buflength  = count;
-       info.bufoffset  = ppos ? *ppos : 0;
-       info.filpos     = 0;
-       info.buffillen  = 0;
-       if (hptiop_get_controller_info(hba, &con_info))
-               return -EIO;
-       for (i = 0; i < con_info.num_buses; i++) {
-               if (hptiop_get_channel_info(hba, i, &chan_info) == 0) {
-                       if (hpt_id_valid(chan_info.devices[0]))
-                               hptiop_dump_devinfo(hba, &info,
-                                               chan_info.devices[0], 0);
-                       if (hpt_id_valid(chan_info.devices[1]))
-                               hptiop_dump_devinfo(hba, &info,
-                                               chan_info.devices[1], 0);
-               }
-       }
-       ndev = hptiop_get_logical_devices(hba, ids,
-                                       sizeof(ids) / sizeof(ids[0]));
-       /*
-        * if hptiop_get_logical_devices fails, ndev==-1 and it just
-        * output nothing here
-        */
-       for (j = 0; j < ndev; j++)
-               hptiop_dump_devinfo(hba, &info, ids[j], 0);
-       if (ppos)
-               *ppos += info.buffillen;
-       return info.buffillen;
- }
- static int hptiop_cdev_ioctl(struct inode *inode,  struct file *file,
-                                       unsigned int cmd, unsigned long arg)
- {
-       struct hptiop_hba *hba = file->private_data;
-       struct hpt_ioctl_u ioctl_u;
-       struct hpt_ioctl_k ioctl_k;
-       u32 bytes_returned;
-       int err = -EINVAL;
-       if (copy_from_user(&ioctl_u,
-               (void __user *)arg, sizeof(struct hpt_ioctl_u)))
-               return -EINVAL;
-       if (ioctl_u.magic != HPT_IOCTL_MAGIC)
-               return -EINVAL;
-       ioctl_k.ioctl_code = ioctl_u.ioctl_code;
-       ioctl_k.inbuf = NULL;
-       ioctl_k.inbuf_size = ioctl_u.inbuf_size;
-       ioctl_k.outbuf = NULL;
-       ioctl_k.outbuf_size = ioctl_u.outbuf_size;
-       ioctl_k.hba = hba;
-       ioctl_k.bytes_returned = &bytes_returned;
-       /* verify user buffer */
-       if ((ioctl_k.inbuf_size && !access_ok(VERIFY_READ,
-                       ioctl_u.inbuf, ioctl_k.inbuf_size)) ||
-               (ioctl_k.outbuf_size && !access_ok(VERIFY_WRITE,
-                       ioctl_u.outbuf, ioctl_k.outbuf_size)) ||
-               (ioctl_u.bytes_returned && !access_ok(VERIFY_WRITE,
-                       ioctl_u.bytes_returned, sizeof(u32))) ||
-               ioctl_k.inbuf_size + ioctl_k.outbuf_size > 0x10000) {
-               dprintk("scsi%d: got bad user address\n", hba->host->host_no);
-               return -EINVAL;
-       }
-       /* map buffer to kernel. */
-       if (ioctl_k.inbuf_size) {
-               ioctl_k.inbuf = kmalloc(ioctl_k.inbuf_size, GFP_KERNEL);
-               if (!ioctl_k.inbuf) {
-                       dprintk("scsi%d: fail to alloc inbuf\n",
-                                       hba->host->host_no);
-                       err = -ENOMEM;
-                       goto err_exit;
-               }
-               if (copy_from_user(ioctl_k.inbuf,
-                               ioctl_u.inbuf, ioctl_k.inbuf_size)) {
-                       goto err_exit;
-               }
-       }
-       if (ioctl_k.outbuf_size) {
-               ioctl_k.outbuf = kmalloc(ioctl_k.outbuf_size, GFP_KERNEL);
-               if (!ioctl_k.outbuf) {
-                       dprintk("scsi%d: fail to alloc outbuf\n",
-                                       hba->host->host_no);
-                       err = -ENOMEM;
-                       goto err_exit;
-               }
-       }
-       hptiop_do_ioctl(&ioctl_k);
-       if (ioctl_k.result == HPT_IOCTL_RESULT_OK) {
-               if (ioctl_k.outbuf_size &&
-                       copy_to_user(ioctl_u.outbuf,
-                               ioctl_k.outbuf, ioctl_k.outbuf_size))
-                       goto err_exit;
-               if (ioctl_u.bytes_returned &&
-                       copy_to_user(ioctl_u.bytes_returned,
-                               &bytes_returned, sizeof(u32)))
-                       goto err_exit;
-               err = 0;
-       }
- err_exit:
-       kfree(ioctl_k.inbuf);
-       kfree(ioctl_k.outbuf);
-       return err;
- }
- static int hptiop_cdev_open(struct inode *inode, struct file *file)
- {
-       struct hptiop_hba *hba;
-       unsigned i = 0, minor = iminor(inode);
-       int ret = -ENODEV;
-       spin_lock(&hptiop_hba_list_lock);
-       list_for_each_entry(hba, &hptiop_hba_list, link) {
-               if (i == minor) {
-                       file->private_data = hba;
-                       ret = 0;
-                       goto out;
-               }
-               i++;
-       }
- out:
-       spin_unlock(&hptiop_hba_list_lock);
-       return ret;
- }
- static struct file_operations hptiop_cdev_fops = {
-       .owner = THIS_MODULE,
-       .read  = hptiop_cdev_read,
-       .ioctl = hptiop_cdev_ioctl,
-       .open  = hptiop_cdev_open,
- };
  static ssize_t hptiop_show_fw_version(struct class_device *class_dev, char *buf)
  {
        struct Scsi_Host *host = class_to_shost(class_dev);
@@@ -1295,19 -771,13 +770,13 @@@ static int __devinit hptiop_probe(struc
                goto unmap_pci_bar;
        }
  
-       if (scsi_add_host(host, &pcidev->dev)) {
-               printk(KERN_ERR "scsi%d: scsi_add_host failed\n",
-                                       hba->host->host_no);
-               goto unmap_pci_bar;
-       }
        pci_set_drvdata(pcidev, host);
  
        if (request_irq(pcidev->irq, hptiop_intr, IRQF_SHARED,
                                        driver_name, hba)) {
                printk(KERN_ERR "scsi%d: request irq %d failed\n",
                                        hba->host->host_no, pcidev->irq);
-               goto remove_scsi_host;
+               goto unmap_pci_bar;
        }
  
        /* Allocate request mem */
        if (hptiop_initialize_iop(hba))
                goto free_request_mem;
  
-       spin_lock(&hptiop_hba_list_lock);
-       list_add_tail(&hba->link, &hptiop_hba_list);
-       spin_unlock(&hptiop_hba_list_lock);
+       if (scsi_add_host(host, &pcidev->dev)) {
+               printk(KERN_ERR "scsi%d: scsi_add_host failed\n",
+                                       hba->host->host_no);
+               goto free_request_mem;
+       }
  
        scsi_scan_host(host);
  
@@@ -1371,9 -844,6 +843,6 @@@ free_request_mem
  free_request_irq:
        free_irq(hba->pcidev->irq, hba);
  
- remove_scsi_host:
-       scsi_remove_host(host);
  unmap_pci_bar:
        iounmap(hba->iop);
  
@@@ -1421,10 -891,6 +890,6 @@@ static void hptiop_remove(struct pci_de
  
        scsi_remove_host(host);
  
-       spin_lock(&hptiop_hba_list_lock);
-       list_del_init(&hba->link);
-       spin_unlock(&hptiop_hba_list_lock);
        hptiop_shutdown(pcidev);
  
        free_irq(hba->pcidev->irq, hba);
@@@ -1461,27 -927,12 +926,12 @@@ static struct pci_driver hptiop_pci_dri
  
  static int __init hptiop_module_init(void)
  {
-       int error;
        printk(KERN_INFO "%s %s\n", driver_name_long, driver_ver);
-       error = pci_register_driver(&hptiop_pci_driver);
-       if (error < 0)
-               return error;
-       hptiop_cdev_major = register_chrdev(0, "hptiop", &hptiop_cdev_fops);
-       if (hptiop_cdev_major < 0) {
-               printk(KERN_WARNING "unable to register hptiop device.\n");
-               return hptiop_cdev_major;
-       }
-       return 0;
+       return pci_register_driver(&hptiop_pci_driver);
  }
  
  static void __exit hptiop_module_exit(void)
  {
-       dprintk("hptiop_module_exit\n");
-       unregister_chrdev(hptiop_cdev_major, "hptiop");
        pci_unregister_driver(&hptiop_pci_driver);
  }
  
diff --combined drivers/scsi/libata-eh.c
@@@ -32,6 -32,7 +32,6 @@@
   *
   */
  
 -#include <linux/config.h>
  #include <linux/kernel.h>
  #include <scsi/scsi.h>
  #include <scsi/scsi_host.h>
@@@ -763,12 -764,27 +763,27 @@@ static void ata_eh_about_to_do(struct a
                               unsigned int action)
  {
        unsigned long flags;
+       struct ata_eh_info *ehi = &ap->eh_info;
+       struct ata_eh_context *ehc = &ap->eh_context;
  
        spin_lock_irqsave(ap->lock, flags);
  
-       ata_eh_clear_action(dev, &ap->eh_info, action);
+       /* Reset is represented by combination of actions and EHI
+        * flags.  Suck in all related bits before clearing eh_info to
+        * avoid losing requested action.
+        */
+       if (action & ATA_EH_RESET_MASK) {
+               ehc->i.action |= ehi->action & ATA_EH_RESET_MASK;
+               ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK;
+               /* make sure all reset actions are cleared & clear EHI flags */
+               action |= ATA_EH_RESET_MASK;
+               ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
+       }
+       ata_eh_clear_action(dev, ehi, action);
  
-       if (!(ap->eh_context.i.flags & ATA_EHI_QUIET))
+       if (!(ehc->i.flags & ATA_EHI_QUIET))
                ap->pflags |= ATA_PFLAG_RECOVERED;
  
        spin_unlock_irqrestore(ap->lock, flags);
  static void ata_eh_done(struct ata_port *ap, struct ata_device *dev,
                        unsigned int action)
  {
+       /* if reset is complete, clear all reset actions & reset modifier */
+       if (action & ATA_EH_RESET_MASK) {
+               action |= ATA_EH_RESET_MASK;
+               ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
+       }
        ata_eh_clear_action(dev, &ap->eh_context.i, action);
  }
  
@@@ -1275,8 -1297,6 +1296,6 @@@ static int ata_eh_speed_down(struct ata
  static void ata_eh_autopsy(struct ata_port *ap)
  {
        struct ata_eh_context *ehc = &ap->eh_context;
-       unsigned int action = ehc->i.action;
-       struct ata_device *failed_dev = NULL;
        unsigned int all_err_mask = 0;
        int tag, is_io = 0;
        u32 serror;
                ehc->i.serror |= serror;
                ata_eh_analyze_serror(ap);
        } else if (rc != -EOPNOTSUPP)
-               action |= ATA_EH_HARDRESET;
+               ehc->i.action |= ATA_EH_HARDRESET;
  
        /* analyze NCQ failure */
        ata_eh_analyze_ncq_error(ap);
                qc->err_mask |= ehc->i.err_mask;
  
                /* analyze TF */
-               action |= ata_eh_analyze_tf(qc, &qc->result_tf);
+               ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf);
  
                /* DEV errors are probably spurious in case of ATA_BUS error */
                if (qc->err_mask & AC_ERR_ATA_BUS)
                /* SENSE_VALID trumps dev/unknown error and revalidation */
                if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
                        qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
-                       action &= ~ATA_EH_REVALIDATE;
+                       ehc->i.action &= ~ATA_EH_REVALIDATE;
                }
  
                /* accumulate error info */
-               failed_dev = qc->dev;
+               ehc->i.dev = qc->dev;
                all_err_mask |= qc->err_mask;
                if (qc->flags & ATA_QCFLAG_IO)
                        is_io = 1;
        /* enforce default EH actions */
        if (ap->pflags & ATA_PFLAG_FROZEN ||
            all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT))
-               action |= ATA_EH_SOFTRESET;
+               ehc->i.action |= ATA_EH_SOFTRESET;
        else if (all_err_mask)
-               action |= ATA_EH_REVALIDATE;
+               ehc->i.action |= ATA_EH_REVALIDATE;
  
        /* if we have offending qcs and the associated failed device */
-       if (failed_dev) {
+       if (ehc->i.dev) {
                /* speed down */
-               action |= ata_eh_speed_down(failed_dev, is_io, all_err_mask);
+               ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io,
+                                                  all_err_mask);
  
                /* perform per-dev EH action only on the offending device */
-               ehc->i.dev_action[failed_dev->devno] |=
-                       action & ATA_EH_PERDEV_MASK;
-               action &= ~ATA_EH_PERDEV_MASK;
+               ehc->i.dev_action[ehc->i.dev->devno] |=
+                       ehc->i.action & ATA_EH_PERDEV_MASK;
+               ehc->i.action &= ~ATA_EH_PERDEV_MASK;
        }
  
-       /* record autopsy result */
-       ehc->i.dev = failed_dev;
-       ehc->i.action |= action;
        DPRINTK("EXIT\n");
  }
  
@@@ -1482,6 -1499,9 +1498,9 @@@ static int ata_eh_reset(struct ata_por
        ata_reset_fn_t reset;
        int i, did_followup_srst, rc;
  
+       /* about to reset */
+       ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
        /* Determine which reset to use and record in ehc->i.action.
         * prereset() may examine and modify it.
         */
                ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
                                reset == softreset ? "soft" : "hard");
  
-       /* reset */
-       ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK);
+       /* mark that this EH session started with reset */
        ehc->i.flags |= ATA_EHI_DID_RESET;
  
        rc = ata_do_reset(ap, reset, classes);
                        postreset(ap, classes);
  
                /* reset successful, schedule revalidation */
-               ata_eh_done(ap, NULL, ATA_EH_RESET_MASK);
+               ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
                ehc->i.action |= ATA_EH_REVALIDATE;
        }
  
@@@ -1847,15 -1866,16 +1865,16 @@@ static int ata_eh_skip_recovery(struct 
        for (i = 0; i < ata_port_max_devices(ap); i++) {
                struct ata_device *dev = &ap->device[i];
  
-               if (ata_dev_absent(dev) || ata_dev_ready(dev))
+               if (!(dev->flags & ATA_DFLAG_SUSPENDED))
                        break;
        }
  
        if (i == ata_port_max_devices(ap))
                return 1;
  
-       /* always thaw frozen port and recover failed devices */
-       if (ap->pflags & ATA_PFLAG_FROZEN || ata_port_nr_enabled(ap))
+       /* thaw frozen port, resume link and recover failed devices */
+       if ((ap->pflags & ATA_PFLAG_FROZEN) ||
+           (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap))
                return 0;
  
        /* skip if class codes for all vacant slots are ATA_DEV_NONE */
@@@ -10,7 -10,7 +10,7 @@@
   *       2 of the License, or (at your option) any later version.
   *
   * FILE               : megaraid_mbox.c
-  * Version    : v2.20.4.8 (Apr 11 2006)
+  * Version    : v2.20.4.9 (Jul 16 2006)
   *
   * Authors:
   *    Atul Mukker             <Atul.Mukker@lsil.com>
@@@ -330,21 -330,6 +330,21 @@@ static struct device_attribute *megarai
        NULL,
  };
  
 +/**
 + * megaraid_change_queue_depth - Change the device's queue depth
 + * @sdev:     scsi device struct
 + * @qdepth:   depth to set
 + *
 + * Return value:
 + *    actual depth set
 + **/
 +static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth)
 +{
 +      if (qdepth > MBOX_MAX_SCSI_CMDS)
 +              qdepth = MBOX_MAX_SCSI_CMDS;
 +      scsi_adjust_queue_depth(sdev, 0, qdepth);
 +      return sdev->queue_depth;
 +}
  
  /*
   * Scsi host template for megaraid unified driver
@@@ -358,7 -343,6 +358,7 @@@ static struct scsi_host_template megara
        .eh_device_reset_handler        = megaraid_reset_handler,
        .eh_bus_reset_handler           = megaraid_reset_handler,
        .eh_host_reset_handler          = megaraid_reset_handler,
 +      .change_queue_depth             = megaraid_change_queue_depth,
        .use_clustering                 = ENABLE_CLUSTERING,
        .sdev_attrs                     = megaraid_sdev_attrs,
        .shost_attrs                    = megaraid_shost_attrs,
@@@ -736,6 -720,7 +736,7 @@@ megaraid_init_mbox(adapter_t *adapter
        struct pci_dev          *pdev;
        mraid_device_t          *raid_dev;
        int                     i;
+       uint32_t                magic64;
  
  
        adapter->ito    = MBOX_TIMEOUT;
  
        // Set the DMA mask to 64-bit. All supported controllers as capable of
        // DMA in this range
-       if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK) != 0) {
-               con_log(CL_ANN, (KERN_WARNING
-                       "megaraid: could not set DMA mask for 64-bit.\n"));
-               goto out_free_sysfs_res;
+       pci_read_config_dword(adapter->pdev, PCI_CONF_AMISIG64, &magic64);
+       if (((magic64 == HBA_SIGNATURE_64_BIT) &&
+               ((adapter->pdev->subsystem_device !=
+               PCI_SUBSYS_ID_MEGARAID_SATA_150_6) ||
+               (adapter->pdev->subsystem_device !=
+               PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) ||
+               (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC &&
+               adapter->pdev->device == PCI_DEVICE_ID_VERDE) ||
+               (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC &&
+               adapter->pdev->device == PCI_DEVICE_ID_DOBSON) ||
+               (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC &&
+               adapter->pdev->device == PCI_DEVICE_ID_LINDSAY) ||
+               (adapter->pdev->vendor == PCI_VENDOR_ID_DELL &&
+               adapter->pdev->device == PCI_DEVICE_ID_PERC4_DI_EVERGLADES) ||
+               (adapter->pdev->vendor == PCI_VENDOR_ID_DELL &&
+               adapter->pdev->device == PCI_DEVICE_ID_PERC4E_DI_KOBUK)) {
+               if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK)) {
+                       con_log(CL_ANN, (KERN_WARNING
+                               "megaraid: DMA mask for 64-bit failed\n"));
+                       if (pci_set_dma_mask (adapter->pdev, DMA_32BIT_MASK)) {
+                               con_log(CL_ANN, (KERN_WARNING
+                                       "megaraid: 32-bit DMA mask failed\n"));
+                               goto out_free_sysfs_res;
+                       }
+               }
        }
  
        // setup tasklet for DPC
@@@ -1638,6 -1644,14 +1660,14 @@@ megaraid_mbox_build_cmd(adapter_t *adap
                                rdev->last_disp |= (1L << SCP2CHANNEL(scp));
                        }
  
+                       if (scp->cmnd[1] & MEGA_SCSI_INQ_EVPD) {
+                               scp->sense_buffer[0] = 0x70;
+                               scp->sense_buffer[2] = ILLEGAL_REQUEST;
+                               scp->sense_buffer[12] = MEGA_INVALID_FIELD_IN_CDB;
+                               scp->result = CHECK_CONDITION << 1;
+                               return NULL;
+                       }
                        /* Fall through */
  
                case READ_CAPACITY:
diff --combined include/linux/pci_ids.h
  #define PCI_DEVICE_ID_ALTIMA_AC9100   0x03ea
  #define PCI_DEVICE_ID_ALTIMA_AC1003   0x03eb
  
 +#define PCI_VENDOR_ID_ARECA           0x17d3
 +#define PCI_DEVICE_ID_ARECA_1110      0x1110
 +#define PCI_DEVICE_ID_ARECA_1120      0x1120
 +#define PCI_DEVICE_ID_ARECA_1130      0x1130
 +#define PCI_DEVICE_ID_ARECA_1160      0x1160
 +#define PCI_DEVICE_ID_ARECA_1170      0x1170
 +#define PCI_DEVICE_ID_ARECA_1210      0x1210
 +#define PCI_DEVICE_ID_ARECA_1220      0x1220
 +#define PCI_DEVICE_ID_ARECA_1230      0x1230
 +#define PCI_DEVICE_ID_ARECA_1260      0x1260
 +#define PCI_DEVICE_ID_ARECA_1270      0x1270
 +#define PCI_DEVICE_ID_ARECA_1280      0x1280
 +#define PCI_DEVICE_ID_ARECA_1380      0x1380
 +#define PCI_DEVICE_ID_ARECA_1381      0x1381
 +#define PCI_DEVICE_ID_ARECA_1680      0x1680
 +#define PCI_DEVICE_ID_ARECA_1681      0x1681
 +
  #define PCI_VENDOR_ID_S2IO            0x17d5
  #define       PCI_DEVICE_ID_S2IO_WIN          0x5731
  #define       PCI_DEVICE_ID_S2IO_UNI          0x5831
  #define PCI_DEVICE_ID_INTEL_82820_UP_HB       0x2501
  #define PCI_DEVICE_ID_INTEL_82850_HB  0x2530
  #define PCI_DEVICE_ID_INTEL_82860_HB  0x2531
+ #define PCI_DEVICE_ID_INTEL_E7501_MCH 0x254c
  #define PCI_DEVICE_ID_INTEL_82845G_HB 0x2560
  #define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562
  #define PCI_DEVICE_ID_INTEL_82865_HB  0x2570