NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/46599: atapi xfers through a sil 3112 controller of an odd number of bytes or less than 4 bytes causes system lockup
The following reply was made to PR kern/46599; it has been noted by GNATS.
From: Onno van der Linden <o.vd.linden%quicknet.nl@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: kern/46599: atapi xfers through a sil 3112 controller of an odd
number of bytes or less than 4 bytes causes system lockup
Date: Sat, 28 Jul 2012 23:19:43 +0200
> Synopsis: atapi xfers through a sil 3112 controller
> of an odd number of bytes or less than 4 bytes causes system lockup
The Silicon Image 3114 controller I have doesn't seem to like
bus_space_read_multi_{stream_}[24]() calls where count = 0.
Below is a diff that fixes it for me. I didn't fix the code
after the unaligned label.
*** /usr/src/sys/dev/ic/wdc.c.orig Sat Jul 28 22:19:32 2012
--- /usr/src/sys/dev/ic/wdc.c Sat Jul 28 23:08:25 2012
***************
*** 1879,1906 ****
#endif
if (flags & DRIVE_NOSTREAM) {
! if (flags & DRIVE_CAP32) {
bus_space_read_multi_4(wdr->data32iot,
wdr->data32ioh, 0, bf, len >> 2);
bf = (char *)bf + (len & ~3);
len &= 3;
}
! if (len) {
bus_space_read_multi_2(wdr->cmd_iot,
wdr->cmd_iohs[wd_data], 0, bf, len >> 1);
}
} else {
! if (flags & DRIVE_CAP32) {
bus_space_read_multi_stream_4(wdr->data32iot,
wdr->data32ioh, 0, bf, len >> 2);
bf = (char *)bf + (len & ~3);
len &= 3;
}
! if (len) {
bus_space_read_multi_stream_2(wdr->cmd_iot,
wdr->cmd_iohs[wd_data], 0, bf, len >> 1);
}
}
return;
#ifndef __NO_STRICT_ALIGNMENT
--- 1879,1913 ----
#endif
if (flags & DRIVE_NOSTREAM) {
! if ((flags & DRIVE_CAP32) && len > 3) {
bus_space_read_multi_4(wdr->data32iot,
wdr->data32ioh, 0, bf, len >> 2);
bf = (char *)bf + (len & ~3);
len &= 3;
}
! if (len > 1) {
bus_space_read_multi_2(wdr->cmd_iot,
wdr->cmd_iohs[wd_data], 0, bf, len >> 1);
+ bf = (char *)bf + (len & ~1);
+ len &= 1;
}
} else {
! if ((flags & DRIVE_CAP32) && len > 3) {
bus_space_read_multi_stream_4(wdr->data32iot,
wdr->data32ioh, 0, bf, len >> 2);
bf = (char *)bf + (len & ~3);
len &= 3;
}
! if (len > 1) {
bus_space_read_multi_stream_2(wdr->cmd_iot,
wdr->cmd_iohs[wd_data], 0, bf, len >> 1);
+ bf = (char *)bf + (len & ~1);
+ len &= 1;
}
}
+ if (len)
+ *((uint8_t *)bf) = bus_space_read_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_data], 0);
return;
#ifndef __NO_STRICT_ALIGNMENT
Home |
Main Index |
Thread Index |
Old Index