Jeff, Do you have any comments on my latest patches? What can I do to help get this support merged into libata? Here are some test results for the patchset: 1. sg3utils test to SATA/ATAPI device * Perform the following sg3utils commands to a SATA device: o sg_get_config o sginfo o sg_inq o sg_readcap 2. SATA error injection * Use sg_reset to initiate a PHY reset to a SATA device and verify the host recovers. * Use sysfs to reset the ipr adapter. This will cause the SATA device to receive an out of band PHY reset. Use sg_inq to issue an INQUIRY to the device. Verify error handling gets invoked and the system recovers. 3. stress_cd / internal CD/DVD exerciser (run for > 12 hours) 4. SLAB_DEBUG * Run with memory tainting enabled. 5. SATA add/remove device * Use sysfs to delete a SATA device from SCSI core, which will also cause the associated ATA port to get deleted. * Use sysfs to rescan for the SATA device. Verify the SATA device shows up again. * Verify no unexpected errors are logged. 6. SATA queue_depth * Use sysfs and attempt to change the queue depth of a SATA device. * Verify the queue depth stays at 1. I would be happy to run any additional testcases. Thanks, Brian Brian King wrote: > The following patch enhances libata to allow SAS device drivers > to utilize libata to talk to SATA devices. It introduces some > new APIs which allow libata to be used without allocating a > virtual scsi host. > > New APIs: > > ata_sas_port_alloc - Allocate an ata_port > ata_sas_port_init - Initialize an ata_port (probe device, etc) > ata_sas_port_destroy - Free an ata_port allocated by ata_sas_port_alloc > ata_sas_slave_configure - configure scsi device > ata_sas_queuecmd - queue a scsi command, similar to ata_scsi_queuecomand > > These new APIs can be used either directly by a SAS LLDD or could be used > by the SAS transport class. > > Possible usage for a SAS LLDD would be: > > scsi_scan_host > target_alloc > ata_sas_port_alloc > slave_alloc > ata_sas_port_init > slave_configure > ata_sas_slave_configure > > Commands received by the LLDD for SATA devices would call ata_sas_queuecmd. > > Device teardown would occur with: > > slave_destroy > port_disable > target_destroy > ata_sas_port_destroy > > Acked-by: Jeff Garzik <jgarzik@xxxxxxxxx> > Signed-off-by: Brian King <brking@xxxxxxxxxx> > --- > > drivers/scsi/libata-core.c | 4 - > drivers/scsi/libata-scsi.c | 166 +++++++++++++++++++++++++++++++++++++++++++++ > drivers/scsi/libata.h | 2 > include/linux/libata.h | 9 ++ > 4 files changed, 179 insertions(+), 2 deletions(-) > > diff -puN drivers/scsi/libata-scsi.c~libata_sas drivers/scsi/libata-scsi.c > --- libata-dev/drivers/scsi/libata-scsi.c~libata_sas 2006-07-09 13:07:22.000000000 -0500 > +++ libata-dev-bjking1/drivers/scsi/libata-scsi.c 2006-07-09 13:07:22.000000000 -0500 > @@ -3158,3 +3158,169 @@ void ata_scsi_dev_rescan(void *data) > scsi_rescan_device(&(dev->sdev->sdev_gendev)); > } > } > + > +/** > + * ata_sas_port_alloc - Allocate port for a SAS attached SATA device > + * @pdev: PCI device that the scsi device is attached to > + * @port_info: Information from low-level host driver > + * @host: SCSI host that the scsi device is attached to > + * > + * LOCKING: > + * PCI/etc. bus probe sem. > + * > + * RETURNS: > + * ata_port pointer on success / NULL on failure. > + */ > + > +struct ata_port *ata_sas_port_alloc(struct ata_host_set *host_set, > + struct ata_port_info *port_info, > + struct Scsi_Host *host) > +{ > + struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL); > + int i; > + > + if (!ap) > + return NULL; > + > + ap->dev = host_set->dev; > + ap->host_set = host_set; > + ap->id = ata_unique_id++; > + ap->lock = host->host_lock; > + ap->ops = port_info->port_ops; > + ap->flags = port_info->host_flags | ATA_FLAG_DISABLED; > + ap->pio_mask = port_info->pio_mask; > + ap->mwdma_mask = port_info->mwdma_mask; > + ap->udma_mask = port_info->udma_mask; > + ap->cbl = ATA_CBL_SATA; > + ap->sata_spd_limit = UINT_MAX; > + ap->active_tag = ATA_TAG_POISON; > + ap->last_ctl = 0xFF; > + INIT_WORK(&ap->port_task, NULL, NULL); > + INIT_WORK(&ap->hotplug_task, ata_scsi_hotplug, ap); > + INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan, ap); > + INIT_LIST_HEAD(&ap->eh_done_q); > + init_waitqueue_head(&ap->eh_wait_q); > + > + for (i = 0; i < ATA_MAX_DEVICES; i++) { > + struct ata_device *dev = &ap->device[i]; > + dev->ap = ap; > + dev->devno = i; > + ata_dev_init(dev); > + } > + > + return ap; > +} > +EXPORT_SYMBOL_GPL(ata_sas_port_alloc); > + > +/** > + * ata_sas_port_start - Set port up for dma. > + * @ap: Port to initialize > + * > + * Called just after data structures for each port are > + * initialized. Allocates DMA pad. > + * > + * May be used as the port_start() entry in ata_port_operations. > + * > + * LOCKING: > + * Inherited from caller. > + */ > +int ata_sas_port_start(struct ata_port *ap) > +{ > + return ata_pad_alloc(ap, ap->dev); > +} > +EXPORT_SYMBOL_GPL(ata_sas_port_start); > + > +/** > + * ata_port_stop - Undo ata_sas_port_start() > + * @ap: Port to shut down > + * > + * Frees the DMA pad. > + * > + * May be used as the port_stop() entry in ata_port_operations. > + * > + * LOCKING: > + * Inherited from caller. > + */ > + > +void ata_sas_port_stop(struct ata_port *ap) > +{ > + ata_pad_free(ap, ap->dev); > +} > +EXPORT_SYMBOL_GPL(ata_sas_port_stop); > + > +/** > + * ata_sas_port_init - Initialize a SATA device > + * @ap: SATA port to initialize > + * > + * LOCKING: > + * PCI/etc. bus probe sem. > + * > + * RETURNS: > + * Zero on success, non-zero on error. > + */ > + > +int ata_sas_port_init(struct ata_port *ap) > +{ > + int rc = ap->ops->port_start(ap); > + > + if (!rc) > + rc = ata_bus_probe(ap); > + > + return rc; > +} > +EXPORT_SYMBOL_GPL(ata_sas_port_init); > + > +/** > + * ata_sas_port_destroy - Destroy a SATA port allocated by ata_sas_port_alloc > + * @ap: SATA port to destroy > + * > + */ > + > +void ata_sas_port_destroy(struct ata_port *ap) > +{ > + ap->ops->port_stop(ap); > + kfree(ap); > +} > +EXPORT_SYMBOL_GPL(ata_sas_port_destroy); > + > +/** > + * ata_sas_slave_configure - Default slave_config routine for libata devices > + * @sdev: SCSI device to configure > + * @ap: ATA port to which SCSI device is attached > + * > + * RETURNS: > + * Zero. > + */ > + > +int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap) > +{ > + ata_scsi_sdev_config(sdev); > + ata_scsi_dev_config(sdev, ap->device); > + return 0; > +} > +EXPORT_SYMBOL_GPL(ata_sas_slave_configure); > + > +/** > + * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device > + * @cmd: SCSI command to be sent > + * @done: Completion function, called when command is complete > + * @ap: ATA port to which the command is being sent > + * > + * RETURNS: > + * Zero. > + */ > + > +int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), > + struct ata_port *ap) > +{ > + ata_scsi_dump_cdb(ap, cmd); > + > + if (likely(ata_scsi_dev_enabled(ap->device))) > + __ata_scsi_queuecmd(cmd, done, ap->device); > + else { > + cmd->result = (DID_BAD_TARGET << 16); > + done(cmd); > + } > + return 0; > +} > +EXPORT_SYMBOL_GPL(ata_sas_queuecmd); > diff -puN drivers/scsi/libata.h~libata_sas drivers/scsi/libata.h > --- libata-dev/drivers/scsi/libata.h~libata_sas 2006-07-09 13:07:22.000000000 -0500 > +++ libata-dev-bjking1/drivers/scsi/libata.h 2006-07-09 13:07:22.000000000 -0500 > @@ -43,6 +43,7 @@ extern struct workqueue_struct *ata_aux_ > extern int atapi_enabled; > extern int atapi_dmadir; > extern int libata_fua; > +extern unsigned int ata_unique_id; > extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); > extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); > extern void ata_dev_disable(struct ata_device *dev); > @@ -107,6 +108,7 @@ extern void ata_scsi_rbuf_fill(struct at > u8 *rbuf, unsigned int buflen)); > extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); > extern void ata_scsi_dev_rescan(void *data); > +extern int ata_bus_probe(struct ata_port *ap); > > /* libata-eh.c */ > extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); > diff -puN include/linux/libata.h~libata_sas include/linux/libata.h > --- libata-dev/include/linux/libata.h~libata_sas 2006-07-09 13:07:22.000000000 -0500 > +++ libata-dev-bjking1/include/linux/libata.h 2006-07-09 13:07:22.000000000 -0500 > @@ -689,6 +689,15 @@ extern int ata_scsi_detect(struct scsi_h > extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); > extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); > extern int ata_scsi_release(struct Scsi_Host *host); > +extern void ata_sas_port_destroy(struct ata_port *); > +extern struct ata_port *ata_sas_port_alloc(struct ata_host_set *, > + struct ata_port_info *, struct Scsi_Host *); > +extern int ata_sas_port_init(struct ata_port *); > +extern int ata_sas_port_start(struct ata_port *ap); > +extern void ata_sas_port_stop(struct ata_port *ap); > +extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); > +extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), > + struct ata_port *ap); > extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); > extern int sata_scr_valid(struct ata_port *ap); > extern int sata_scr_read(struct ata_port *ap, int reg, u32 *val); > diff -puN drivers/scsi/libata-core.c~libata_sas drivers/scsi/libata-core.c > --- libata-dev/drivers/scsi/libata-core.c~libata_sas 2006-07-09 13:07:22.000000000 -0500 > +++ libata-dev-bjking1/drivers/scsi/libata-core.c 2006-07-09 13:07:22.000000000 -0500 > @@ -70,7 +70,7 @@ static unsigned int ata_dev_init_params( > static unsigned int ata_dev_set_xfermode(struct ata_device *dev); > static void ata_dev_xfermask(struct ata_device *dev); > > -static unsigned int ata_unique_id = 1; > +unsigned int ata_unique_id = 1; > static struct workqueue_struct *ata_wq; > > struct workqueue_struct *ata_aux_wq; > @@ -1528,7 +1528,7 @@ err_out_nosup: > * Zero on success, negative errno otherwise. > */ > > -static int ata_bus_probe(struct ata_port *ap) > +int ata_bus_probe(struct ata_port *ap) > { > unsigned int classes[ATA_MAX_DEVICES]; > int tries[ATA_MAX_DEVICES]; > _ - : send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html