|
@@ -3158,3 +3158,152 @@ 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);
|
|
|
+ struct ata_probe_ent *ent;
|
|
|
+
|
|
|
+ if (!ap)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ ent = ata_probe_ent_alloc(host_set->dev, port_info);
|
|
|
+ if (!ent) {
|
|
|
+ kfree(ap);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ ata_port_init(ap, host_set, ent, 0);
|
|
|
+ ap->lock = host->host_lock;
|
|
|
+ kfree(ent);
|
|
|
+ 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);
|