NetBSD Problem Report #46599
From www@NetBSD.org Thu Jun 14 19:36:22 2012
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
by www.NetBSD.org (Postfix) with ESMTP id 2B32D63B8E6
for <gnats-bugs@gnats.NetBSD.org>; Thu, 14 Jun 2012 19:36:22 +0000 (UTC)
Message-Id: <20120614193621.5B59963B882@www.NetBSD.org>
Date: Thu, 14 Jun 2012 19:36:21 +0000 (UTC)
From: o.vd.linden@quicknet.nl
Reply-To: o.vd.linden@quicknet.nl
To: gnats-bugs@NetBSD.org
Subject: atapi xfers through a sil 3112 controller of an odd number of bytes or less than 4 bytes causes system lockup
X-Send-Pr-Version: www-1.0
>Number: 46599
>Category: kern
>Synopsis: atapi xfers through a sil 3112 controller of an odd number of bytes or less than 4 bytes causes system lockup
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jun 14 19:40:00 +0000 2012
>Closed-Date: Fri Dec 21 20:44:08 +0000 2012
>Last-Modified: Fri Dec 21 20:44:08 +0000 2012
>Originator: Onno van der Linden
>Release: 6.99.7
>Organization:
>Environment:
NetBSD sheep 6.99.7 NetBSD 6.99.7 (SHEEP) #3: Fri Jun 8 20:53:24 MEST 2012 root@sheep:/usr/src/sys/arch/i386/compile/SHEEP i386
>Description:
Running one of the cdrtool commands with the -scanbus option causes a system
with a sil 3112 controller and an atapi device to lockup solidly after which a hard reset
is the only way out.
>How-To-Repeat:
#include <sys/param.h>
#include <sys/scsiio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <dev/scsipi/scsi_spc.h>
#include <dev/scsipi/scsipiconf.h>
/* XXX hardcoded devicename attached to the sil 3112 ctrl */
const char *dvname = "/dev/rcd0d";
void
scsi_command(int fd, const void *cmd, size_t cmdlen,
void *data, size_t datalen, int timeout, int flags)
{
scsireq_t req;
memset(&req, 0, sizeof(req)); req.datalen = datalen;
req.timeout = timeout;
req.flags = flags;
req.senselen = SENSEBUFLEN;
if (ioctl(fd, SCIOCCOMMAND, &req) == -1)
err(1, "SCIOCCOMMAND");
if (req.retsts == SCCMD_OK)
return;
/* Some problem; report it and exit. */
if (req.retsts == SCCMD_TIMEOUT)
fprintf(stderr, "%s: SCSI command timed out\n", dvname);
else if (req.retsts == SCCMD_BUSY)
fprintf(stderr, "%s: device is busy\n", dvname);
else if (req.retsts == SCCMD_SENSE)
fprintf(stderr, "%s: device returned sense data\n", dvname);
else
fprintf(stderr, "%s: device had unknown status %x\n", dvname,
req.retsts);
exit(1);
}
void
scsi_mode_sense10(int fd, u_int8_t pgcode, u_int8_t pctl, void *buf, size_t len)
{
struct scsi_mode_sense_10 cmd;
memset(&cmd, 0, sizeof(cmd));
memset(buf, 0, len);
cmd.opcode = SCSI_MODE_SENSE_10;
cmd.page = pgcode | pctl;
_lto2b(len, &cmd.length[0]);
scsi_command(fd, &cmd, sizeof(cmd), buf, len, 60000,
SCCMD_READ|SCCMD_ESCAPE);
}
main(int argc, char *argv[])
{
int fd; close(fd);
char buf[256];
fd = open(dvname,O_RDWR,0);
/* 2,3 or any odd number will cause a lockup with satalink(4) */
scsi_mode_sense10(fd, 0x2A, 0, buf, 2);
close(fd);
}
>Fix:
Looks like the silicon image controller doesn't like small (< 4 bytes) or
transfers with an odd number of bytes at all even if the code in
atapi_wdc.c uses PIO instead of DMA in such cases.
Force transfers of at least 4 bytes in even numbers.
>Release-Note:
>Audit-Trail:
From: Onno van der Linden <o.vd.linden@quicknet.nl>
To: gnats-bugs@NetBSD.org
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
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/46599 CVS commit: src/sys/dev/ic
Date: Sun, 29 Jul 2012 14:20:14 -0400
Module Name: src
Committed By: christos
Date: Sun Jul 29 18:20:14 UTC 2012
Modified Files:
src/sys/dev/ic: wdc.c
Log Message:
PR/46599: Onno van der Linden: Don't call bus space commands with 0 len.
Causes the sil 3112 controller to lock up.
To generate a diff of this commit:
cvs rdiff -u -r1.272 -r1.273 src/sys/dev/ic/wdc.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Fri, 21 Dec 2012 20:44:08 +0000
State-Changed-Why:
christos committed it in july
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.