patch-2.4.14 linux/drivers/scsi/megaraid.c
Next file: linux/drivers/scsi/megaraid.h
Previous file: linux/drivers/scsi/mca_53c9x.c
Back to the patch index
Back to the overall index
- Lines: 724
- Date:
Thu Oct 25 13:53:51 2001
- Orig file:
v2.4.13/linux/drivers/scsi/megaraid.c
- Orig date:
Tue Oct 9 17:06:52 2001
diff -u --recursive --new-file v2.4.13/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
@@ -9,9 +9,9 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Version : v1.17a (July 13, 2001)
+ * Version : v1.18 (Oct 11, 2001)
*
- * Description: Linux device driver for AMI MegaRAID controller
+ * Description: Linux device driver for LSI Logic MegaRAID controller
*
* Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 471, 490
* 493.
@@ -427,12 +427,39 @@
* our current formula working to calculate logical drive number, return
* failure for LUN > 7
*
+ *
+ * Version 1.17b
+ * Mon Jul 30 19:24:02 EDT 2001 - AM
+ *
+ * Added support for random deletion of logical drives
+ *
+ * Version 1.17c
+ * Tue Sep 25 09:37:49 EDT 2001 - Atul Mukker <atulm@lsil.com>
+ *
+ * With single and dual channel controllers, some virtaul channels are
+ * displayed negative.
+ *
* Version 1.17a-ac
* Mon Aug 6 14:59:29 BST 2001 - "Michael Johnson" <johnsom@home.com>
*
* Make the HP print formatting and check for buggy firmware runtime not
* ifdef dependant.
*
+ *
+ * Version 1.17d
+ * Thu Oct 11 10:48:45 EDT 2001 - Atul Mukker <atulm@lsil.com>
+ *
+ * Driver 1.17c oops when loaded without controller.
+ *
+ * Special case for "use_sg == 1" removed while building the scatter gather
+ * list.
+ *
+ * Version 1.18
+ * Thu Oct 11 15:02:53 EDT 2001 - Atul Mukker <atulm@lsil.com>
+ *
+ * References to AMI have been changed to LSI Logic.
+ *
+ *
* 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.
@@ -550,16 +577,15 @@
* queue task is a simple api without irq forms
*/
-MODULE_AUTHOR ("American Megatrends Inc.");
-MODULE_DESCRIPTION ("AMI MegaRAID driver");
-MODULE_LICENSE("GPL");
-
+MODULE_AUTHOR ("LSI Logic Corporation");
+MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
+MODULE_LICENSE ("GPL");
#define DRIVER_LOCK_T
#define DRIVER_LOCK_INIT(p)
#define DRIVER_LOCK(p)
#define DRIVER_UNLOCK(p)
-#define IO_LOCK_T unsigned long io_flags = 0;
+#define IO_LOCK_T unsigned long io_flags = 0
#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
@@ -578,14 +604,14 @@
*/
static char kernel_version[] = UTS_RELEASE;
-MODULE_AUTHOR ("American Megatrends Inc.");
-MODULE_DESCRIPTION ("AMI MegaRAID driver");
+MODULE_AUTHOR ("LSI Logic Corporation");
+MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
#define DRIVER_LOCK_T
#define DRIVER_LOCK_INIT(p)
#define DRIVER_LOCK(p)
#define DRIVER_UNLOCK(p)
-#define IO_LOCK_T unsigned long io_flags = 0;
+#define IO_LOCK_T unsigned long io_flags = 0
#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
@@ -746,7 +772,7 @@
static struct mcontroller mcontroller[MAX_CONTROLLERS];
/* The current driver version */
-static u32 driver_ver = 117;
+static u32 driver_ver = 114;
/* major number used by the device for character interface */
static int major;
@@ -1050,7 +1076,11 @@
panic(KERN_ERR "megaraid:Problem...!\n");
}
+ islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) &&
+ (SCpnt->channel <= megaCfg->host->max_channel) );
+#if 0
islogical = (SCpnt->channel == megaCfg->host->max_channel);
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
/* Special Case to handle PassThrough->XferAddrress > 4GB */
@@ -1174,7 +1204,8 @@
mega_ext_passthru *epthru;
long seg;
char islogical;
- char lun = SCpnt->lun;
+ int lun = SCpnt->lun;
+ int max_lun;
if ((SCpnt->cmnd[0] == MEGADEVIOC))
return megadev_doioctl (megaCfg, SCpnt);
@@ -1191,8 +1222,12 @@
}
#endif
+ islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) &&
+ (SCpnt->channel <= megaCfg->host->max_channel) );
+#if 0
islogical = (IS_RAID_CH(SCpnt->channel) && /* virtual ch is raid - AM */
(SCpnt->channel == megaCfg->host->max_channel));
+#endif
if ( ! megaCfg->support_ext_cdb ) {
if (!islogical && lun != 0) {
@@ -1208,21 +1243,28 @@
return NULL;
}
- /*
- * Return error for LUN > 7. The way we calculate logical drive number
- * requires it to be so.
- */
- if( lun > 7 ) {
- SCpnt->result = (DID_BAD_TARGET << 16);
- callDone (SCpnt);
- return NULL;
- }
-
if (islogical) {
- lun = (SCpnt->target * 8) + lun;
+ /* have just LUN 0 for each target on virtual channels */
+ if( SCpnt->lun != 0 ) {
+ SCpnt->result = (DID_BAD_TARGET << 16);
+ callDone (SCpnt);
+ return NULL;
+ }
+
+ lun = mega_get_lun(megaCfg, SCpnt);
- if(lun >= megaCfg->numldrv ) {
+ max_lun = (megaCfg->flag & BOARD_40LD) ?
+ FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;
+
+ /*
+ * max_lun increases by 0x80 if some logical drive was deleted.
+ */
+ if(megaCfg->read_ldidmap) {
+ max_lun += 0x80;
+ }
+
+ if( lun > max_lun ) {
SCpnt->result = (DID_BAD_TARGET << 16);
callDone (SCpnt);
return NULL;
@@ -1241,6 +1283,13 @@
}
}
}
+ } else {
+ if ( lun > 7) {
+ /* Do not support lun >7 for physically accessed devices */
+ SCpnt->result = (DID_BAD_TARGET << 16);
+ callDone (SCpnt);
+ return NULL;
+ }
}
/*-----------------------------------------------------
*
@@ -1503,6 +1552,44 @@
return NULL;
}
+static int
+mega_get_lun(mega_host_config *this_hba, Scsi_Cmnd *sc)
+{
+ int tgt;
+ int lun;
+ int virt_chan;
+
+ tgt = sc->target;
+
+ if ( tgt > 7 ) tgt--; /* we do not get inquires for tgt 7 */
+
+ virt_chan = sc->channel - this_hba->productInfo.SCSIChanPresent;
+ lun = (virt_chan * 15) + tgt;
+
+ /*
+ * If "delete logical drive" feature is enabled on this controller.
+ * Do only if at least one delete logical drive operation was done.
+ *
+ * Also, after logical drive deletion, instead of logical drive number,
+ * the value returned should be 0x80+logical drive id.
+ *
+ * These is valid only for IO commands.
+ */
+
+ if( this_hba->support_random_del && this_hba->read_ldidmap ) {
+ switch(sc->cmnd[0]) {
+ case READ_6: /* fall through */
+ case WRITE_6: /* fall through */
+ case READ_10: /* fall through */
+ case WRITE_10:
+ lun += 0x80;
+ }
+ }
+
+ return lun;
+}
+
+
static mega_passthru *
mega_prepare_passthru(mega_host_config *megacfg, mega_scb *scb, Scsi_Cmnd *sc)
{
@@ -1969,7 +2056,7 @@
*--------------------------------------------------------------------*/
static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
{
- IO_LOCK_T
+ IO_LOCK_T;
mega_host_config * megaCfg;
u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE];
u32 dword = 0;
@@ -2367,7 +2454,7 @@
}
sgList = (struct scatterlist *) scb->SCpnt->request_buffer;
-
+#if 0
if (scb->SCpnt->use_sg == 1) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
@@ -2395,7 +2482,7 @@
return 0;
}
-
+#endif
/* Copy Scatter-Gather list info into controller structure */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
sgcnt = pci_map_sg (megaCfg->dev,
@@ -2640,7 +2727,7 @@
mboxData[2] = NC_SUBOP_PRODUCT_INFO; /* i.e. 0x0E */
if ((retval = megaIssueCmd (megaCfg, mboxData, NULL, 0)) != 0)
- printk ("ami:Product_info cmd failed with error: %d\n",
+ printk ("megaraid: Product_info cmd failed with error: %d\n",
retval);
pci_unmap_single (megaCfg->dev,
@@ -2649,12 +2736,21 @@
PCI_DMA_FROMDEVICE);
}
- megaCfg->host->max_channel = megaCfg->productInfo.SCSIChanPresent;
+ /*
+ * kernel scans the channels from 0 to <= max_channel
+ */
+ megaCfg->host->max_channel =
+ megaCfg->productInfo.SCSIChanPresent + NVIRT_CHAN -1;
+
megaCfg->host->max_id = 16; /* max targets per channel */
/*(megaCfg->flag & BOARD_40LD)?FC_MAX_TARGETS_PER_CHANNEL:MAX_TARGET+1; */
+#if 0
megaCfg->host->max_lun = /* max lun */
- (megaCfg->
- flag & BOARD_40LD) ? FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;
+ (megaCfg->flag & BOARD_40LD) ?
+ FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;
+#endif
+ megaCfg->host->max_lun = 7; /* Upto 7 luns for non disk devices */
+
megaCfg->host->cmd_per_lun = MAX_CMD_PER_LUN;
megaCfg->numldrv = enquiry3Pnt->numLDrv;
@@ -2670,27 +2766,27 @@
}
#endif
- /* use HP firmware and bios version encoding */
-if (megaCfg->productInfo.subSystemVendorID == HP_SUBSYS_ID) {
- sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
- 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",
- 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, (char *) megaCfg->productInfo.FwVer, 4);
- megaCfg->fwVer[4] = 0;
+ /* use HP firmware and bios version encoding */
+ if (megaCfg->productInfo.subSystemVendorID == HP_SUBSYS_ID) {
+ sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
+ megaCfg->productInfo.FwVer[2],
+ megaCfg->productInfo.FwVer[1] >> 8,
+ megaCfg->productInfo.FwVer[1] & 0x0f,
+ megaCfg->productInfo.FwVer[0] >> 8,
+ megaCfg->productInfo.FwVer[0] & 0x0f);
+ sprintf (megaCfg->biosVer, "%c%d%d.%d%d",
+ megaCfg->productInfo.BiosVer[2],
+ megaCfg->productInfo.BiosVer[1] >> 8,
+ megaCfg->productInfo.BiosVer[1] & 0x0f,
+ megaCfg->productInfo.BiosVer[0] >> 8,
+ megaCfg->productInfo.BiosVer[0] & 0x0f);
+ } else {
+ memcpy (megaCfg->fwVer, (char *) megaCfg->productInfo.FwVer, 4);
+ megaCfg->fwVer[4] = 0;
- memcpy (megaCfg->biosVer, (char *) megaCfg->productInfo.BiosVer, 4);
- megaCfg->biosVer[4] = 0;
-}
+ memcpy (megaCfg->biosVer, (char *) megaCfg->productInfo.BiosVer, 4);
+ megaCfg->biosVer[4] = 0;
+ }
megaCfg->support_ext_cdb = mega_support_ext_cdb(megaCfg);
printk (KERN_NOTICE "megaraid: [%s:%s] detected %d logical drives" M_RD_CRLFSTR,
@@ -2737,7 +2833,7 @@
u32 magic64;
#endif
- int i;
+ int i;
#ifdef __LP64__
u64 megaBase;
@@ -2859,7 +2955,6 @@
if (!host)
goto err_unmap;
-#if 0
/*
* Comment the following initialization if you know 'max_sectors' is
* not defined for this kernel.
@@ -2867,7 +2962,6 @@
* greatly increases the IO performance - AM
*/
host->max_sectors = 1024;
-#endif
scsi_set_pci_device(host, pdev);
megaCfg = (mega_host_config *) host->hostdata;
@@ -2894,6 +2988,9 @@
megaCfg->lock_pend = SPIN_LOCK_UNLOCKED;
megaCfg->lock_scsicmd = SPIN_LOCK_UNLOCKED;
megaCfg->flag = flag;
+ megaCfg->int_qh = NULL;
+ megaCfg->int_qt = NULL;
+ megaCfg->int_qlen = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
megaCfg->dev = pdev;
@@ -2999,7 +3096,7 @@
* Find out which channel is raid and which is scsi
*/
mega_enum_raid_scsi(megaCfg);
- for( i = 0; i < megaCfg->host->max_channel; i++ ) {
+ for( i = 0; i < megaCfg->productInfo.SCSIChanPresent; i++ ) {
if(IS_RAID_CH(i))
printk(KERN_NOTICE"megaraid: channel[%d] is raid.\n", i+1);
else
@@ -3014,6 +3111,12 @@
mega_hbas[numCtlrs].hostdata_addr = megaCfg;
+ /*
+ * Do we support random deletion and addition of logical drives
+ */
+ megaCfg->read_ldidmap = 0; /* set it after first logdrv delete cmd */
+ megaCfg->support_random_del = mega_support_random_del(megaCfg);
+
/* Initialize SCBs */
if (mega_init_scb (megaCfg)) {
pci_free_consistent (megaCfg->dev,
@@ -3100,7 +3203,7 @@
skip_id = (skip_id > 15) ? -1 : skip_id;
}
- printk (KERN_NOTICE "megaraid: " MEGARAID_VERSION M_RD_CRLFSTR);
+ printk (KERN_NOTICE "megaraid: " MEGARAID_VERSION);
memset (mega_hbas, 0, sizeof (mega_hbas));
@@ -3267,6 +3370,7 @@
{
mega_mailbox *mboxp;
unsigned char mbox[16];
+ int i;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
dma_addr_t dma_handle;
@@ -3299,8 +3403,10 @@
if( megaIssueCmd(megacfg, mbox, NULL, 0) == 0 ) {
mega_ch_class = *((char *)megacfg->mega_buffer);
- /* logical drives channel is RAID */
- mega_ch_class |= (0x01 << megacfg->host->max_channel);
+ for( i = 0; i < NVIRT_CHAN; i++ ) {
+ /* logical drives channel is RAID */
+ mega_ch_class |= (0x01 << (megacfg->productInfo.SCSIChanPresent+i));
+ }
}
else {
mega_ch_class = 0xFF;
@@ -3572,7 +3678,7 @@
megaCfg = (mega_host_config *) pSHost->hostdata;
sprintf (buffer,
- "AMI MegaRAID %s %d commands %d targs %d chans %d luns",
+ "LSI Logic MegaRAID %s %d commands %d targs %d chans %d luns",
megaCfg->fwVer, megaCfg->productInfo.MaxConcCmds,
megaCfg->host->max_id, megaCfg->host->max_channel,
megaCfg->host->max_lun);
@@ -3604,14 +3710,15 @@
DRIVER_LOCK (megaCfg);
if (!(megaCfg->flag & (1L << SCpnt->channel))) {
- if (SCpnt->channel < SCpnt->host->max_channel)
+ if (SCpnt->channel < megaCfg->productInfo.SCSIChanPresent)
printk ( KERN_NOTICE
- "scsi%d: scanning channel %c for devices.\n",
- megaCfg->host->host_no, SCpnt->channel + '1');
+ "scsi%d: scanning channel %d for devices.\n",
+ megaCfg->host->host_no, SCpnt->channel);
else
printk ( KERN_NOTICE
- "scsi%d: scanning virtual channel for logical drives.\n",
- megaCfg->host->host_no);
+ "scsi%d: scanning virtual channel %d for logical drives.\n",
+ megaCfg->host->host_no,
+ SCpnt->channel-megaCfg->productInfo.SCSIChanPresent+1);
megaCfg->flag |= (1L << SCpnt->channel);
}
@@ -3657,21 +3764,38 @@
megaCfg->flag |= IN_QUEUE;
/* Allocate and build a SCB request */
if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
- /*build SCpnt for M_RD_IOCTL_CMD_NEW cmd in mega_ioctl() */
- /* Add SCB to the head of the pending queue */
- /* Add SCB to the head of the pending queue */
- if (megaCfg->qPendingH == NULL) {
- megaCfg->qPendingH = megaCfg->qPendingT = pScb;
- } else {
- megaCfg->qPendingT->next = pScb;
- megaCfg->qPendingT = pScb;
- }
- megaCfg->qPendingT->next = NULL;
- megaCfg->qPcnt++;
- if (mega_runpendq (megaCfg) == -1) {
- DRIVER_UNLOCK (megaCfg);
- return 0;
+ /*
+ * Check if the HBA is in quiescent state, e.g., during a delete
+ * logical drive opertion. If it is, queue the commands in the
+ * internal queue until the delete operation is complete.
+ */
+ if( ! megaCfg->quiescent ) {
+ /* Add SCB to the head of the pending queue */
+ if (megaCfg->qPendingH == NULL) {
+ megaCfg->qPendingH = megaCfg->qPendingT = pScb;
+ } else {
+ megaCfg->qPendingT->next = pScb;
+ megaCfg->qPendingT = pScb;
+ }
+ megaCfg->qPendingT->next = NULL;
+ megaCfg->qPcnt++;
+
+ if (mega_runpendq (megaCfg) == -1) {
+ DRIVER_UNLOCK (megaCfg);
+ return 0;
+ }
+ }
+ else {
+ /* Add SCB to the internal queue */
+ if (megaCfg->int_qh == NULL) {
+ megaCfg->int_qh = megaCfg->int_qt = pScb;
+ } else {
+ megaCfg->int_qt->next = pScb;
+ megaCfg->int_qt = pScb;
+ }
+ megaCfg->int_qt->next = NULL;
+ megaCfg->int_qlen++;
}
if (pScb->SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
@@ -4184,6 +4308,7 @@
return -1;
if( *(unsigned short *)(bh->b_data + 510) == 0xAA55 ) {
+
for( largest_cyl = -1, p = (struct partition *)(0x1BE + bh->b_data),
i = 0; i < 4; ++i, ++p) {
@@ -4197,6 +4322,7 @@
}
}
}
+
if (largest) {
heads = largest->end_head + 1;
sectors = largest->end_sector & 0x3f;
@@ -4519,6 +4645,14 @@
break;
case M_RD_IOCTL_CMD_NEW:
+
+ /*
+ * Deletion of logical drives is only handled in 0x80 commands
+ */
+ if( ioc.mbox[0] == FC_DEL_LOGDRV && ioc.mbox[2] == OP_DEL_LOGDRV ) {
+ return -EINVAL;
+ }
+
/* which adapter? */
adapno = ioc.ui.fcs.adapno;
@@ -4686,6 +4820,28 @@
}
if(shpnt == NULL) return -ENODEV;
+ /*
+ * ioctls for deleting logical drives is a special case, so check
+ * for it first
+ */
+ if( ioc.mbox[0] == FC_DEL_LOGDRV && ioc.mbox[2] == OP_DEL_LOGDRV ) {
+
+ if( !megacfg->support_random_del ) {
+ printk("megaraid: logdrv delete on non supporting f/w.\n");
+ return -EINVAL;
+ }
+
+ uioc = (struct uioctl_t *)arg;
+
+ ret = mega_del_logdrv(megacfg, ioc.mbox[3]);
+
+ put_user(1, &uioc->mbox[16]); /* numstatus */
+ put_user(ret, &uioc->mbox[17]); /* status */
+
+ /* if deletion failed, let the user know by failing ioctl */
+ return ret;
+ }
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
scsicmd = (Scsi_Cmnd *)kmalloc(sizeof(Scsi_Cmnd), GFP_KERNEL|GFP_DMA);
#else
@@ -4760,8 +4916,7 @@
put_user (scsicmd->result, &uioc->pthru.scsistatus);
} else {
put_user (1, &uioc->mbox[16]); /* numstatus */
- /* status */
- put_user (scsicmd->result, &uioc->mbox[17]);
+ put_user (scsicmd->result, &uioc->mbox[17]); /* status */
}
if (kvaddr) {
@@ -4918,6 +5073,139 @@
return !ret;
}
+
+/*
+ * Find out if this controller supports random deletion and addition of
+ * logical drives
+ */
+static int
+mega_support_random_del(mega_host_config *this_hba)
+{
+ mega_mailbox *mboxpnt;
+ unsigned char mbox[16];
+ int ret;
+
+ mboxpnt = (mega_mailbox *)mbox;
+
+ memset(mbox, 0, sizeof(mbox));
+
+ /*
+ * issue command
+ */
+ mbox[0] = FC_DEL_LOGDRV;
+ mbox[2] = OP_SUP_DEL_LOGDRV;
+
+ ret = megaIssueCmd(this_hba, mbox, NULL, 0);
+
+ return !ret;
+}
+
+static int
+mega_del_logdrv(mega_host_config *this_hba, int logdrv)
+{
+ int rval;
+ IO_LOCK_T;
+ DECLARE_WAIT_QUEUE_HEAD(wq);
+ mega_scb *scbp;
+
+ /*
+ * Stop sending commands to the controller, queue them internally.
+ * When deletion is complete, ISR will flush the queue.
+ */
+ IO_LOCK;
+ this_hba->quiescent = 1;
+ IO_UNLOCK;
+
+ while( this_hba->qPcnt ) {
+ sleep_on_timeout( &wq, 1*HZ ); /* sleep for 1s */
+ }
+ rval = mega_do_del_logdrv(this_hba, logdrv);
+
+ IO_LOCK;
+ /*
+ * Attach the internal queue to the pending queue
+ */
+ if( this_hba->qPendingH == NULL ) {
+ /*
+ * If pending queue head is null, make internal queue as
+ * pending queue
+ */
+ this_hba->qPendingH = this_hba->int_qh;
+ this_hba->qPendingT = this_hba->int_qt;
+ this_hba->qPcnt = this_hba->int_qlen;
+ }
+ else {
+ /*
+ * Append pending queue to internal queue
+ */
+ if( this_hba->int_qt ) {
+ this_hba->int_qt->next = this_hba->qPendingH;
+
+ this_hba->qPendingH = this_hba->int_qh;
+ this_hba->qPcnt += this_hba->int_qlen;
+ }
+ }
+
+ this_hba->int_qh = this_hba->int_qt = NULL;
+ this_hba->int_qlen = 0;
+
+ /*
+ * If delete operation was successful, add 0x80 to the logical drive
+ * ids for commands in the pending queue.
+ */
+ if( this_hba->read_ldidmap) {
+ for( scbp = this_hba->qPendingH; scbp; scbp = scbp->next ) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+ if( scbp->pthru->logdrv < 0x80 )
+ scbp->pthru->logdrv += 0x80;
+#else
+ if( scbp->pthru.logdrv < 0x80 )
+ scbp->pthru.logdrv += 0x80;
+#endif
+ }
+ }
+ this_hba->quiescent = 0;
+
+ IO_UNLOCK;
+
+ return rval;
+}
+
+
+static int
+mega_do_del_logdrv(mega_host_config *this_hba, int logdrv)
+{
+ mega_mailbox *mboxpnt;
+ unsigned char mbox[16];
+ int rval;
+
+ mboxpnt = (mega_mailbox *)mbox;
+
+ memset(mbox, 0, sizeof(mbox));
+
+ mbox[0] = FC_DEL_LOGDRV;
+ mbox[2] = OP_DEL_LOGDRV;
+ mbox[3] = logdrv;
+
+ rval = megaIssueCmd(this_hba, mbox, NULL, 0);
+
+ /* log this event */
+ if( rval != 0 ) {
+ printk("megaraid: Attempt to delete logical drive %d failed.",
+ logdrv);
+ return rval;
+ }
+
+ printk("megaraid: logical drive %d deleted.\n", logdrv);
+
+ /*
+ * After deleting first logical drive, the logical drives must be
+ * addressed by adding 0x80 to the logical drive id.
+ */
+ this_hba->read_ldidmap = 1;
+
+ return rval;
+}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
void *
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)