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