NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/46599: atapi xfers through a sil 3112 controller of an odd number of bytes or less than 4 bytes causes system lockup
>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: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jun 14 19:40:00 +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.
Home |
Main Index |
Thread Index |
Old Index