Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 299200 Details for
Bug 230717
kernel panic with ciss driver upon kdump/kexec execution w/DLx85 platforms
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
My apologies, the last patch had compile warnings.
p00003_cciss_kdump_complete_rhel52.patch-3 (text/plain), 15.73 KB, created by
Mike Miller (OS Dev)
on 2008-03-26 17:42:30 UTC
(
hide
)
Description:
My apologies, the last patch had compile warnings.
Filename:
MIME Type:
Creator:
Mike Miller (OS Dev)
Created:
2008-03-26 17:42:30 UTC
Size:
15.73 KB
patch
obsolete
>diff -urNp linux-2.6.18.i386-orig/drivers/block/cciss.c linux-2.6.18.i386/drivers/block/cciss.c >--- linux-2.6.18.i386-orig/drivers/block/cciss.c 2008-03-14 13:50:14.000000000 -0500 >+++ linux-2.6.18.i386/drivers/block/cciss.c 2008-03-26 11:26:25.000000000 -0500 >@@ -190,6 +190,16 @@ static int sendcmd_withirq(__u8 cmd, int > > static void fail_all_cmds(unsigned long ctlr); > static void cciss_shutdown(struct pci_dev *); >+static void print_cmd(CommandList_struct *); >+static int cciss_reset_controller(struct pci_dev *, int, ctlr_info_t *); >+ >+/* Create a thread to poll for completions if we're coming up >+ * in a crashkernel. >+ */ >+static int cciss_completion_thread(void *ctlr); >+static int start_completion_thread(ctlr_info_t *h, >+ int (*cciss_completion_thread)(void *), int *rc); >+ > > #ifdef CONFIG_PROC_FS > static void cciss_procinit(int i); >@@ -336,7 +346,7 @@ static int cciss_seq_show(struct seq_fil > drv->raid_level = RAID_UNKNOWN; > seq_printf(seq, "cciss/c%dd%d:" > "\t%4u.%02uGB\tRAID %s\n", >- ctlr, *pos, (int)vol_sz, (int)vol_sz_frac, >+ ctlr, (int) *pos, (int)vol_sz, (int)vol_sz_frac, > raid_label[drv->raid_level]); > > return 0; >@@ -566,8 +576,17 @@ static int cciss_open(struct inode *inod > printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name); > #endif /* CCISS_DEBUG */ > >- if (host->busy_initializing || drv->busy_configuring) >- return -EBUSY; >+ if (reset_devices) { >+ spin_lock(CCISS_LOCK(host->ctlr)); >+ if (host->busy_initializing || drv->busy_configuring) { >+ spin_unlock(CCISS_LOCK(host->ctlr)); >+ return -EBUSY; >+ } >+ spin_unlock(CCISS_LOCK(host->ctlr)); >+ } else >+ if (host->busy_initializing || drv->busy_configuring) >+ return -EBUSY; >+ > /* > * Root is allowed to open raw volume zero even if it's not configured > * so array config can still work. Root is also allowed to open any >@@ -1817,7 +1836,7 @@ static int fill_cmd(CommandList_struct * > case 0: /* ABORT message */ > c->Request.CDBLen = 12; > c->Request.Type.Attribute = ATTR_SIMPLE; >- c->Request.Type.Direction = XFER_WRITE; >+ c->Request.Type.Direction = XFER_NONE; > c->Request.Timeout = 0; > c->Request.CDB[0] = cmd; /* abort */ > c->Request.CDB[1] = 0; /* abort a command */ >@@ -1825,18 +1844,17 @@ static int fill_cmd(CommandList_struct * > memcpy(&c->Request.CDB[4], buff, 8); > break; > case 1: /* RESET message */ >- c->Request.CDBLen = 12; >+ c->Request.CDBLen = 16; > c->Request.Type.Attribute = ATTR_SIMPLE; >- c->Request.Type.Direction = XFER_WRITE; >+ c->Request.Type.Direction = XFER_NONE; > c->Request.Timeout = 0; > memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); > c->Request.CDB[0] = cmd; /* reset */ >- c->Request.CDB[1] = 0x04; /* reset a LUN */ > break; > case 3: /* No-Op message */ > c->Request.CDBLen = 1; > c->Request.Type.Attribute = ATTR_SIMPLE; >- c->Request.Type.Direction = XFER_WRITE; >+ c->Request.Type.Direction = XFER_NONE; > c->Request.Timeout = 0; > c->Request.CDB[0] = cmd; > break; >@@ -2146,11 +2164,18 @@ static int cciss_revalidate(struct gendi > static unsigned long pollcomplete(int ctlr) > { > unsigned long done; >- int i; >+ int i, timeout; > >- /* Wait (up to 20 seconds) for a command to complete */ >+ /* Wait (up to 20 seconds) for a command to complete >+ * under normal conditions. >+ * If reset_devices wait at least 60 seconds. It takes >+ * longer than advertised for the controller to become >+ * ready after a reset. I'd rather have a more dynamic >+ * method to determine if it's ready. >+ */ > >- for (i = 20 * HZ; i > 0; i--) { >+ timeout = reset_devices ? 60 * HZ : 20 * HZ; >+ for (i = timeout; i > 0; i--) { > done = hba[ctlr]->access.command_completed(hba[ctlr]); > if (done == FIFO_EMPTY) > schedule_timeout_uninterruptible(1); >@@ -2181,7 +2206,7 @@ static int add_sendcmd_reject(__u8 cmd, > > /* If it's not the scsi tape stuff doing error handling, (abort */ > /* or reset) then we don't expect anything weird. */ >- if (cmd != CCISS_RESET_MSG && cmd != CCISS_ABORT_MSG) { >+ if (cmd != CCISS_RESET_MSG && cmd != CCISS_ABORT_MSG && !reset_devices) { > #endif > printk(KERN_WARNING "cciss cciss%d: SendCmd " > "Invalid command list address returned! (%lx)\n", >@@ -2207,8 +2232,10 @@ static int add_sendcmd_reject(__u8 cmd, > return 1; > } > /* Save it for later */ >- srl->complete[srl->ncompletions] = complete; >- srl->ncompletions++; >+ if (!reset_devices) { >+ srl->complete[srl->ncompletions] = complete; >+ srl->ncompletions++; >+ } > #endif > return 0; > } >@@ -2240,7 +2267,7 @@ static int sendcmd(__u8 cmd, int ctlr, v > cmd_free(info_p, c, 1); > return status; > } >- resend_cmd1: >+resend_cmd1: > /* > * Disable interrupt > */ >@@ -2276,6 +2303,7 @@ static int sendcmd(__u8 cmd, int ctlr, v > #endif /* CCISS_DEBUG */ > > if (complete == 1) { >+ print_cmd(c); > printk(KERN_WARNING > "cciss cciss%d: SendCmd Timeout out, " > "No command list address returned!\n", ctlr); >@@ -2726,13 +2754,17 @@ static irqreturn_t do_cciss_intr(int irq > unsigned long flags; > __u32 a, a1, a2; > >- if (interrupt_not_for_us(h)) >- return IRQ_NONE; >+ if (!reset_devices) { >+ if (interrupt_not_for_us(h)) >+ return IRQ_NONE; >+ } >+ > /* > * If there are completed commands in the completion queue, > * we had better do something about it. > */ > spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); >+ > while (interrupt_pending(h)) { > while ((a = get_next_completion(h)) != FIFO_EMPTY) { > a1 = a; >@@ -2878,7 +2910,6 @@ static void __devinit cciss_interrupt_mo > (board_id == 0x40800E11) || > (board_id == 0x40820E11) || (board_id == 0x40830E11)) > goto default_int_mode; >- > if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { > err = pci_enable_msix(pdev, cciss_msix_entries, 4); > if (!err) { >@@ -2956,9 +2987,11 @@ static int cciss_pci_init(ctlr_info_t *c > #endif /* CCISS_DEBUG */ > > /* If the kernel supports MSI/MSI-X we will try to enable that functionality, >- * else we use the IO-APIC interrupt assigned to us by system ROM. >+ * else we use the IO-APIC interrupt assigned to us by system ROM. If we're >+ * booting into a crashkernel we use polling mode. > */ >- cciss_interrupt_mode(c, pdev, board_id); >+ if (!reset_devices) >+ cciss_interrupt_mode(c, pdev, board_id); > > /* > * Memory base addr is first addr , the second points to the config >@@ -3223,7 +3256,7 @@ static void cciss_getgeometry(int cntl_n > goto geo_inq; > } > cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); >- >+ > /* If read_capacity returns all F's the volume is >2TB */ > /* so we switch to 16-byte CDBs for all read/write ops */ > if(total_size == 0xFFFFFFFFULL) { >@@ -3287,6 +3320,111 @@ static void free_hba(int i) > } > > /* >+ * If were coming up in a crash kernel we need to reset >+ * the controller to clear any outstanding commands and >+ * get the card in a sane state. >+ * We use polling mode operation while in the crash kernel >+ * to avoid interrupt related issues. >+ */ >+static int cciss_reset_controller(struct pci_dev *pdev, >+ int c, ctlr_info_t *hba) >+{ >+ >+ int rc, i, err; >+ char reset_buf[4]; >+ CommandList_struct *cmd; >+ dma_addr_t cmd_dhandle; >+ ushort subsystem_vendor_id, subsystem_device_id; >+ __u32 board_id, scratchpad = 0; >+ u64bit temp64; >+ >+ /* Set up the buffer w/reset controller message. */ >+ memset(reset_buf, RESET_CONTROLLER, 4); >+ >+ /* Set up pci mappings so we can access registers. */ >+ hba->paddr = pci_resource_start(pdev, 0); >+ hba->vaddr = remap_pci_mem(hba->paddr, 0x250); >+ hba->pdev = pdev; >+ >+ /* Find our access methods for this board. */ >+ subsystem_vendor_id = pdev->subsystem_vendor; >+ subsystem_device_id = pdev->subsystem_device; >+ board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | >+ subsystem_vendor_id); >+ for (i = 0; i < ARRAY_SIZE(products); i++) { >+ if (board_id == products[i].board_id) { >+ hba->product_name = products[i].product_name; >+ hba->access = *(products[i].access); >+ hba->nr_cmds = products[i].nr_cmds; >+ break; >+ } >+ } >+ >+ /* make sure the board interrupts are off */ >+ hba->access.set_intr_mask(hba, CCISS_INTR_OFF); >+ >+ /* Allocate a cmd & error info struct and set up ptrs. */ >+ cmd = (CommandList_struct *) pci_alloc_consistent(hba->pdev, >+ sizeof(CommandList_struct) + sizeof(ErrorInfo_struct), >+ &cmd_dhandle); >+ memset(cmd, 0, sizeof(*cmd) + sizeof(*cmd->err_info)); >+ cmd->err_info = ((void *) cmd) + sizeof(*cmd); >+ cmd->busaddr = (__u32) cmd_dhandle; >+ temp64.val = (__u64) cmd_dhandle + sizeof(CommandList_struct); >+ cmd->ErrDesc.Addr.lower = temp64.val32.lower; >+ cmd->ErrDesc.Addr.upper = temp64.val32.upper; >+ cmd->ErrDesc.Len = sizeof(ErrorInfo_struct); >+ >+ /* Build the command. */ >+ rc = fill_cmd(cmd, CCISS_RESET_MSG, c, reset_buf, 4, 0, >+ 0, 0, NULL, TYPE_MSG); >+ if (rc == IO_ERROR) >+ return -EIO; >+ else >+ rc = 0; >+ >+ /* Send it down. */ >+ hba->access.submit_command(hba, cmd); >+ >+ /* Wait some time for the scratchpad to be reset. */ >+ do { >+ mdelay(25); >+ scratchpad = readl(hba->vaddr + SA5_SCRATCHPAD_OFFSET); >+ } while (scratchpad == CCISS_FIRMWARE_READY); >+ >+ /* Now wait for the scratchpad to become ready. */ >+ for (i = 0; i < 1200; i++) { >+ scratchpad = readl(hba->vaddr + SA5_SCRATCHPAD_OFFSET); >+ if (scratchpad == CCISS_FIRMWARE_READY) { >+ break; >+ } >+ set_current_state(TASK_INTERRUPTIBLE); >+ schedule_timeout(HZ / 10); /* wait 100ms */ >+ } >+ if (scratchpad != CCISS_FIRMWARE_READY) { >+ printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); >+ err = -ENODEV; >+ } >+ >+ /* Free the command. */ >+ pci_free_consistent(pdev, sizeof(*cmd) + sizeof(*cmd->err_info), >+ cmd, cmd_dhandle); >+ >+ return rc; >+} >+ >+static void kill_polling_thread(ctlr_info_t *h) >+{ >+ int flags = 0; >+ if (h->polling_thread) { >+ printk("starting to kill the polling thread\n"); >+ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); >+ h->polling_thread_run = 0; >+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); >+ } >+} >+ >+/* > * This is it. Find all the controllers and register them. I really hate > * stealing all these major device numbers. > * returns the number of block devices registered. >@@ -3305,6 +3443,16 @@ static int __devinit cciss_init_one(stru > > hba[i]->busy_initializing = 1; > >+ if (reset_devices) { >+ rc = cciss_reset_controller(pdev, i, hba[i]); >+ if (rc) { >+ printk(KERN_WARNING "cciss: controller reset" >+ " failed with %d\n", rc); >+ free_hba(i); >+ return -EIO; >+ } >+ } >+ > if (cciss_pci_init(hba[i], pdev) != 0) > goto clean1; > >@@ -3342,11 +3490,16 @@ static int __devinit cciss_init_one(stru > > /* make sure the board interrupts are off */ > hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); >- if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr, >- IRQF_DISABLED | IRQF_SHARED, hba[i]->devname, hba[i])) { >- printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", >- hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname); >- goto clean2; >+ >+ if (!reset_devices) { >+ printk(KERN_WARNING "cciss: requesting IRQ\n"); >+ if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr, >+ IRQF_DISABLED | IRQF_SHARED, >+ hba[i]->devname, hba[i])) { >+ printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", >+ hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname); >+ goto clean2; >+ } > } > > printk(KERN_INFO "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", >@@ -3370,6 +3523,7 @@ static int __devinit cciss_init_one(stru > printk(KERN_ERR "cciss: out of memory"); > goto clean4; > } >+ > #ifdef CONFIG_CISS_SCSI_TAPE > hba[i]->scsi_rejects.complete = > kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) * >@@ -3398,8 +3552,17 @@ static int __devinit cciss_init_one(stru > > cciss_scsi_setup(i); > >- /* Turn the interrupts on so we can service requests */ >- hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); >+ if (reset_devices) { >+ if (start_completion_thread(hba[i], >+ cciss_completion_thread, &rc) != 0) >+ printk("Unable to start cciss_completion_thread\n"); >+ } >+ >+ /* If we're not booting a crashkernel then turn interrupts >+ * on so we can service requests >+ */ >+ if (!reset_devices) >+ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); > > cciss_procinit(i); > >@@ -3491,7 +3654,8 @@ static int __devinit cciss_init_one(stru > blk_cleanup_queue(drv->queue); > } > pci_release_regions(pdev); >- pci_disable_device(pdev); >+ printk("cciss: would have called pci_disable_device\n"); >+ /* pci_disable_device(pdev); */ > pci_set_drvdata(pdev, NULL); > free_hba(i); > return -1; >@@ -3558,6 +3722,9 @@ static void __devexit cciss_remove_one(s > } > } > >+ if (reset_devices) >+ kill_polling_thread(hba[i]); >+ > cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ > > cciss_shutdown(pdev); >@@ -3608,6 +3775,34 @@ static int __init cciss_init(void) > return pci_register_driver(&cciss_pci_driver); > } > >+static int start_completion_thread(ctlr_info_t *h, >+ int (*cciss_completion_thread)(void *), int *rc) { >+ >+ int flags = 0; >+ >+ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); >+ h->polling_thread_run = 1; >+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); >+ >+ kernel_thread(cciss_completion_thread, h, 0); >+ return 0; >+} >+ >+static int cciss_completion_thread(void *ctlr) >+{ >+ ctlr_info_t *h = (ctlr_info_t *) ctlr; >+ daemonize("cciss_completion"); >+ >+ h->polling_thread = current; >+ >+ while (h->polling_thread_run) { >+ do_cciss_intr(0, h, NULL); >+ msleep(1); >+ } >+ >+ return 0; >+} >+ > static void __exit cciss_cleanup(void) > { > int i; >diff -urNp linux-2.6.18.i386-orig/drivers/block/cciss_cmd.h linux-2.6.18.i386/drivers/block/cciss_cmd.h >--- linux-2.6.18.i386-orig/drivers/block/cciss_cmd.h 2008-03-14 13:50:06.000000000 -0500 >+++ linux-2.6.18.i386/drivers/block/cciss_cmd.h 2008-03-14 14:11:05.000000000 -0500 >@@ -102,6 +102,31 @@ typedef struct _InquiryData_struct > BYTE data_byte[36]; > } InquiryData_struct; > >+/* defines for the messages supported by Smart Array */ >+#define CISS_ABORT_MSG 0x00 >+#define CISS_RESET_MSG 0x01 >+#define CISS_SCAN_MSG 0x02 >+#define CISS_NO_OP 0x03 >+ >+/* target defines for CCISS_ABORT_MSG */ >+#define TASK_ABORT 0x00 /* abort a command */ >+#define TASKSET_ABORT 0x01 /* abort all commands to a target */ >+#define CISS_CLEAR_ACA 0x02 /* clear ACA condition */ >+#define CLEAR_TASKSET 0x03 /* abort all commands to a target */ >+ >+/* target defines for CCISS_RESET_MSG */ >+#define RESET_CONTROLLER 0x00 /* reset the controller */ >+#define RESET_BUS 0x01 /* reset the bus */ >+#define RESET_TARGET 0x03 /* reset a target device */ >+#define RESET_LUN 0x04 /* reset a logical volume */ >+ >+/* target defines for CCISS_SCAN_MSG >+ * the target is specified in the LUN field */ >+#define SCAN_ALL 0x00 /* scan all buses */ >+#define SCAN_BUS 0x01 /* scan a bus */ >+#define SCAN_TARGET 0x03 /* scan a target device */ >+#define SCAN_LUN 0x04 /* scan a logical volume */ >+ > #define CISS_REPORT_LOG 0xc2 /* Report Logical LUNs */ > #define CISS_REPORT_PHYS 0xc3 /* Report Physical LUNs */ > // Data returned >diff -urNp linux-2.6.18.i386-orig/drivers/block/cciss.h linux-2.6.18.i386/drivers/block/cciss.h >--- linux-2.6.18.i386-orig/drivers/block/cciss.h 2008-03-14 13:50:07.000000000 -0500 >+++ linux-2.6.18.i386/drivers/block/cciss.h 2008-03-14 14:11:05.000000000 -0500 >@@ -59,6 +59,8 @@ struct ctlr_info > __u32 board_id; > void __iomem *vaddr; > unsigned long paddr; >+ struct task_struct *polling_thread; >+ int polling_thread_run; > int nr_cmds; /* Number of commands allowed on this controller */ > CfgTable_struct __iomem *cfgtable; > int interrupts_enabled; >diff -urNp linux-2.6.18.i386-orig/drivers/block/cciss_scsi.c linux-2.6.18.i386/drivers/block/cciss_scsi.c >--- linux-2.6.18.i386-orig/drivers/block/cciss_scsi.c 2008-03-14 13:50:14.000000000 -0500 >+++ linux-2.6.18.i386/drivers/block/cciss_scsi.c 2008-03-14 14:11:05.000000000 -0500 >@@ -293,6 +293,8 @@ print_bytes (unsigned char *c, int len, > } > } > >+#endif >+ > static void > print_cmd(CommandList_struct *cp) > { >@@ -339,8 +341,6 @@ print_cmd(CommandList_struct *cp) > > } > >-#endif >- > static int > find_bus_target_lun(int ctlr, int *bus, int *target, int *lun) > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 230717
:
149128
|
149208
|
292178
|
293393
|
293602
|
293604
|
294226
|
298090
|
298451
|
298533
|
298806
|
299186
| 299200 |
302760
|
302938
|
303074