linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PATA Sil680 Disabling IRQ
@ 2008-02-27  0:47 Fajun Chen
  2008-02-27  0:58 ` Jeff Garzik
  0 siblings, 1 reply; 9+ messages in thread
From: Fajun Chen @ 2008-02-27  0:47 UTC (permalink / raw)
  To: linux-ide@vger.kernel.org; +Cc: Mark Lord, Tejun Heo

[-- Attachment #1: Type: text/plain, Size: 1763 bytes --]

Hi All,

Attached is the source code to Identify Device through sg (courtesy of
Mark Lord).  I intentionally change the data transfer from
SG_DXFER_FROM_DEV to SG_DXFER_TO_DEV to expose the problem.  When the
code is run on SATA Sil3124 controller,  it's working well. But when
it is run on PATA Sil680,  IRQ was disabled right away (see dmesg log
below). I have a old kernel 2.6.18 rc2 but I suspect the same problem
exists in latest kernel release as well.  Please execute above code in
your system and see what happens.

dmesg log:
[1204070913 936910] irq 15: nobody cared (try booting with the "irqpoll" option)
[1204070913 936978]  [<c0127037>] __report_bad_irq+0x2b/0x69
[1204070913 937039]  [<c012720f>] note_interrupt+0x19a/0x1d3
[1204070913 937089]  [<c0126848>] handle_IRQ_event+0x21/0x47
[1204070913 937138]  [<c01268de>] __do_IRQ+0x70/0x9f
[1204070913 937183]  [<c01044a9>] do_IRQ+0x43/0x52
[1204070913 937236]  [<c0102d7a>] common_interrupt+0x1a/0x20
[1204070913 937283]  [<c0114d58>] __do_softirq+0x27/0x6e
[1204070913 937341]  [<c0114dc1>] do_softirq+0x22/0x26
[1204070913 937386]  [<c01044ae>] do_IRQ+0x48/0x52
[1204070913 937430]  [<c0102d7a>] common_interrupt+0x1a/0x20
[1204070913 937478]  [<c01014b4>] default_idle+0x31/0x59
[1204070913 937523]  [<c010151b>] cpu_idle+0x3f/0x57
[1204070913 937568]  [<c02de63a>] start_kernel+0x2ba/0x2bc
[1204070913 937617] handlers:
[1204070913 937651] [<c01e2bb0>] (ata_interrupt+0x0/0x173)
[1204070913 937703] Disabling IRQ #15
[1204070917 801261] ata5 port frozen
[1204070917 801335] ata5.00: exception Emask 0x0 SAct 0x0 SErr 0x0
action 0x0 frozen
[1204070917 801407] ata5.00: tag 0 cmd 0xec Emask 0x6 stat 0x58 err
0x0 (timeout)
[1204070917 801476] ata5.00: lba 0x0 hob_lba 0x0 device 0x0

Thanks,
Fajun

[-- Attachment #2: sg_identify.c --]
[-- Type: application/octet-stream, Size: 3676 bytes --]

/*
 * This code is copyright 2007 by Mark Lord,
 * and is made available to all under the terms
 * of the GNU General Public License v2.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <linux/fs.h>
#include <linux/hdreg.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
#include <sys/mman.h>

typedef unsigned long long u64;

enum {
	ATA_CMD_PIO_IDENTIFY		= 0xec,
	ATA_CMD_PIO_PIDENTIFY		= 0xa1,

	/* normal sector size (bytes) for PIO/DMA */
	ATA_SECT_SIZE			= 512,

	ATA_16				= 0x85,
	ATA_16_LEN			= 16,

	ATA_DEV_REG_LBA			= (1 << 6),

	ATA_LBA48			= 1,

	/* data transfer protocols; only basic PIO and DMA actually work */
	ATA_PROTO_NON_DATA		= ( 3 << 1),
	ATA_PROTO_PIO_IN		= ( 4 << 1),
	ATA_PROTO_PIO_OUT		= ( 5 << 1),
	ATA_PROTO_DMA			= ( 6 << 1),
	ATA_PROTO_UDMA_IN		= (11 << 1), /* unsupported */
	ATA_PROTO_UDMA_OUT		= (12 << 1), /* unsupported */
};

/*
 * Taskfile layout for ATA_16 cdb (LBA28/LBA48):
 *
 *	cdb[ 4] = feature
 *	cdb[ 6] = nsect
 *	cdb[ 8] = lbal
 *	cdb[10] = lbam
 *	cdb[12] = lbah
 *	cdb[13] = device
 *	cdb[14] = command
 *
 * "high order byte" (hob) fields for LBA48 commands:
 *
 *	cdb[ 3] = hob_feature
 *	cdb[ 5] = hob_nsect
 *	cdb[ 7] = hob_lbal
 *	cdb[ 9] = hob_lbam
 *	cdb[11] = hob_lbah
 *
 * dxfer_direction choices:
 *
 *	SG_DXFER_TO_DEV		(writing to drive)
 *	SG_DXFER_FROM_DEV	(reading from drive)
 *	SG_DXFER_NONE		(non-data commands)
 */

static int sg_issue (int fd, unsigned char ata_op, void *buf)
{
	unsigned char cdb[ATA_16_LEN]
		= { ATA_16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	unsigned char sense[32];
	unsigned int nsects = 1;
	struct sg_io_hdr hdr;

	cdb[ 1] = ATA_PROTO_PIO_IN;
	cdb[ 6] = nsects;
	cdb[14] = ata_op;

	memset(&hdr, 0, sizeof(struct sg_io_hdr));
	hdr.interface_id	= 'S';
	hdr.cmd_len		= ATA_16_LEN;
	hdr.mx_sb_len		= sizeof(sense);
	hdr.dxfer_direction	= SG_DXFER_TO_DEV;
	hdr.dxfer_len		= nsects * ATA_SECT_SIZE;
	hdr.dxferp		= buf;
	hdr.cmdp		= cdb;
	hdr.sbp			= sense;
	hdr.timeout		= 5000; /* milliseconds */

	memset(sense, 0, sizeof(sense));
	if (ioctl(fd, SG_IO, &hdr) < 0) {
		perror("ioctl(SG_IO)");
		return (-1);
	}
	if (hdr.status == 0 && hdr.host_status == 0 && hdr.driver_status == 0)
		return 0; /* success */

	if (hdr.status > 0) {
		unsigned char *d = sense + 8;
		/* SCSI status is non-zero */
		fprintf(stderr, "SG_IO error: SCSI sense=0x%x/%02x/%02x, ATA=0x%02x/%02x\n",
			sense[1] & 0xf, sense[2], sense[3], d[13], d[3]);
		return -1;
	}
	/* some other error we don't know about yet */
	fprintf(stderr, "SG_IO returned: SCSI status=0x%x, host_status=0x%x, driver_status=0x%x\n",
		hdr.status, hdr.host_status, hdr.driver_status);
	return -1;
}

int main (int argc, char *argv[])
{
	const char *devpath;
	int i, rc, fd;
#if 0
	unsigned short id[ATA_SECT_SIZE / 2];
	memset(id, 0, sizeof(id));
#else
	unsigned short *id;
	id = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
	if (id == MAP_FAILED) {
		perror("mmap");
		exit(1);
	}
#endif
	if (argc != 2) {
		fprintf(stderr, "%s: bad/missing parm: expected <devpath>\n", argv[0]);
		exit(1);
	}
	devpath = argv[1];

	fd = open(devpath, O_RDWR|O_NONBLOCK);
	if (fd == -1) {
		perror(devpath);
		exit(1);
	}
	rc = sg_issue(fd, ATA_CMD_PIO_IDENTIFY, id);
	if (rc != 0)
		rc = sg_issue(fd, ATA_CMD_PIO_PIDENTIFY, id);
	if (rc == 0) {
		unsigned short *d = id;
		for (i = 0; i < (256/8); ++i) {
			printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
				d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]);
			d += 8;
		}
		exit(0);
	}
	exit(1);
}

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-02-29 11:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-27  0:47 PATA Sil680 Disabling IRQ Fajun Chen
2008-02-27  0:58 ` Jeff Garzik
2008-02-28  0:20   ` Fajun Chen
2008-02-28 20:22     ` Alan Cox
2008-02-28 22:11       ` Fajun Chen
2008-02-28 22:24         ` Jeff Garzik
2008-02-28 23:10         ` Alan Cox
2008-02-29  1:07           ` Fajun Chen
2008-02-29 11:21             ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).