You can subscribe to this list here.
| 2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(16) |
Dec
(3) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2005 |
Jan
(2) |
Feb
(2) |
Mar
(7) |
Apr
(12) |
May
(10) |
Jun
|
Jul
|
Aug
|
Sep
(6) |
Oct
|
Nov
|
Dec
|
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
|
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <lkd...@li...> - 2009-07-02 06:13:30
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD> <META http-equiv=Content-Type content="text/html; charset=iso-8859-1"> </HEAD> <BODY><table cellpadding="0" cellspacing="0" border="0" align="center" width="600" style="font: normal 14px Helvetica, Arial, sans-serif; line-height: 19px; color: #2c2c2c;"> <tr><td height="25" bgcolor="#f3f3f3" style=""> <table cellpadding="0" cellspacing="0" border="0" align="center" width="560" > <tr> <td style="font: normal 11px Helvetica, Arial, sans-serif; line-height: 13px; color: #b5b5b5;" align="left"> <a href="http://OAEyW.followletter.com/" style="text-decoration: none; color: #00aff0; font-weight: bold;">Tell a friend</a> <span style="padding: 0 5px;">|</span> <a href="http://mygUC.followletter.com/" style="text-decoration: none; color: #00aff0; font-weight: bold;">Download latest version</a></td> <td style="font: normal 11px Helvetica, Arial, sans-serif; line-height: 13px; color: #b5b5b5;" align="right"> <a href="http://9j3X.followletter.com/" style="text-decoration: none; color: #b5b5b5; font-weight: bold;">See this email as a webpage</a></td> </tr></table></td></tr></table> <table cellpadding="0" cellspacing="0" border="0" align="center" width="600" style="font: normal 14px Helvetica, Arial, sans-serif; line-height: 19px; color: #2c2c2c;"> <tr><td style="padding: 20px 0;"> <table border="0" cellspacing="0" cellpadding="0" width="560" align="center"> <tr><td align="left" width="450"> <h1 style="font: bold 20px Helvetica, Arial, sans-serif; line-height: 28px; color: #999;">Hello!</h1></td> <td align="right" width="110"></td></tr> </table></td></tr><tr valign="top"><td> <table cellpadding="0" cellspacing="0" border="0" width="600" bgcolor="#ffffff"> <tr valign="top"><td><table border="0" cellspacing="0" cellpadding="0" width="600"> <tr valign="top"><td width="19" height="20" bgcolor="#ffffff" valign="top"></td> <td width="562" bgcolor="#ffffff" valign="top"></td><td width="19" bgcolor="#ffffff" valign="top"></td> </tr><tr valign="top"><td bgcolor="#ffffff"></td><td bgcolor="#ffffff" valign="top" height="70"> <h1 style="font: bold 32px Helvetica, Arial, sans-serif; line-height: 32px; margin: 0; padding: 0; color: #000000; text-align: center"> <a style="color:#454545; text-decoration:none;" href="http://NFEWB.followletter.com/">Shipped Privately And Discreetly To Your Door!</a><br><br></h1></td> <td bgcolor="#ffffff"></td></tr><tr valign="top"><td height="340" colspan="3" bgcolor="#ffffff" valign="top" align="center"> <a href="http://UY4PT.followletter.com/" style="color: #fff; text-decoration: none;"> <img src="http://bQMY3.followletter.com/xMmWS.gif" alt="See this email as a webpage" border="0"/></a></td> </tr></table></td></tr><tr><td><table cellpadding="0" cellspacing="0" border="0"> <tr><td width="20"> </td> <td width="560" style="padding: 24px 0 15px 0; font:normal 14px/19px Helvetica, Arial, sans-serif;"><strong> We want to put a great big grin on your face in 2009.</strong> You'll be to rejoice all year.</td> <td width="20"> </td></tr></table></td></tr></table></td></tr><tr> <td style="padding: 20px 0 40px 0; margin: 0;"> <table border="0" cellspacing="0" cellpadding="0" width="560" align="center"> <tr><td> <p style="font: normal 11px Helvetica, Arial, sans-serif; line-height: 13px; color: #b5b5b5;"> <a href="http://qwkDk.followletter.com/" style="text-decoration: none; color: #00aff0; font-weight: bold;">Unsubscribe</a> <span style="padding: 0 5px;">|</span> <a href="http://4Xip6.followletter.com" style="text-decoration: none; color: #00aff0; font-weight: bold;"> Lost Password</a> <span style="padding: 0 5px;">|</span> <a href="http://ZBwa4.followletter.com/" style="text-decoration: none; color: #00aff0; font-weight: bold;"> Account Settings</a> <span style="padding: 0 5px;">|</span> <a href="http://1g07N.followletter.com/" style="text-decoration: none; color: #00aff0; font-weight: bold;">Help</a> <span style="padding: 0 5px;">|</span> <a href="http://Zodzo.followletter.com/" style="text-decoration: none; color: #00aff0; font-weight: bold;">Terms of Service</a> <span style="padding: 0 5px;">|</span> <a href="http://NG061.followletter.com/" style="text-decoration: none; color: #00aff0; font-weight: bold;">Privacy</a> </p><p style="font: normal 11px Helvetica, Arial, sans-serif; line-height: 13px; color: #b5b5b5;"> <strong>Ottho Heldringstraat 2, 83840 AZ Amsterdam, The Netherlands</p> <p style="font: normal 11px Helvetica, Arial, sans-serif; line-height: 13px; color: #b5b5b5;"></td> </tr></table></td></tr></table></BODY></HTML> |
|
From: O`Henry <ha...@tv...> - 2007-11-10 18:01:56
|
We offer the software for downloads only. It means that you do not receive a fancy package and a printed manual that actually aggregate the largest part of the retail price. And one more advantage of OEM Software is that you don't need to wait for delivery. You can download and install you software at once after paying for it. http://msmirfy.cheapestoemshop.net |
|
From: Takao I. <ind...@jp...> - 2007-09-25 02:05:47
|
Hi Rick, On Mon, 24 Sep 2007 17:04:17 -0400, Rick Beldin wrote: > I have been trying to assist a customer who is trying to > minimize the amount of space that will be used for a dump. > With a large number of 16GB systems, the end customer is > interested in minimizing the space used. > > Do you know of any studies that have been performed that will > provided some level of estimation for diskdump with dump_level > set to varying amounts? That might be helpful especially > when coupled with the compression that is available in > diskdump. > > Of course, I understand that this is all highly variable, > depending on the architecture, the amount of memory, the > load on the system and so forth but was wondering if there > was some resource other than the README in diskdumputils. I'm sorry I don't know material for estimating. Actually, I tried to estimate the amounts of dump by trial and error before, but I couldn't because the size of dump was very variable, as you know... Regards, Takao Indoh |
|
From: Rick B. <ric...@hp...> - 2007-09-24 21:04:59
|
Hi...
I have been trying to assist a customer who is trying to
minimize the amount of space that will be used for a dump.
With a large number of 16GB systems, the end customer is
interested in minimizing the space used.
Do you know of any studies that have been performed that will
provided some level of estimation for diskdump with dump_level
set to varying amounts? That might be helpful especially
when coupled with the compression that is available in
diskdump.
Of course, I understand that this is all highly variable,
depending on the architecture, the amount of memory, the
load on the system and so forth but was wondering if there
was some resource other than the README in diskdumputils.
Thanks,
Rick
--
+----------------------------------------------------------------------+
| Rick Beldin | Hewlett-Packard Company |
| email: Ric...@hp... | Global Solutions Engineering |
| | 5555 Windward Parkway West |
| | Alpharetta, GA 30004 |
| phone: (770)343-0219 | |
+----------------------------------------------------------------------+
|
|
From: Takao I. <ind...@jp...> - 2007-05-07 06:35:02
|
Hi, On Sun, 6 May 2007 10:16:42 +0100 (BST), rahul Katariya wrote: >I am working on 64 bit redhat AS 4 update 3. I installed diskdumputils-1.2.8 > package on my machine. > > I configured diskdump on my machine. > ================================================ > $ cat /etc/sysconfig/diskdump >DEVICE=/dev/sdam2 > > I executed folowing commands >================================================ > $ service diskdump initialformat >Formatting dump device: >Do you want to format /dev/sdam2 (yes/NO)? yes >/dev/sdam2: [100.0%] > > $ service diskdump start >Starting diskdump: > [ OK ] > > > $ dmesg -c >disk_dump: Maximum block size: 16384 >disk_dump: total blocks required: 1048433 (header 3 + bitmap 38 + memory >1048392) > > $ tail -f /var/log/messages >May 6 14:31:14 kernel: disk_dump: Maximum block size: 16384 >May 6 14:31:14 kernel: disk_dump: total blocks required: 1048433 (header 3 >+ bitmap 38 + memory 1048392) >May 6 14:31:15 diskdump: activating succeeded > > $ cat /proc/diskdump ># sample_rate: 8 ># block_order: 2 ># fallback_on_err: 1 ># allow_risky_dumps: 1 ># dump_level: 0 ># compress: 0 ># total_blocks: 1048433 ># >================================================ > > Why "cat /proc/diskdump" command does not show registered device? > > I tried to test diskdump functionality by executing "echo c > /proc/sysrq- >trigger " command. > > After reboot I execute "savecore /dev/sdam2" command. But it is not >successful as dump has not taken on the device. > > How to solve this problem? Your dump device (/dev/sdam2) may not be available to diskdump. Diskdump of RHEL4 u3 supports only the following device. Please check your HBA of dump device. o aic7xxx o aic79xx o ipr o mptfusion o megaraid o sym53c8xx o sata_promise o ata_piix Takao Indoh |
|
From: rahul K. <rah...@ya...> - 2007-05-06 09:16:53
|
I am working on 64 bit redhat AS 4 update 3. I installed diskdumputils-1.2.8 package on my machine.
I configured diskdump on my machine.
================================================
$ cat /etc/sysconfig/diskdump
DEVICE=/dev/sdam2
I executed folowing commands
================================================
$ service diskdump initialformat
Formatting dump device:
Do you want to format /dev/sdam2 (yes/NO)? yes
/dev/sdam2: [100.0%]
$ service diskdump start
Starting diskdump: [ OK ]
$ dmesg -c
disk_dump: Maximum block size: 16384
disk_dump: total blocks required: 1048433 (header 3 + bitmap 38 + memory 1048392)
$ tail -f /var/log/messages
May 6 14:31:14 kernel: disk_dump: Maximum block size: 16384
May 6 14:31:14 kernel: disk_dump: total blocks required: 1048433 (header 3 + bitmap 38 + memory 1048392)
May 6 14:31:15 diskdump: activating succeeded
$ cat /proc/diskdump
# sample_rate: 8
# block_order: 2
# fallback_on_err: 1
# allow_risky_dumps: 1
# dump_level: 0
# compress: 0
# total_blocks: 1048433
#
================================================
Why "cat /proc/diskdump" command does not show registered device?
I tried to test diskdump functionality by executing "echo c > /proc/sysrq-trigger " command.
After reboot I execute "savecore /dev/sdam2" command. But it is not successful as dump has not taken on the device.
How to solve this problem?
---------------------------------
Check out what you're missing if you're not on Yahoo! Messenger |
|
From: rahul K. <rah...@ya...> - 2006-12-13 14:25:48
|
Hi, I am using Red Hat Enterprise Linux AS release 4 Update 3 machine. I had problem of running diskdump and saving core dump on scsi device /dev/sdq5. Then, I downloaded kernel 2.6.9 and patched with patches present in diskdump-1.0.tar.gz. I have patched megaraid diskdump patch for kernel 2.6.9. Then I compiled the kernel. And installed diskdumputils of version 1.3.15. Whenever I run "service diskdump start" command. It always fails (I have already run service diskdump initialformat). I have debugged the script /etc/init.d/diskdump and found that "/sbin/diskdumpfmt -c /dev/sdq5" command always returns 4. I tried diskdump for swap device (/dev/sda2). Its failing for swap device also. Why it is always failing? Am I missing any configuration? Any help will be appreciated. Thanks and regards, Rahul --------------------------------- Find out what India is talking about on - Yahoo! Answers India Send FREE SMS to your friend's mobile from Yahoo! Messenger Version 8. Get it NOW |
|
From: <tac...@mx...> - 2005-09-02 03:55:37
|
This patch is for diskdumputils-0.6.1-1. Masaki Tachibana |
|
From: <tac...@mx...> - 2005-09-02 03:47:47
|
This patch is for the kernel. Apply the partial dump patch to the kernel beforehand. See the following mail. From: Takao Indoh <indou@jp...>.fujitsu.com> [PATCH]Support partial dump 2005-03-24 05:44 Masaki Tachibana |
|
From: <tac...@mx...> - 2005-09-02 03:04:23
|
This patch is for diskdumputils-0.6.1-1. Masaki Tachibana |
|
From: <tac...@mx...> - 2005-09-02 02:58:07
|
This patch is for kernel. Apply the partial dump patch to the kernel beforehand. See the following mail. From: Takao Indoh <indou@jp...>.fujitsu.com> [PATCH]Support partial dump 2005-03-24 05:44 Masaki Tachibana |
|
From: <tac...@mx...> - 2005-09-02 02:44:35
|
Hi all, These two patches enable diskdump to compress memory and dump to the device in the LKCD dump format. This functionality can make a dump file size greatly smaller. The configuration is specified by module parameter of diskdump like "dump_level=xx" where (xx & 0x10) is non-zero. Currently, these patches support only x86_64, but i386 and ia64 support will also be available soon. Masaki Tachibana |
|
From: <tac...@mx...> - 2005-09-02 02:36:55
|
Hi all,
These two patches improve diskdump to support multiple dump devices.
Diskdump automatically tries to dump to another device when the troubles
like I/O error occur.
Multiple dump devices can be configured as follows. The dump devices
should be delimited by ":". The number of dump devices is unlimited.
For example:
# cat /etc/sysconfig/diskdump
DEVICE=/dev/sdb6:/dev/sdb5
In this cace, if the I/O error occurs on /dev/sdb6, diskdump tries to
dump to /dev/sdb5.
Masaki Tachibana
|
|
From: Miller, M. (OS Dev) <mik...@hp...> - 2005-05-24 16:44:45
|
> > People are of course free to use your work, but we do not=20 > want it in=20 > > the upstream kernels or any vendors distro. >=20 > Yes. This patch should not be included to upstream kernels. > It is intended to be alternative cciss driver in a certain=20 > distribution that I work for. >=20 Cool, mikem |
|
From: Akinobu M. <mi...@mi...> - 2005-05-24 16:28:55
|
On Wednesday 25 May 2005 00:36, Miller, Mike (OS Dev) wrote: > Thanks for doing this patch, but it creates undesirable dependencies for > the cciss driver. We are currently working on a blockdump driver that > eliminates these dependencies. No ETA yet. > People are of course free to use your work, but we do not want it in the > upstream kernels or any vendors distro. Yes. This patch should not be included to upstream kernels. It is intended to be alternative cciss driver in a certain distribution that I work for. |
|
From: Miller, M. (OS Dev) <mik...@hp...> - 2005-05-24 15:37:07
|
Mita,
Thanks for doing this patch, but it creates undesirable dependencies for
the cciss driver. We are currently working on a blockdump driver that
eliminates these dependencies. No ETA yet.
People are of course free to use your work, but we do not want it in the
upstream kernels or any vendors distro.
Thanks,
mikem
>=20
> Hello,
> I made cciss diskdump support patch for kernel 2.6.
> This patch is based on your 2.4 patch.
> I've send the following mail to lkdump-develop, but I forgot=20
> CC-ing to you.
>=20
> ---------- Forwarded Message ----------
>=20
> Subject: [lkdump-develop] [PATCH] diskdump cciss support for 2.6.9
> Date: Monday 23 May 2005 15:32
> From: Akinobu Mita <mi...@mi...>
> To: lkd...@li...
>=20
> Hello,
>=20
> I made a diskdump cciss support patch.
> This patch is based on Mike Mirror's patch which add support=20
> for diskdump His patch seems to be written for Red Hat=20
> Enterprise Linux 3.
> So I rewrote it for kernel-2.6.
>=20
> But this patch doesn't have flexibility about setting dump device.
>=20
> If you want to select /dev/cciss/c0d1p1 as a dump partition,
>=20
> 1. append "options cciss dump_drive=3D1" into modprobe.conf
>=20
> (If you select /dev/cciss/c0d[#a]p[#b],
> append "options cciss dump_drive=3D[#a]")
>=20
> 2. reload cciss module
>=20
> (If you are loading cciss module from initrd, you need to recreate
> initrd and reboot your machine)
>=20
> 3. set dump partition:
>=20
> # echo 1 > /sys/block/cciss\!c0d1/device/dump
>=20
> (If you select /dev/cciss/c0d[#a]p[#b],
> do echo [#b] > /sys/block/cciss\!c0d[#a]/device/dump
>=20
>=20
> diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/block/cciss.c=20
> 2.6.9-diskdump-1.0/drivers/block/cciss.c
> --- 2.6.9-diskdump-1.0.orig/drivers/block/cciss.c=09
> 2005-05-23 14:10:02.553869328 +0900
> +++ 2.6.9-diskdump-1.0/drivers/block/cciss.c 2005-05-23=20
> 14:18:23.367734048 +0900
> @@ -44,6 +44,18 @@
> #include <linux/blkdev.h>
> #include <linux/genhd.h>
> #include <linux/completion.h>
> +#include <linux/crc32.h>
> +#include <linux/diskdump.h>
> +
> +#define Dbg(x, ...) pr_debug("cciss_dump: " x "\n", ## __VA_ARGS__)
> +#define Err(x, ...) pr_err ("cciss_dump: " x "\n", ## __VA_ARGS__)
> +#define Warn(x, ...) pr_warn ("cciss_dump: " x "\n", ## __VA_ARGS__)
> +#define Info(x, ...) pr_info ("cciss_dump: " x "\n", ## __VA_ARGS__)
> +
> +/* blocks to 512byte secors */
> +#define BLOCK_SECTOR(s) ((s) << (DUMP_BLOCK_SHIFT - 9))
> +
> +static uint32_t module_crc;
> =20
> #define CCISS_DRIVER_VERSION(maj,min,submin)=20
> ((maj<<16)|(min<<8)|(submin)) #define DRIVER_NAME "HP CISS=20
> Driver (v 2.6.2)"
> @@ -139,7 +151,7 @@ static void cciss_getgeometry(int cntl_n =20
> static void start_io( ctlr_info_t *h); static int sendcmd(=20
> __u8 cmd, int ctlr, void *buff, size_t size,
> unsigned int use_unit_num, unsigned int log_unit, __u8=20
> page_code,
> - unsigned char *scsi3addr, int cmd_type);
> + unsigned char *scsi3addr, int block_nr, int cmd_type);
> =20
> #ifdef CONFIG_PROC_FS
> static int cciss_proc_get_info(char *buffer, char **start,=20
> off_t offset, @@ -157,6 +169,181 @@ static struct=20
> block_device_operations cc
> .revalidate_disk=3D cciss_revalidate,
> };
> =20
> +static CommandList_struct *cciss_dump_cmnd;
> +
> +/*
> + * cciss sysfs interface routines
> + */
> +static DEVICE_ATTR(dump, S_IRUGO | S_IWUSR, diskdump_sysfs_show,=20
> +diskdump_sysfs_store);
> +
> +/* device attributes */
> +static struct device_attribute *cciss_sysfs_attrs[] =3D {
> + &dev_attr_dump,
> + NULL
> +};
> +
> +static int cciss_attr_add(struct pci_dev *pdev) {
> + int i, error =3D 0;
> + for (i =3D 0; cciss_sysfs_attrs[i]; i++) {
> + error =3D device_create_file(&pdev->dev,=20
> cciss_sysfs_attrs[i]);
> + if (error)
> + break;
> + }
> + return error;
> +}
> +
> +static int dump_drive =3D -1;
> +module_param(dump_drive, int, S_IRUGO);
> +
> +static void
> +cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
> + int withirq, unsigned int *total_size, unsigned int=20
> *block_size);
> +
> +static int cciss_dump_sanity_check(struct disk_dump_device=20
> +*dump_device) {
> + struct pci_dev *pdev =3D dump_device->device;
> + ctlr_info_t *h =3D pci_get_drvdata(pdev);
> + ReadCapdata_struct size_buff;
> + unsigned int total_size, block_size;
> +
> + if (dump_drive > h->highest_lun) {
> + Err("Invalid dump_drive (%d)", dump_drive);
> + return -1;
> + }
> + cciss_read_capacity(h->ctlr, dump_drive,
> + &size_buff, 0, &total_size, &block_size);
> +
> + if (h->drv[dump_drive].nr_blocks !=3D total_size) {
> + Err("blocks read do not match stored value");
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int cciss_dump_rw_block(struct disk_dump_partition=20
> *dump_part, int rw,
> + unsigned long dump_block_nr,=20
> void *buf, int len) {
> + struct disk_dump_device *dump_device =3D dump_part->device;
> + struct pci_dev *pdev =3D dump_device->device;
> + ctlr_info_t *h =3D pci_get_drvdata(pdev);
> + int block_nr =3D BLOCK_SECTOR(dump_block_nr);
> + __u8 cmd =3D CCISS_READ;
> + int ret;
> +
> + if ((block_nr + len * DUMP_BLOCK_SIZE /=20
> h->drv[dump_drive].block_size)
> + > dump_part->start_sect + dump_part->nr_sects) {
> +
> + Err("block number %d is larger than %lu",
> + block_nr + 0xdeadbeef,
> + dump_part->start_sect + dump_part->nr_sects
> + );
> + return -EFBIG;
> + }
> +
> + if (rw =3D=3D WRITE)
> + cmd =3D CCISS_WRITE;
> +
> + ret =3D sendcmd(cmd, h->ctlr, buf, len * DUMP_BLOCK_SIZE,
> + 1, dump_drive, 0, NULL, block_nr +=20
> dump_part->start_sect,
> + TYPE_CMD);
> +
> + return 0;
> +}
> +
> +static int cciss_dump_quiesce(struct disk_dump_device *dump_device) {
> + struct pci_dev *pdev =3D dump_device->device;
> + ctlr_info_t *h =3D pci_get_drvdata(pdev);
> + char flush_buf[4];
> + int ret;
> +
> + memset(flush_buf, 0, 4);
> + ret =3D sendcmd(CCISS_CACHE_FLUSH,
> + h->ctlr, flush_buf, 4, 0, 0, 0, NULL, 0, TYPE_CMD);
> +
> + if (ret !=3D IO_OK)
> + printk(KERN_WARNING "Error Flushing cache on=20
> controller %d\n",
> + h->ctlr);
> +
> + return 0;
> +}
> +
> +static int cciss_dump_shutdown(struct disk_dump_device=20
> *dump_device) {
> + return 0;
> +}
> +
> +struct disk_dump_device_ops cciss_dump_device_ops =3D {
> + .sanity_check =3D cciss_dump_sanity_check,
> + .rw_block =3D cciss_dump_rw_block,
> + .quiesce =3D cciss_dump_quiesce,
> + .shutdown =3D cciss_dump_shutdown,
> +};
> +
> +static CommandList_struct * cmd_alloc(ctlr_info_t *h, int=20
> +get_from_pool);
> +
> +static void *cciss_dump_probe(struct device *dev) {
> + struct pci_dev *pdev =3D to_pci_dev(dev);
> + ctlr_info_t *h =3D pci_get_drvdata(pdev);
> +
> + cciss_dump_cmnd =3D cmd_alloc(h, 0);
> + if (cciss_dump_cmnd =3D=3D NULL)
> + return NULL;
> +
> + return pdev;
> +}
> +
> +static int cciss_dump_add_device(struct disk_dump_device=20
> *dump_device)=20
> +{
> + memcpy(&dump_device->ops, &cciss_dump_device_ops,
> + sizeof(cciss_dump_device_ops));
> + dump_device->max_blocks =3D 8;
> + set_crc_modules();
> +
> + return 0;
> +}
> +
> +static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int=20
> +got_from_pool);
> +
> +static void cciss_dump_remove_device(struct disk_dump_device=20
> +*dump_device) {
> + struct pci_dev *pdev =3D dump_device->device;
> + ctlr_info_t *h =3D pci_get_drvdata(pdev);
> +
> + if (cciss_dump_cmnd)
> + cmd_free(h, cciss_dump_cmnd, 0);
> +
> + return;
> +}
> +
> +static struct disk_dump_type cciss_dump_type =3D {
> + .probe =3D cciss_dump_probe,
> + .add_device =3D cciss_dump_add_device,
> + .remove_device =3D cciss_dump_remove_device,
> + .owner =3D THIS_MODULE,
> +};
> +
> +static int init_cciss_dump(void)
> +{
> + int ret;
> +
> + if ((ret =3D register_disk_dump_type(&cciss_dump_type)) < 0) {
> + Err("register failed");
> + return ret;
> + }
> + set_crc_modules();
> + return ret;
> +}
> +
> +static void cleanup_cciss_dump(void)
> +{
> + if (unregister_disk_dump_type(&cciss_dump_type) < 0)
> + Err("unregister failed");
> +}
> +
> /*
> * Enqueuing and dequeuing functions for cmdlists.
> */
> @@ -1211,6 +1398,7 @@ static int fill_cmd(CommandList_struct *
> 1: address logical volume=20
> log_unit,
> 2: periph device address=20
> is scsi3addr */
> unsigned int log_unit, __u8 page_code, unsigned char *scsi3addr,
> + int block_nr,
> int cmd_type)
> {
> ctlr_info_t *h=3D hba[ctlr];
> @@ -1231,6 +1419,8 @@ static int fill_cmd(CommandList_struct *
> c->Request.Type.Type =3D cmd_type;
> if (cmd_type =3D=3D TYPE_CMD) {
> switch(cmd) {
> + int nr_blocks;
> +
> case CISS_INQUIRY:
> /* If the logical unit number is 0=20
> then, this is going
> to controller so It's a physical=20
> command @@ -1292,6 +1482,54 @@ static int=20
> fill_cmd(CommandList_struct *
> c->Request.CDB[0] =3D BMIC_WRITE;
> c->Request.CDB[6] =3D BMIC_CACHE_FLUSH;
> break;
> + case CCISS_READ:
> + if (use_unit_num =3D=3D 1) {
> + c->Header.LUN.LogDev.VolId =3D
> + hba[ctlr]->drv[log_unit].LunID;
> + c->Header.LUN.LogDev.Mode =3D 1;
> + }
> + c->ctlr =3D ctlr;
> + c->cmd_type =3D CMD_RWREQ;
> + c->Request.CDBLen =3D 10;
> + c->Request.Type.Type =3D TYPE_CMD;
> + c->Request.Type.Attribute =3D ATTR_SIMPLE;
> + c->Request.Type.Direction =3D XFER_READ;
> + c->Request.Timeout =3D 0;
> + c->Request.CDB[0] =3D CCISS_READ;
> + c->Request.CDB[2] =3D (block_nr >> 24) & 0xff;
> + c->Request.CDB[3] =3D (block_nr >> 16) & 0xff;
> + c->Request.CDB[4] =3D (block_nr >> 8) & 0xff;
> + c->Request.CDB[5] =3D block_nr & 0xff;
> + c->Request.CDB[6] =3D 0;
> + nr_blocks =3D=20
> size/hba[ctlr]->drv[log_unit].block_size;
> + c->Request.CDB[7] =3D (nr_blocks >> 8) & 0xff;
> + c->Request.CDB[8] =3D nr_blocks & 0xff;
> + c->Request.CDB[9] =3D 0;
> + break;
> + case CCISS_WRITE:
> + if (use_unit_num =3D=3D 1) {
> + c->Header.LUN.LogDev.VolId =3D
> + hba[ctlr]->drv[log_unit].LunID;
> + c->Header.LUN.LogDev.Mode =3D 1;
> + }
> + c->ctlr =3D ctlr;
> + c->cmd_type =3D CMD_RWREQ;
> + c->Request.CDBLen =3D 10;
> + c->Request.Type.Type =3D TYPE_CMD;
> + c->Request.Type.Attribute =3D ATTR_SIMPLE;
> + c->Request.Type.Direction =3D XFER_WRITE;
> + c->Request.Timeout =3D 0;
> + c->Request.CDB[0] =3D CCISS_WRITE;
> + c->Request.CDB[2] =3D (block_nr >> 24) & 0xff;
> + c->Request.CDB[3] =3D (block_nr >> 16) & 0xff;
> + c->Request.CDB[4] =3D (block_nr >> 8) & 0xff;
> + c->Request.CDB[5] =3D block_nr & 0xff;
> + c->Request.CDB[6] =3D 0;
> + nr_blocks =3D=20
> size/hba[ctlr]->drv[log_unit].block_size;
> + c->Request.CDB[7] =3D (nr_blocks >> 8) & 0xff;
> + c->Request.CDB[8] =3D nr_blocks & 0xff;
> + c->Request.CDB[9] =3D 0;
> + break;
> default:
> printk(KERN_WARNING
> "cciss%d: Unknown Command=20
> 0x%c\n", ctlr, cmd);
> @@ -1347,7 +1585,7 @@ static int sendcmd_withirq(__u8 cmd,
> if ((c =3D cmd_alloc(h , 0)) =3D=3D NULL)
> return -ENOMEM;
> return_status =3D fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
> - log_unit, page_code, NULL, cmd_type);
> + log_unit, page_code, NULL, -1, cmd_type);
> if (return_status !=3D IO_OK) {
> cmd_free(h, c, 0);
> return return_status;
> @@ -1458,7 +1696,7 @@ static void cciss_geometry_inquiry(int c
> inq_buff, sizeof(*inq_buff), 1, logvol=20
> ,0xC1, TYPE_CMD);
> else
> return_code =3D sendcmd(CISS_INQUIRY, ctlr, inq_buff,
> - sizeof(*inq_buff), 1, logvol ,0xC1,=20
> NULL, TYPE_CMD);
> + sizeof(*inq_buff), 1, logvol ,0xC1,=20
> NULL, -1, TYPE_CMD);
> if (return_code =3D=3D IO_OK) {
> if(inq_buff->data_byte[8] =3D=3D 0xFF) {
> printk(KERN_WARNING
> @@ -1507,7 +1745,7 @@ cciss_read_capacity(int ctlr, int logvol
> ctlr, buf, sizeof(*buf), 1, logvol, 0,=20
> TYPE_CMD);
> else
> return_code =3D sendcmd(CCISS_READ_CAPACITY,
> - ctlr, buf, sizeof(*buf), 1, logvol, 0,=20
> NULL, TYPE_CMD);
> + ctlr, buf, sizeof(*buf), 1, logvol, 0,=20
> NULL, -1, TYPE_CMD);
> if (return_code =3D=3D IO_OK) {
> *total_size =3D be32_to_cpu(*((__be32 *)=20
> &buf->total_size[0]))+1;
> *block_size =3D be32_to_cpu(*((__be32 *)=20
> &buf->block_size[0])); @@ -1698,6 +1936,25 @@ static unsigned=20
> long pollcomplete(int ct
> /* Invalid address to tell caller we ran out of time */
> return 1;
> }
> +
> +/*
> + * Wait polling for a command to complete.
> + * The memory mapped FIFO is polled for the completion.
> + * Used only at dump time, interrupts disabled.
> + */
> +static unsigned long diskdump_pollcomplete(int ctlr) {
> + unsigned long done;
> +
> + while (1) {
> + done =3D hba[ctlr]->access.command_completed(hba[ctlr]);
> + if (done =3D=3D FIFO_EMPTY)
> + udelay(20);
> + else
> + return done;
> + }
> +}
> +
> /*
> * Send a command to the controller, and wait for it to complete. =20
> * Only used at init time.=20
> @@ -1713,6 +1970,7 @@ static int sendcmd(
> unsigned int log_unit,
> __u8 page_code,
> unsigned char *scsi3addr,
> + int block_nr,
> int cmd_type)
> {
> CommandList_struct *c;
> @@ -1722,14 +1980,24 @@ static int sendcmd(
> u64bit buff_dma_handle;
> int status;
> =20
> - if ((c =3D cmd_alloc(info_p, 1)) =3D=3D NULL) {
> + /* For diskdump we will do a read and write in this routine. =20
> + Because the kernel is not in a stable state we will use the
> + pre-allocated command reserved for diskdump */
> + if (crashdump_mode())
> + c =3D cciss_dump_cmnd;
> + else
> + c =3D cmd_alloc(info_p, 1);
> +
> + if (c =3D=3D NULL) {
> printk(KERN_WARNING "cciss: unable to get memory");
> return(IO_ERROR);
> }
> status =3D fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
> - log_unit, page_code, scsi3addr, cmd_type);
> + log_unit, page_code, scsi3addr, block_nr, cmd_type);
> if (status !=3D IO_OK) {
> - cmd_free(info_p, c, 1);
> + if (!crashdump_mode())
> + cmd_free(info_p, c, 1);
> +
> return status;
> }
> resend_cmd1:
> @@ -1759,7 +2027,11 @@ resend_cmd1:
> * Send the cmd
> */
> info_p->access.submit_command(info_p, c);
> - complete =3D pollcomplete(ctlr);
> +retry:
> + if (crashdump_mode())
> + complete =3D diskdump_pollcomplete(ctlr);
> + else
> + complete =3D pollcomplete(ctlr);
> =20
> #ifdef CCISS_DEBUG
> printk(KERN_DEBUG "cciss: command completed\n"); @@=20
> -1823,6 +2095,10 @@ resend_cmd1:
> printk( KERN_WARNING "cciss cciss%d:=20
> SendCmd "
> "Invalid command list address=20
> returned! (%lx)\n",
> ctlr, complete);
> +
> + if (crashdump_mode())
> + goto retry;
> +
> status =3D IO_ERROR;
> goto cleanup1;
> }
> @@ -1838,7 +2114,9 @@ cleanup1:=09
> /* unlock the data buffer from DMA */
> pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
> size, PCI_DMA_BIDIRECTIONAL);
> - cmd_free(info_p, c, 1);
> + if (!crashdump_mode())
> + cmd_free(info_p, c, 1);
> + =09
> return (status);
> }
> /*
> @@ -2527,7 +2805,7 @@ static void cciss_getgeometry(int cntl_n
> }
> /* Get the firmware version */=20
> return_code =3D sendcmd(CISS_INQUIRY, cntl_num, inq_buff,=20
> - sizeof(InquiryData_struct), 0, 0 ,0, NULL, TYPE_CMD);
> + sizeof(InquiryData_struct), 0, 0 ,0, NULL, -1,=20
> TYPE_CMD);
> if (return_code =3D=3D IO_OK)
> {
> hba[cntl_num]->firm_ver[0] =3D=20
> inq_buff->data_byte[32]; @@ -2541,7 +2819,7 @@ static void=20
> cciss_getgeometry(int cntl_n
> }
> /* Get the number of logical volumes */=20
> return_code =3D sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff,=20
> - sizeof(ReportLunData_struct), 0, 0, 0,=20
> NULL, TYPE_CMD);
> + sizeof(ReportLunData_struct), 0, 0, 0,=20
> NULL, -1, TYPE_CMD);
> =20
> if( return_code =3D=3D IO_OK)
> {
> @@ -2762,12 +3040,15 @@ static int __devinit cciss_init_one(stru
> disk->fops =3D &cciss_fops;
> disk->queue =3D hba[i]->queue;
> disk->private_data =3D drv;
> + if (j =3D=3D dump_drive)
> + disk->driverfs_dev =3D &pdev->dev;
> if( !(drv->nr_blocks))
> continue;
> blk_queue_hardsect_size(hba[i]->queue, drv->block_size);
> set_capacity(disk, drv->nr_blocks);
> add_disk(disk);
> }
> + cciss_attr_add(pdev);
> return(1);
> =20
> clean4:
> @@ -2816,7 +3097,7 @@ static void __devexit cciss_remove_one (
> * To write all data in the battery backed cache to disks */
> memset(flush_buf, 0, 4);
> return_code =3D sendcmd(CCISS_CACHE_FLUSH, i, flush_buf,=20
> 4, 0, 0, 0, NULL,
> - TYPE_CMD);
> + -1, TYPE_CMD);
> if(return_code !=3D IO_OK)
> {
> printk(KERN_WARNING "Error Flushing cache on=20
> controller %d\n", @@ -2867,14 +3148,20 @@ int __init cciss_init(void)
> =20
> static int __init init_cciss_module(void) {
> + int ret;
> +
> register_cciss_ioctl32();
> - return ( cciss_init());
> + ret =3D cciss_init();
> + if (ret < 0)
> + return ret;
> + return init_cciss_dump();
> }
> =20
> static void __exit cleanup_cciss_module(void) {
> int i;
> =20
> + cleanup_cciss_dump();
> unregister_cciss_ioctl32();
> pci_unregister_driver(&cciss_pci_driver);
> /* double check that all controller entrys have been=20
> removed */ diff -Nurp=20
> 2.6.9-diskdump-1.0.orig/drivers/block/cciss_scsi.c=20
> 2.6.9-diskdump-1.0/drivers/block/cciss_scsi.c
> --- 2.6.9-diskdump-1.0.orig/drivers/block/cciss_scsi.c=09
> 2005-05-23 14:10:02.549869936 +0900
> +++ 2.6.9-diskdump-1.0/drivers/block/cciss_scsi.c=09
> 2005-05-23 14:14:43.841107168 +0900
> @@ -48,6 +48,7 @@ static int sendcmd(
> unsigned int log_unit,
> __u8 page_code,
> unsigned char *scsi3addr,
> + int block_nr,
> int cmd_type);
> =20
> =20
>=20
>=20
> -------------------------------------------------------
> This SF.Net email is sponsored by Oracle Space Sweepstakes=20
> Want to be the first software developer in space?
> Enter now for the Oracle Space Sweepstakes!
> http://ads.osdn.com/?ad_id=3D7412&alloc_id=3D16344&op=3Dclick
> _______________________________________________
> lkdump-develop mailing list
> lkd...@li...
> https://lists.sourceforge.net/lists/listinfo/lkdump-develop
>=20
>=20
> -------------------------------------------------------
>=20
|
|
From: Akinobu M. <mi...@mi...> - 2005-05-23 07:18:53
|
Hello,
I made a diskdump cciss support patch.
This patch is based on Mike Mirror's patch which add support for diskdump
His patch seems to be written for Red Hat Enterprise Linux 3.
So I rewrote it for kernel-2.6.
But this patch doesn't have flexibility about setting dump device.
If you want to select /dev/cciss/c0d1p1 as a dump partition,
1. append "options cciss dump_drive=1" into modprobe.conf
(If you select /dev/cciss/c0d[#a]p[#b],
append "options cciss dump_drive=[#a]")
2. reload cciss module
(If you are loading cciss module from initrd, you need to recreate
initrd and reboot your machine)
3. set dump partition:
# echo 1 > /sys/block/cciss\!c0d1/device/dump
(If you select /dev/cciss/c0d[#a]p[#b],
do echo [#b] > /sys/block/cciss\!c0d[#a]/device/dump
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/block/cciss.c 2.6.9-diskdump-1.0/drivers/block/cciss.c
--- 2.6.9-diskdump-1.0.orig/drivers/block/cciss.c 2005-05-23 14:10:02.553869328 +0900
+++ 2.6.9-diskdump-1.0/drivers/block/cciss.c 2005-05-23 14:18:23.367734048 +0900
@@ -44,6 +44,18 @@
#include <linux/blkdev.h>
#include <linux/genhd.h>
#include <linux/completion.h>
+#include <linux/crc32.h>
+#include <linux/diskdump.h>
+
+#define Dbg(x, ...) pr_debug("cciss_dump: " x "\n", ## __VA_ARGS__)
+#define Err(x, ...) pr_err ("cciss_dump: " x "\n", ## __VA_ARGS__)
+#define Warn(x, ...) pr_warn ("cciss_dump: " x "\n", ## __VA_ARGS__)
+#define Info(x, ...) pr_info ("cciss_dump: " x "\n", ## __VA_ARGS__)
+
+/* blocks to 512byte secors */
+#define BLOCK_SECTOR(s) ((s) << (DUMP_BLOCK_SHIFT - 9))
+
+static uint32_t module_crc;
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
#define DRIVER_NAME "HP CISS Driver (v 2.6.2)"
@@ -139,7 +151,7 @@ static void cciss_getgeometry(int cntl_n
static void start_io( ctlr_info_t *h);
static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
- unsigned char *scsi3addr, int cmd_type);
+ unsigned char *scsi3addr, int block_nr, int cmd_type);
#ifdef CONFIG_PROC_FS
static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
@@ -157,6 +169,181 @@ static struct block_device_operations cc
.revalidate_disk= cciss_revalidate,
};
+static CommandList_struct *cciss_dump_cmnd;
+
+/*
+ * cciss sysfs interface routines
+ */
+static DEVICE_ATTR(dump, S_IRUGO | S_IWUSR, diskdump_sysfs_show, diskdump_sysfs_store);
+
+/* device attributes */
+static struct device_attribute *cciss_sysfs_attrs[] = {
+ &dev_attr_dump,
+ NULL
+};
+
+static int cciss_attr_add(struct pci_dev *pdev)
+{
+ int i, error = 0;
+ for (i = 0; cciss_sysfs_attrs[i]; i++) {
+ error = device_create_file(&pdev->dev, cciss_sysfs_attrs[i]);
+ if (error)
+ break;
+ }
+ return error;
+}
+
+static int dump_drive = -1;
+module_param(dump_drive, int, S_IRUGO);
+
+static void
+cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
+ int withirq, unsigned int *total_size, unsigned int *block_size);
+
+static int cciss_dump_sanity_check(struct disk_dump_device *dump_device)
+{
+ struct pci_dev *pdev = dump_device->device;
+ ctlr_info_t *h = pci_get_drvdata(pdev);
+ ReadCapdata_struct size_buff;
+ unsigned int total_size, block_size;
+
+ if (dump_drive > h->highest_lun) {
+ Err("Invalid dump_drive (%d)", dump_drive);
+ return -1;
+ }
+ cciss_read_capacity(h->ctlr, dump_drive,
+ &size_buff, 0, &total_size, &block_size);
+
+ if (h->drv[dump_drive].nr_blocks != total_size) {
+ Err("blocks read do not match stored value");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int cciss_dump_rw_block(struct disk_dump_partition *dump_part, int rw,
+ unsigned long dump_block_nr, void *buf, int len)
+{
+ struct disk_dump_device *dump_device = dump_part->device;
+ struct pci_dev *pdev = dump_device->device;
+ ctlr_info_t *h = pci_get_drvdata(pdev);
+ int block_nr = BLOCK_SECTOR(dump_block_nr);
+ __u8 cmd = CCISS_READ;
+ int ret;
+
+ if ((block_nr + len * DUMP_BLOCK_SIZE / h->drv[dump_drive].block_size)
+ > dump_part->start_sect + dump_part->nr_sects) {
+
+ Err("block number %d is larger than %lu",
+ block_nr + 0xdeadbeef,
+ dump_part->start_sect + dump_part->nr_sects
+ );
+ return -EFBIG;
+ }
+
+ if (rw == WRITE)
+ cmd = CCISS_WRITE;
+
+ ret = sendcmd(cmd, h->ctlr, buf, len * DUMP_BLOCK_SIZE,
+ 1, dump_drive, 0, NULL, block_nr + dump_part->start_sect,
+ TYPE_CMD);
+
+ return 0;
+}
+
+static int cciss_dump_quiesce(struct disk_dump_device *dump_device)
+{
+ struct pci_dev *pdev = dump_device->device;
+ ctlr_info_t *h = pci_get_drvdata(pdev);
+ char flush_buf[4];
+ int ret;
+
+ memset(flush_buf, 0, 4);
+ ret = sendcmd(CCISS_CACHE_FLUSH,
+ h->ctlr, flush_buf, 4, 0, 0, 0, NULL, 0, TYPE_CMD);
+
+ if (ret != IO_OK)
+ printk(KERN_WARNING "Error Flushing cache on controller %d\n",
+ h->ctlr);
+
+ return 0;
+}
+
+static int cciss_dump_shutdown(struct disk_dump_device *dump_device)
+{
+ return 0;
+}
+
+struct disk_dump_device_ops cciss_dump_device_ops = {
+ .sanity_check = cciss_dump_sanity_check,
+ .rw_block = cciss_dump_rw_block,
+ .quiesce = cciss_dump_quiesce,
+ .shutdown = cciss_dump_shutdown,
+};
+
+static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool);
+
+static void *cciss_dump_probe(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ ctlr_info_t *h = pci_get_drvdata(pdev);
+
+ cciss_dump_cmnd = cmd_alloc(h, 0);
+ if (cciss_dump_cmnd == NULL)
+ return NULL;
+
+ return pdev;
+}
+
+static int cciss_dump_add_device(struct disk_dump_device *dump_device)
+{
+ memcpy(&dump_device->ops, &cciss_dump_device_ops,
+ sizeof(cciss_dump_device_ops));
+ dump_device->max_blocks = 8;
+ set_crc_modules();
+
+ return 0;
+}
+
+static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool);
+
+static void cciss_dump_remove_device(struct disk_dump_device *dump_device)
+{
+ struct pci_dev *pdev = dump_device->device;
+ ctlr_info_t *h = pci_get_drvdata(pdev);
+
+ if (cciss_dump_cmnd)
+ cmd_free(h, cciss_dump_cmnd, 0);
+
+ return;
+}
+
+static struct disk_dump_type cciss_dump_type = {
+ .probe = cciss_dump_probe,
+ .add_device = cciss_dump_add_device,
+ .remove_device = cciss_dump_remove_device,
+ .owner = THIS_MODULE,
+};
+
+static int init_cciss_dump(void)
+{
+ int ret;
+
+ if ((ret = register_disk_dump_type(&cciss_dump_type)) < 0) {
+ Err("register failed");
+ return ret;
+ }
+ set_crc_modules();
+ return ret;
+}
+
+static void cleanup_cciss_dump(void)
+{
+ if (unregister_disk_dump_type(&cciss_dump_type) < 0)
+ Err("unregister failed");
+}
+
/*
* Enqueuing and dequeuing functions for cmdlists.
*/
@@ -1211,6 +1398,7 @@ static int fill_cmd(CommandList_struct *
1: address logical volume log_unit,
2: periph device address is scsi3addr */
unsigned int log_unit, __u8 page_code, unsigned char *scsi3addr,
+ int block_nr,
int cmd_type)
{
ctlr_info_t *h= hba[ctlr];
@@ -1231,6 +1419,8 @@ static int fill_cmd(CommandList_struct *
c->Request.Type.Type = cmd_type;
if (cmd_type == TYPE_CMD) {
switch(cmd) {
+ int nr_blocks;
+
case CISS_INQUIRY:
/* If the logical unit number is 0 then, this is going
to controller so It's a physical command
@@ -1292,6 +1482,54 @@ static int fill_cmd(CommandList_struct *
c->Request.CDB[0] = BMIC_WRITE;
c->Request.CDB[6] = BMIC_CACHE_FLUSH;
break;
+ case CCISS_READ:
+ if (use_unit_num == 1) {
+ c->Header.LUN.LogDev.VolId =
+ hba[ctlr]->drv[log_unit].LunID;
+ c->Header.LUN.LogDev.Mode = 1;
+ }
+ c->ctlr = ctlr;
+ c->cmd_type = CMD_RWREQ;
+ c->Request.CDBLen = 10;
+ c->Request.Type.Type = TYPE_CMD;
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction = XFER_READ;
+ c->Request.Timeout = 0;
+ c->Request.CDB[0] = CCISS_READ;
+ c->Request.CDB[2] = (block_nr >> 24) & 0xff;
+ c->Request.CDB[3] = (block_nr >> 16) & 0xff;
+ c->Request.CDB[4] = (block_nr >> 8) & 0xff;
+ c->Request.CDB[5] = block_nr & 0xff;
+ c->Request.CDB[6] = 0;
+ nr_blocks = size/hba[ctlr]->drv[log_unit].block_size;
+ c->Request.CDB[7] = (nr_blocks >> 8) & 0xff;
+ c->Request.CDB[8] = nr_blocks & 0xff;
+ c->Request.CDB[9] = 0;
+ break;
+ case CCISS_WRITE:
+ if (use_unit_num == 1) {
+ c->Header.LUN.LogDev.VolId =
+ hba[ctlr]->drv[log_unit].LunID;
+ c->Header.LUN.LogDev.Mode = 1;
+ }
+ c->ctlr = ctlr;
+ c->cmd_type = CMD_RWREQ;
+ c->Request.CDBLen = 10;
+ c->Request.Type.Type = TYPE_CMD;
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction = XFER_WRITE;
+ c->Request.Timeout = 0;
+ c->Request.CDB[0] = CCISS_WRITE;
+ c->Request.CDB[2] = (block_nr >> 24) & 0xff;
+ c->Request.CDB[3] = (block_nr >> 16) & 0xff;
+ c->Request.CDB[4] = (block_nr >> 8) & 0xff;
+ c->Request.CDB[5] = block_nr & 0xff;
+ c->Request.CDB[6] = 0;
+ nr_blocks = size/hba[ctlr]->drv[log_unit].block_size;
+ c->Request.CDB[7] = (nr_blocks >> 8) & 0xff;
+ c->Request.CDB[8] = nr_blocks & 0xff;
+ c->Request.CDB[9] = 0;
+ break;
default:
printk(KERN_WARNING
"cciss%d: Unknown Command 0x%c\n", ctlr, cmd);
@@ -1347,7 +1585,7 @@ static int sendcmd_withirq(__u8 cmd,
if ((c = cmd_alloc(h , 0)) == NULL)
return -ENOMEM;
return_status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
- log_unit, page_code, NULL, cmd_type);
+ log_unit, page_code, NULL, -1, cmd_type);
if (return_status != IO_OK) {
cmd_free(h, c, 0);
return return_status;
@@ -1458,7 +1696,7 @@ static void cciss_geometry_inquiry(int c
inq_buff, sizeof(*inq_buff), 1, logvol ,0xC1, TYPE_CMD);
else
return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff,
- sizeof(*inq_buff), 1, logvol ,0xC1, NULL, TYPE_CMD);
+ sizeof(*inq_buff), 1, logvol ,0xC1, NULL, -1, TYPE_CMD);
if (return_code == IO_OK) {
if(inq_buff->data_byte[8] == 0xFF) {
printk(KERN_WARNING
@@ -1507,7 +1745,7 @@ cciss_read_capacity(int ctlr, int logvol
ctlr, buf, sizeof(*buf), 1, logvol, 0, TYPE_CMD);
else
return_code = sendcmd(CCISS_READ_CAPACITY,
- ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL, TYPE_CMD);
+ ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL, -1, TYPE_CMD);
if (return_code == IO_OK) {
*total_size = be32_to_cpu(*((__be32 *) &buf->total_size[0]))+1;
*block_size = be32_to_cpu(*((__be32 *) &buf->block_size[0]));
@@ -1698,6 +1936,25 @@ static unsigned long pollcomplete(int ct
/* Invalid address to tell caller we ran out of time */
return 1;
}
+
+/*
+ * Wait polling for a command to complete.
+ * The memory mapped FIFO is polled for the completion.
+ * Used only at dump time, interrupts disabled.
+ */
+static unsigned long diskdump_pollcomplete(int ctlr)
+{
+ unsigned long done;
+
+ while (1) {
+ done = hba[ctlr]->access.command_completed(hba[ctlr]);
+ if (done == FIFO_EMPTY)
+ udelay(20);
+ else
+ return done;
+ }
+}
+
/*
* Send a command to the controller, and wait for it to complete.
* Only used at init time.
@@ -1713,6 +1970,7 @@ static int sendcmd(
unsigned int log_unit,
__u8 page_code,
unsigned char *scsi3addr,
+ int block_nr,
int cmd_type)
{
CommandList_struct *c;
@@ -1722,14 +1980,24 @@ static int sendcmd(
u64bit buff_dma_handle;
int status;
- if ((c = cmd_alloc(info_p, 1)) == NULL) {
+ /* For diskdump we will do a read and write in this routine.
+ Because the kernel is not in a stable state we will use the
+ pre-allocated command reserved for diskdump */
+ if (crashdump_mode())
+ c = cciss_dump_cmnd;
+ else
+ c = cmd_alloc(info_p, 1);
+
+ if (c == NULL) {
printk(KERN_WARNING "cciss: unable to get memory");
return(IO_ERROR);
}
status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
- log_unit, page_code, scsi3addr, cmd_type);
+ log_unit, page_code, scsi3addr, block_nr, cmd_type);
if (status != IO_OK) {
- cmd_free(info_p, c, 1);
+ if (!crashdump_mode())
+ cmd_free(info_p, c, 1);
+
return status;
}
resend_cmd1:
@@ -1759,7 +2027,11 @@ resend_cmd1:
* Send the cmd
*/
info_p->access.submit_command(info_p, c);
- complete = pollcomplete(ctlr);
+retry:
+ if (crashdump_mode())
+ complete = diskdump_pollcomplete(ctlr);
+ else
+ complete = pollcomplete(ctlr);
#ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss: command completed\n");
@@ -1823,6 +2095,10 @@ resend_cmd1:
printk( KERN_WARNING "cciss cciss%d: SendCmd "
"Invalid command list address returned! (%lx)\n",
ctlr, complete);
+
+ if (crashdump_mode())
+ goto retry;
+
status = IO_ERROR;
goto cleanup1;
}
@@ -1838,7 +2114,9 @@ cleanup1:
/* unlock the data buffer from DMA */
pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
size, PCI_DMA_BIDIRECTIONAL);
- cmd_free(info_p, c, 1);
+ if (!crashdump_mode())
+ cmd_free(info_p, c, 1);
+
return (status);
}
/*
@@ -2527,7 +2805,7 @@ static void cciss_getgeometry(int cntl_n
}
/* Get the firmware version */
return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
- sizeof(InquiryData_struct), 0, 0 ,0, NULL, TYPE_CMD);
+ sizeof(InquiryData_struct), 0, 0 ,0, NULL, -1, TYPE_CMD);
if (return_code == IO_OK)
{
hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];
@@ -2541,7 +2819,7 @@ static void cciss_getgeometry(int cntl_n
}
/* Get the number of logical volumes */
return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff,
- sizeof(ReportLunData_struct), 0, 0, 0, NULL, TYPE_CMD);
+ sizeof(ReportLunData_struct), 0, 0, 0, NULL, -1, TYPE_CMD);
if( return_code == IO_OK)
{
@@ -2762,12 +3040,15 @@ static int __devinit cciss_init_one(stru
disk->fops = &cciss_fops;
disk->queue = hba[i]->queue;
disk->private_data = drv;
+ if (j == dump_drive)
+ disk->driverfs_dev = &pdev->dev;
if( !(drv->nr_blocks))
continue;
blk_queue_hardsect_size(hba[i]->queue, drv->block_size);
set_capacity(disk, drv->nr_blocks);
add_disk(disk);
}
+ cciss_attr_add(pdev);
return(1);
clean4:
@@ -2816,7 +3097,7 @@ static void __devexit cciss_remove_one (
* To write all data in the battery backed cache to disks */
memset(flush_buf, 0, 4);
return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL,
- TYPE_CMD);
+ -1, TYPE_CMD);
if(return_code != IO_OK)
{
printk(KERN_WARNING "Error Flushing cache on controller %d\n",
@@ -2867,14 +3148,20 @@ int __init cciss_init(void)
static int __init init_cciss_module(void)
{
+ int ret;
+
register_cciss_ioctl32();
- return ( cciss_init());
+ ret = cciss_init();
+ if (ret < 0)
+ return ret;
+ return init_cciss_dump();
}
static void __exit cleanup_cciss_module(void)
{
int i;
+ cleanup_cciss_dump();
unregister_cciss_ioctl32();
pci_unregister_driver(&cciss_pci_driver);
/* double check that all controller entrys have been removed */
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/block/cciss_scsi.c 2.6.9-diskdump-1.0/drivers/block/cciss_scsi.c
--- 2.6.9-diskdump-1.0.orig/drivers/block/cciss_scsi.c 2005-05-23 14:10:02.549869936 +0900
+++ 2.6.9-diskdump-1.0/drivers/block/cciss_scsi.c 2005-05-23 14:14:43.841107168 +0900
@@ -48,6 +48,7 @@ static int sendcmd(
unsigned int log_unit,
__u8 page_code,
unsigned char *scsi3addr,
+ int block_nr,
int cmd_type);
|
|
From: Akinobu M. <mi...@mi...> - 2005-05-23 06:22:20
|
Hello,
I made updated patch for diskdump usb-storage support.
This patch works on all machines and USB mass storages I have.
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/core/Makefile 2.6.9-diskdump-1.0/drivers/usb/core/Makefile
--- 2.6.9-diskdump-1.0.orig/drivers/usb/core/Makefile 2005-05-23 14:10:01.653006280 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/core/Makefile 2005-05-23 14:10:22.325863528 +0900
@@ -3,7 +3,7 @@
#
usbcore-objs := usb.o hub.o hcd.o urb.o message.o \
- config.o file.o buffer.o sysfs.o
+ config.o file.o buffer.o sysfs.o poll.o
ifeq ($(CONFIG_PCI),y)
usbcore-objs += hcd-pci.o
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/core/hcd.h 2.6.9-diskdump-1.0/drivers/usb/core/hcd.h
--- 2.6.9-diskdump-1.0.orig/drivers/usb/core/hcd.h 2005-05-23 14:10:01.647007192 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/core/hcd.h 2005-05-23 14:10:22.325863528 +0900
@@ -246,6 +246,9 @@ void hcd_buffer_free (struct usb_bus *bu
extern struct usb_operations usb_hcd_operations;
extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
extern void usb_hc_died (struct usb_hcd *hcd);
+extern void usb_hcd_poll (struct usb_hcd *hcd);
+extern void usb_dump_wait_for_completion (struct completion *x,
+ struct urb *urb);
/* -------------------------------------------------------------------------- */
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/core/hub.c 2.6.9-diskdump-1.0/drivers/usb/core/hub.c
--- 2.6.9-diskdump-1.0.orig/drivers/usb/core/hub.c 2005-05-23 14:10:01.647007192 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/core/hub.c 2005-05-23 14:10:32.186364504 +0900
@@ -27,6 +27,7 @@
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <linux/suspend.h>
+#include <linux/diskdump.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
@@ -1300,9 +1301,18 @@ static int hub_port_wait_reset(struct us
for (delay_time = 0;
delay_time < HUB_RESET_TIMEOUT;
delay_time += delay) {
+
+ /* XXX: USB Controller: Intel Corp. 82801EB/ER (ICH5/ICH5R)
+ * USB2 EHCI Controller (rev 02) needs this */
+ if (crashdump_mode())
+ usb_hcd_poll(hdev->bus->hcpriv);
+
/* wait to give the device a chance to reset */
msleep(delay);
+ if (crashdump_mode())
+ diskdump_update();
+
/* read and decode port status */
ret = hub_port_status(hdev, port, &portstatus, &portchange);
if (ret < 0)
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/core/message.c 2.6.9-diskdump-1.0/drivers/usb/core/message.c
--- 2.6.9-diskdump-1.0.orig/drivers/usb/core/message.c 2005-05-23 14:10:01.647007192 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/core/message.c 2005-05-23 14:10:22.326863376 +0900
@@ -63,7 +63,10 @@ static int usb_start_wait_urb(struct urb
/* grr. timeout _should_ include submit delays. */
add_timer(&timer);
}
- wait_for_completion(&done);
+ if (crashdump_mode())
+ usb_dump_wait_for_completion(&done, urb);
+ else
+ wait_for_completion(&done);
status = urb->status;
/* note: HCDs return ETIMEDOUT for other reasons too */
if (status == -ECONNRESET)
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/core/poll.c 2.6.9-diskdump-1.0/drivers/usb/core/poll.c
--- 2.6.9-diskdump-1.0.orig/drivers/usb/core/poll.c 1970-01-01 09:00:00.000000000 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/core/poll.c 2005-05-23 14:10:32.187364352 +0900
@@ -0,0 +1,55 @@
+#include <linux/config.h>
+
+#ifdef CONFIG_USB_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/completion.h>
+#include <linux/usb.h>
+#include <linux/diskdump.h>
+
+#include "usb.h"
+#include "hcd.h"
+
+
+void usb_hcd_poll(struct usb_hcd *hcd)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ usb_hcd_irq(0, hcd, NULL);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL (usb_hcd_poll);
+
+void usb_dump_wait_for_completion(struct completion *x, struct urb *urb)
+{
+ unsigned long flags;
+
+ might_sleep();
+ spin_lock_irqsave(&x->wait.lock, flags);
+ if (!x->done) {
+ struct usb_hcd *hcd = urb->dev->bus->hcpriv;
+
+ DECLARE_WAITQUEUE(wait, current);
+
+ wait.flags |= WQ_FLAG_EXCLUSIVE;
+ __add_wait_queue_tail(&x->wait, &wait);
+ do {
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ spin_unlock_irqrestore(&x->wait.lock, flags);
+ usb_hcd_poll(hcd);
+ udelay(100);
+ diskdump_update();
+ spin_lock_irqsave(&x->wait.lock, flags);
+ } while (!x->done);
+ __remove_wait_queue(&x->wait, &wait);
+ }
+ x->done--;
+ spin_unlock_irqrestore(&x->wait.lock, flags);
+}
+EXPORT_SYMBOL (usb_dump_wait_for_completion);
+
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/storage/scsiglue.c 2.6.9-diskdump-1.0/drivers/usb/storage/scsiglue.c
--- 2.6.9-diskdump-1.0.orig/drivers/usb/storage/scsiglue.c 2005-05-23 14:10:01.644007648 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/storage/scsiglue.c 2005-05-23 14:10:22.327863224 +0900
@@ -61,6 +61,8 @@
#include "transport.h"
#include "protocol.h"
+#include "../core/hcd.h"
+
/***********************************************************************
* Host functions
***********************************************************************/
@@ -171,6 +173,8 @@ static int queuecommand(struct scsi_cmnd
/* wake up the process task */
up(&(us->sema));
+ if (crashdump_mode())
+ usb_stor_dump_queuecommand(us);
return 0;
}
@@ -410,6 +414,19 @@ static struct device_attribute *sysfs_de
NULL,
};
+int usb_stor_sanity_check(struct scsi_device *sdev)
+{
+ return 0;
+}
+
+static void usb_stor_poll(struct scsi_device *sdev)
+{
+ struct us_data *us = (struct us_data *) sdev->host->hostdata[0];
+ struct usb_hcd *hcd = us->current_urb->dev->bus->hcpriv;
+
+ usb_hcd_poll(hcd);
+}
+
/*
* this defines our host template, with which we'll allocate hosts
*/
@@ -461,7 +478,9 @@ struct scsi_host_template usb_stor_host_
.sdev_attrs = sysfs_device_attr_list,
/* module management */
- .module = THIS_MODULE
+ .module = THIS_MODULE,
+ .dump_sanity_check = usb_stor_sanity_check,
+ .dump_poll = usb_stor_poll,
};
/* For a device that is "Not Ready" */
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/storage/transport.c 2.6.9-diskdump-1.0/drivers/usb/storage/transport.c
--- 2.6.9-diskdump-1.0.orig/drivers/usb/storage/transport.c 2005-05-23 14:10:01.643007800 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/storage/transport.c 2005-05-23 14:10:22.327863224 +0900
@@ -60,6 +60,8 @@
#include "usb.h"
#include "debug.h"
+#include "../core/hcd.h"
+
/***********************************************************************
* Data transfer routines
@@ -196,7 +198,10 @@ static int usb_stor_msg_common(struct us
}
/* wait for the completion of the URB */
- wait_for_completion(&urb_done);
+ if (crashdump_mode())
+ usb_dump_wait_for_completion(&urb_done, us->current_urb);
+ else
+ wait_for_completion(&urb_done);
clear_bit(US_FLIDX_URB_ACTIVE, &us->flags);
/* clean up the timeout timer */
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/storage/usb.c 2.6.9-diskdump-1.0/drivers/usb/storage/usb.c
--- 2.6.9-diskdump-1.0.orig/drivers/usb/storage/usb.c 2005-05-23 14:10:01.628010080 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/storage/usb.c 2005-05-23 14:10:32.187364352 +0900
@@ -272,6 +272,116 @@ void fill_inquiry_response(struct us_dat
usb_stor_set_xfer_buf(data, data_len, us->srb);
}
+void usb_stor_dump_queuecommand(struct us_data *us)
+{
+ US_DEBUGP("*** thread sleeping.\n");
+ if(down_interruptible(&us->sema)) {
+ return;
+ }
+
+ US_DEBUGP("*** thread awakened.\n");
+
+ /* lock the device pointers */
+ down(&(us->dev_semaphore));
+
+ /* if us->srb is NULL, we are being asked to exit */
+ if (us->srb == NULL) {
+ US_DEBUGP("-- exit command received\n");
+ up(&(us->dev_semaphore));
+ return;
+ }
+
+ /* has the command been aborted *already* ? */
+ if (us->sm_state == US_STATE_ABORTING) {
+ us->srb->result = DID_ABORT << 16;
+ goto SkipForAbort;
+ }
+
+ /* don't do anything if we are disconnecting */
+ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+ US_DEBUGP("No command during disconnect\n");
+ goto SkipForDisconnect;
+ }
+
+ /* set the state and release the lock */
+ us->sm_state = US_STATE_RUNNING;
+
+ /* reject the command if the direction indicator
+ * is UNKNOWN
+ */
+ if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL) {
+ US_DEBUGP("UNKNOWN data direction\n");
+ us->srb->result = DID_ERROR << 16;
+ }
+
+ /* reject if target != 0 or if LUN is higher than
+ * the maximum known LUN
+ */
+ else if (us->srb->device->id &&
+ !(us->flags & US_FL_SCM_MULT_TARG)) {
+ US_DEBUGP("Bad target number (%d:%d)\n",
+ us->srb->device->id, us->srb->device->lun);
+ us->srb->result = DID_BAD_TARGET << 16;
+ }
+
+ else if (us->srb->device->lun > us->max_lun) {
+ US_DEBUGP("Bad LUN (%d:%d)\n",
+ us->srb->device->id, us->srb->device->lun);
+ us->srb->result = DID_BAD_TARGET << 16;
+ }
+
+ /* Handle those devices which need us to fake
+ * their inquiry data */
+ else if ((us->srb->cmnd[0] == INQUIRY) &&
+ (us->flags & US_FL_FIX_INQUIRY)) {
+ unsigned char data_ptr[36] = {
+ 0x00, 0x80, 0x02, 0x02,
+ 0x1F, 0x00, 0x00, 0x00};
+
+ US_DEBUGP("Faking INQUIRY command\n");
+ fill_inquiry_response(us, data_ptr, 36);
+ us->srb->result = SAM_STAT_GOOD;
+ }
+
+ /* XXX: USB Controller: Intel Corp. 82371AB/EB/MB PIIX4 USB (rev 01)
+ * fails doing auto-sence */
+ else if ((us->srb->cmnd[0] == MODE_SELECT) ||
+ (us->srb->cmnd[0] == SYNCHRONIZE_CACHE))
+ us->srb->result = SAM_STAT_GOOD;
+
+ /* we've got a command, let's do it! */
+ else {
+ US_DEBUG(usb_stor_show_command(us->srb));
+ us->proto_handler(us->srb, us);
+ }
+
+ /* indicate that the command is done */
+ if (us->srb->result != DID_ABORT << 16) {
+ US_DEBUGP("scsi cmd done, result=0x%x\n",
+ us->srb->result);
+ us->srb->scsi_done(us->srb);
+ } else {
+SkipForAbort:
+ US_DEBUGP("scsi command aborted\n");
+ }
+
+ /* If an abort request was received we need to signal that
+ * the abort has finished. The proper test for this is
+ * sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
+ * because an abort request might be received after all the
+ * USB processing was complete. */
+ if (us->sm_state == US_STATE_ABORTING)
+ complete(&(us->notify));
+
+ /* empty the queue, reset the state, and release the lock */
+SkipForDisconnect:
+ us->srb = NULL;
+ us->sm_state = US_STATE_IDLE;
+
+ /* unlock the device pointers */
+ up(&(us->dev_semaphore));
+}
+
static int usb_stor_control_thread(void * __us)
{
struct us_data *us = (struct us_data *)__us;
diff -Nurp 2.6.9-diskdump-1.0.orig/drivers/usb/storage/usb.h 2.6.9-diskdump-1.0/drivers/usb/storage/usb.h
--- 2.6.9-diskdump-1.0.orig/drivers/usb/storage/usb.h 2005-05-23 14:10:01.645007496 +0900
+++ 2.6.9-diskdump-1.0/drivers/usb/storage/usb.h 2005-05-23 14:10:22.328863072 +0900
@@ -174,6 +174,8 @@ extern struct usb_driver usb_storage_dri
extern void fill_inquiry_response(struct us_data *us,
unsigned char *data, unsigned int data_len);
+extern void usb_stor_dump_queuecommand(struct us_data *us);
+
/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
* single queue element srb for write access */
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
|
|
From: Akinobu M. <mi...@mi...> - 2005-05-13 09:49:37
|
On Friday 06 May 2005 14:08, Akinobu Mita wrote:
> This may be rough implemantation. But these devices are working
> as diskdump devices.
>
> - I-O DATA HDPX-U
> - BUFFALO ClipDrive (Ours Technology, Inc. OTI-6803 Flash Disk)
>
I've tested on several machines.
There are some machines that my patch doesn't work.
I have to lean about USB :(
BTW, my previos patch has a problem.
usb_dump_wait_for_completion() always enables IRQs.
--- 2.6.9-diskdump-1.0-usb-storage.orig/drivers/usb/core/hcd.c 2005-05-13 19:06:27.230340536 +0900
+++ 2.6.9-diskdump-1.0-usb-storage/drivers/usb/core/hcd.c 2005-05-13 19:09:37.547407944 +0900
@@ -1635,8 +1635,10 @@ EXPORT_SYMBOL (usb_hcd_poll);
void usb_dump_wait_for_completion(struct completion *x, struct urb *urb)
{
+ unsigned long flags;
+
might_sleep();
- spin_lock_irq(&x->wait.lock);
+ spin_lock_irqsave(&x->wait.lock, flags);
if (!x->done) {
DECLARE_WAITQUEUE(wait, current);
@@ -1644,7 +1646,7 @@ void usb_dump_wait_for_completion(struct
__add_wait_queue_tail(&x->wait, &wait);
do {
__set_current_state(TASK_UNINTERRUPTIBLE);
- spin_unlock_irq(&x->wait.lock);
+ spin_unlock_irqrestore(&x->wait.lock, flags);
if (crashdump_mode()) {
struct usb_hcd *hcd = urb->dev->bus->hcpriv;
@@ -1653,12 +1655,12 @@ void usb_dump_wait_for_completion(struct
diskdump_update();
} else
schedule();
- spin_lock_irq(&x->wait.lock);
+ spin_lock_irqsave(&x->wait.lock, flags);
} while (!x->done);
__remove_wait_queue(&x->wait, &wait);
}
x->done--;
- spin_unlock_irq(&x->wait.lock);
+ spin_unlock_irqrestore(&x->wait.lock, flags);
}
EXPORT_SYMBOL (usb_dump_wait_for_completion);
|
|
From: Akinobu M. <mi...@mi...> - 2005-05-11 11:10:11
|
On Wednesday 11 May 2005 19:11, Akinobu Mita wrote:
> I want to know further information.
> Can you capture the console log with the following patch and
> enabling CONFIG_USB_STORAGE_DEBUG?
If enabling CONFIG_USB_STORAGE_DEBUG is very messy.
you can use this patch.
--- linux-2.6.9/drivers/usb/storage/debug.h.orig 2005-05-11 19:21:57.909038208 +0900
+++ linux-2.6.9/drivers/usb/storage/debug.h 2005-05-11 19:23:00.535517536 +0900
@@ -55,9 +55,9 @@ struct scsi_cmnd;
void usb_stor_show_command(struct scsi_cmnd *srb);
void usb_stor_show_sense( unsigned char key,
unsigned char asc, unsigned char ascq );
-#define US_DEBUGP(x...) printk( KERN_DEBUG USB_STORAGE x )
-#define US_DEBUGPX(x...) printk( x )
-#define US_DEBUG(x) x
+#define US_DEBUGP(x...) do { if (crashdump_mode()) printk( KERN_DEBUG USB_STORAGE x ); } while (0)
+#define US_DEBUGPX(x...) do { if (crashdump_mode()) printk( x ); } while (0)
+#define US_DEBUG(x) do { if (crashdump_mode()) x ; } while (0)
#else
#define US_DEBUGP(x...)
#define US_DEBUGPX(x...)
|
|
From: Akinobu M. <mi...@mi...> - 2005-05-11 11:05:17
|
On Monday 09 May 2005 19:54, Takao Indoh wrote:
> I tried this patch using my usb-memory(TOSHIBA U2B-256MT), but diskdump
> stopped with message "usb 2-1: reset full speed USB device using address
> 2".
Thank you for trying my patch.
I want to know further information.
Can you capture the console log with the following patch and
enabling CONFIG_USB_STORAGE_DEBUG?
--- 2.6.9-diskdump-1.0/drivers/block/diskdump.c.orig 2005-04-26 12:58:52.375511304 +0900
+++ 2.6.9-diskdump-1.0/drivers/block/diskdump.c 2005-04-26 12:59:26.032394680 +0900
@@ -42,7 +42,7 @@
#include <linux/diskdump.h>
#include <asm/diskdump.h>
-#define Dbg(x, ...) pr_debug("disk_dump: " x "\n", ## __VA_ARGS__)
+#define Dbg(x, ...) printk(KERN_DEBUG "disk_dump: " x "\n", ## __VA_ARGS__)
#define Err(x, ...) pr_err ("disk_dump: " x "\n", ## __VA_ARGS__)
#define Warn(x, ...) pr_warn ("disk_dump: " x "\n", ## __VA_ARGS__)
#define Info(x, ...) pr_info ("disk_dump: " x "\n", ## __VA_ARGS__)
--- 2.6.9-diskdump-1.0/drivers/scsi/scsi_dump.c.orig 2005-04-26 13:01:34.043933968 +0900
+++ 2.6.9-diskdump-1.0/drivers/scsi/scsi_dump.c 2005-04-26 13:01:52.550120600 +0900
@@ -50,7 +50,7 @@
#define MAX_RETRIES 5
#define SD_TIMEOUT (60 * HZ)
-#define Dbg(x, ...) pr_debug("scsi_dump: " x "\n", ## __VA_ARGS__)
+#define Dbg(x, ...) printk(KERN_DEBUG "scsi_dump: " x "\n", ## __VA_ARGS__)
#define Err(x, ...) pr_err ("scsi_dump: " x "\n", ## __VA_ARGS__)
#define Warn(x, ...) pr_warn ("scsi_dump: " x "\n", ## __VA_ARGS__)
#define Info(x, ...) pr_info ("scsi_dump: " x "\n", ## __VA_ARGS__)
|
|
From: Takao I. <ind...@jp...> - 2005-05-09 18:21:05
|
Hi! On Fri, 6 May 2005 14:08:57 +0900, Akinobu Mita wrote: >Hello, > >I made diskdump support for usb-storage. >This is unusual implemantation as scsi-dump device. >Because queuecommand() on crashdump mode is not executed >asynchronously. So dump_poll() routine does not make sense (never called). > >This may be rough implemantation. But these devices are working >as diskdump devices. > >- I-O DATA HDPX-U >- BUFFALO ClipDrive (Ours Technology, Inc. OTI-6803 Flash Disk) > >The core part of this patch is usb_stor_dump_queuecommand() which is taken >from usb_stor_control_thread():drivers/usb/storage/usb.c Good Job! I tried this patch using my usb-memory(TOSHIBA U2B-256MT), but diskdump stopped with message "usb 2-1: reset full speed USB device using address 2". Takao Indoh |
|
From: Akinobu M. <mi...@mi...> - 2005-05-06 05:39:51
|
Hello,
I made diskdump support for usb-storage.
This is unusual implemantation as scsi-dump device.
Because queuecommand() on crashdump mode is not executed
asynchronously. So dump_poll() routine does not make sense (never called).
This may be rough implemantation. But these devices are working
as diskdump devices.
- I-O DATA HDPX-U
- BUFFALO ClipDrive (Ours Technology, Inc. OTI-6803 Flash Disk)
The core part of this patch is usb_stor_dump_queuecommand() which is taken
from usb_stor_control_thread():drivers/usb/storage/usb.c
--- 2.6.9-diskdump-1.0.orig/drivers/usb/core/hcd.c 2005-04-26 12:50:15.000000000 +0900
+++ 2.6.9-diskdump-1.0-usb-storage/drivers/usb/core/hcd.c 2005-05-06 12:53:52.485459208 +0900
@@ -42,6 +42,7 @@
#include <asm/byteorder.h>
#include <linux/usb.h>
+#include <linux/diskdump.h>
#include "usb.h"
#include "hcd.h"
@@ -1622,3 +1623,43 @@ void usb_hc_died (struct usb_hcd *hcd)
}
EXPORT_SYMBOL (usb_hc_died);
+void usb_hcd_poll(struct usb_hcd *hcd)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ usb_hcd_irq(0, hcd, NULL);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL (usb_hcd_poll);
+
+void usb_dump_wait_for_completion(struct completion *x, struct urb *urb)
+{
+ might_sleep();
+ spin_lock_irq(&x->wait.lock);
+ if (!x->done) {
+ DECLARE_WAITQUEUE(wait, current);
+
+ wait.flags |= WQ_FLAG_EXCLUSIVE;
+ __add_wait_queue_tail(&x->wait, &wait);
+ do {
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ spin_unlock_irq(&x->wait.lock);
+ if (crashdump_mode()) {
+ struct usb_hcd *hcd = urb->dev->bus->hcpriv;
+
+ usb_hcd_poll(hcd);
+ udelay(100);
+ diskdump_update();
+ } else
+ schedule();
+ spin_lock_irq(&x->wait.lock);
+ } while (!x->done);
+ __remove_wait_queue(&x->wait, &wait);
+ }
+ x->done--;
+ spin_unlock_irq(&x->wait.lock);
+}
+
+EXPORT_SYMBOL (usb_dump_wait_for_completion);
+
--- 2.6.9-diskdump-1.0.orig/drivers/usb/core/hcd.h 2005-04-26 12:50:15.000000000 +0900
+++ 2.6.9-diskdump-1.0-usb-storage/drivers/usb/core/hcd.h 2005-05-06 12:53:52.474460880 +0900
@@ -246,6 +246,9 @@ void hcd_buffer_free (struct usb_bus *bu
extern struct usb_operations usb_hcd_operations;
extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
extern void usb_hc_died (struct usb_hcd *hcd);
+extern void usb_hcd_poll (struct usb_hcd *hcd);
+extern void usb_dump_wait_for_completion (struct completion *x,
+ struct urb *urb);
/* -------------------------------------------------------------------------- */
--- 2.6.9-diskdump-1.0.orig/drivers/usb/core/message.c 2005-04-26 12:50:15.000000000 +0900
+++ 2.6.9-diskdump-1.0-usb-storage/drivers/usb/core/message.c 2005-05-06 12:53:52.474460880 +0900
@@ -63,7 +63,7 @@ static int usb_start_wait_urb(struct urb
/* grr. timeout _should_ include submit delays. */
add_timer(&timer);
}
- wait_for_completion(&done);
+ usb_dump_wait_for_completion(&done, urb);
status = urb->status;
/* note: HCDs return ETIMEDOUT for other reasons too */
if (status == -ECONNRESET)
--- 2.6.9-diskdump-1.0.orig/drivers/usb/storage/scsiglue.c 2005-04-26 12:50:15.000000000 +0900
+++ 2.6.9-diskdump-1.0-usb-storage/drivers/usb/storage/scsiglue.c 2005-05-06 12:59:30.414086248 +0900
@@ -61,6 +61,8 @@
#include "transport.h"
#include "protocol.h"
+#include "../core/hcd.h"
+
/***********************************************************************
* Host functions
***********************************************************************/
@@ -171,6 +173,8 @@ static int queuecommand(struct scsi_cmnd
/* wake up the process task */
up(&(us->sema));
+ if (crashdump_mode())
+ usb_stor_dump_queuecommand(us);
return 0;
}
@@ -410,6 +414,19 @@ static struct device_attribute *sysfs_de
NULL,
};
+int usb_stor_sanity_check(struct scsi_device *sdev)
+{
+ return 0;
+}
+
+static void usb_stor_poll(struct scsi_device *sdev)
+{
+ struct us_data *us = (struct us_data *) sdev->host->hostdata[0];
+ struct usb_hcd *hcd = us->current_urb->dev->bus->hcpriv;
+
+ usb_hcd_poll(hcd);
+}
+
/*
* this defines our host template, with which we'll allocate hosts
*/
@@ -461,7 +478,9 @@ struct scsi_host_template usb_stor_host_
.sdev_attrs = sysfs_device_attr_list,
/* module management */
- .module = THIS_MODULE
+ .module = THIS_MODULE,
+ .dump_sanity_check = usb_stor_sanity_check,
+ .dump_poll = usb_stor_poll,
};
/* For a device that is "Not Ready" */
--- 2.6.9-diskdump-1.0.orig/drivers/usb/storage/transport.c 2005-04-26 12:50:15.000000000 +0900
+++ 2.6.9-diskdump-1.0-usb-storage/drivers/usb/storage/transport.c 2005-05-06 12:53:52.472461184 +0900
@@ -60,6 +60,8 @@
#include "usb.h"
#include "debug.h"
+#include "../core/hcd.h"
+
/***********************************************************************
* Data transfer routines
@@ -196,7 +198,7 @@ static int usb_stor_msg_common(struct us
}
/* wait for the completion of the URB */
- wait_for_completion(&urb_done);
+ usb_dump_wait_for_completion(&urb_done, us->current_urb);
clear_bit(US_FLIDX_URB_ACTIVE, &us->flags);
/* clean up the timeout timer */
--- 2.6.9-diskdump-1.0.orig/drivers/usb/storage/usb.c 2005-04-26 12:50:15.000000000 +0900
+++ 2.6.9-diskdump-1.0-usb-storage/drivers/usb/storage/usb.c 2005-05-06 13:19:06.545287128 +0900
@@ -272,6 +272,110 @@ void fill_inquiry_response(struct us_dat
usb_stor_set_xfer_buf(data, data_len, us->srb);
}
+void usb_stor_dump_queuecommand(struct us_data *us)
+{
+ US_DEBUGP("*** thread sleeping.\n");
+ if(down_interruptible(&us->sema)) {
+ return;
+ }
+
+ US_DEBUGP("*** thread awakened.\n");
+
+ /* lock the device pointers */
+ down(&(us->dev_semaphore));
+
+ /* if us->srb is NULL, we are being asked to exit */
+ if (us->srb == NULL) {
+ US_DEBUGP("-- exit command received\n");
+ up(&(us->dev_semaphore));
+ return;
+ }
+
+ /* has the command been aborted *already* ? */
+ if (us->sm_state == US_STATE_ABORTING) {
+ us->srb->result = DID_ABORT << 16;
+ goto SkipForAbort;
+ }
+
+ /* don't do anything if we are disconnecting */
+ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+ US_DEBUGP("No command during disconnect\n");
+ goto SkipForDisconnect;
+ }
+
+ /* set the state and release the lock */
+ us->sm_state = US_STATE_RUNNING;
+
+ /* reject the command if the direction indicator
+ * is UNKNOWN
+ */
+ if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL) {
+ US_DEBUGP("UNKNOWN data direction\n");
+ us->srb->result = DID_ERROR << 16;
+ }
+
+ /* reject if target != 0 or if LUN is higher than
+ * the maximum known LUN
+ */
+ else if (us->srb->device->id &&
+ !(us->flags & US_FL_SCM_MULT_TARG)) {
+ US_DEBUGP("Bad target number (%d:%d)\n",
+ us->srb->device->id, us->srb->device->lun);
+ us->srb->result = DID_BAD_TARGET << 16;
+ }
+
+ else if (us->srb->device->lun > us->max_lun) {
+ US_DEBUGP("Bad LUN (%d:%d)\n",
+ us->srb->device->id, us->srb->device->lun);
+ us->srb->result = DID_BAD_TARGET << 16;
+ }
+
+ /* Handle those devices which need us to fake
+ * their inquiry data */
+ else if ((us->srb->cmnd[0] == INQUIRY) &&
+ (us->flags & US_FL_FIX_INQUIRY)) {
+ unsigned char data_ptr[36] = {
+ 0x00, 0x80, 0x02, 0x02,
+ 0x1F, 0x00, 0x00, 0x00};
+
+ US_DEBUGP("Faking INQUIRY command\n");
+ fill_inquiry_response(us, data_ptr, 36);
+ us->srb->result = SAM_STAT_GOOD;
+ }
+
+ /* we've got a command, let's do it! */
+ else {
+ US_DEBUG(usb_stor_show_command(us->srb));
+ us->proto_handler(us->srb, us);
+ }
+
+ /* indicate that the command is done */
+ if (us->srb->result != DID_ABORT << 16) {
+ US_DEBUGP("scsi cmd done, result=0x%x\n",
+ us->srb->result);
+ us->srb->scsi_done(us->srb);
+ } else {
+SkipForAbort:
+ US_DEBUGP("scsi command aborted\n");
+ }
+
+ /* If an abort request was received we need to signal that
+ * the abort has finished. The proper test for this is
+ * sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
+ * because an abort request might be received after all the
+ * USB processing was complete. */
+ if (us->sm_state == US_STATE_ABORTING)
+ complete(&(us->notify));
+
+ /* empty the queue, reset the state, and release the lock */
+SkipForDisconnect:
+ us->srb = NULL;
+ us->sm_state = US_STATE_IDLE;
+
+ /* unlock the device pointers */
+ up(&(us->dev_semaphore));
+}
+
static int usb_stor_control_thread(void * __us)
{
struct us_data *us = (struct us_data *)__us;
--- 2.6.9-diskdump-1.0.orig/drivers/usb/storage/usb.h 2005-04-26 12:50:15.000000000 +0900
+++ 2.6.9-diskdump-1.0-usb-storage/drivers/usb/storage/usb.h 2005-05-06 12:58:35.135489872 +0900
@@ -174,6 +174,8 @@ extern struct usb_driver usb_storage_dri
extern void fill_inquiry_response(struct us_data *us,
unsigned char *data, unsigned int data_len);
+extern void usb_stor_dump_queuecommand(struct us_data *us);
+
/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
* single queue element srb for write access */
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
|
|
From: Miller, M. (OS Dev) <mik...@hp...> - 2005-04-20 13:57:18
|
> From: Takao Indoh [mailto:ind...@jp...]=20 >=20 > What is the purpose of block_dump? Could you please explain=20 > the summary of these patches? Sorry, I should have done that. blockdump.patch=20 Adds the .c and .h files for the mid-layer. It allows block drivers to provice diskdump functionality while removing dependencies from the low level device drivers. cciss_diskdump.patch This file contains the functions used by the cciss driver to perform diskdump operations. cciss.patch Modifies cciss.c to include declaration of extended device operations and modifies our sendcmd function to operate during a dump (polling vs interrupt driven, etc) configin.patch Gives the user the option of adding blockdump support to cciss. diskdump_doc.patch Adds cciss to the list of supported devices in the README file of the diskdumputils package. diskdumpsh.patch Adds support to load the required block_dump driver at boot time. fs_h.patch Adds a new entry to block_device_operations structure to allow drivers to define if they support diskdump. Required by block_dump to see if the LLDD is a valid dump device. makefile.patch Adds block_dump to the block layer Makefile. README.blockdump The README file. Thanks, mikem >=20 > Takao Indoh >=20 |
|
From: Akinobu M. <mi...@mi...> - 2005-04-20 04:28:05
|
I'm sorry. I did a couple of typos. On Wednesday 20 April 2005 13:12, Akinobu Mita wrote: > 3. reload the scsi_dump module > > # rmmod scsi_mod > # modprobe scsi_mod > # rmmod scsi_dump # modprobe scsi_dump |