* [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters
2005-10-24 22:17 ` [PATCH " Brian King
@ 2005-10-24 22:20 ` Brian King
2005-10-25 17:58 ` Jeff Garzik
0 siblings, 1 reply; 6+ messages in thread
From: Brian King @ 2005-10-24 22:20 UTC (permalink / raw)
To: brking; +Cc: Jeff Garzik, Bartlomiej Zolnierkiewicz, linux-ide, linux-scsi
[-- Attachment #1: Type: text/plain, Size: 0 bytes --]
[-- Attachment #2: libata_sas.patch --]
[-- Type: text/plain, Size: 11795 bytes --]
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.
Since the last time I posted this code, I have removed all
dependence on the ata_host_set struct.
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
slave_alloc
ata_sas_port_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
ata_sas_port_destroy
Signed-off-by: Brian King <brking@us.ibm.com>
---
linux-2.6-bjking1/drivers/scsi/libata-core.c | 32 ++--
linux-2.6-bjking1/drivers/scsi/libata-scsi.c | 191 +++++++++++++++++++++++----
linux-2.6-bjking1/drivers/scsi/libata.h | 7
linux-2.6-bjking1/include/linux/libata.h | 7
4 files changed, 199 insertions(+), 38 deletions(-)
diff -puN drivers/scsi/libata-scsi.c~libata_sas drivers/scsi/libata-scsi.c
--- linux-2.6/drivers/scsi/libata-scsi.c~libata_sas 2005-10-24 15:08:27.000000000 -0500
+++ linux-2.6-bjking1/drivers/scsi/libata-scsi.c 2005-10-24 16:53:48.000000000 -0500
@@ -325,6 +325,30 @@ void ata_to_sense_error(struct ata_queue
}
}
+static void ata_scsi_sdev_config(struct scsi_device *sdev)
+{
+ sdev->use_10_for_rw = 1;
+ sdev->use_10_for_ms = 1;
+}
+
+static void ata_scsi_dev_config(struct scsi_device *sdev,
+ struct ata_device *dev)
+{
+ /* TODO: 1024 is an arbitrary number, not the
+ * hardware maximum. This should be increased to
+ * 65534 when Jens Axboe's patch for dynamically
+ * determining max_sectors is merged.
+ */
+ if ((dev->flags & ATA_DFLAG_LBA48) &&
+ ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
+ /*
+ * do not overwrite sdev->host->max_sectors, since
+ * other drives on this host may not support LBA48
+ */
+ blk_queue_max_sectors(sdev->request_queue, 2048);
+ }
+}
+
/**
* ata_scsi_slave_config - Set SCSI device attributes
* @sdev: SCSI device to examine
@@ -339,9 +363,7 @@ void ata_to_sense_error(struct ata_queue
int ata_scsi_slave_config(struct scsi_device *sdev)
{
- sdev->use_10_for_rw = 1;
- sdev->use_10_for_ms = 1;
-
+ ata_scsi_sdev_config(sdev);
blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);
if (sdev->id < ATA_MAX_DEVICES) {
@@ -351,19 +373,7 @@ int ata_scsi_slave_config(struct scsi_de
ap = (struct ata_port *) &sdev->host->hostdata[0];
dev = &ap->device[sdev->id];
- /* TODO: 1024 is an arbitrary number, not the
- * hardware maximum. This should be increased to
- * 65534 when Jens Axboe's patch for dynamically
- * determining max_sectors is merged.
- */
- if ((dev->flags & ATA_DFLAG_LBA48) &&
- ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
- /*
- * do not overwrite sdev->host->max_sectors, since
- * other drives on this host may not support LBA48
- */
- blk_queue_max_sectors(sdev->request_queue, 2048);
- }
+ ata_scsi_dev_config(sdev, dev);
}
return 0; /* scsi layer doesn't check return value, sigh */
@@ -1541,6 +1551,21 @@ static inline void ata_scsi_dump_cdb(str
#endif
}
+static void __ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
+ struct ata_port *ap, struct ata_device *dev)
+{
+ if (dev->class == ATA_DEV_ATA) {
+ ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
+ cmd->cmnd[0]);
+
+ if (xlat_func)
+ ata_scsi_translate(ap, dev, cmd, done, xlat_func);
+ else
+ ata_scsi_simulate(dev->id, cmd, done);
+ } else
+ ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
+}
+
/**
* ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device
* @cmd: SCSI command to be sent
@@ -1577,16 +1602,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *
goto out_unlock;
}
- if (dev->class == ATA_DEV_ATA) {
- ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
- cmd->cmnd[0]);
-
- if (xlat_func)
- ata_scsi_translate(ap, dev, cmd, done, xlat_func);
- else
- ata_scsi_simulate(dev->id, cmd, done);
- } else
- ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
+ __ata_scsi_queuecmd(cmd, done, ap, dev);
out_unlock:
return 0;
@@ -1678,3 +1694,126 @@ void ata_scsi_simulate(u16 *id,
}
}
+/**
+ * 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
+ *
+ * LOCKING:
+ * PCI/etc. bus probe sem.
+ *
+ * RETURNS:
+ * ata_port pointer on success / NULL on failure.
+ */
+
+struct ata_port *ata_sas_port_alloc(struct pci_dev *pdev,
+ struct ata_port_info *port_info)
+{
+ struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL);
+
+ if (!ap)
+ return NULL;
+
+ ap->dev = &pdev->dev;
+ ap->ops = port_info->port_ops;
+ ap->flags = port_info->host_flags;
+ 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->active_tag = ATA_TAG_POISON;
+ ap->last_ctl = 0xFF;
+ return ap;
+}
+EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
+
+static void ata_sas_port_free(struct ata_port *ap)
+{
+ kfree(ap);
+}
+
+/**
+ * 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)
+{
+ if (ap) {
+ ap->ops->port_stop(ap);
+ ata_sas_port_free(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);
+ if (ata_dev_knobble(ap))
+ blk_queue_max_sectors(sdev->request_queue, ATA_MAX_SECTORS);
+ 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)
+{
+ if (unlikely(!ata_dev_present(ap->device))) {
+ cmd->result = (DID_BAD_TARGET << 16);
+ done(cmd);
+ return 0;
+ }
+
+ if (cmd->cmd_len > ap->cdb_len) {
+ cmd->result = (DID_ABORT << 16);
+ done(cmd);
+ return 0;
+ }
+
+ __ata_scsi_queuecmd(cmd, done, ap, ap->device);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ata_sas_queuecmd);
diff -puN drivers/scsi/libata-core.c~libata_sas drivers/scsi/libata-core.c
--- linux-2.6/drivers/scsi/libata-core.c~libata_sas 2005-10-24 15:08:27.000000000 -0500
+++ linux-2.6-bjking1/drivers/scsi/libata-core.c 2005-10-24 15:08:27.000000000 -0500
@@ -1106,6 +1106,21 @@ static inline void ata_dump_id(struct at
dev->id[93]);
}
+static void ata_set_cdb_len(struct ata_port *ap, unsigned int cdb_len)
+{
+ ap->cdb_len = cdb_len;
+ if (ap->host)
+ ap->host->max_cmd_len = cdb_len;
+}
+
+static void ata_set_max_sectors(struct ata_port *ap, unsigned int max_sectors)
+{
+ if (ap->host) {
+ ap->host->max_sectors = ATA_MAX_SECTORS;
+ ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
+ }
+}
+
/**
* ata_dev_identify - obtain IDENTIFY x DEVICE page
* @ap: port on which device we wish to probe resides
@@ -1266,7 +1281,7 @@ retry:
dev->n_sectors = ata_id_u32(dev->id, 60);
}
- ap->host->max_cmd_len = 16;
+ ata_set_cdb_len(ap, 16);
/* print device info to dmesg */
printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
@@ -1286,8 +1301,8 @@ retry:
printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
goto err_out_nosup;
}
- ap->cdb_len = (unsigned int) rc;
- ap->host->max_cmd_len = (unsigned char) ap->cdb_len;
+
+ ata_set_cdb_len(ap, rc);
/* print device info to dmesg */
printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
@@ -1306,12 +1321,6 @@ err_out:
DPRINTK("EXIT, err\n");
}
-
-static inline u8 ata_dev_knobble(struct ata_port *ap)
-{
- return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
-}
-
/**
* ata_dev_config - Run device specific handlers and check for
* SATA->PATA bridges
@@ -1328,8 +1337,7 @@ void ata_dev_config(struct ata_port *ap,
printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
ap->id, ap->device->devno);
ap->udma_mask &= ATA_UDMA5;
- ap->host->max_sectors = ATA_MAX_SECTORS;
- ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
+ ata_set_max_sectors(ap, ATA_MAX_SECTORS);
ap->device->flags |= ATA_DFLAG_LOCK_SECTORS;
}
@@ -1352,7 +1360,7 @@ void ata_dev_config(struct ata_port *ap,
* Zero on success, non-zero on error.
*/
-static int ata_bus_probe(struct ata_port *ap)
+int ata_bus_probe(struct ata_port *ap)
{
unsigned int i, found = 0;
diff -puN drivers/scsi/libata.h~libata_sas drivers/scsi/libata.h
--- linux-2.6/drivers/scsi/libata.h~libata_sas 2005-10-24 15:08:27.000000000 -0500
+++ linux-2.6-bjking1/drivers/scsi/libata.h 2005-10-24 15:08:27.000000000 -0500
@@ -79,6 +79,8 @@ extern void ata_scsi_badcmd(struct scsi_
extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
unsigned int (*actor) (struct ata_scsi_args *args,
u8 *rbuf, unsigned int buflen));
+extern int ata_bus_probe(struct ata_port *ap);
+extern int ata_sas_port_init(struct ata_port *ap);
static inline void ata_bad_scsiop(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
@@ -90,4 +92,9 @@ static inline void ata_bad_cdb(struct sc
ata_scsi_badcmd(cmd, done, 0x24, 0x00);
}
+static inline u8 ata_dev_knobble(struct ata_port *ap)
+{
+ return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
+}
+
#endif /* __LIBATA_H__ */
diff -puN include/linux/libata.h~libata_sas include/linux/libata.h
--- linux-2.6/include/linux/libata.h~libata_sas 2005-10-24 15:08:27.000000000 -0500
+++ linux-2.6-bjking1/include/linux/libata.h 2005-10-24 15:08:27.000000000 -0500
@@ -401,6 +401,13 @@ extern int ata_scsi_ioctl(struct scsi_de
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
extern int ata_scsi_error(struct Scsi_Host *host);
extern int ata_scsi_release(struct Scsi_Host *host);
+extern void ata_sas_port_destroy(struct ata_port *ap);
+extern struct ata_port *ata_sas_port_alloc(struct pci_dev *pdev,
+ struct ata_port_info *port_info);
+extern int ata_sas_port_init(struct ata_port *ap);
+extern int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap);
+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);
/*
* Default driver ops implementations
_
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters
2005-10-24 22:20 ` [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters Brian King
@ 2005-10-25 17:58 ` Jeff Garzik
0 siblings, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2005-10-25 17:58 UTC (permalink / raw)
To: brking; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-scsi
Brian King wrote:
> +/**
> + * 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
> + *
> + * LOCKING:
> + * PCI/etc. bus probe sem.
> + *
> + * RETURNS:
> + * ata_port pointer on success / NULL on failure.
> + */
> +
> +struct ata_port *ata_sas_port_alloc(struct pci_dev *pdev,
> + struct ata_port_info *port_info)
> +{
> + struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL);
> +
> + if (!ap)
> + return NULL;
> +
> + ap->dev = &pdev->dev;
> + ap->ops = port_info->port_ops;
> + ap->flags = port_info->host_flags;
> + 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->active_tag = ATA_TAG_POISON;
> + ap->last_ctl = 0xFF;
> + return ap;
> +}
> +EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
> +
> +static void ata_sas_port_free(struct ata_port *ap)
> +{
> + kfree(ap);
> +}
> +
> +/**
> + * 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)
> +{
> + if (ap) {
> + ap->ops->port_stop(ap);
> + ata_sas_port_free(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);
> + if (ata_dev_knobble(ap))
> + blk_queue_max_sectors(sdev->request_queue, ATA_MAX_SECTORS);
> + 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)
> +{
> + if (unlikely(!ata_dev_present(ap->device))) {
> + cmd->result = (DID_BAD_TARGET << 16);
> + done(cmd);
> + return 0;
> + }
> +
> + if (cmd->cmd_len > ap->cdb_len) {
> + cmd->result = (DID_ABORT << 16);
> + done(cmd);
> + return 0;
> + }
> +
> + __ata_scsi_queuecmd(cmd, done, ap, ap->device);
> + return 0;
> +}
I'm still thinking about these functions, so it would be nice to split
them up into a third patch. That would allow me to apply the other
cleanups in this patch.
Jeff
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters
@ 2006-07-13 13:35 Brian King
2006-07-20 14:17 ` Brian King
2006-08-03 21:25 ` Jeff Garzik
0 siblings, 2 replies; 6+ messages in thread
From: Brian King @ 2006-07-13 13:35 UTC (permalink / raw)
To: jgarzik; +Cc: linux-ide, linux-scsi, brking
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@pobox.com>
Signed-off-by: Brian King <brking@us.ibm.com>
---
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];
_
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters
2006-07-13 13:35 [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters Brian King
@ 2006-07-20 14:17 ` Brian King
2006-07-28 14:01 ` Brian King
2006-08-03 21:25 ` Jeff Garzik
1 sibling, 1 reply; 6+ messages in thread
From: Brian King @ 2006-07-20 14:17 UTC (permalink / raw)
To: Brian King; +Cc: jgarzik, linux-ide, linux-scsi
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@pobox.com>
> Signed-off-by: Brian King <brking@us.ibm.com>
> ---
>
> 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];
> _
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters
2006-07-20 14:17 ` Brian King
@ 2006-07-28 14:01 ` Brian King
0 siblings, 0 replies; 6+ messages in thread
From: Brian King @ 2006-07-28 14:01 UTC (permalink / raw)
To: Brian King; +Cc: jgarzik, linux-ide, linux-scsi
Ping
Brian King wrote:
> 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@pobox.com>
>> Signed-off-by: Brian King <brking@us.ibm.com>
>> ---
>>
>> 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];
>> _
>
--
Brian King
eServer Storage I/O
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters
2006-07-13 13:35 [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters Brian King
2006-07-20 14:17 ` Brian King
@ 2006-08-03 21:25 ` Jeff Garzik
1 sibling, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2006-08-03 21:25 UTC (permalink / raw)
To: Brian King; +Cc: linux-ide, linux-scsi
You shouldn't be duplicating all that init code from ata_host_init().
Fix that issue (presumably by factoring out common code), and I'll apply
this SAS<->SATA attachment API patchset.
Jeff
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-08-03 21:25 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-13 13:35 [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters Brian King
2006-07-20 14:17 ` Brian King
2006-07-28 14:01 ` Brian King
2006-08-03 21:25 ` Jeff Garzik
-- strict thread matches above, loose matches on Subject: below --
2005-10-03 21:56 [RFC 0/2] libata: support SATA devices on SAS HBAs Brian King
2005-10-04 9:56 ` Jeff Garzik
2005-10-04 10:22 ` Bartlomiej Zolnierkiewicz
2005-10-04 20:56 ` Bartlomiej Zolnierkiewicz
2005-10-05 20:59 ` Jeff Garzik
2005-10-24 22:17 ` [PATCH " Brian King
2005-10-24 22:20 ` [PATCH 2/2] libata: Add support for SATA attachment to SAS adapters Brian King
2005-10-25 17:58 ` Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).