Errata

Linux Device Drivers

Errata for Linux Device Drivers, Third Edition

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
Printed
Page xi
last paragraph

twelth
->
twelfth

######################################

Anonymous    May 01, 2007
Printed
Page xiii
first para, Greg's introduction

... but whose kernel had never taken the time to look into.
->
... but whose kernel I had never taken the time to look into.

######################################

Anonymous    May 01, 2007
Printed
Page xiv
Second-last paragraph, last sentence

In Chapters 1 and 1, however...
->
In Chapters 9 and 10, however...

######################################

Anonymous    May 01, 2007
Printed
Page xvii
3rd paragraph under Acknowledgements

"Michael Boerner" added to the list of technical reviewers thanked.

######################################

Anonymous    May 01, 2007
Printed
kdb> mm cf26ac0c 0x50

->

Anonymous    May 01, 2007
Printed
kdb> mm cf36ac0c 0x50

######################################

Anonymous    May 01, 2007
Printed
Page back cover
3rd paragraph

".. been competely updated for Version 2.6.10 .."
should read:
.. been completely updated for Version 2.6.10 .."

Anonymous    Jan 01, 2010
Printed
Page 7
last paragraph

...I2O drivers.
->
...I2C drivers.

######################################

Anonymous    May 01, 2007
Printed
Page 17
code output

Goodbye cruel world
->
Goodbye, cruel world

######################################

Anonymous    May 01, 2007
Printed
Page 26
Last sentence

"This header file, automatically included by linux/module.h, defines the following macros:"

NOW READS:
"This header file defines the following macros:"

Anonymous    Mar 01, 2006
Printed
Page 29
third line from bottom of page

executible
->
executable

######################################

Anonymous    May 01, 2007
Printed
Page 32
3rd paragraph, last sentence

...necessary to enable to kernel...
->
...necessary to enable the kernel...

######################################

Anonymous    May 01, 2007
Printed
Page 34
last paragraph (the code example)

"if (!item2 || !item2)"

NOW READS:
"if (!item1 || !item2)"

Anonymous    Mar 01, 2006
Printed
Page 37
second paragraph

The parameter "num" in module_param_array(name,type,num,perm) is actually a "pointer to a integer variable". Change the name of the parameter to "nump" to avoid the confusion. Also, the two mentions of "num" in the following paragraph should be changed to "nump."

Anonymous    Jan 01, 2010
Printed
Page 41
Two first lines

Add the MODULE_LICENSE macro to the MODULE_XXX list.

Note from the Author or Editor:

The proper fix would be to place it as a separate entry:
MODULE_LICENSE(license);
Declare the license governing this module.

Anonymous    Jan 01, 2010
Printed
Page 41
1st definition, last sentence

"The second form exports without using versioning information, and the third
limits the export to GPL-licensed modules."
should read:
"The second form limits use of the exported symbol to GPL-licensed modules."

Anonymous    Jan 01, 2010
Printed
Page 41
middle

The following entries already appear earlier in the same list on p.39 (Quick Ref. for
Ch. 2):
module_init(init_function);
module_exit(cleanup_function);

Anonymous    Jan 01, 2010
Printed
Page 45
Middle of page, 5th paragraph

"dynamicly"

NOW READS:
"dynamically"

Anonymous    Mar 01, 2006
Printed
Page 45
6th paragraph, last sentence

"The count and name parameters work like those given to request_chrdev_region."

NOW READS:
"The count and name parameters work like those given to register_chrdev_region."

Anonymous    Mar 01, 2006
Printed
Page 47
The script scull_load

major=$(awk "\$2=="module$" {print \$1}" /proc/devices)

NOW READS:
major=$(awk "$2=="module$" {print $1}" /proc/devices)

Anonymous    Mar 01, 2006
Printed
Page 54
2nd Definition (f_flags)

In parentheses the sentence says 'we discuss nonblocking I/O in the section "Blocking
and Nonblocking Operations" in Chapter 1'. The chapter number referenced should be 6,
as the section is on page 151.

Anonymous    Jan 01, 2010
Printed
Page 58
3rd to last paragraph, 1st line

"This macro takes a pointer to a field of type container_field..."

NOW READS:
"This macro takes a pointer to a field named container_field..."

Anonymous    Mar 01, 2006
Printed
Page 61
Last paragraph

"In scull, each device is a linked list of pointers, each of which points to a
scull_dev structure."

NOW READS:
"In scull, each device is a linked list of pointers, each of which points to a
scull_qset structure."

Anonymous    Mar 01, 2006
Printed
Page 62
1st paragraph, 2nd line

"12,000 thousand bytes"

NOW READS:
"12,000 bytes"

Anonymous    Mar 01, 2006
Printed
Page 62
2nd paragraph, 4th line

The phrase "charge in" at end of line HAS BEEN REMOVED.

Anonymous    Mar 01, 2006
Printed
Page 64
1st normal paragraph

...in the section "Using the ioctl Argument" in Chapter 1...
should read:
...in the section "Using the ioctl Argument" in Chapter 6...

Anonymous    Jan 01, 2010
Printed
Page 67
code listing for scull_read(), 3rd line of body

The assignments to 'quantum' and 'qset' should be protected by a
semaphore, to avoid the following (admittedly unlikely) race
condition:

- The device is opened for reading by one process.
- Somebody changes the quantum value with ioctl().
- A read begins on the device, reading its quantum value, but the
semaphore is not yet taken.
- A second process opens the device O_WRONLY, causing it to be
reinitialized, thus changing the device's quantum value
- That process writes to the scull device
- The first read resumes

Note from the Author or Editor:

1) In the declaration lines at the top, take out the initializations so they read:

int quantum, qset;
int itemsize; /* how many bytes in the listitem */

2) Make the code look like this

if (down_interruptible(&dev->sem))
return -ERESTARTSYS;
quantum = dev->quantum;
qset = dev->qset;
itemsize = quantum*qset;

if (*f_pos >= dev->size)

The three assignments are the new stuff, bracketed by the "if" statements which are already there (and need not be changed).

Anonymous    Jan 01, 2010
PDF
Page 69
2nd paragraph of readv and writev

'. . . is achieved by . . .' not '. . . is acheived by . . .'

Anonymous  Nov 19, 2008 
Printed
Page 82
Second section, first paragraph

...associated withp the hardware...
->
...associated with the hardware...

######################################

Anonymous    May 01, 2007
Printed
Page 90
Last paragraph

ioctl, which we show you how to use in Chapter 1, is ...
should read:
ioctl, which we show you how to use in Chapter 6, is ...

Anonymous    Jan 01, 2010
Printed
Page 103
3rd code snippet, 1st line

Anonymous    May 01, 2007
Printed
Page 109
Last paragraph, 2nd sentence

...any further processes...
->
...any further progress...

######################################

Anonymous    May 01, 2007
Printed
Page 114
Completions section, first paragraph, 4th line

It such cases...
->
In such cases...

######################################

Anonymous    May 01, 2007
Printed
Page 119
2nd paragraph under "The Spinlock Functions" heading

"There are actually four functions that can lock a spinlock:"

NOW READS:
"There are actually four functions* that can lock a spinlock:"

At the bottom of the page, the following footnote HAS BEEN ADDED:
* Actually, these are macros defined in <linux/spinlock.h>, not
functions. That is why the flags parameter of spin_lock_irqsave()
is not a pointer, as one might expect.

Anonymous    Mar 01, 2006
Printed
Page 125
First paragraph

But a full locking regime seems like over-
head for a simple integer value.

->

But a full locking regime seems like over-
kill for a simple integer value.

######################################

Anonymous    May 01, 2007
Printed
Page 142
last line

" 'Type' is user-oriented" NOW READS " 'direction' is user-oriented".

Anonymous    Mar 01, 2006
Printed
Page 149
Third paragraph

dynamicly
->
dynamically

######################################

Anonymous    May 01, 2007
Printed
Page 158
Last comment in code block at the top of the page

explained late in chapter 5
->
explained late in chapter 6

######################################

Anonymous    May 01, 2007
Printed
Page 163
first paragraph, line 2

...each allow a process...
->
...each allows a process...

######################################

Anonymous    May 01, 2007
Printed
Page 163
Last line (above footnote)

void poll_wait (struct file *, wait_queue_head_t *, poll_table *);
->
void poll_wait (struct file *filp, wait_queue_head_t *wait_queue, poll_table *wait);

######################################

Anonymous    May 01, 2007
Printed
Page 181
mid-page, 1st argument in all 7 wake_up_*() function prototypes

"struct wait_queue **q"

NOW READS:
"wait_queue_head_t *q"

Anonymous    Mar 01, 2006
Printed
Page 191
4th paragraph, 2nd sentence

"...and lines are guaranteed to be 20 bytes each."

NOW READS:
"...and lines are guaranteed to be 22 bytes each."

Anonymous    Mar 01, 2006
Printed
Page 191
small paragraph next to bear trap icon, last sentence

"...freezes the computer for 205 seconds."

NOW READS:
"...freezes the computer for 186 seconds."

Anonymous    Mar 01, 2006
Printed
Page 191
last paragraph, 1st sentence

"The suggested command to read /proc/jitbusy is dd bs=20 < /proc/jitbusy,."

NOW READS:
"The suggested command to read /proc/jitbusy is dd bs=22 < /proc/jitbusy,..."

Anonymous    Mar 01, 2006
Printed
Page 191
last paragraph, 2nd sentence

"Each 20-byte line returned by the file represents the value the jiffy counter
had before and after the delay."

NOW READS:
"Each 22-byte line returned by the file represents the least significant 32 bits
of the value the jiffy counter had before and after the delay."

Anonymous    Mar 01, 2006
Printed
Page 191
computer printout at bottom of page

phon% dd bs=20 count=5 < /proc/jitbusy
1686518 1687518
1687519 1688519
1688520 1689520
1689520 1690520
1690521 1691521

-> [note new bs= value, and alignment of columns]:

phon% dd bs=22 count=5 < /proc/jitbusy
1686518 1687518
1687519 1688519
1688520 1689520
1689520 1690520
1690521 1691521

######################################

Anonymous    May 01, 2007
Printed
Page 192
computer printout at top of page

phon% dd bs=20 count=5 < /proc/jitbusy
1911226 1912226
1913323 1914323
1919529 1920529
1925632 1926632
1931835 1932835

-> [note new bs= value, and alignment of columns]:

phon% dd bs=22 count=5 < /proc/jitbusy
1911226 1912226
1913323 1914323
1919529 1920529
1925632 1926632
1931835 1932835

######################################

Anonymous    May 01, 2007
Printed
Page 192
computer printout in middle of page

phon% dd bs=20 count=5 < /proc/jitbusy
14940680 14942777
14942778 14945430
14945431 14948491
14948492 14951960
14951961 14955840

-> [note new bs= value, and alignment of columns]:

phon% dd bs=22 count=5 < /proc/jitbusy
14940680 14942777
14942778 14945430
14945431 14948491
14948492 14951960
14951961 14955840

######################################

Anonymous    May 01, 2007
Printed
Page 193
2nd line below the code snippet

However, is still isn't optimal
Should be:
However, it still isn't optimal

Anonymous  Sep 10, 2008 
Printed
Page 193
computer printout in middle of page

phon% dd bs=20 count=5 < /proc/jitsched
1760205 1761207
1761209 1762211
1762212 1763212
1763213 1764213
1764214 1765217

-> [note new bs= value, and alignment of columns]:

phon% dd bs=22 count=5 < /proc/jitsched
1760205 1761207
1761209 1762211
1762212 1763212
1763213 1764213
1764214 1765217

######################################

Anonymous    May 01, 2007
Printed
Page 194
2nd paragraph

Text states that the return value of wait_event_timeout and wait_event_interruptible timeout
is never negative. This is correct for wait_event_timeout only.
In fact, the interruptible version will return -ERESTARTSYS.

Anonymous   
Printed
Page 194
computer printout in middle of page

phon% dd bs=20 count=5 < /proc/jitqueue
2027024 2028024
2028025 2029025
2029026 2030026
2030027 2031027
2031028 2032028

-> [note new bs= value, and alignment of columns]:

phon% dd bs=22 count=5 < /proc/jitqueue
2027024 2028024
2028025 2029025
2029026 2030026
2030027 2031027
2031028 2032028

######################################

Anonymous    May 01, 2007
Printed
Page 196
3rd paragraph from bottom, 1st sentence

The first two functions puts the calling process to sleep...
->
The first two functions put the calling process to sleep...

######################################

Anonymous    May 01, 2007
Printed
Page 197
4th paragraph

... in the section "Spinlocks and Atomic Context" in Chapter 1, ...
should read:
... in the section "Spinlocks and Atomic Context" in Chapter 5, ...

Anonymous    Jul 01, 2009
Printed
Page 198
5th paragraph

...(discussed in the section "Atomic Variables" in Chapter 1)...
should read:
...(discussed in the section "Atomic Variables" in Chapter 5)...

Anonymous    Jan 01, 2010
Printed
Page 199
First paragraph, second line

iteslf
->
itself

######################################

Anonymous    May 01, 2007
Printed
Page 203
The last feature of tasklets

A tasklets can be ...
Should be
A tasklet can be ...

Anonymous  Sep 11, 2008 
Printed
Page 206
paragraph near top beginning with "Either one..."

The return-value from these functions is 0 if the work was successfully
added to the queue; a nonzero result means that this work_struct stucture
was already waiting in the queue, and was not added a second time.
->
The return-value from these functions is nonzero if the work was successfully
added to the queue; a zero result means that this work_struct stucture was
already waiting in the queue, and was not added a second time.

######################################

Anonymous    May 01, 2007
Printed
Page 209
2nd code block

rdtscll(var32)
->
rdtscll(var64)

######################################

Anonymous    May 01, 2007
Printed
Page 215
paragraph under _GFP_COLD

"Chapter 1"
should read:
"Chapter 15"

Anonymous    Jan 01, 2010
Printed
Page 216
3rd paragraph

"Chapter 1"
should read:
"Chapter 15"

Anonymous    Jan 01, 2010
Printed
Page 230
paragraph under Obtaining Large Buffers

"Chapter 1"
should read:
"Chapter 15"

Anonymous    Jan 01, 2010
Printed
Page 241
Last paragraph, third line down

... I/O port or the same size
->
... I/O port of the same size

######################################

Anonymous    May 01, 2007
Printed
Page 242
Sixth line of first paragraph under section "Pausing I/O"

out b
->
outb

######################################

Anonymous    May 01, 2007
Printed
Page 249
2nd para,2nd line

When access passes though page tables...
->
When access passes through page tables...

######################################

Anonymous    May 01, 2007
Printed
Page 250
First line on page

"vmalloc and Friends" in Chapter 1.
should read:
"vmalloc and Friends" in Chapter 8.

Anonymous    Jan 01, 2010
Printed
Page 251
First paragraph, first sentence

These functions read or write count values from the given buf to the given addr.
->
The ioread functions read count values from the given addr to the given buf, while
the iowrite functions write count values from the given buf to the given addr.

######################################

Anonymous    May 01, 2007
Printed
Page 251
2nd Paragraph

perform all I/O
->
all perform I/O

######################################

Anonymous    May 01, 2007
Printed
Page 254
2nd code block

iowrite8
->
iowrite32

######################################

Anonymous    May 01, 2007
Printed
Page 257
First ten lines

unsigned readb(address);
unsigned readw(address);
unsigned readl(address);
void writeb(unsigned value, address);
void writew(unsigned value, address);
void writel(unsigned value, address);
memset_io(address, value, count);
memcpy_fromio(dest, source, nbytes);
memcpy_toio(dest, source, nbytes);
Older, type-unsafe functions for accessing I/O memory.

->

unsigned readb(address);
unsigned readw(address);
unsigned readl(address);
void writeb(unsigned value, address);
void writew(unsigned value, address);
void writel(unsigned value, address);
Older, type-unsafe functions for accessing I/O memory.

memset_io(address, value, count);
memcpy_fromio(dest, source, nbytes);
memcpy_toio(dest, source, nbytes);
Functions that operate on a block of I/O memory.

######################################

Anonymous    May 01, 2007
Printed
Page 262
halfway down page

root@montalcino:/bike/corbet/write/ldd3/src/short# m /proc/interrupts
->
root@montalcino:/bike/corbet/write/ldd3/src/short# cat /proc/interrupts

######################################

Anonymous    May 01, 2007
Printed
Page 270
5th line from the bottom

By taking care to prevent in inconsistent value...
->
By taking care to prevent an inconsistent value...

######################################

Anonymous    May 01, 2007
Printed
Page 271
Code for short_i_read() function, 7th line from end of function

count0 = short_buffer + PAGE_SIZE - short_tail;
->
count0 = short_head + PAGE_SIZE - short_tail;

######################################

Anonymous    May 01, 2007
Printed
Page 274
11th line from bottom

Note that flags is passed directly, not by pointer.
->
Note that flags is passed directly, not by pointer; this is because
local_irq_save() is actually implemented as a macro, not a function.

######################################

Anonymous    May 01, 2007
Printed
Page 275
2nd Paragraph from End (Under "Top and Bottom Halves"

The alternative to tasklets is workqueues, which may have a higher latency
but that are allowed to sleep.
->
The alternative to tasklets is workqueues, which may have a higher latency
but which are allowed to sleep.

######################################

Anonymous    May 01, 2007
Printed
Page 276
last paragraph example

There is a synchronization mistake in example shown after:

void short_do_tasklet (unsigned long unused)
{
int savecount = short_wq_count, written;

This is not safe to clean the variable <short_wq_count> in this manner
If at this time hw interrupt will occur, we will lose one(or maybe more) tick for <short_wq_count>
We should use the <spin_lock_irqsave> to prevent such a problem

short_wq_count = 0; /* we have already removed from the queue */

Author response: You are correct - there is a very narrow window in which
we can race with the interrupt handler. As you suggest, it could be fixed
with a spinlock, though, perhaps, a seqlock would be a more suitable tool
for this situation.

Anonymous   
Printed
Page 276
2nd paragraph, 2nd sentence

Therefore, an interrupt handler can be secure that...
->
Therefore, an interrupt handler can be sure that...

######################################

Anonymous    May 01, 2007
Printed
Page 281
2nd paragraph

"IRQ 5 is used for the serial ATA and IEEE 1394 controllers;"
should be
"IRQ 5 is used for the serial ATA and USB 2.0 controllers;"

Anonymous    Jan 01, 2010
Printed
Page 289
Near top of page, 3rd line of computer output

i686
->
i386

######################################

Anonymous    May 01, 2007
Printed
Page 293
2nd last paragraph

le16_to_cpus does not do "signed" conversion but "in situ" conversion. See kernel
header include/linux/byteorder/generic.h.

Anonymous   
Printed
Page 298
Both versions of the todo_add_entry() function, last line

list_add_tail(&new->list, &todo_struct);
->
list_add_tail(&new->list, &todo_list);

######################################

Anonymous    May 01, 2007
Printed
Page 308
Figure 12-2, top row of registers

The Class Code register should be shaded, to indicate that it is
a required register.

Anonymous   
Printed
Page 309
15th line from bottom

The class register is a 16-bit value...
->
The class register is a 24-bit value...

######################################

Anonymous    May 01, 2007
Printed
Page 310
last sentence under the paragraph headed by "__u32 class_mask;"

If a driver can handle any subsystem ID, the value PCI_ANY_ID should be used
for these fields.
->
If a driver can handle any class, the value 0 should be used for these fields.

######################################

Anonymous    May 01, 2007
Printed
Page 326
2/3 way down page, the pci_write_config_*() function prototypes

int pci_write_config_byte (struct pci_dev *dev, int where, u8 *val);
int pci_write_config_word (struct pci_dev *dev, int where, u16 *val);
int pci_write_config_dword (struct pci_dev *dev, int where, u32 *val);

->

int pci_write_config_byte (struct pci_dev *dev, int where, u8 val);
int pci_write_config_word (struct pci_dev *dev, int where, u16 val);
int pci_write_config_dword (struct pci_dev *dev, int where, u32 val);

######################################

Anonymous    May 01, 2007
Printed
Page 342
1st paragraph under Interrupt urbs

"sent to a interrupt endpoint of a USB device:"
Should be:
"sent to an interrupt endpoint of a USB device:"

Anonymous    Jan 01, 2010
Printed
Page 343
Last paragraph under "Bulk urbs"

The usb_fill_int_urb function does not set the transfer_flags...
->
The usb_fill_bulk_urb function does not set the transfer_flags...

######################################

Anonymous    May 01, 2007
Printed
Page 345
2nd line

This value should be used if the driver is in the block I/O patch.
->
This value should be used if the driver is in the block I/O path.

######################################

Anonymous    May 01, 2007
Printed
Page 349
last paragraph, 2nd sentence

This is done with a call to usb_deregister_driver.
->
This is done with a call to usb_deregister.

######################################

Anonymous    May 01, 2007
Printed
Page 355
last paragraph, line 3

Remember that the urb callback is running in interrupt context, so it should
do any memory allocation...
->
Remember that the urb callback is running in interrupt context, so it should
not do any memory allocation...

######################################

Anonymous    May 01, 2007
Printed
Page 366
2nd paragraph from bottom

A successful call to kobject_get increments the kobject's reference counter and
returns a pointer to the kobject. If, however, the kobject is already in the process of
being destroyed, the operation fails, and kobject_get returns NULL. This return value
must always be tested, or no end of unpleasant race conditions could result.

->

A call to kobject_get increments the kobject's reference counter and
returns a pointer to the kobject.

######################################

Anonymous    May 01, 2007
Printed
Page 369
Last paragraph (above bullets)

...their parent's fields
->
...their parent fields

######################################

Anonymous    May 01, 2007
Printed
Page 376
2nd Paragraph under "Hotplug Operations"

...the kernel searchs up through...
->
...the kernel searches up through...

######################################

Anonymous    May 01, 2007
Printed
Page 383
last code example

#define to_ldd_device(dev) container_of(dev, struct ldd_device, dev)
->
#define to_ldd_device(_dev) container_of(_dev, struct ldd_device, dev)

######################################

Anonymous    May 01, 2007
Printed
Page 388
"The class_simple Interface", entire section

The class_simple interface is no longer present in kernels from 2.6.13 on. All
references in the book to this interface and its functions are obsolete now,
and should be removed.

Anonymous   
Printed
Page 388
Third paragraph in "The class_simple interface"

"Chapter 1"
should read:
"Chapter 11"

Anonymous    Jan 01, 2010
Printed
Page 396
1st paragraph under "Add a Driver", 5th line

structdevice_driver
->
struct device_driver

######################################

Anonymous    May 01, 2007
Printed
Page 415
3rd paragraph, 4th line

If you discard the offset and shift the rest of an offset to the right...
->
If you discard the offset and shift the rest of an address to the right...

######################################

Anonymous    May 01, 2007
Printed
Page 416
Second paragraph

...while not breaking 32-bit application and the...
->
...while not breaking 32-bit applications and the...

######################################

Anonymous    May 01, 2007
Printed
Page 416,418
Bottom (by page number)

The Chapter information at bottom of page is incorrect.

Chapter 1: Memory Mapping and DMA
should be
Chapter 15: Memory Mapping and DMA

Anonymous    Jan 01, 2010
Printed
Page 418
2nd paragraph: kunmap

a limited number of such mappings is available,
->
a limited number of such mappings are available,

######################################

Anonymous    May 01, 2007
Printed
Page 419
Paragraph starting "The memory areas"

by looking in /proc/<pid/maps>
->
by looking in /proc/<pid>/maps

######################################

Anonymous    May 01, 2007
Printed
Page 429
programming example under "Remapping Specific I/O Regions"

unsigned long physical = simple_region_start + off;
->
unsigned long pfn = page_to_pfn(simple_region_start + off);

######################################

Anonymous    May 01, 2007
Printed
Page 429
same example

remap_pfn_range(vma, vma_>vm_start, physical, vsize, vma->vm_page_prot);
->
remap_pfn_range(vma, vma->vm_start, pfn, vsize, vma->vm_page_prot);

######################################

Anonymous    May 01, 2007
Printed
Page 442
Third paragraph

arrises
->
arises

######################################

Anonymous    May 01, 2007
Printed
Page 449
1st paragraph after bullets, 2nd sentence from end

dma_unmap_single
->
dma_map_single

######################################

Anonymous    May 01, 2007
Printed
Page 451
paragraph starting "Your driver should"

pci_map_sg
->
dma_map_sg

######################################

Anonymous    May 01, 2007
Printed
Page 469
2nd & 3rd code fragments

in second fragment it says --
struct sbull_dev {
...
int size; /Device size in sectors */
...

in the third frgament, this is being initialized as bytes??!!
dev->size = nsectors * hardsect_size;

which is it?

AUTHOR'S REPLY:

Yes, the comment is wrong; somewhere along the line, that field became
the size in bytes. So, among other things, that means that the "int"
type may not be the best choice - though it's unlikely to overflow for
the sizes normally used with sample RAM disks.

Anonymous   
Printed
Page 476
5th line

sbull_transfer(dev, req->sector, req->current_nr_sectors,
->
sbull_transfer(dev, req->sector, req->nr_sectors,

######################################

Anonymous    May 01, 2007
Printed
Page 476
3rd Paragraph

The call to block_fs_request tells us...
->
The call to blk_fs_request tells us...

######################################

Anonymous    May 01, 2007
Printed
Page 506
1st paragraph under "Hardware Information", 2nd sentence

...most modern drivers do make use of them...
->
...most modern drivers do not make use of them...

######################################

Anonymous    May 01, 2007
Printed
Page 516
3rd paragraph from bottom, 2nd sentence

...it calls the driver's hard_start_transmit method...
->
...it calls the driver's hard_start_xmit method...

######################################

Anonymous    May 01, 2007
Printed
Page 524
Code example, first line

static void snull_regular_interrupt(int irq, void *dev_id, struct pt_regs *regs)
->
static irqreturn_t snull_regular_interrupt(int irq, void *dev_id, struct pt_regs *regs)

######################################

Anonymous    May 01, 2007
Printed
Page 524
Code example, last line before the closing "}"

return;
->
return IRQ_HANDLED;

######################################

Anonymous    May 01, 2007
Printed
Page 539
Code example eighth line from bottom

/* If there's more addresses...
->
/* If there are more addresses...

######################################

Anonymous    May 01, 2007
Printed
Page 548
Last paragraph, 3rd line

"It it used to register" should be:
"It is used to register"

Anonymous    Jan 01, 2010
Printed
Page 549
Second line

paramater
->
parameter

######################################

Anonymous    May 01, 2007
Printed
Page 556
3rd paragraph of the section "Flow of Data"

This paragraph says that I cannot call copy_from_user, kmalloc, and
*printk* in an interrupt context. But on page 79, the first
paragraph says I can call printk from anywhere, including interrupt
handlers. I think page 79 is true, and the tiny_write() sample code
on page 556 does call printk without checking context.

AUTHOR'S COMMENTS:

You are right, printk() is designed to be callable from anywhere -
though it might lose output if called at the wrong time from interrupt
context. Sorry for the confusion.

Anonymous   
Printed
Page 561
Last paragraph, 1st sentence

There are a two basic types of...
->
There are two basic types of...

######################################

Anonymous    May 01, 2007
Printed
Page 575
In the appendix, third paragraph

Deleted the second sentence, beginning "The program called repatch..."

######################################

Anonymous    May 01, 2007
Printed
Page 590-592
function listing in index

One of the very useful things in this book is the function listing in the index.

However (you knew there would be one), the value of this list is lessened because
some of the functions are alphabetized under their return value rather than their
name, while most are alphabetized by their name. Examples include:

"const char *dev_name" under "const" rather than "dev_name"
"int seq_escape" under "int" rather than "seq_escape"
"void tasklet_disable" under "void" rather than "tasklet_disable"

There are mis-alphabetized functions listed under "const", "int", "unsigned", and
"void".

Anonymous   
Printed
Page 604
index, middle of 2nd column

The following entries are missing:
"pci_module_init, 325"
"pci_register_driver, 312-313, 325"

Anonymous   
Printed
Page 613
index, top of page

The following entry is missing:
"udev, 403-405

Anonymous