aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorBrian King <brking@us.ibm.com>2006-08-07 15:27:31 -0400
committerJeff Garzik <jeff@garzik.org>2006-08-09 00:08:39 -0400
commit80289167fd3ebaeb7b2641e69cbec44b61165fe7 (patch)
treecb979ef0563377b9c901359dbcb1f117ff7d48d5 /drivers/scsi
parentf6d950e2a5209bd7e3fb1a238f43f24f3697f5b0 (diff)
[PATCH] libata: Add support for SATA attachment to SAS adapters
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 Signed-off-by: Brian King <brking@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/libata-core.c2
-rw-r--r--drivers/scsi/libata-scsi.c149
-rw-r--r--drivers/scsi/libata.h1
3 files changed, 151 insertions, 1 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index dc35cccd2898..83d93fc0751b 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1528,7 +1528,7 @@ err_out_nosup:
1528 * Zero on success, negative errno otherwise. 1528 * Zero on success, negative errno otherwise.
1529 */ 1529 */
1530 1530
1531static int ata_bus_probe(struct ata_port *ap) 1531int ata_bus_probe(struct ata_port *ap)
1532{ 1532{
1533 unsigned int classes[ATA_MAX_DEVICES]; 1533 unsigned int classes[ATA_MAX_DEVICES];
1534 int tries[ATA_MAX_DEVICES]; 1534 int tries[ATA_MAX_DEVICES];
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 1638e57028cb..37ec02661433 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -3158,3 +3158,152 @@ void ata_scsi_dev_rescan(void *data)
3158 scsi_rescan_device(&(dev->sdev->sdev_gendev)); 3158 scsi_rescan_device(&(dev->sdev->sdev_gendev));
3159 } 3159 }
3160} 3160}
3161
3162/**
3163 * ata_sas_port_alloc - Allocate port for a SAS attached SATA device
3164 * @pdev: PCI device that the scsi device is attached to
3165 * @port_info: Information from low-level host driver
3166 * @host: SCSI host that the scsi device is attached to
3167 *
3168 * LOCKING:
3169 * PCI/etc. bus probe sem.
3170 *
3171 * RETURNS:
3172 * ata_port pointer on success / NULL on failure.
3173 */
3174
3175struct ata_port *ata_sas_port_alloc(struct ata_host_set *host_set,
3176 struct ata_port_info *port_info,
3177 struct Scsi_Host *host)
3178{
3179 struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL);
3180 struct ata_probe_ent *ent;
3181
3182 if (!ap)
3183 return NULL;
3184
3185 ent = ata_probe_ent_alloc(host_set->dev, port_info);
3186 if (!ent) {
3187 kfree(ap);
3188 return NULL;
3189 }
3190
3191 ata_port_init(ap, host_set, ent, 0);
3192 ap->lock = host->host_lock;
3193 kfree(ent);
3194 return ap;
3195}
3196EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
3197
3198/**
3199 * ata_sas_port_start - Set port up for dma.
3200 * @ap: Port to initialize
3201 *
3202 * Called just after data structures for each port are
3203 * initialized. Allocates DMA pad.
3204 *
3205 * May be used as the port_start() entry in ata_port_operations.
3206 *
3207 * LOCKING:
3208 * Inherited from caller.
3209 */
3210int ata_sas_port_start(struct ata_port *ap)
3211{
3212 return ata_pad_alloc(ap, ap->dev);
3213}
3214EXPORT_SYMBOL_GPL(ata_sas_port_start);
3215
3216/**
3217 * ata_port_stop - Undo ata_sas_port_start()
3218 * @ap: Port to shut down
3219 *
3220 * Frees the DMA pad.
3221 *
3222 * May be used as the port_stop() entry in ata_port_operations.
3223 *
3224 * LOCKING:
3225 * Inherited from caller.
3226 */
3227
3228void ata_sas_port_stop(struct ata_port *ap)
3229{
3230 ata_pad_free(ap, ap->dev);
3231}
3232EXPORT_SYMBOL_GPL(ata_sas_port_stop);
3233
3234/**
3235 * ata_sas_port_init - Initialize a SATA device
3236 * @ap: SATA port to initialize
3237 *
3238 * LOCKING:
3239 * PCI/etc. bus probe sem.
3240 *
3241 * RETURNS:
3242 * Zero on success, non-zero on error.
3243 */
3244
3245int ata_sas_port_init(struct ata_port *ap)
3246{
3247 int rc = ap->ops->port_start(ap);
3248
3249 if (!rc)
3250 rc = ata_bus_probe(ap);
3251
3252 return rc;
3253}
3254EXPORT_SYMBOL_GPL(ata_sas_port_init);
3255
3256/**
3257 * ata_sas_port_destroy - Destroy a SATA port allocated by ata_sas_port_alloc
3258 * @ap: SATA port to destroy
3259 *
3260 */
3261
3262void ata_sas_port_destroy(struct ata_port *ap)
3263{
3264 ap->ops->port_stop(ap);
3265 kfree(ap);
3266}
3267EXPORT_SYMBOL_GPL(ata_sas_port_destroy);
3268
3269/**
3270 * ata_sas_slave_configure - Default slave_config routine for libata devices
3271 * @sdev: SCSI device to configure
3272 * @ap: ATA port to which SCSI device is attached
3273 *
3274 * RETURNS:
3275 * Zero.
3276 */
3277
3278int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap)
3279{
3280 ata_scsi_sdev_config(sdev);
3281 ata_scsi_dev_config(sdev, ap->device);
3282 return 0;
3283}
3284EXPORT_SYMBOL_GPL(ata_sas_slave_configure);
3285
3286/**
3287 * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device
3288 * @cmd: SCSI command to be sent
3289 * @done: Completion function, called when command is complete
3290 * @ap: ATA port to which the command is being sent
3291 *
3292 * RETURNS:
3293 * Zero.
3294 */
3295
3296int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
3297 struct ata_port *ap)
3298{
3299 ata_scsi_dump_cdb(ap, cmd);
3300
3301 if (likely(ata_scsi_dev_enabled(ap->device)))
3302 __ata_scsi_queuecmd(cmd, done, ap->device);
3303 else {
3304 cmd->result = (DID_BAD_TARGET << 16);
3305 done(cmd);
3306 }
3307 return 0;
3308}
3309EXPORT_SYMBOL_GPL(ata_sas_queuecmd);
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 0b7a37c2785d..d4a4f82360ec 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -111,6 +111,7 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
111 u8 *rbuf, unsigned int buflen)); 111 u8 *rbuf, unsigned int buflen));
112extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); 112extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
113extern void ata_scsi_dev_rescan(void *data); 113extern void ata_scsi_dev_rescan(void *data);
114extern int ata_bus_probe(struct ata_port *ap);
114 115
115/* libata-eh.c */ 116/* libata-eh.c */
116extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); 117extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);