11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  sata_promise.h - Promise SATA common definitions and inline funcs
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Copyright 2003-2004 Red Hat, Inc.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *
7af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  This program is free software; you can redistribute it and/or modify
8af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  it under the terms of the GNU General Public License as published by
9af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  the Free Software Foundation; either version 2, or (at your option)
10af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  any later version.
11af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *
12af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  This program is distributed in the hope that it will be useful,
13af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  GNU General Public License for more details.
16af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *
17af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  You should have received a copy of the GNU General Public License
18af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  along with this program; see the file COPYING.  If not, write to
19af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *
21af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *
22af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  libata documentation is available via 'make {ps|pdf}docs',
23af36d7f0df56de3e3e4bbfb15d0915097ecb8cabJeff Garzik *  as Documentation/DocBook/libata.*
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __SATA_PROMISE_H__
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __SATA_PROMISE_H__
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ata.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum pdc_packet_bits {
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PDC_PKT_READ		= (1 << 2),
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PDC_PKT_NODATA		= (1 << 3),
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PDC_PKT_SIZEMASK	= (1 << 7) | (1 << 6) | (1 << 5),
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PDC_PKT_CLEAR_BSY	= (1 << 4),
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PDC_PKT_WAIT_DRDY	= (1 << 3) | (1 << 4),
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PDC_LAST_REG		= (1 << 3),
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PDC_REG_DEVCTL		= (1 << 3) | (1 << 2) | (1 << 1),
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned int pdc_pkt_header(struct ata_taskfile *tf,
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					  dma_addr_t sg_table,
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					  unsigned int devno, u8 *buf)
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 dev_reg;
494ca4e439640cd1d3659cbcf60e7a73c2ae0450b3Al Viro	__le32 *buf32 = (__le32 *) buf;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* set control bits (byte 0), zero delay seq id (byte 3),
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * and seq id (byte 2)
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (tf->protocol) {
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ATA_PROT_DMA:
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!(tf->flags & ATA_TFLAG_WRITE))
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			buf32[0] = cpu_to_le32(PDC_PKT_READ);
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			buf32[0] = 0;
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ATA_PROT_NODATA:
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf32[0] = cpu_to_le32(PDC_PKT_NODATA);
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		BUG();
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf32[1] = cpu_to_le32(sg_table);	/* S/G table addr */
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf32[2] = 0;				/* no next-packet */
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (devno == 0)
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dev_reg = ATA_DEVICE_OBS;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dev_reg = ATA_DEVICE_OBS | ATA_DEV1;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* select device */
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[12] = (1 << 5) | PDC_PKT_CLEAR_BSY | ATA_REG_DEVICE;
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[13] = dev_reg;
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* device control register */
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[14] = (1 << 5) | PDC_REG_DEVCTL;
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[15] = tf->ctl;
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 16; 	/* offset of next byte */
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned int pdc_pkt_footer(struct ata_taskfile *tf, u8 *buf,
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  unsigned int i)
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (tf->flags & ATA_TFLAG_DEVICE) {
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf[i++] = (1 << 5) | ATA_REG_DEVICE;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf[i++] = tf->device;
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* and finally the command itself; also includes end-of-pkt marker */
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (1 << 5) | PDC_LAST_REG | ATA_REG_CMD;
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->command;
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return i;
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned int pdc_prep_lba28(struct ata_taskfile *tf, u8 *buf, unsigned int i)
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* the "(1 << 5)" should be read "(count << 5)" */
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* ATA command block registers */
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (1 << 5) | ATA_REG_FEATURE;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->feature;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (1 << 5) | ATA_REG_NSECT;
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->nsect;
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (1 << 5) | ATA_REG_LBAL;
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->lbal;
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (1 << 5) | ATA_REG_LBAM;
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->lbam;
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (1 << 5) | ATA_REG_LBAH;
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->lbah;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return i;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned int pdc_prep_lba48(struct ata_taskfile *tf, u8 *buf, unsigned int i)
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* the "(2 << 5)" should be read "(count << 5)" */
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* ATA command block registers */
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (2 << 5) | ATA_REG_FEATURE;
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->hob_feature;
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->feature;
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (2 << 5) | ATA_REG_NSECT;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->hob_nsect;
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->nsect;
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (2 << 5) | ATA_REG_LBAL;
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->hob_lbal;
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->lbal;
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (2 << 5) | ATA_REG_LBAM;
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->hob_lbam;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->lbam;
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = (2 << 5) | ATA_REG_LBAH;
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->hob_lbah;
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf[i++] = tf->lbah;
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return i;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __SATA_PROMISE_H__ */
158