[git patches] 2.6.x libata updates

3 views
Skip to first unread message

Jeff Garzik

unread,
Oct 27, 2005, 8:49:36 PM10/27/05
to Andrew Morton, Linus Torvalds, linu...@vger.kernel.org, linux-...@vger.kernel.org

Please pull from 'upstream' branch of
master.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git

Broad changes:
* improved PATA support
* new drivers: pdc_adma, sata_sil24
* vastly improved sata_mv driver (60xx only, alas)
* small cleanups etc.


Documentation/DocBook/libata.tmpl | 1072 +++++++++++++++++++++++++++++++++++
drivers/scsi/Kconfig | 22
drivers/scsi/Makefile | 2
drivers/scsi/ahci.c | 41 -
drivers/scsi/ata_piix.c | 4
drivers/scsi/libata-core.c | 876 +++++++++++++++++++----------
drivers/scsi/libata-scsi.c | 736 +++++++++++++++++-------
drivers/scsi/libata.h | 19
drivers/scsi/pdc_adma.c | 739 ++++++++++++++++++++++++
drivers/scsi/sata_mv.c | 1145 +++++++++++++++++++++++++++++++-------
drivers/scsi/sata_nv.c | 8
drivers/scsi/sata_promise.c | 26
drivers/scsi/sata_qstor.c | 8
drivers/scsi/sata_sil.c | 6
drivers/scsi/sata_sil24.c | 875 +++++++++++++++++++++++++++++
drivers/scsi/sata_sis.c | 4
drivers/scsi/sata_svw.c | 4
drivers/scsi/sata_sx4.c | 29
drivers/scsi/sata_uli.c | 4
drivers/scsi/sata_via.c | 4
drivers/scsi/sata_vsc.c | 14
include/linux/ata.h | 41 +
include/linux/libata.h | 113 ++-
23 files changed, 4973 insertions(+), 819 deletions(-)

Al Viro:
iomem annotations (sata_nv)
iomem annotations (ahci)
iomem annotations (sata_promise)
enum safety (sata_qstor)
iomem annotations (sata_sx4)
iomem annotations (sata_sil)
iomem annotations (sata_vsc)

Alan Cox:
ata: re-order speeds sensibly.
libata: bitmask based pci init functions for one or two ports
libata: handle early device PIO modes correctly
Add ide-timing functionality to libata.
[libata] ata_timing fix

Albert Lee:
[libata] C/H/S support, for older devices
libata: indent and whitespace change
libata: rename host states
libata: minor whitespace, comment, debug message updates
[libata scsi] tidy up SCSI lba and xfer len calculations
[libata scsi] add CHS support to ata_scsi_start_stop_xlat()
libata CHS: move the initialization of taskfile LBA flags (revise #6)
libata CHS: calculate read/write commands and protocol on the fly (revise #6)
libata CHS: reread device identify info (revise #6)

Andy Currid:
Fix sata_nv handling of NVIDIA MCP51/55

Brett Russ:
libata: Marvell SATA support (DMA mode) (resend: v0.22)
libata: Marvell spinlock fixes and simplification
libata: Marvell function headers
libata: Marvell endian fix

Douglas Gilbert:
[libata scsi] add ata_scsi_set_sense helper
[libata scsi] improve scsi error handling with ata_scsi_set_sense()

Jeff Garzik:
libata: move EH docs to separate DocBook chapter
[libata] improve device scan
[libata] improve device scan even more
libata: add ata_ratelimit(), use it in AHCI driver irq handler
libata: ATAPI command completion tweaks and notes
libata: move atapi_request_sense() to libata-scsi module
[libata sata_mv] fix warning
libata: minor cleanups
[libata pdc_adma] license update, minor cleanup
libata: turn on block layer clustering
libata: const-ification bombing run

Mark Lord:
libata: add new driver pdc_adma for PDC ADMA ATA cards

Randy Dunlap:
libata kernel-doc fixes

Tejun Heo:
SATA: rewritten sil24 driver
sil24: add FIXME comment above ata_device_add
sil24: remove irq disable code on spurious interrupt
sil24: add testing for PCI fault
sil24: move error handling out of hot interrupt path
sil24: remove PORT_TF
sil24: replace pp->port w/ ap->ioaddr.cmd_addr
sil24: fix PORT_CTRL_STAT constants
sil24: add more comments for constants
sil24: initialization fix
libata EH document update
libata: add ATA exceptions chapter to doc
sil24: ignore non-error exception irqs
sil24: remove CMDERR clearing
sil24: implement proper TF register reading & caching
sil24: implement tf_read callback
[libata sata_sil24] nit pickings
[libata sata_sil24] add support for 3131/3531

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Linus Torvalds

unread,
Oct 28, 2005, 12:10:16 PM10/28/05
to Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org

On Thu, 27 Oct 2005, Jeff Garzik wrote:
>
> Please pull from 'upstream' branch of
> master.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git

Btw, that would be missing a ':'

Pulled, pushed out.

Linus

Jeff Garzik

unread,
Oct 29, 2005, 2:23:15 PM10/29/05
to Andrew Morton, Linus Torvalds, linu...@vger.kernel.org, linux-...@vger.kernel.org

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git

to obtain misc fixes and cleanups, and to merge
the ATA passthru (SMART support) feature.

drivers/scsi/libata-core.c | 18 -
drivers/scsi/libata-scsi.c | 790 ++++++++++++++++++++++++++++++++++++--------
drivers/scsi/libata.h | 3
drivers/scsi/pdc_adma.c | 28 -
drivers/scsi/sata_promise.c | 4
drivers/scsi/sata_qstor.c | 2
drivers/scsi/sata_sil24.c | 35 +
drivers/scsi/sata_svw.c | 22 -
drivers/scsi/sata_vsc.c | 20 -
include/scsi/scsi.h | 3
10 files changed, 740 insertions(+), 185 deletions(-)

Al Viro:
sata_sil24 iomem annotations and fixes

Douglas Gilbert:
[libata scsi] MODE SELECT, strengthen mode sense

Ed Kear:
libata: add support for Promise SATA 300 TX2plus PDC40775

Jeff Garzik:
[libata] ATA passthru (arbitrary ATA command execution)
libata: Update 'passthru' branch for latest libata
[libata passthru] add (DRIVER_SENSE << 24) to all check-conditions
[libata passthru] update ATAPI completion for new error handling
[libata pdc_adma] minor fixes and cleanups
[libata sata_promise] add pci id
[libata] ensure ->tf_read() hook reads Status and Error registers

Jeff Raubitschek:
[libata passthru] fix leak on error

Randy Dunlap:
libata-core cleanups (updated)

diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index f53d7b8..b1b1c6f 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -370,6 +370,8 @@ static void ata_tf_read_pio(struct ata_p
{
struct ata_ioports *ioaddr = &ap->ioaddr;

+ tf->command = ata_check_status(ap);
+ tf->feature = ata_chk_err(ap);
tf->nsect = inb(ioaddr->nsect_addr);
tf->lbal = inb(ioaddr->lbal_addr);
tf->lbam = inb(ioaddr->lbam_addr);
@@ -402,6 +404,8 @@ static void ata_tf_read_mmio(struct ata_
{
struct ata_ioports *ioaddr = &ap->ioaddr;

+ tf->command = ata_check_status(ap);
+ tf->feature = ata_chk_err(ap);
tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
@@ -4254,11 +4258,10 @@ int ata_device_add(const struct ata_prob

DPRINTK("ENTER\n");
/* alloc a container for our list of ATA ports (buses) */
- host_set = kmalloc(sizeof(struct ata_host_set) +
+ host_set = kzalloc(sizeof(struct ata_host_set) +
(ent->n_ports * sizeof(void *)), GFP_KERNEL);
if (!host_set)
return 0;
- memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));
spin_lock_init(&host_set->lock);

host_set->dev = dev;
@@ -4298,10 +4301,8 @@ int ata_device_add(const struct ata_prob
count++;
}

- if (!count) {
- kfree(host_set);
- return 0;
- }
+ if (!count)
+ goto err_free_ret;

/* obtain irq, that is shared between channels */
if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
@@ -4359,6 +4360,7 @@ err_out:
ata_host_remove(host_set->ports[i], 1);
scsi_host_put(host_set->ports[i]->host);
}
+err_free_ret:
kfree(host_set);
VPRINTK("EXIT, returning 0\n");
return 0;
@@ -4468,15 +4470,13 @@ ata_probe_ent_alloc(struct device *dev,
{
struct ata_probe_ent *probe_ent;

- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent) {
printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
kobject_name(&(dev->kobj)));
return NULL;
}

- memset(probe_ent, 0, sizeof(*probe_ent));
-
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->dev = dev;

diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 5885888..89a04b1 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -40,14 +40,56 @@
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include <linux/hdreg.h>
#include <asm/uaccess.h>

#include "libata.h"

+#define SECTOR_SIZE 512
+
typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
static struct ata_device *
ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);

+#define RW_RECOVERY_MPAGE 0x1
+#define RW_RECOVERY_MPAGE_LEN 12
+#define CACHE_MPAGE 0x8
+#define CACHE_MPAGE_LEN 20
+#define CONTROL_MPAGE 0xa
+#define CONTROL_MPAGE_LEN 12
+#define ALL_MPAGES 0x3f
+#define ALL_SUB_MPAGES 0xff
+
+
+static const u8 def_rw_recovery_mpage[] = {
+ RW_RECOVERY_MPAGE,
+ RW_RECOVERY_MPAGE_LEN - 2,
+ (1 << 7) | /* AWRE, sat-r06 say it shall be 0 */
+ (1 << 6), /* ARRE (auto read reallocation) */
+ 0, /* read retry count */
+ 0, 0, 0, 0,
+ 0, /* write retry count */
+ 0, 0, 0
+};
+
+static const u8 def_cache_mpage[CACHE_MPAGE_LEN] = {
+ CACHE_MPAGE,
+ CACHE_MPAGE_LEN - 2,
+ 0, /* contains WCE, needs to be 0 for logic */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, /* contains DRA, needs to be 0 for logic */
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
+ CONTROL_MPAGE,
+ CONTROL_MPAGE_LEN - 2,
+ 2, /* DSENSE=0, GLTSD=1 */
+ 0, /* [QAM+QERR may be 1, see 05-359r1] */
+ 0, 0, 0, 0, 0xff, 0xff,
+ 0, 30 /* extended self test time, see 05-359r1 */
+};
+

static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
@@ -86,6 +128,150 @@ int ata_std_bios_param(struct scsi_devic
return 0;
}

+/**
+ * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
+ * @dev: Device to whom we are issuing command
+ * @arg: User provided data for issuing command
+ *
+ * LOCKING:
+ * Defined by the SCSI layer. We don't really care.
+ *
+ * RETURNS:
+ * Zero on success, negative errno on error.
+ */
+
+int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
+{
+ int rc = 0;
+ u8 scsi_cmd[MAX_COMMAND_SIZE];
+ u8 args[4], *argbuf = NULL;
+ int argsize = 0;
+ struct scsi_request *sreq;
+
+ if (NULL == (void *)arg)
+ return -EINVAL;
+
+ if (copy_from_user(args, arg, sizeof(args)))
+ return -EFAULT;
+
+ sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
+ if (!sreq)
+ return -EINTR;
+
+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
+
+ if (args[3]) {
+ argsize = SECTOR_SIZE * args[3];
+ argbuf = kmalloc(argsize, GFP_KERNEL);
+ if (argbuf == NULL) {
+ rc = -ENOMEM;
+ goto error;
+ }
+
+ scsi_cmd[1] = (4 << 1); /* PIO Data-in */
+ scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev,
+ block count in sector count field */
+ sreq->sr_data_direction = DMA_FROM_DEVICE;
+ } else {
+ scsi_cmd[1] = (3 << 1); /* Non-data */
+ /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+ sreq->sr_data_direction = DMA_NONE;
+ }
+
+ scsi_cmd[0] = ATA_16;
+
+ scsi_cmd[4] = args[2];
+ if (args[0] == WIN_SMART) { /* hack -- ide driver does this too... */
+ scsi_cmd[6] = args[3];
+ scsi_cmd[8] = args[1];
+ scsi_cmd[10] = 0x4f;
+ scsi_cmd[12] = 0xc2;
+ } else {
+ scsi_cmd[6] = args[1];
+ }
+ scsi_cmd[14] = args[0];
+
+ /* Good values for timeout and retries? Values below
+ from scsi_ioctl_send_command() for default case... */
+ scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5);
+
+ if (sreq->sr_result) {
+ rc = -EIO;
+ goto error;
+ }
+
+ /* Need code to retrieve data from check condition? */
+
+ if ((argbuf)
+ && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
+ rc = -EFAULT;
+error:
+ scsi_release_request(sreq);
+
+ if (argbuf)
+ kfree(argbuf);
+
+ return rc;
+}
+
+/**
+ * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
+ * @dev: Device to whom we are issuing command
+ * @arg: User provided data for issuing command
+ *
+ * LOCKING:
+ * Defined by the SCSI layer. We don't really care.
+ *
+ * RETURNS:
+ * Zero on success, negative errno on error.
+ */
+int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
+{
+ int rc = 0;
+ u8 scsi_cmd[MAX_COMMAND_SIZE];
+ u8 args[7];
+ struct scsi_request *sreq;
+
+ if (NULL == (void *)arg)
+ return -EINVAL;
+
+ if (copy_from_user(args, arg, sizeof(args)))
+ return -EFAULT;
+
+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
+ scsi_cmd[0] = ATA_16;
+ scsi_cmd[1] = (3 << 1); /* Non-data */
+ /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+ scsi_cmd[4] = args[1];
+ scsi_cmd[6] = args[2];
+ scsi_cmd[8] = args[3];
+ scsi_cmd[10] = args[4];
+ scsi_cmd[12] = args[5];
+ scsi_cmd[14] = args[0];
+
+ sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
+ if (!sreq) {
+ rc = -EINTR;
+ goto error;
+ }
+
+ sreq->sr_data_direction = DMA_NONE;
+ /* Good values for timeout and retries? Values below
+ from scsi_ioctl_send_command() for default case... */
+ scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5);
+
+ if (sreq->sr_result) {
+ rc = -EIO;
+ goto error;
+ }
+
+ /* Need code to retrieve data from check condition? */
+
+error:
+ scsi_release_request(sreq);
+ return rc;
+}
+
int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
{
struct ata_port *ap;
@@ -115,6 +301,16 @@ int ata_scsi_ioctl(struct scsi_device *s
return -EINVAL;
return 0;

+ case HDIO_DRIVE_CMD:
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+ return -EACCES;
+ return ata_cmd_ioctl(scsidev, arg);
+
+ case HDIO_DRIVE_TASK:
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+ return -EACCES;
+ return ata_task_ioctl(scsidev, arg);
+
default:
rc = -ENOTTY;
break;
@@ -173,23 +369,70 @@ struct ata_queued_cmd *ata_scsi_qc_new(s
}

/**
+ * ata_dump_status - user friendly display of error info
+ * @id: id of the port in question
+ * @tf: ptr to filled out taskfile
+ *
+ * Decode and dump the ATA error/status registers for the user so
+ * that they have some idea what really happened at the non
+ * make-believe layer.
+ *
+ * LOCKING:
+ * inherited from caller
+ */
+void ata_dump_status(unsigned id, struct ata_taskfile *tf)
+{
+ u8 stat = tf->command, err = tf->feature;
+
+ printk(KERN_WARNING "ata%u: status=0x%02x { ", id, stat);
+ if (stat & ATA_BUSY) {
+ printk("Busy }\n"); /* Data is not valid in this case */
+ } else {
+ if (stat & 0x40) printk("DriveReady ");
+ if (stat & 0x20) printk("DeviceFault ");
+ if (stat & 0x10) printk("SeekComplete ");
+ if (stat & 0x08) printk("DataRequest ");
+ if (stat & 0x04) printk("CorrectedError ");
+ if (stat & 0x02) printk("Index ");
+ if (stat & 0x01) printk("Error ");
+ printk("}\n");
+
+ if (err) {
+ printk(KERN_WARNING "ata%u: error=0x%02x { ", id, err);
+ if (err & 0x04) printk("DriveStatusError ");
+ if (err & 0x80) {
+ if (err & 0x04) printk("BadCRC ");
+ else printk("Sector ");
+ }
+ if (err & 0x40) printk("UncorrectableError ");
+ if (err & 0x10) printk("SectorIdNotFound ");
+ if (err & 0x02) printk("TrackZeroNotFound ");
+ if (err & 0x01) printk("AddrMarkNotFound ");
+ printk("}\n");
+ }
+ }
+}
+
+/**
* ata_to_sense_error - convert ATA error to SCSI error
- * @qc: Command that we are erroring out
* @drv_stat: value contained in ATA status register
+ * @drv_err: value contained in ATA error register
+ * @sk: the sense key we'll fill out
+ * @asc: the additional sense code we'll fill out
+ * @ascq: the additional sense code qualifier we'll fill out
*
- * Converts an ATA error into a SCSI error. While we are at it
- * we decode and dump the ATA error for the user so that they
- * have some idea what really happened at the non make-believe
- * layer.
+ * Converts an ATA error into a SCSI error. Fill out pointers to
+ * SK, ASC, and ASCQ bytes for later use in fixed or descriptor
+ * format sense blocks.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*/
-
-void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
+ u8 *ascq)
{
- struct scsi_cmnd *cmd = qc->scsicmd;
- u8 err = 0;
+ int i;
+
/* Based on the 3ware driver translation table */
static unsigned char sense_table[][4] = {
/* BBD|ECC|ID|MAR */
@@ -230,96 +473,184 @@ void ata_to_sense_error(struct ata_queue
{0x04, RECOVERED_ERROR, 0x11, 0x00}, // Recovered ECC error Medium error, recovered
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
};
- int i = 0;

/*
* Is this an error we can process/parse
*/
-
- if(drv_stat & ATA_ERR)
- /* Read the err bits */
- err = ata_chk_err(qc->ap);
-
- /* Display the ATA level error info */
-
- printk(KERN_WARNING "ata%u: status=0x%02x { ", qc->ap->id, drv_stat);
- if(drv_stat & 0x80)
- {
- printk("Busy ");
- err = 0; /* Data is not valid in this case */
+ if (drv_stat & ATA_BUSY) {
+ drv_err = 0; /* Ignore the err bits, they're invalid */
}
- else {
- if(drv_stat & 0x40) printk("DriveReady ");
- if(drv_stat & 0x20) printk("DeviceFault ");
- if(drv_stat & 0x10) printk("SeekComplete ");
- if(drv_stat & 0x08) printk("DataRequest ");
- if(drv_stat & 0x04) printk("CorrectedError ");
- if(drv_stat & 0x02) printk("Index ");
- if(drv_stat & 0x01) printk("Error ");
- }
- printk("}\n");
-
- if(err)
- {
- printk(KERN_WARNING "ata%u: error=0x%02x { ", qc->ap->id, err);
- if(err & 0x04) printk("DriveStatusError ");
- if(err & 0x80)
- {
- if(err & 0x04)
- printk("BadCRC ");
- else
- printk("Sector ");
+
+ if (drv_err) {
+ /* Look for drv_err */
+ for (i = 0; sense_table[i][0] != 0xFF; i++) {
+ /* Look for best matches first */
+ if ((sense_table[i][0] & drv_err) ==
+ sense_table[i][0]) {
+ *sk = sense_table[i][1];
+ *asc = sense_table[i][2];
+ *ascq = sense_table[i][3];
+ goto translate_done;
+ }
}
- if(err & 0x40) printk("UncorrectableError ");
- if(err & 0x10) printk("SectorIdNotFound ");
- if(err & 0x02) printk("TrackZeroNotFound ");
- if(err & 0x01) printk("AddrMarkNotFound ");
- printk("}\n");
+ /* No immediate match */
+ printk(KERN_WARNING "ata%u: no sense translation for "
+ "error 0x%02x\n", id, drv_err);
+ }

- /* Should we dump sector info here too ?? */
+ /* Fall back to interpreting status bits */
+ for (i = 0; stat_table[i][0] != 0xFF; i++) {
+ if (stat_table[i][0] & drv_stat) {
+ *sk = stat_table[i][1];
+ *asc = stat_table[i][2];
+ *ascq = stat_table[i][3];
+ goto translate_done;
+ }
}
+ /* No error? Undecoded? */
+ printk(KERN_WARNING "ata%u: no sense translation for status: 0x%02x\n",
+ id, drv_stat);
+
+ /* For our last chance pick, use medium read error because
+ * it's much more common than an ATA drive telling you a write
+ * has failed.
+ */
+ *sk = MEDIUM_ERROR;
+ *asc = 0x11; /* "unrecovered read error" */
+ *ascq = 0x04; /* "auto-reallocation failed" */
+
+ translate_done:
+ printk(KERN_ERR "ata%u: translated ATA stat/err 0x%02x/%02x to "
+ "SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n", id, drv_stat, drv_err,
+ *sk, *asc, *ascq);
+ return;
+}
+
+/*
+ * ata_gen_ata_desc_sense - Generate check condition sense block.
+ * @qc: Command that completed.
+ *
+ * This function is specific to the ATA descriptor format sense
+ * block specified for the ATA pass through commands. Regardless
+ * of whether the command errored or not, return a sense
+ * block. Copy all controller registers into the sense
+ * block. Clear sense key, ASC & ASCQ if there is no error.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ struct ata_taskfile *tf = &qc->tf;
+ unsigned char *sb = cmd->sense_buffer;
+ unsigned char *desc = sb + 8;

+ memset(sb, 0, SCSI_SENSE_BUFFERSIZE);

- /* Look for err */
- while(sense_table[i][0] != 0xFF)
- {
- /* Look for best matches first */
- if((sense_table[i][0] & err) == sense_table[i][0])
- {
- ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */,
- sense_table[i][2] /* asc */,
- sense_table[i][3] /* ascq */ );
- return;
- }
- i++;
+ cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+ /*
+ * Read the controller registers.
+ */
+ assert(NULL != qc->ap->ops->tf_read);
+ qc->ap->ops->tf_read(qc->ap, tf);
+
+ /*
+ * Use ata_to_sense_error() to map status register bits
+ * onto sense key, asc & ascq.
+ */
+ if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
+ ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
+ &sb[1], &sb[2], &sb[3]);
+ sb[1] &= 0x0f;
}
- /* No immediate match */
- if(err)
- printk(KERN_DEBUG "ata%u: no sense translation for 0x%02x\n", qc->ap->id, err);

- i = 0;
- /* Fall back to interpreting status bits */
- while(stat_table[i][0] != 0xFF)
- {
- if(stat_table[i][0] & drv_stat)
- {
- ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */,
- sense_table[i][2] /* asc */,
- sense_table[i][3] /* ascq */ );
- return;
- }
- i++;
+ /*
+ * Sense data is current and format is descriptor.
+ */
+ sb[0] = 0x72;
+
+ desc[0] = 0x09;
+
+ /*
+ * Set length of additional sense data.
+ * Since we only populate descriptor 0, the total
+ * length is the same (fixed) length as descriptor 0.
+ */
+ desc[1] = sb[7] = 14;
+
+ /*
+ * Copy registers into sense buffer.
+ */
+ desc[2] = 0x00;
+ desc[3] = tf->feature; /* == error reg */
+ desc[5] = tf->nsect;
+ desc[7] = tf->lbal;
+ desc[9] = tf->lbam;
+ desc[11] = tf->lbah;
+ desc[12] = tf->device;
+ desc[13] = tf->command; /* == status reg */
+
+ /*
+ * Fill in Extend bit, and the high order bytes
+ * if applicable.
+ */
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ desc[2] |= 0x01;
+ desc[4] = tf->hob_nsect;
+ desc[6] = tf->hob_lbal;
+ desc[8] = tf->hob_lbam;
+ desc[10] = tf->hob_lbah;
}
- /* No error ?? */
- printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat);
- /* additional-sense-code[-qualifier] */
-
- if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
- ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0x11, 0x4);
- /* "unrecovered read error" */
- } else {
- ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0xc, 0x2);
- /* "write error - auto-reallocation failed" */
+}
+
+/**
+ * ata_gen_fixed_sense - generate a SCSI fixed sense block
+ * @qc: Command that we are erroring out
+ *
+ * Leverage ata_to_sense_error() to give us the codes. Fit our
+ * LBA in here if there's room.
+ *
+ * LOCKING:
+ * inherited from caller
+ */
+void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ struct ata_taskfile *tf = &qc->tf;
+ unsigned char *sb = cmd->sense_buffer;
+
+ memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+
+ cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+ /*
+ * Read the controller registers.
+ */
+ assert(NULL != qc->ap->ops->tf_read);
+ qc->ap->ops->tf_read(qc->ap, tf);
+
+ /*
+ * Use ata_to_sense_error() to map status register bits
+ * onto sense key, asc & ascq.
+ */
+ if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
+ ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
+ &sb[2], &sb[12], &sb[13]);
+ sb[2] &= 0x0f;
+ }
+
+ sb[0] = 0x70;
+ sb[7] = 0x0a;
+
+ if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) {
+ /* A small (28b) LBA will fit in the 32b info field */
+ sb[0] |= 0x80; /* set valid bit */
+ sb[3] = tf->device & 0x0f;
+ sb[4] = tf->lbah;
+ sb[5] = tf->lbam;
+ sb[6] = tf->lbal;
}
}

@@ -871,11 +1202,36 @@ nothing_to_do:
static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
{
struct scsi_cmnd *cmd = qc->scsicmd;
+ int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ);

- if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
- ata_to_sense_error(qc, drv_stat);
- else
- cmd->result = SAM_STAT_GOOD;
+ /* For ATA pass thru (SAT) commands, generate a sense block if
+ * user mandated it or if there's an error. Note that if we
+ * generate because the user forced us to, a check condition
+ * is generated and the ATA register values are returned
+ * whether the command completed successfully or not. If there
+ * was no error, SK, ASC and ASCQ will all be zero.
+ */
+ if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) &&
+ ((cmd->cmnd[2] & 0x20) || need_sense)) {
+ ata_gen_ata_desc_sense(qc);
+ } else {
+ if (!need_sense) {
+ cmd->result = SAM_STAT_GOOD;
+ } else {
+ /* TODO: decide which descriptor format to use
+ * for 48b LBA devices and call that here
+ * instead of the fixed desc, which is only
+ * good for smaller LBA (and maybe CHS?)
+ * devices.
+ */
+ ata_gen_fixed_sense(qc);
+ }
+ }
+
+ if (need_sense) {
+ /* The ata_gen_..._sense routines fill in tf */
+ ata_dump_status(qc->ap->id, &qc->tf);
+ }

qc->scsidone(cmd);

@@ -1266,13 +1622,9 @@ static void ata_msense_push(u8 **ptr_io,
static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
const u8 *last)
{
- u8 page[] = {
- 0x8, /* page code */
- 0x12, /* page length */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 zeroes */
- 0, 0, 0, 0, 0, 0, 0, 0 /* 8 zeroes */
- };
+ u8 page[CACHE_MPAGE_LEN];

+ memcpy(page, def_cache_mpage, sizeof(page));
if (ata_id_wcache_enabled(id))
page[2] |= (1 << 2); /* write cache enable */
if (!ata_id_rahead_enabled(id))
@@ -1296,15 +1648,9 @@ static unsigned int ata_msense_caching(u

static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
{
- const u8 page[] = {0xa, 0xa, 6, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 30};
-
- /* byte 2: set the descriptor format sense data bit (bit 2)
- * since we need to support returning this format for SAT
- * commands and any SCSI commands against a 48b LBA device.
- */
-
- ata_msense_push(ptr_io, last, page, sizeof(page));
- return sizeof(page);
+ ata_msense_push(ptr_io, last, def_control_mpage,
+ sizeof(def_control_mpage));
+ return sizeof(def_control_mpage);
}

/**
@@ -1321,15 +1667,10 @@ static unsigned int ata_msense_ctl_mode(

static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
{
- const u8 page[] = {
- 0x1, /* page code */
- 0xa, /* page length */
- (1 << 7) | (1 << 6), /* note auto r/w reallocation */
- 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 9 zeroes */
- };

- ata_msense_push(ptr_io, last, page, sizeof(page));
- return sizeof(page);
+ ata_msense_push(ptr_io, last, def_rw_recovery_mpage,
+ sizeof(def_rw_recovery_mpage));
+ return sizeof(def_rw_recovery_mpage);
}

/**
@@ -1338,7 +1679,9 @@ static unsigned int ata_msense_rw_recove
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* @buflen: Response buffer length.
*
- * Simulate MODE SENSE commands.
+ * Simulate MODE SENSE commands. Assume this is invoked for direct
+ * access devices (e.g. disks) only. There should be no block
+ * descriptor for other device types.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
@@ -1348,15 +1691,22 @@ unsigned int ata_scsiop_mode_sense(struc
unsigned int buflen)
{
u8 *scsicmd = args->cmd->cmnd, *p, *last;
- unsigned int page_control, six_byte, output_len;
+ const u8 sat_blk_desc[] = {
+ 0, 0, 0, 0, /* number of blocks: sat unspecified */
+ 0,
+ 0, 0x2, 0x0 /* block length: 512 bytes */
+ };
+ u8 pg, spg;
+ unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen;

VPRINTK("ENTER\n");

six_byte = (scsicmd[0] == MODE_SENSE);
-
- /* we only support saved and current values (which we treat
- * in the same manner)
+ ebd = !(scsicmd[1] & 0x8); /* dbd bit inverted == edb */
+ /*
+ * LLBA bit in msense(10) ignored (compliant)
*/
+
page_control = scsicmd[2] >> 6;
switch (page_control) {
case 0: /* current */
@@ -1369,29 +1719,42 @@ unsigned int ata_scsiop_mode_sense(struc
goto invalid_fld;
}

- if (six_byte)
- output_len = 4;
- else
- output_len = 8;
+ if (six_byte) {
+ output_len = 4 + (ebd ? 8 : 0);
+ alloc_len = scsicmd[4];
+ } else {
+ output_len = 8 + (ebd ? 8 : 0);
+ alloc_len = (scsicmd[7] << 8) + scsicmd[8];
+ }
+ minlen = (alloc_len < buflen) ? alloc_len : buflen;

p = rbuf + output_len;
- last = rbuf + buflen - 1;
+ last = rbuf + minlen - 1;
+
+ pg = scsicmd[2] & 0x3f;
+ spg = scsicmd[3];
+ /*
+ * No mode subpages supported (yet) but asking for _all_
+ * subpages may be valid
+ */
+ if (spg && (spg != ALL_SUB_MPAGES))
+ goto invalid_fld;

- switch(scsicmd[2] & 0x3f) {
- case 0x01: /* r/w error recovery */
+ switch(pg) {
+ case RW_RECOVERY_MPAGE:
output_len += ata_msense_rw_recovery(&p, last);
break;

- case 0x08: /* caching */
+ case CACHE_MPAGE:
output_len += ata_msense_caching(args->id, &p, last);
break;

- case 0x0a: { /* control mode */
+ case CONTROL_MPAGE: {
output_len += ata_msense_ctl_mode(&p, last);
break;
}

- case 0x3f: /* all pages */
+ case ALL_MPAGES:
output_len += ata_msense_rw_recovery(&p, last);
output_len += ata_msense_caching(args->id, &p, last);
output_len += ata_msense_ctl_mode(&p, last);
@@ -1401,15 +1764,31 @@ unsigned int ata_scsiop_mode_sense(struc
goto invalid_fld;
}

+ if (minlen < 1)
+ return 0;
if (six_byte) {
output_len--;
rbuf[0] = output_len;
+ if (ebd) {
+ if (minlen > 3)
+ rbuf[3] = sizeof(sat_blk_desc);
+ if (minlen > 11)
+ memcpy(rbuf + 4, sat_blk_desc,
+ sizeof(sat_blk_desc));
+ }
} else {
output_len -= 2;
rbuf[0] = output_len >> 8;
- rbuf[1] = output_len;
+ if (minlen > 1)
+ rbuf[1] = output_len;
+ if (ebd) {
+ if (minlen > 7)
+ rbuf[7] = sizeof(sat_blk_desc);
+ if (minlen > 15)
+ memcpy(rbuf + 8, sat_blk_desc,
+ sizeof(sat_blk_desc));
+ }
}
-
return 0;

invalid_fld:
@@ -1623,7 +2002,12 @@ static int atapi_qc_complete(struct ata_
VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat);

if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ)))
- ata_to_sense_error(qc, drv_stat);
+ /* FIXME: not quite right; we don't want the
+ * translation of taskfile registers into
+ * a sense descriptors, since that's only
+ * correct for ATA, not ATAPI
+ */
+ ata_gen_ata_desc_sense(qc);

else if (unlikely(drv_stat & ATA_ERR)) {
DPRINTK("request check condition\n");
@@ -1782,6 +2166,143 @@ ata_scsi_find_dev(struct ata_port *ap, c
return dev;
}

+/*
+ * ata_scsi_map_proto - Map pass-thru protocol value to taskfile value.
+ * @byte1: Byte 1 from pass-thru CDB.
+ *
+ * RETURNS:
+ * ATA_PROT_UNKNOWN if mapping failed/unimplemented, protocol otherwise.
+ */
+static u8
+ata_scsi_map_proto(u8 byte1)
+{
+ switch((byte1 & 0x1e) >> 1) {
+ case 3: /* Non-data */
+ return ATA_PROT_NODATA;
+
+ case 6: /* DMA */
+ return ATA_PROT_DMA;
+
+ case 4: /* PIO Data-in */
+ case 5: /* PIO Data-out */
+ if (byte1 & 0xe0) {
+ return ATA_PROT_PIO_MULT;
+ }
+ return ATA_PROT_PIO;
+
+ case 10: /* Device Reset */
+ case 0: /* Hard Reset */
+ case 1: /* SRST */
+ case 2: /* Bus Idle */
+ case 7: /* Packet */
+ case 8: /* DMA Queued */
+ case 9: /* Device Diagnostic */
+ case 11: /* UDMA Data-in */
+ case 12: /* UDMA Data-Out */
+ case 13: /* FPDMA */
+ default: /* Reserved */
+ break;
+ }
+
+ return ATA_PROT_UNKNOWN;
+}
+
+/**
+ * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
+ * @qc: command structure to be initialized
+ * @cmd: SCSI command to convert
+ *
+ * Handles either 12 or 16-byte versions of the CDB.
+ *
+ * RETURNS:
+ * Zero on success, non-zero on failure.
+ */
+static unsigned int
+ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
+{
+ struct ata_taskfile *tf = &(qc->tf);
+ struct scsi_cmnd *cmd = qc->scsicmd;
+
+ if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
+ return 1;
+
+ /*
+ * 12 and 16 byte CDBs use different offsets to
+ * provide the various register values.
+ */
+ if (scsicmd[0] == ATA_16) {
+ /*
+ * 16-byte CDB - may contain extended commands.
+ *
+ * If that is the case, copy the upper byte register values.
+ */
+ if (scsicmd[1] & 0x01) {
+ tf->hob_feature = scsicmd[3];
+ tf->hob_nsect = scsicmd[5];
+ tf->hob_lbal = scsicmd[7];
+ tf->hob_lbam = scsicmd[9];
+ tf->hob_lbah = scsicmd[11];
+ tf->flags |= ATA_TFLAG_LBA48;
+ } else
+ tf->flags &= ~ATA_TFLAG_LBA48;
+
+ /*
+ * Always copy low byte, device and command registers.
+ */
+ tf->feature = scsicmd[4];
+ tf->nsect = scsicmd[6];
+ tf->lbal = scsicmd[8];
+ tf->lbam = scsicmd[10];
+ tf->lbah = scsicmd[12];
+ tf->device = scsicmd[13];
+ tf->command = scsicmd[14];
+ } else {
+ /*
+ * 12-byte CDB - incapable of extended commands.
+ */
+ tf->flags &= ~ATA_TFLAG_LBA48;
+
+ tf->feature = scsicmd[3];
+ tf->nsect = scsicmd[4];
+ tf->lbal = scsicmd[5];
+ tf->lbam = scsicmd[6];
+ tf->lbah = scsicmd[7];
+ tf->device = scsicmd[8];
+ tf->command = scsicmd[9];
+ }
+
+ /*
+ * Filter SET_FEATURES - XFER MODE command -- otherwise,
+ * SET_FEATURES - XFER MODE must be preceded/succeeded
+ * by an update to hardware-specific registers for each
+ * controller (i.e. the reason for ->set_piomode(),
+ * ->set_dmamode(), and ->post_set_mode() hooks).
+ */
+ if ((tf->command == ATA_CMD_SET_FEATURES)
+ && (tf->feature == SETFEATURES_XFER))
+ return 1;
+
+ /*
+ * Set flags so that all registers will be written,
+ * and pass on write indication (used for PIO/DMA
+ * setup.)
+ */
+ tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
+
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ tf->flags |= ATA_TFLAG_WRITE;
+
+ /*
+ * Set transfer length.
+ *
+ * TODO: find out if we need to do more here to
+ * cover scatter/gather case.
+ */
+ qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
+
+ return 0;
+}
+
/**
* ata_get_xlat_func - check if SCSI to ATA translation is possible
* @dev: ATA device
@@ -1814,6 +2335,11 @@ static inline ata_xlat_func_t ata_get_xl
case VERIFY:
case VERIFY_16:
return ata_scsi_verify_xlat;
+
+ case ATA_12:
+ case ATA_16:
+ return ata_scsi_pass_thru;
+
case START_STOP:
return ata_scsi_start_stop_xlat;
}
@@ -1972,7 +2498,7 @@ void ata_scsi_simulate(u16 *id,
ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns);
break;

- /* mandantory commands we haven't implemented yet */
+ /* mandatory commands we haven't implemented yet */
case REQUEST_SENSE:

/* all other commands */
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 3d60190..65c264b 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -50,13 +50,14 @@ extern void ata_dev_select(struct ata_po
unsigned int wait, unsigned int can_sleep);
extern void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf);
extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
+extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
+extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);


/* libata-scsi.c */
extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd);
extern void ata_scsi_scan_host(struct ata_port *ap);
-extern void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat);
extern int ata_scsi_error(struct Scsi_Host *host);
extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
unsigned int buflen);
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index 9820f27..af99feb 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -46,7 +46,7 @@
#include <linux/libata.h>

#define DRV_NAME "pdc_adma"
-#define DRV_VERSION "0.01"
+#define DRV_VERSION "0.03"

/* macro to calculate base address for ATA regs */
#define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40))
@@ -79,7 +79,6 @@ enum {
aNIEN = (1 << 8), /* irq mask: 1==masked */
aGO = (1 << 7), /* packet trigger ("Go!") */
aRSTADM = (1 << 5), /* ADMA logic reset */
- aRSTA = (1 << 2), /* ATA hard reset */
aPIOMD4 = 0x0003, /* PIO mode 4 */

/* ADMA_STATUS register bits */
@@ -452,24 +451,25 @@ static inline unsigned int adma_intr_pkt
struct adma_port_priv *pp;
struct ata_queued_cmd *qc;
void __iomem *chan = ADMA_REGS(mmio_base, port_no);
- u8 drv_stat, status = readb(chan + ADMA_STATUS);
+ u8 drv_stat = 0, status = readb(chan + ADMA_STATUS);

if (status == 0)
continue;
handled = 1;
adma_enter_reg_mode(ap);
- if ((ap->flags & ATA_FLAG_PORT_DISABLED))
+ if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))
continue;
pp = ap->private_data;
if (!pp || pp->state != adma_state_pkt)
continue;
qc = ata_qc_from_tag(ap, ap->active_tag);
- drv_stat = 0;
- if ((status & (aPERR | aPSD | aUIRQ)))
- drv_stat = ATA_ERR;
- else if (pp->pkt[0] != cDONE)
- drv_stat = ATA_ERR;
- ata_qc_complete(qc, drv_stat);
+ if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+ if ((status & (aPERR | aPSD | aUIRQ)))
+ drv_stat = ATA_ERR;
+ else if (pp->pkt[0] != cDONE)
+ drv_stat = ATA_ERR;
+ ata_qc_complete(qc, drv_stat);
+ }
}
return handled;
}
@@ -490,7 +490,7 @@ static inline unsigned int adma_intr_mmi
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {

/* check main status, clearing INTRQ */
- u8 status = ata_chk_status(ap);
+ u8 status = ata_check_status(ap);
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
@@ -561,15 +561,15 @@ static int adma_port_start(struct ata_po
if ((pp->pkt_dma & 7) != 0) {
printk("bad alignment for pp->pkt_dma: %08x\n",
(u32)pp->pkt_dma);
- goto err_out_kfree2;
+ dma_free_coherent(dev, ADMA_PKT_BYTES,
+ pp->pkt, pp->pkt_dma);
+ goto err_out_kfree;
}
memset(pp->pkt, 0, ADMA_PKT_BYTES);
ap->private_data = pp;
adma_reinit_engine(ap);
return 0;

-err_out_kfree2:
- kfree(pp);
err_out_kfree:
kfree(pp);
err_out:
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index eee93b0..63911f1 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -195,6 +195,8 @@ static struct ata_port_info pdc_port_inf
static struct pci_device_id pdc_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
+ { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
@@ -207,6 +209,8 @@ static struct pci_device_id pdc_ata_pci_
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
+ { PCI_VENDOR_ID_PROMISE, 0x3d73, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_2037x },

{ PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20319 },
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index 250dafa..1aaf330 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -433,7 +433,7 @@ static inline unsigned int qs_intr_mmio(
if (qc && (!(qc->tf.ctl & ATA_NIEN))) {

/* check main status, clearing INTRQ */
- u8 status = ata_chk_status(ap);
+ u8 status = ata_check_status(ap);
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 32d730b..51855d3 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -220,8 +220,8 @@ struct sil24_port_priv {

/* ap->host_set->private_data */
struct sil24_host_priv {
- void *host_base; /* global controller control (128 bytes @BAR0) */
- void *port_base; /* port registers (4 * 8192 bytes @BAR2) */
+ void __iomem *host_base; /* global controller control (128 bytes @BAR0) */
+ void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */
};

static u8 sil24_check_status(struct ata_port *ap);
@@ -349,10 +349,12 @@ static struct ata_port_info sil24_port_i
static inline void sil24_update_tf(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
- void *port = (void *)ap->ioaddr.cmd_addr;
- struct sil24_prb *prb = port;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ struct sil24_prb __iomem *prb = port;
+ u8 fis[6 * 4];

- ata_tf_from_fis(prb->fis, &pp->tf);
+ memcpy_fromio(fis, prb->fis, 6 * 4);
+ ata_tf_from_fis(fis, &pp->tf);
}

static u8 sil24_check_status(struct ata_port *ap)
@@ -376,9 +378,9 @@ static int sil24_scr_map[] = {

static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
{
- void *scr_addr = (void *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
- void *addr;
+ void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
return readl(scr_addr + sil24_scr_map[sc_reg] * 4);
}
@@ -387,9 +389,9 @@ static u32 sil24_scr_read(struct ata_por

static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
{
- void *scr_addr = (void *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
- void *addr;
+ void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
writel(val, scr_addr + sil24_scr_map[sc_reg] * 4);
}
@@ -454,7 +456,7 @@ static void sil24_qc_prep(struct ata_que
static int sil24_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void *port = (void *)ap->ioaddr.cmd_addr;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
struct sil24_port_priv *pp = ap->private_data;
dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block);

@@ -467,7 +469,7 @@ static void sil24_irq_clear(struct ata_p
/* unused */
}

-static int __sil24_reset_controller(void *port)
+static int __sil24_reset_controller(void __iomem *port)
{
int cnt;
u32 tmp;
@@ -493,7 +495,7 @@ static void sil24_reset_controller(struc
{
printk(KERN_NOTICE DRV_NAME
" ata%u: resetting controller...\n", ap->id);
- if (__sil24_reset_controller((void *)ap->ioaddr.cmd_addr))
+ if (__sil24_reset_controller((void __iomem *)ap->ioaddr.cmd_addr))
printk(KERN_ERR DRV_NAME
" ata%u: failed to reset controller\n", ap->id);
}
@@ -527,7 +529,7 @@ static void sil24_error_intr(struct ata_
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
struct sil24_port_priv *pp = ap->private_data;
- void *port = (void *)ap->ioaddr.cmd_addr;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
u32 irq_stat, cmd_err, sstatus, serror;

irq_stat = readl(port + PORT_IRQ_STAT);
@@ -574,7 +576,7 @@ static void sil24_error_intr(struct ata_
static inline void sil24_host_intr(struct ata_port *ap)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
- void *port = (void *)ap->ioaddr.cmd_addr;
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
u32 slot_stat;

slot_stat = readl(port + PORT_SLOT_STAT);
@@ -689,7 +691,8 @@ static int sil24_init_one(struct pci_dev
struct ata_port_info *pinfo = &sil24_port_info[board_id];
struct ata_probe_ent *probe_ent = NULL;
struct sil24_host_priv *hpriv = NULL;
- void *host_base = NULL, *port_base = NULL;
+ void __iomem *host_base = NULL;
+ void __iomem *port_base = NULL;
int i, rc;

if (!printed_version++)
@@ -771,7 +774,7 @@ static int sil24_init_one(struct pci_dev
writel(0, host_base + HOST_CTRL);

for (i = 0; i < probe_ent->n_ports; i++) {
- void *port = port_base + i * PORT_REGS_SIZE;
+ void __iomem *port = port_base + i * PORT_REGS_SIZE;
unsigned long portu = (unsigned long)port;
u32 tmp;
int cnt;
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index e0f9570..46208f5 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -84,6 +84,8 @@
/* Port stride */
#define K2_SATA_PORT_OFFSET 0x100

+static u8 k2_stat_check_status(struct ata_port *ap);
+

static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
@@ -136,16 +138,24 @@ static void k2_sata_tf_load(struct ata_p
static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- u16 nsect, lbal, lbam, lbah;
+ u16 nsect, lbal, lbam, lbah, feature;

- nsect = tf->nsect = readw(ioaddr->nsect_addr);
- lbal = tf->lbal = readw(ioaddr->lbal_addr);
- lbam = tf->lbam = readw(ioaddr->lbam_addr);
- lbah = tf->lbah = readw(ioaddr->lbah_addr);
+ tf->command = k2_stat_check_status(ap);
tf->device = readw(ioaddr->device_addr);
+ feature = readw(ioaddr->error_addr);
+ nsect = readw(ioaddr->nsect_addr);
+ lbal = readw(ioaddr->lbal_addr);
+ lbam = readw(ioaddr->lbam_addr);
+ lbah = readw(ioaddr->lbah_addr);
+
+ tf->feature = feature;
+ tf->nsect = nsect;
+ tf->lbal = lbal;
+ tf->lbam = lbam;
+ tf->lbah = lbah;

if (tf->flags & ATA_TFLAG_LBA48) {
- tf->hob_feature = readw(ioaddr->error_addr) >> 8;
+ tf->hob_feature = feature >> 8;
tf->hob_nsect = nsect >> 8;
tf->hob_lbal = lbal >> 8;
tf->hob_lbam = lbam >> 8;
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index 5af05fd..54273e0 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -153,16 +153,24 @@ static void vsc_sata_tf_load(struct ata_
static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- u16 nsect, lbal, lbam, lbah;
+ u16 nsect, lbal, lbam, lbah, feature;

- nsect = tf->nsect = readw(ioaddr->nsect_addr);
- lbal = tf->lbal = readw(ioaddr->lbal_addr);
- lbam = tf->lbam = readw(ioaddr->lbam_addr);
- lbah = tf->lbah = readw(ioaddr->lbah_addr);
+ tf->command = ata_check_status(ap);
tf->device = readw(ioaddr->device_addr);
+ feature = readw(ioaddr->error_addr);
+ nsect = readw(ioaddr->nsect_addr);
+ lbal = readw(ioaddr->lbal_addr);
+ lbam = readw(ioaddr->lbam_addr);
+ lbah = readw(ioaddr->lbah_addr);
+
+ tf->feature = feature;
+ tf->nsect = nsect;
+ tf->lbal = lbal;
+ tf->lbam = lbam;
+ tf->lbah = lbah;

if (tf->flags & ATA_TFLAG_LBA48) {
- tf->hob_feature = readb(ioaddr->error_addr);
+ tf->hob_feature = feature >> 8;
tf->hob_nsect = nsect >> 8;
tf->hob_lbal = lbal >> 8;
tf->hob_lbam = lbam >> 8;
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index b361172..6cb1e27 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -116,6 +116,9 @@ extern const char *const scsi_device_typ
/* values for service action in */
#define SAI_READ_CAPACITY_16 0x10

+/* Values for T10/04-262r7 */
+#define ATA_16 0x85 /* 16-byte pass-thru */
+#define ATA_12 0xa1 /* 12-byte pass-thru */

/*
* SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft

Andrew Morton

unread,
Oct 29, 2005, 3:17:50 PM10/29/05
to Jeff Garzik, torv...@osdl.org, linu...@vger.kernel.org, linux-...@vger.kernel.org
Jeff Garzik <jga...@pobox.com> wrote:
>
> Please pull from 'upstream-linus' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
>
> to obtain misc fixes and cleanups, and to merge
> the ATA passthru (SMART support) feature.

Are you sure this doesn't propagate Max Kellermann's "2.6.14-rc4-mm1 and
later: second ata_piix controller is invisible" regression?

He did confirm that git-libata-all.patch caused it.

Jeff Garzik

unread,
Oct 29, 2005, 3:20:38 PM10/29/05
to Andrew Morton, torv...@osdl.org, linu...@vger.kernel.org, linux-...@vger.kernel.org
Andrew Morton wrote:
> Jeff Garzik <jga...@pobox.com> wrote:
>
>>Please pull from 'upstream-linus' branch of
>> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
>>
>> to obtain misc fixes and cleanups, and to merge
>> the ATA passthru (SMART support) feature.
>
>
> Are you sure this doesn't propagate Max Kellermann's "2.6.14-rc4-mm1 and
> later: second ata_piix controller is invisible" regression?
>
> He did confirm that git-libata-all.patch caused it.

Highly doubtful.

Even so, it's easy, to I'll ask him to test 2.6.14, 2.6.14-git1, and
(tonight's upcoming) 2.6.14-git2 (with my latest pull included) to see
if anything breaks.

I think it's some of Alan's changes that aren't yet merged upstream,
though I could be wrong.

Jeff

Linus Torvalds

unread,
Oct 29, 2005, 3:39:24 PM10/29/05
to Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org

On Sat, 29 Oct 2005, Jeff Garzik wrote:
>
> Even so, it's easy, to I'll ask him to test 2.6.14, 2.6.14-git1, and
> (tonight's upcoming) 2.6.14-git2 (with my latest pull included) to see if
> anything breaks.

Side note: one of the downsides of the new "merge lots of stuff early in
the development series" approach is that the first few daily snapshots end
up being _huge_.

So the -git1 and -git2 patches are/will be very big indeed.

For example, patch-2.6.14-git1 literally ended up being a megabyte
compressed. Right now my diff to 2.6.14 (after just two days) is 1.6MB
compressed.

Admittedly, some of it is due to things like the MIPS merge, but the point
I'm trying to make is that it makes the daily snapshot diffs a lot less
useful to people who try to figure out where something broke.

Now, I've gotten several positive comments on how easy "git bisect" is to
use, and I've used it myself, but this is the first time that patch users
_really_ become very much second-class citizens, and you can't necessarily
always do useful things with just the tar-trees and patches. That's sad,
and possibly a really big downside.

Don't get me wrong - I personally think that the new merge policy is a
clear improvement, but it does have this downside.

Linus

Al Viro

unread,
Oct 29, 2005, 4:10:12 PM10/29/05
to Linus Torvalds, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
On Sat, Oct 29, 2005 at 12:37:58PM -0700, Linus Torvalds wrote:
> Now, I've gotten several positive comments on how easy "git bisect" is to
> use, and I've used it myself, but this is the first time that patch users
> _really_ become very much second-class citizens, and you can't necessarily
> always do useful things with just the tar-trees and patches. That's sad,
> and possibly a really big downside.
>
> Don't get me wrong - I personally think that the new merge policy is a
> clear improvement, but it does have this downside.

Well... All it takes is extra patches when incremental gets too large;
e.g. have a script pick idle interval close to splitting the thing in
half until parts get less than <size>. The question is, how much extra
load would that create? Another problem is that a lot of intermediates
will not build, but that is just as true for -git<n> snapshots ;-/

Jeff Garzik

unread,
Oct 29, 2005, 4:16:57 PM10/29/05
to Linus Torvalds, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
Linus Torvalds wrote:
> Side note: one of the downsides of the new "merge lots of stuff early in
> the development series" approach is that the first few daily snapshots end
> up being _huge_.

Yeah. Back when I did the BK snapshots, I would occasionally do a
middle-of-the-day snapshot if there were a ton of incoming merges in a
24-hour span.

If this "huge -git1" becomes a real problem, we could always

* give you a manual "do snapshot" button

* ask the maintainers to spread out their submits across multiple days,
as I am doing now

* sell you on capping the daily push-to-kernel.org limit. merge stuff
into "day1", "day2", etc. branches when the main branch "fills up" for
the day.

None of these are terribly painful, but none are terribly appealing either.

Jeff

Nicolas Pitre

unread,
Oct 29, 2005, 4:18:43 PM10/29/05
to Linus Torvalds, lkml
On Sat, 29 Oct 2005, Linus Torvalds wrote:

> Now, I've gotten several positive comments on how easy "git bisect" is to
> use, and I've used it myself, but this is the first time that patch users
> _really_ become very much second-class citizens, and you can't necessarily
> always do useful things with just the tar-trees and patches. That's sad,
> and possibly a really big downside.

Since GIT is real free software that even purists may use without fear,
this downside is certainly not as critical as it was in the BK days.

The fact is: tar and patches simply do not scale anymore.


Nicolas

Linus Torvalds

unread,
Oct 29, 2005, 5:02:18 PM10/29/05
to Nicolas Pitre, lkml

On Sat, 29 Oct 2005, Nicolas Pitre wrote:
>
> Since GIT is real free software that even purists may use without fear,
> this downside is certainly not as critical as it was in the BK days.

I don't think that's the problem.

It's the learning curve. I don't think git is that hard to use (certainly
not if you just follow somebody elses tree and occasionally do a "git
bisect"), but git _is_ different. And if you're not a developer, or even
if you are, and you're just somebody who has alway sjust used CVS, then
something like "patch" is simply to understand what it's doing, with
basically no abstractions anywhere.

Compared to tar-files + patches, git has a _lot_ of abstract things going
on that you have to get used to before you aren't intimidated by it.

And the thing is, the most important bug-reports often come from people
who aren't necessarily developers - because they are the ones that see a
bug that none of the developers saw.. So making it easy for people like
that to test a few different versions is probably important.

Linus

Andrew Morton

unread,
Oct 29, 2005, 6:25:47 PM10/29/05
to Linus Torvalds, jga...@pobox.com, linu...@vger.kernel.org, linux-...@vger.kernel.org
Linus Torvalds <torv...@osdl.org> wrote:
>
>
>
> On Sat, 29 Oct 2005, Jeff Garzik wrote:
> >
> > Even so, it's easy, to I'll ask him to test 2.6.14, 2.6.14-git1, and
> > (tonight's upcoming) 2.6.14-git2 (with my latest pull included) to see if
> > anything breaks.
>
> Side note: one of the downsides of the new "merge lots of stuff early in
> the development series" approach is that the first few daily snapshots end
> up being _huge_.
>
> So the -git1 and -git2 patches are/will be very big indeed.
>
> For example, patch-2.6.14-git1 literally ended up being a megabyte
> compressed. Right now my diff to 2.6.14 (after just two days) is 1.6MB
> compressed.
>

However there's usually little overlap between the subsystems trees - with
a net update, a USB update, a SCSI update and an ia64 update it's usually
pretty obvious which one caused a particular regression.

And given that the size of each individual subsystem update is unaltered,
it doesn't really matter whether or not they all came on the same day.

The individual -mm-only patches tend to be more scattered around the tree,
which is why I send them as batches of 100-200 every couple of days: to get
a bit of separation in the -git snapshots. This hasn't actually proven to
be very useful, though.

Linus Torvalds

unread,
Oct 29, 2005, 6:31:32 PM10/29/05
to Andrew Morton, jga...@pobox.com, linu...@vger.kernel.org, linux-...@vger.kernel.org

On Sat, 29 Oct 2005, Andrew Morton wrote:
>
> However there's usually little overlap between the subsystems trees - with
> a net update, a USB update, a SCSI update and an ia64 update it's usually
> pretty obvious which one caused a particular regression.

Yes, that's true, but the subsystem trees themselves now tend to have more
time to grow, and tend to be merged more int one go.

Which is all intentional, of course - the whole _point_ of the new thing
is that they should be in your tree and tested and then merged into my
tree during a short "merge window" for further testing.

But it means that updates that used to "tricke in" to my kernel now tend
to be more of a "big merge", making the daily snapshot less effective.

So when we get a "uhhuh, networking failed between daily snapshot X and
X+1" we now more often have a single biger merge of networking stuff that
was just waiting for the merge window to open..

> The individual -mm-only patches tend to be more scattered around the tree,
> which is why I send them as batches of 100-200 every couple of days: to get
> a bit of separation in the -git snapshots. This hasn't actually proven to
> be very useful, though.

One issue is of course that a lot of people doing reports don't actually
even test the daily snapshots.

Some bug reporters do, and I'm very grateful, and they are wonderful
people. Others do after some prodding, and yet others will never bother to
try a couple of different kernels at all ;/

So the snapshot separation doesn't always necessarily help, even when it's
there.

Linus

Tony Luck

unread,
Oct 29, 2005, 8:55:41 PM10/29/05
to Linus Torvalds, Andrew Morton, jga...@pobox.com, linu...@vger.kernel.org, linux-...@vger.kernel.org
Perhaps the script that creates the -git1 etc. nightly snapshots
could peek at how many commits were included since the
previous snapshot ... if it is above some threshhold, then it
could run "git bisect" to create a -git0.5 (recursing if needed
to make -git0.25 etc.)

-Tony

Horst von Brand

unread,
Oct 30, 2005, 1:49:08 AM10/30/05
to Linus Torvalds, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
Linus Torvalds <torv...@osdl.org> wrote:
> On Sat, 29 Oct 2005, Jeff Garzik wrote:
> >
> > Even so, it's easy, to I'll ask him to test 2.6.14, 2.6.14-git1, and
> > (tonight's upcoming) 2.6.14-git2 (with my latest pull included) to see if
> > anything breaks.
>
> Side note: one of the downsides of the new "merge lots of stuff early in
> the development series" approach is that the first few daily snapshots end
> up being _huge_.

How about doing it in several stages at the beginning? I.e., have -git1
after one set of patches (pulling in from somebody, etc), and so on?
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria +56 32 654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513

Rob Landley

unread,
Oct 30, 2005, 7:44:59 AM10/30/05
to Linus Torvalds, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
On Saturday 29 October 2005 14:37, Linus Torvalds wrote:
> Now, I've gotten several positive comments on how easy "git bisect" is to
> use, and I've used it myself, but this is the first time that patch users
> _really_ become very much second-class citizens, and you can't necessarily
> always do useful things with just the tar-trees and patches. That's sad,
> and possibly a really big downside.
>
> Don't get me wrong - I personally think that the new merge policy is a
> clear improvement, but it does have this downside.

One possible solution:

Rather than making the patch a simple diff of the trees, make the patch a cat
of the individual patches/commits (preferably with descriptions) that got
applied, in the order they got applied.

This makes the patch bigger, but it also means that bisect can be done with
vi, simply by truncating the file at the last interesting patch and applying
the truncated version to a clean tree. Since patch applies hunks in order
and sifts out hunks from description already...

Is this a viable option?

Rob

Nicolas Pitre

unread,
Oct 30, 2005, 10:47:36 AM10/30/05
to Linus Torvalds, lkml
On Sat, 29 Oct 2005, Linus Torvalds wrote:

> On Sat, 29 Oct 2005, Nicolas Pitre wrote:
> >
> > Since GIT is real free software that even purists may use without fear,
> > this downside is certainly not as critical as it was in the BK days.
>
> I don't think that's the problem.
>
> It's the learning curve. I don't think git is that hard to use (certainly
> not if you just follow somebody elses tree and occasionally do a "git
> bisect"), but git _is_ different. And if you're not a developer, or even
> if you are, and you're just somebody who has alway sjust used CVS, then
> something like "patch" is simply to understand what it's doing, with
> basically no abstractions anywhere.

Agreed.

> Compared to tar-files + patches, git has a _lot_ of abstract things going
> on that you have to get used to before you aren't intimidated by it.

Maybe gitweb could be extended to provide any arbitrary patch with a
front-end to git-bisect...


Nicolas

Pavel Machek

unread,
Oct 30, 2005, 2:33:08 PM10/30/05
to Linus Torvalds, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
Hi!

> > Even so, it's easy, to I'll ask him to test 2.6.14, 2.6.14-git1, and
> > (tonight's upcoming) 2.6.14-git2 (with my latest pull included) to see if
> > anything breaks.
>
> Side note: one of the downsides of the new "merge lots of stuff early in
> the development series" approach is that the first few daily snapshots end
> up being _huge_.
>
> So the -git1 and -git2 patches are/will be very big indeed.
>
> For example, patch-2.6.14-git1 literally ended up being a megabyte
> compressed. Right now my diff to 2.6.14 (after just two days) is 1.6MB
> compressed.

..


> Now, I've gotten several positive comments on how easy "git bisect" is to
> use, and I've used it myself, but this is the first time that patch users
> _really_ become very much second-class citizens, and you can't necessarily
> always do useful things with just the tar-trees and patches. That's sad,
> and possibly a really big downside.
>
> Don't get me wrong - I personally think that the new merge policy is a
> clear improvement, but it does have this downside.

Well, git bisect helps a bit, but does not really cut it. If changes are
merged slowly enough, you usually don't need to go through history;
you know it is broken, you know it worked yesterday, and diff is small enough...

Pavel
--
64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms

Linus Torvalds

unread,
Oct 30, 2005, 5:37:16 PM10/30/05
to Rob Landley, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org

On Sun, 30 Oct 2005, Rob Landley wrote:
>
> Rather than making the patch a simple diff of the trees, make the patch a cat
> of the individual patches/commits (preferably with descriptions) that got
> applied, in the order they got applied.
>
> This makes the patch bigger, but it also means that bisect can be done with
> vi, simply by truncating the file at the last interesting patch and applying
> the truncated version to a clean tree. Since patch applies hunks in order
> and sifts out hunks from description already...
>
> Is this a viable option?

No.

There is no "ordering" in a distributed environment. We have things
happening in parallel, adn you can't really linearize the patches.

The closest you can get is "git bisect", which does the right thing.

Linus

Rob Landley

unread,
Oct 30, 2005, 6:32:31 PM10/30/05
to Linus Torvalds, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
On Sunday 30 October 2005 16:36, Linus Torvalds wrote:
> > Is this a viable option?
>
> No.
>
> There is no "ordering" in a distributed environment. We have things
> happening in parallel, adn you can't really linearize the patches.
>
> The closest you can get is "git bisect", which does the right thing.
>
> Linus

I know there isn't an absolute or stable ordering, but can't a temporary
ordering be exported?

I was under the impression that the bk->cvs gateway squashed changes into a
sort of order, way back when. Admittedly this order wasn't stable, and new
changes perturbed the whole list. But just for debugging purposes with a
"patch vs last -rc"?

Rob

Rob Landley

unread,
Oct 30, 2005, 7:00:47 PM10/30/05
to Linus Torvalds, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
On Sunday 30 October 2005 16:36, Linus Torvalds wrote:

> > Is this a viable option?
>
> No.
>
> There is no "ordering" in a distributed environment. We have things
> happening in parallel, adn you can't really linearize the patches.

To clarify my thinking:

It doesn't matter what the ordering is, as long as A) the patches are
separated somehow, B) the resulting kernel from applying any initial subset
(patches 1-X in the series) has some reasonable chance to build and work.

Any arbitrary order is theoretically fine for (A). Alphabetical by msgid or
sha1sum. Or the order they appear in the changelog.

It's (B) that's the tricky bit, but not an insoluble problem. "The order
Linux imported them into his tree" might give that.

> The closest you can get is "git bisect", which does the right thing.

Ok, so we've already got an order, whatever order git bisect puts them in.
(It doesn't have to be stable between releases, just a snapshot in time of a
set of individual patches which, cumulatively applied,would have the same
effect as the big rc1->rc2 diffs we've been getting.)

It doesn't sound like it would be _too_ hard to abuse the "git bisect"
mechanism to work out each possible bisection point between -rc1 and -rc1,
and if that can be done why can't it spit out the individual patches (with
descriptions) and cat them together?

Why wouldn't this work?

> Linus

Rob

Randy.Dunlap

unread,
Oct 30, 2005, 7:17:23 PM10/30/05
to Rob Landley, torv...@osdl.org, jga...@pobox.com, ak...@osdl.org, linu...@vger.kernel.org, linux-...@vger.kernel.org
On Sun, 30 Oct 2005 17:59:39 -0600 Rob Landley wrote:

> On Sunday 30 October 2005 16:36, Linus Torvalds wrote:
>
> > > Is this a viable option?
> >
> > No.
> >
> > There is no "ordering" in a distributed environment. We have things
> > happening in parallel, adn you can't really linearize the patches.
>
> To clarify my thinking:
>
> It doesn't matter what the ordering is, as long as A) the patches are
> separated somehow, B) the resulting kernel from applying any initial subset
> (patches 1-X in the series) has some reasonable chance to build and work.
>
> Any arbitrary order is theoretically fine for (A). Alphabetical by msgid or
> sha1sum. Or the order they appear in the changelog.
>
> It's (B) that's the tricky bit, but not an insoluble problem. "The order
> Linux imported them into his tree" might give that.
>
> > The closest you can get is "git bisect", which does the right thing.
>
> Ok, so we've already got an order, whatever order git bisect puts them in.
> (It doesn't have to be stable between releases, just a snapshot in time of a
> set of individual patches which, cumulatively applied,would have the same
> effect as the big rc1->rc2 diffs we've been getting.)
>
> It doesn't sound like it would be _too_ hard to abuse the "git bisect"
> mechanism to work out each possible bisection point between -rc1 and -rc1,
> and if that can be done why can't it spit out the individual patches (with
> descriptions) and cat them together?
>
> Why wouldn't this work?

Why isn't there a linus.git ordering? that can be made to work.

---
~Randy

Linus Torvalds

unread,
Oct 30, 2005, 7:58:49 PM10/30/05
to Rob Landley, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org

On Sun, 30 Oct 2005, Rob Landley wrote:
>

> I know there isn't an absolute or stable ordering, but can't a temporary
> ordering be exported?

Not generally, no. And definitely not easily.

> I was under the impression that the bk->cvs gateway squashed changes into a
> sort of order, way back when.

I have to say that the bk->cvs gateway is actually a very impressive
linearization, and I don't even know how it did it. But even that one
wasn't perfect - occasionally it ended up with big patches for merges.

Using "git bisect" to generate successive bisections (and then building up
a linearization patch from that) would work, but it would result in some
_really_ strange things: it would basically have one patch do one thing,
then the next patch might _undo_ that, and do another, and then the third
patch would re-do it and do them both together.

And that's really sometimes the best linearization you can do. But that's
just too strange and confusing, I think. And the patches would be horribly
inefficient.

At that point I'd rather teach people to use "git bisect" natively. It
wouldn't be any less confusing than the patches ;)

Linus

Rob Landley

unread,
Oct 30, 2005, 9:36:09 PM10/30/05
to Linus Torvalds, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
On Sunday 30 October 2005 18:58, Linus Torvalds wrote:

> Using "git bisect" to generate successive bisections (and then building up
> a linearization patch from that) would work, but it would result in some
> _really_ strange things:

Which is fine for a debugging tool.

It sounds like any git user could make one of these patches now, and put them
up each time you cut a release. (Hmmm, is this likely to be scriptable, or
does it require poking at the git source? Coming up to speed on git is a
to-do item for me. It has its own _vocabulary_, not exactly a trivial time
expenditure to understand what's going on for those of us who never got
around to using bitkeeper...)

> it would basically have one patch do one thing,
> then the next patch might _undo_ that, and do another, and then the third
> patch would re-do it and do them both together.
>
> And that's really sometimes the best linearization you can do. But that's
> just too strange and confusing, I think. And the patches would be horribly
> inefficient.

"Horribly inefficient" seems pretty standard for a debugging tool. Dwarf2
bloats executables by a factor of 10 or more. If it's a big issue, perhaps
kernel.org could offer both "rc1-rc2.patch" (the "simple diff between trees"
version) and "rc1-rc2-bisect.patch" (the "ugly granular debugging" version).

Also, the patch description in the bisect version could easily include a URL
to an online git diff viewer (can http://www.kernel.org/git do this?) in case
people want to see what it did, since the patch for artificially linearized
changes can easily be unintelligible, ala:

The human readable version of this patch is at:
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3e6716e748609a3a899e8d670e42832921bd45bc

> At that point I'd rather teach people to use "git bisect" natively. It
> wouldn't be any less confusing than the patches ;)

The problem with teaching people to use "git bisect" is you have people who
aren't kernel developers who have a bug, and want to help track down the bug,
and you're telling them "Ok, to debug this you need to install git, use it to
check out the linux-kernel repository, then..."

I suspect even the best-intentioned dilettantes seldom make it to "then".
Telling them to binary search through a downloadable text file on the marker
"===newpatch===" or some such sounds like a much easier sell. It doesn't
even need a shell script:

grep -n MARKER bisect.patch | less
(pick a line number)
head -n linenumber bisect.patch > test.patch

If that's not it, revert test.patch and then try again. Tell us the first
line number that failed, which is the end of the patch we want...

Hmmm... The logical place to put the URL to gitweb is at the _end_ of the
patch, attached to the marker. So that's what they see in the grep, and the
last thing they test when they cut at that line with head -n...

> Linus

Rob

Rob Landley

unread,
Oct 30, 2005, 9:53:28 PM10/30/05
to linux-...@vger.kernel.org
On Sunday 30 October 2005 18:58, Linus Torvalds wrote:
> Using "git bisect" to generate successive bisections (and then building up
> a linearization patch from that) would work,

I don't suppose I could make puppy eyes at somebody _else_ to bang on git a
bit and try to come up with a proof-of-concept patch? (Say
2.6.14-rc5-bisect.patch?)

I just downloaded the git source snapshot to find out it won't compile without
openssl headers. (Thanks, ubuntu, for stripping out every darn development
header and making them separate things you have to hunt down and install
individually, even though the box actually _has_ whatever darn library it's
complaining about and really couldn't _function_ without it. Sigh.)

Rob

(kynaptic
--install-the-development-headers-for-all-installed-packages-already)

David Lang

unread,
Oct 30, 2005, 10:57:11 PM10/30/05
to Linus Torvalds, Jeff Garzik, Andrew Morton, linu...@vger.kernel.org, linux-...@vger.kernel.org
On Sat, 29 Oct 2005, Linus Torvalds wrote:

> On Sat, 29 Oct 2005, Jeff Garzik wrote:
>>
>> Even so, it's easy, to I'll ask him to test 2.6.14, 2.6.14-git1, and
>> (tonight's upcoming) 2.6.14-git2 (with my latest pull included) to see if
>> anything breaks.
>
> Side note: one of the downsides of the new "merge lots of stuff early in
> the development series" approach is that the first few daily snapshots end
> up being _huge_.
>
> So the -git1 and -git2 patches are/will be very big indeed.
>
> For example, patch-2.6.14-git1 literally ended up being a megabyte
> compressed. Right now my diff to 2.6.14 (after just two days) is 1.6MB
> compressed.
>
> Admittedly, some of it is due to things like the MIPS merge, but the point
> I'm trying to make is that it makes the daily snapshot diffs a lot less
> useful to people who try to figure out where something broke.
>
> Now, I've gotten several positive comments on how easy "git bisect" is to
> use, and I've used it myself, but this is the first time that patch users
> _really_ become very much second-class citizens, and you can't necessarily
> always do useful things with just the tar-trees and patches. That's sad,
> and possibly a really big downside.
>
> Don't get me wrong - I personally think that the new merge policy is a
> clear improvement, but it does have this downside.
>
> Linus

how about setting up something on a webserver (ideally kernel.org) to do
the git bisect and output patches against the daily snapshots.

if a lot of people used it the load would be an issue, but if it's only
used by a relativly few people tracking down bugs it's probably worth it.

David Lang

--
There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.
-- C.A.R. Hoare

Junio C Hamano

unread,
Oct 31, 2005, 2:47:19 AM10/31/05
to linux-...@vger.kernel.org, Rob Landley
Rob Landley <r...@landley.net> writes:

> grep -n MARKER bisect.patch | less
> (pick a line number)
> head -n linenumber bisect.patch > test.patch
>
> If that's not it, revert test.patch and then try again. Tell us the first
> line number that failed, which is the end of the patch we want...
>
> Hmmm... The logical place to put the URL to gitweb is at the _end_ of the
> patch, attached to the marker. So that's what they see in the grep, and the
> last thing they test when they cut at that line with head -n...

Well, do people realize that 'git bisect' is *not* a textual
half-way between, but rather is computed every time you feed
new "the patch you told me to test last time was good/bad"
information? I do not think statically generating a huge text
and telling the user to apply up to halfway and bisect by hand
would not work -- it would be quite different from what git
bisect would give you.

I think public webserver based bisect service David Lang
suggests might work. The interaction with it would start by the
end user somehow giving it the last known-working commit ID (A)
(pick from gitweb shortlog, perhaps) and a commit ID newer than
that that broke things (B) (again, pick from gitweb shortlog).
Then the service runs bisect on the server side, spit out a diff
against (A). The end user applies the patch, try it, and then
come back and tell if it worked or not,... Since we are talking
about the kernel development, I think the cycle might involve
rebooting the machine; so you would probably need two machines
(one guinea-pig machine to reboot, another to keep the browser
open so that your state can be kept somehow).

David Lang

unread,
Oct 31, 2005, 3:11:32 AM10/31/05
to Junio C Hamano, linux-...@vger.kernel.org, Rob Landley

given the time required to compile a kernel and reboot you can't plan to
keep the info server side (browser connections will time out well before
this finishes)

instead this will require saving something on the client and passing it
back to the server.

offhand I'd say that it would end up working something like this.

1. go to the website and pick starting good/bad points
2. the server will give you a tgz (bzip is significantly more load on the
server) that contains the patch and a status file.
3. apply the patch to the starting tree (in theory it may be a smaller
patch to either tree, but it's easier to explain if one is picked all the
time so initially it should be the working tree). compile the tree and
test
4. go back to the website, upload the status file and indicate sucess or
failure
5. goto 2

the file would basicly save and report what git bisect would normally
store in environment variables.

the server will have to do some sanity checking on the good and bad points
it's given (for security reasons if nothing else)

potentially it should suggest checking an officially tagged release
that's between the good and bad points. this may actually slow testing
slightly (if you know it worked on 2.6.7 and failed on 2.6.12 you would
probably be the most efficiant if you start bisecting directly, but it's
far easier for others to understand things if you test 2.6.10 and other
tagged releases first)

I also suspect that a log of what people are testing would be intereating
to people as well (if you see a bunch of people bisecting in the same area
it's an indication that more attention needs to be paied to that area)

David Lang

--
There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.
-- C.A.R. Hoare

David Lang

unread,
Oct 31, 2005, 3:29:44 AM10/31/05
to Junio C Hamano, linux-...@vger.kernel.org, Rob Landley

an alternate approach that would be a little cleaner would be to use a
cookie to store the bisect state info so that it is just a patch that's
downloaded (although this does limit someone to bisecting one thing at a
time, I think that's not an unreasonable limitation)

Junio C Hamano

unread,
Oct 31, 2005, 4:00:53 AM10/31/05
to David Lang, linux-...@vger.kernel.org, Rob Landley
David Lang <david...@digitalinsight.com> writes:

> given the time required to compile a kernel and reboot you can't plan to
> keep the info server side (browser connections will time out well before
> this finishes)
>
> instead this will require saving something on the client and passing it
> back to the server.

I was thinking about doing thatn in hidden input fields and
passing form back and forth. After all what real git bisect
keeps locally are one bad commit ID and bunch of good commit
IDs.

David Lang

unread,
Oct 31, 2005, 4:20:08 AM10/31/05
to Junio C Hamano, linux-...@vger.kernel.org, Rob Landley
On Mon, 31 Oct 2005, Junio C Hamano wrote:

> David Lang <david...@digitalinsight.com> writes:
>
>> given the time required to compile a kernel and reboot you can't plan to
>> keep the info server side (browser connections will time out well before
>> this finishes)
>>
>> instead this will require saving something on the client and passing it
>> back to the server.
>
> I was thinking about doing thatn in hidden input fields and
> passing form back and forth. After all what real git bisect
> keeps locally are one bad commit ID and bunch of good commit
> IDs.

if it's kept in a file or cookie then it can survive a reboot and other
distractions (remember that this process can take days if the problem
doesn't show up at boot). a cookie can hold a couple K worth of data, a
file has no size limit.

it would also be a good idea if the web page could give an estimate
estimate of how many additional tests may end up being required.

David Lang
--
There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.
-- C.A.R. Hoare

Rob Landley

unread,
Oct 31, 2005, 4:41:33 AM10/31/05
to David Lang, Junio C Hamano, linux-...@vger.kernel.org
On Monday 31 October 2005 03:13, David Lang wrote:
> > I was thinking about doing thatn in hidden input fields and
> > passing form back and forth. After all what real git bisect
> > keeps locally are one bad commit ID and bunch of good commit
> > IDs.
>
> if it's kept in a file or cookie then it can survive a reboot and other
> distractions (remember that this process can take days if the problem
> doesn't show up at boot). a cookie can hold a couple K worth of data, a
> file has no size limit.

Actually, lots of Linux browsers these days treats all cookies as session
cookies for security reasons. So surviving a reboot still isn't guaranteed.
But it's possible.

You can also have 'em bookmark a URL...

> it would also be a good idea if the web page could give an estimate
> estimate of how many additional tests may end up being required.

Bisect already says how many commits are left in the pool, so roughly log(2)
of that...

> David Lang

Rob

Giuseppe Bilotta

unread,
Oct 31, 2005, 6:57:01 AM10/31/05
to linux-...@vger.kernel.org
On Mon, 31 Oct 2005 03:34:34 -0600, Rob Landley wrote:

> On Monday 31 October 2005 03:13, David Lang wrote:
>>> I was thinking about doing thatn in hidden input fields and
>>> passing form back and forth. After all what real git bisect
>>> keeps locally are one bad commit ID and bunch of good commit
>>> IDs.
>>
>> if it's kept in a file or cookie then it can survive a reboot and other
>> distractions (remember that this process can take days if the problem
>> doesn't show up at boot). a cookie can hold a couple K worth of data, a
>> file has no size limit.
>
> Actually, lots of Linux browsers these days treats all cookies as session
> cookies for security reasons. So surviving a reboot still isn't guaranteed.
> But it's possible.
>
> You can also have 'em bookmark a URL...

Trac has a 'Session ID' key that stores something like a cookie,
except that it's serverside. Something halfway a cookie and an actual
login. The user can write down the session ID or just assign its own,
and the re-enter the session ID and all things are restored to the
settings he had chosen. Something like this, maybe?

--
Giuseppe "Oblomov" Bilotta

"I'm never quite so stupid
as when I'm being smart" --Linus van Pelt

David Lang

unread,
Oct 31, 2005, 12:53:19 PM10/31/05
to Giuseppe Bilotta, linux-...@vger.kernel.org
On Mon, 31 Oct 2005, Giuseppe Bilotta wrote:

> On Mon, 31 Oct 2005 03:34:34 -0600, Rob Landley wrote:
>
>> On Monday 31 October 2005 03:13, David Lang wrote:
>>>> I was thinking about doing thatn in hidden input fields and
>>>> passing form back and forth. After all what real git bisect
>>>> keeps locally are one bad commit ID and bunch of good commit
>>>> IDs.
>>>
>>> if it's kept in a file or cookie then it can survive a reboot and other
>>> distractions (remember that this process can take days if the problem
>>> doesn't show up at boot). a cookie can hold a couple K worth of data, a
>>> file has no size limit.
>>
>> Actually, lots of Linux browsers these days treats all cookies as session
>> cookies for security reasons. So surviving a reboot still isn't guaranteed.
>> But it's possible.

I haven't seen a browser that does this (it would break a lot of sites), I
have seen the option when you go to accept a cookie to accept it for this
session only, so a note to the user to allow the cookie to persist may be
enough, or we can just go the tarball route and the file that gets saved
and uploaded would be enough.

what browser have you seen this default bahavior on?

>> You can also have 'em bookmark a URL...
>
> Trac has a 'Session ID' key that stores something like a cookie,
> except that it's serverside. Something halfway a cookie and an actual
> login. The user can write down the session ID or just assign its own,
> and the re-enter the session ID and all things are restored to the
> settings he had chosen. Something like this, maybe?

saving the state on the server means that you have to deal with (or
somehow eliminate) collisions between different users, it means that you
need to have the server-side data time out and get garbage collected, and
in general adds significant complexity to the project.

David Lang

--
There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.
-- C.A.R. Hoare

Giuseppe Bilotta

unread,
Oct 31, 2005, 1:10:52 PM10/31/05
to linux-...@vger.kernel.org
On Mon, 31 Oct 2005 09:49:28 -0800 (PST), David Lang wrote:

> On Mon, 31 Oct 2005, Giuseppe Bilotta wrote:
>
>> Trac has a 'Session ID' key that stores something like a cookie,
>> except that it's serverside. Something halfway a cookie and an actua
l
>> login. The user can write down the session ID or just assign its own
,
>> and the re-enter the session ID and all things are restored to the
>> settings he had chosen. Something like this, maybe?
>
> saving the state on the server means that you have to deal with (or
> somehow eliminate) collisions between different users, it means that
you
> need to have the server-side data time out and get garbage collected,
and
> in general adds significant complexity to the project.

Well, I honestly don't have the slightest idea about this is handled
internally by Trac, but it seemed to be that something like this would
fit the needs, more or less. Of course it may need to be tuned for the
specific purpose ...

--
Giuseppe "Oblomov" Bilotta

"E la storia dell'umanitŕ, babbo?"
"Ma niente: prima si fanno delle cazzate,
poi si studia che cazzate si sono fatte"
(Altan)
("And what about the history of the human race, dad?"
"Oh, nothing special: first they make some foolish things,
then you study what foolish things have been made")

Matthias Urlichs

unread,
Nov 9, 2005, 7:41:02 PM11/9/05
to linux-...@vger.kernel.org, linu...@vger.kernel.org
Hi, Linus Torvalds wrote:

> I have to say that the bk->cvs gateway is actually a very impressive
> linearization, and I don't even know how it did it.

That's easy -- it found the longest path from A to B and generated patches
between each step.

Looking at the latest tree with gitk, I'd guess that the previous rate
of roughly 50% is no longer achievable; linearizing would aggregate
some large chunks of patch-series and subtree merges (no surprise there).

--
Matthias Urlichs | {M:U} IT Design @ m-u-it.de | sm...@smurf.noris.de
Disclaimer: The quote was selected randomly. Really. | http://smurf.noris.de
- -
Automobile, n.:
A four-wheeled vehicle that runs up hills and down pedestrians.

Jeff Garzik

unread,
Nov 11, 2005, 11:24:02 AM11/11/05
to Andrew Morton, Linus Torvalds, linu...@vger.kernel.org, linux-...@vger.kernel.org

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git

to receive the following updates:

drivers/scsi/ahci.c | 2 +-
drivers/scsi/ata_piix.c | 2 +-
drivers/scsi/libata-core.c | 2 ++
drivers/scsi/libata-scsi.c | 2 ++
drivers/scsi/pdc_adma.c | 2 +-
drivers/scsi/sata_mv.c | 4 +++-
drivers/scsi/sata_nv.c | 2 +-
drivers/scsi/sata_promise.c | 2 +-
drivers/scsi/sata_qstor.c | 2 +-
drivers/scsi/sata_sil.c | 2 +-
drivers/scsi/sata_sil24.c | 2 +-
drivers/scsi/sata_sis.c | 2 +-
drivers/scsi/sata_svw.c | 2 +-
drivers/scsi/sata_sx4.c | 2 +-
drivers/scsi/sata_uli.c | 2 +-
drivers/scsi/sata_via.c | 2 +-
drivers/scsi/sata_vsc.c | 2 +-
include/linux/libata.h | 2 ++
18 files changed, 23 insertions(+), 15 deletions(-)

Alan Cox:
libata: Note a nasty ATA quirk
libata: propogate host private data from probe function

Andrew Morton:
libata.h needs dma-mapping.h

Jeff Garzik:
[libata] constify PCI ID table in several drivers
[libata sata_mv] add Adaptec 1420SA PCI ID

diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 10c470e..57ef7ae 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -255,7 +255,7 @@ static struct ata_port_info ahci_port_in
},
};

-static struct pci_device_id ahci_pci_tbl[] = {
+static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_ahci }, /* ICH6 */
{ PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index a1bd8d9..855428f 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -95,7 +95,7 @@ static void piix_set_dmamode (struct ata

static unsigned int in_module_init = 1;

-static struct pci_device_id piix_pci_tbl[] = {
+static const struct pci_device_id piix_pci_tbl[] = {
#ifdef ATA_ENABLE_PATA
{ 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata },
{ 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata },
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index a74b407..e51d9a8 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -4563,6 +4563,7 @@ ata_pci_init_native_mode(struct pci_dev

probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
+ probe_ent->private_data = port[0]->private_data;

if (ports & ATA_PORT_PRIMARY) {
probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
@@ -4599,6 +4600,7 @@ static struct ata_probe_ent *ata_pci_ini
probe_ent->legacy_mode = 1;
probe_ent->n_ports = 1;
probe_ent->hard_port_no = port_num;
+ probe_ent->private_data = port->private_data;

switch(port_num)
{
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index bb30fcd..7e37f48 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1129,6 +1129,8 @@ static unsigned int ata_scsi_rw_xlat(str
* length 0 means transfer 0 block of data.
* However, for ATA R/W commands, sector count 0 means
* 256 or 65536 sectors, not 0 sectors as in SCSI.
+ *
+ * WARNING: one or two older ATA drives treat 0 as 0...
*/
goto nothing_to_do;

diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index 78b4ff1..f557f17 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -190,7 +190,7 @@ static struct ata_port_info adma_port_in
},
};

-static struct pci_device_id adma_ata_pci_tbl[] = {
+static const struct pci_device_id adma_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_1841_idx },

diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 93d5523..257c128 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -349,7 +349,7 @@ static struct ata_port_info mv_port_info
},
};

-static struct pci_device_id mv_pci_tbl[] = {
+static const struct pci_device_id mv_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_508x},
@@ -359,6 +359,8 @@ static struct pci_device_id mv_pci_tbl[]
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x},
{PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x},
+
+ {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x0241), 0, 0, chip_604x},
{} /* terminate list */
};

diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 37a4fae..4954896 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -137,7 +137,7 @@ enum nv_host_type
CK804
};

-static struct pci_device_id nv_pci_tbl[] = {
+static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE2 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 9edc9d9..242d906 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -193,7 +193,7 @@ static struct ata_port_info pdc_port_inf
},
};

-static struct pci_device_id pdc_ata_pci_tbl[] = {
+static const struct pci_device_id pdc_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2037x },
{ PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index d274ab2..b2f6324 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -184,7 +184,7 @@ static struct ata_port_info qs_port_info
},
};

-static struct pci_device_id qs_ata_pci_tbl[] = {
+static const struct pci_device_id qs_ata_pci_tbl[] = {
{ PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_2068_idx },

diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index d0e3c3c..3609186 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -87,7 +87,7 @@ static void sil_scr_write (struct ata_po
static void sil_post_set_mode (struct ata_port *ap);


-static struct pci_device_id sil_pci_tbl[] = {
+static const struct pci_device_id sil_pci_tbl[] = {
{ 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
{ 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
{ 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 4682a50..d3198d9 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -240,7 +240,7 @@ static void sil24_port_stop(struct ata_p
static void sil24_host_stop(struct ata_host_set *host_set);
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);

-static struct pci_device_id sil24_pci_tbl[] = {
+static const struct pci_device_id sil24_pci_tbl[] = {
{ 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
{ 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 },
{ 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 },
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 42d7c4e..32e1262 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -67,7 +67,7 @@ static int sis_init_one (struct pci_dev
static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);

-static struct pci_device_id sis_pci_tbl[] = {
+static const struct pci_device_id sis_pci_tbl[] = {
{ PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
{ PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
{ PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 },
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 9895d1c..57e5a9d 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -466,7 +466,7 @@ err_out:
* 0x24a is device ID for BCM5785 (aka HT1000) HT southbridge integrated SATA
* controller
* */
-static struct pci_device_id k2_sata_pci_tbl[] = {
+static const struct pci_device_id k2_sata_pci_tbl[] = {
{ 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
{ 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
{ 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index d5a3878..b4bbe48 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -229,7 +229,7 @@ static struct ata_port_info pdc_port_inf

};

-static struct pci_device_id pdc_sata_pci_tbl[] = {
+static const struct pci_device_id pdc_sata_pci_tbl[] = {
{ PCI_VENDOR_ID_PROMISE, 0x6622, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_20621 },
{ } /* terminate list */
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index cf0baaa..b2422a0 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -55,7 +55,7 @@ static int uli_init_one (struct pci_dev
static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);

-static struct pci_device_id uli_pci_tbl[] = {
+static const struct pci_device_id uli_pci_tbl[] = {
{ PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
{ PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
{ PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index ab19d2b..c762156 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -75,7 +75,7 @@ static int svia_init_one (struct pci_dev
static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);

-static struct pci_device_id svia_pci_tbl[] = {
+static const struct pci_device_id svia_pci_tbl[] = {
{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
{ 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 },

diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index ce8a2fd..77a6e4b 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -400,7 +400,7 @@ err_out:
* 0x8086/0x3200 is the Intel 31244, which is supposed to be identical
* compatibility is untested as of yet
*/
-static struct pci_device_id vsc_sata_pci_tbl[] = {
+static const struct pci_device_id vsc_sata_pci_tbl[] = {
{ 0x1725, 0x7174, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
{ 0x8086, 0x3200, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 },
{ }
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 6f07522..1464a75 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -29,6 +29,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <linux/ata.h>
#include <linux/workqueue.h>
@@ -404,6 +405,7 @@ struct ata_port_info {
unsigned long mwdma_mask;
unsigned long udma_mask;
const struct ata_port_operations *port_ops;
+ void *private_data;
};

struct ata_timing {

Reply all
Reply to author
Forward
0 new messages