[PATCH] [2.6.0-test3] request_firmware related problems.

From: Manuel Estrada Sainz
Date: Sun Aug 10 2003 - 17:19:26 EST


Hi,

Please apply the following patches.

Matthew Wilcox seams busy lately and didn't confirm the PCI changes,
but I have tested them and it works. He can modify it later with nicer
code if he finds it necessary, sysfs binary support has been broken for
too much time already being in this stage of development :-/.

Since this is just a single change plus side effects I just merged it
back together.

ChangeLog:
- undo recent change, made in the believe that "buffer" was the
size of the whole file, it is just PAGE_SIZE in size. This was
causing kernel memory corruption.

- Since files are allowed to have unknown sizes, by
setting their size to 0, we can't preallocate a buffer
of their size on open.

- Adapt request_firmware() to the sysfs change.

- Adapt drivers/pci/pci-sysfs.c to the sysfs change.

Sorry again for the multi-patch email

Manuel

--
--- Manuel Estrada Sainz <ranty@xxxxxxxxxx>
<ranty@xxxxxxxxxxx>
<ranty@xxxxxxxxxxxxxxxxxxxxx>
------------------------ <manuel.estrada@xxxxxxxxxxxxx> -------------------
Let us have the serenity to accept the things we cannot change, courage to
change the things we can, and wisdom to know the difference.
diff -u drivers/base/firmware_class.c drivers/base/firmware_class.c
--- drivers/base/firmware_class.c 26 Jul 2003 08:38:07 -0000
+++ drivers/base/firmware_class.c 1 Aug 2003 14:26:41 -0000
@@ -151,7 +151,7 @@
if (offset + count > fw->size)
count = fw->size - offset;

- memcpy(buffer + offset, fw->data + offset, count);
+ memcpy(buffer, fw->data + offset, count);
return count;
}
static int
@@ -200,7 +200,7 @@
if (retval)
return retval;

- memcpy(fw->data + offset, buffer + offset, count);
+ memcpy(fw->data + offset, buffer, count);

fw->size = max_t(size_t, offset + count, fw->size);

only in patch2:
unchanged:
--- drivers/pci/pci-sysfs.c 4 Jul 2003 02:21:18 -0000 1.6
+++ drivers/pci/pci-sysfs.c 1 Aug 2003 14:26:43 -0000
@@ -67,6 +67,7 @@
{
struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
unsigned int size = 64;
+ loff_t init_off = off;

/* Several chips lock up trying to read undefined config space */
if (capable(CAP_SYS_ADMIN)) {
@@ -87,7 +88,7 @@
while (off & 3) {
unsigned char val;
pci_read_config_byte(dev, off, &val);
- buf[off] = val;
+ buf[off - init_off] = val;
off++;
if (--size == 0)
break;
@@ -96,10 +97,10 @@
while (size > 3) {
unsigned int val;
pci_read_config_dword(dev, off, &val);
- buf[off] = val & 0xff;
- buf[off + 1] = (val >> 8) & 0xff;
- buf[off + 2] = (val >> 16) & 0xff;
- buf[off + 3] = (val >> 24) & 0xff;
+ buf[off - init_off] = val & 0xff;
+ buf[off - init_off + 1] = (val >> 8) & 0xff;
+ buf[off - init_off + 2] = (val >> 16) & 0xff;
+ buf[off - init_off + 3] = (val >> 24) & 0xff;
off += 4;
size -= 4;
}
@@ -107,7 +108,7 @@
while (size > 0) {
unsigned char val;
pci_read_config_byte(dev, off, &val);
- buf[off] = val;
+ buf[off - init_off] = val;
off++;
--size;
}
@@ -120,6 +121,7 @@
{
struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
unsigned int size = count;
+ loff_t init_off = off;

if (off > 256)
return 0;
@@ -129,24 +131,24 @@
}

while (off & 3) {
- pci_write_config_byte(dev, off, buf[off]);
+ pci_write_config_byte(dev, off, buf[off - init_off]);
off++;
if (--size == 0)
break;
}

while (size > 3) {
- unsigned int val = buf[off];
- val |= (unsigned int) buf[off + 1] << 8;
- val |= (unsigned int) buf[off + 2] << 16;
- val |= (unsigned int) buf[off + 3] << 24;
+ unsigned int val = buf[off - init_off];
+ val |= (unsigned int) buf[off - init_off + 1] << 8;
+ val |= (unsigned int) buf[off - init_off + 2] << 16;
+ val |= (unsigned int) buf[off - init_off + 3] << 24;
pci_write_config_dword(dev, off, val);
off += 4;
size -= 4;
}

while (size > 0) {
- pci_write_config_byte(dev, off, buf[off]);
+ pci_write_config_byte(dev, off, buf[off - init_off]);
off++;
--size;
}
only in patch2:
unchanged:
--- fs/sysfs/bin.c 4 Jul 2003 02:21:18 -0000 1.9
+++ fs/sysfs/bin.c 1 Aug 2003 14:26:45 -0000
@@ -47,7 +47,7 @@
return ret;
count = ret;

- if (copy_to_user(userbuf, buffer + offs, count) != 0)
+ if (copy_to_user(userbuf, buffer, count) != 0)
return -EINVAL;

pr_debug("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count);
@@ -83,7 +83,7 @@
count = size - offs;
}

- if (copy_from_user(buffer + offs, userbuf, count))
+ if (copy_from_user(buffer, userbuf, count))
return -EFAULT;

count = flush_write(dentry, buffer, offs, count);