- if (ap->flags & ATA_FLAG_DISABLED)
- return;
-
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- struct ata_device *dev = &ap->device[i];
- struct scsi_device *sdev;
-
- if (!ata_dev_enabled(dev) || dev->sdev)
- continue;
-
- sdev = __scsi_add_device(ap->host, 0, i, 0, NULL);
- if (!IS_ERR(sdev)) {
- dev->sdev = sdev;
- scsi_device_put(sdev);
- }
- }
-}
-
-/**
- * ata_scsi_offline_dev - offline attached SCSI device
- * @dev: ATA device to offline attached SCSI device for
- *
- * This function is called from ata_eh_hotplug() and responsible
- * for taking the SCSI device attached to @dev offline. This
- * function is called with host_set lock which protects dev->sdev
- * against clearing.
- *
- * LOCKING:
- * spin_lock_irqsave(host_set lock)
- *
- * RETURNS:
- * 1 if attached SCSI device exists, 0 otherwise.
- */
-int ata_scsi_offline_dev(struct ata_device *dev)
-{
- if (dev->sdev) {
- scsi_device_set_state(dev->sdev, SDEV_OFFLINE);
- return 1;
- }
- return 0;
-}
-
-/**
- * ata_scsi_remove_dev - remove attached SCSI device
- * @dev: ATA device to remove attached SCSI device for
- *
- * This function is called from ata_eh_scsi_hotplug() and
- * responsible for removing the SCSI device attached to @dev.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- */
-static void ata_scsi_remove_dev(struct ata_device *dev)
-{
- struct ata_port *ap = dev->ap;
- struct scsi_device *sdev;
- unsigned long flags;
-
- /* Alas, we need to grab scan_mutex to ensure SCSI device
- * state doesn't change underneath us and thus
- * scsi_device_get() always succeeds. The mutex locking can
- * be removed if there is __scsi_device_get() interface which
- * increments reference counts regardless of device state.
- */
- mutex_lock(&ap->host->scan_mutex);
- spin_lock_irqsave(ap->lock, flags);
-
- /* clearing dev->sdev is protected by host_set lock */
- sdev = dev->sdev;
- dev->sdev = NULL;
-
- if (sdev) {
- /* If user initiated unplug races with us, sdev can go
- * away underneath us after the host_set lock and
- * scan_mutex are released. Hold onto it.
- */
- if (scsi_device_get(sdev) == 0) {
- /* The following ensures the attached sdev is
- * offline on return from ata_scsi_offline_dev()
- * regardless it wins or loses the race
- * against this function.
- */
- scsi_device_set_state(sdev, SDEV_OFFLINE);
- } else {
- WARN_ON(1);
- sdev = NULL;
- }
- }
-
- spin_unlock_irqrestore(ap->lock, flags);
- mutex_unlock(&ap->host->scan_mutex);
-
- if (sdev) {
- ata_dev_printk(dev, KERN_INFO, "detaching (SCSI %s)\n",
- sdev->sdev_gendev.bus_id);
-
- scsi_remove_device(sdev);
- scsi_device_put(sdev);
- }
-}
-
-/**
- * ata_scsi_hotplug - SCSI part of hotplug
- * @data: Pointer to ATA port to perform SCSI hotplug on
- *
- * Perform SCSI part of hotplug. It's executed from a separate
- * workqueue after EH completes. This is necessary because SCSI
- * hot plugging requires working EH and hot unplugging is
- * synchronized with hot plugging with a mutex.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- */
-void ata_scsi_hotplug(void *data)
-{
- struct ata_port *ap = data;
- int i;
-
- if (ap->pflags & ATA_PFLAG_UNLOADING) {
- DPRINTK("ENTER/EXIT - unloading\n");