diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
| -rw-r--r-- | drivers/ata/libata-scsi.c | 85 |
1 files changed, 71 insertions, 14 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e9364434182c..9afba2ba489e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -104,7 +104,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { | |||
| 104 | * libata transport template. libata doesn't do real transport stuff. | 104 | * libata transport template. libata doesn't do real transport stuff. |
| 105 | * It just needs the eh_timed_out hook. | 105 | * It just needs the eh_timed_out hook. |
| 106 | */ | 106 | */ |
| 107 | struct scsi_transport_template ata_scsi_transport_template = { | 107 | static struct scsi_transport_template ata_scsi_transport_template = { |
| 108 | .eh_strategy_handler = ata_scsi_error, | 108 | .eh_strategy_handler = ata_scsi_error, |
| 109 | .eh_timed_out = ata_scsi_timed_out, | 109 | .eh_timed_out = ata_scsi_timed_out, |
| 110 | .user_scan = ata_scsi_user_scan, | 110 | .user_scan = ata_scsi_user_scan, |
| @@ -2678,6 +2678,18 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) | |||
| 2678 | tf->device = qc->dev->devno ? | 2678 | tf->device = qc->dev->devno ? |
| 2679 | tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; | 2679 | tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; |
| 2680 | 2680 | ||
| 2681 | /* READ/WRITE LONG use a non-standard sect_size */ | ||
| 2682 | qc->sect_size = ATA_SECT_SIZE; | ||
| 2683 | switch (tf->command) { | ||
| 2684 | case ATA_CMD_READ_LONG: | ||
| 2685 | case ATA_CMD_READ_LONG_ONCE: | ||
| 2686 | case ATA_CMD_WRITE_LONG: | ||
| 2687 | case ATA_CMD_WRITE_LONG_ONCE: | ||
| 2688 | if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1) | ||
| 2689 | goto invalid_fld; | ||
| 2690 | qc->sect_size = scmd->request_bufflen; | ||
| 2691 | } | ||
| 2692 | |||
| 2681 | /* | 2693 | /* |
| 2682 | * Filter SET_FEATURES - XFER MODE command -- otherwise, | 2694 | * Filter SET_FEATURES - XFER MODE command -- otherwise, |
| 2683 | * SET_FEATURES - XFER MODE must be preceded/succeeded | 2695 | * SET_FEATURES - XFER MODE must be preceded/succeeded |
| @@ -2792,8 +2804,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, | |||
| 2792 | { | 2804 | { |
| 2793 | int rc = 0; | 2805 | int rc = 0; |
| 2794 | 2806 | ||
| 2795 | if (unlikely(!scmd->cmd_len)) { | 2807 | if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) { |
| 2796 | ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n"); | 2808 | DPRINTK("bad CDB len=%u, max=%u\n", |
| 2809 | scmd->cmd_len, dev->cdb_len); | ||
| 2797 | scmd->result = DID_ERROR << 16; | 2810 | scmd->result = DID_ERROR << 16; |
| 2798 | done(scmd); | 2811 | done(scmd); |
| 2799 | return 0; | 2812 | return 0; |
| @@ -2948,6 +2961,48 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, | |||
| 2948 | } | 2961 | } |
| 2949 | } | 2962 | } |
| 2950 | 2963 | ||
| 2964 | int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) | ||
| 2965 | { | ||
| 2966 | int i, rc; | ||
| 2967 | |||
| 2968 | for (i = 0; i < host->n_ports; i++) { | ||
| 2969 | struct ata_port *ap = host->ports[i]; | ||
| 2970 | struct Scsi_Host *shost; | ||
| 2971 | |||
| 2972 | rc = -ENOMEM; | ||
| 2973 | shost = scsi_host_alloc(sht, sizeof(struct ata_port *)); | ||
| 2974 | if (!shost) | ||
| 2975 | goto err_alloc; | ||
| 2976 | |||
| 2977 | *(struct ata_port **)&shost->hostdata[0] = ap; | ||
| 2978 | ap->scsi_host = shost; | ||
| 2979 | |||
| 2980 | shost->transportt = &ata_scsi_transport_template; | ||
| 2981 | shost->unique_id = ap->print_id; | ||
| 2982 | shost->max_id = 16; | ||
| 2983 | shost->max_lun = 1; | ||
| 2984 | shost->max_channel = 1; | ||
| 2985 | shost->max_cmd_len = 16; | ||
| 2986 | |||
| 2987 | rc = scsi_add_host(ap->scsi_host, ap->host->dev); | ||
| 2988 | if (rc) | ||
| 2989 | goto err_add; | ||
| 2990 | } | ||
| 2991 | |||
| 2992 | return 0; | ||
| 2993 | |||
| 2994 | err_add: | ||
| 2995 | scsi_host_put(host->ports[i]->scsi_host); | ||
| 2996 | err_alloc: | ||
| 2997 | while (--i >= 0) { | ||
| 2998 | struct Scsi_Host *shost = host->ports[i]->scsi_host; | ||
| 2999 | |||
| 3000 | scsi_remove_host(shost); | ||
| 3001 | scsi_host_put(shost); | ||
| 3002 | } | ||
| 3003 | return rc; | ||
| 3004 | } | ||
| 3005 | |||
| 2951 | void ata_scsi_scan_host(struct ata_port *ap) | 3006 | void ata_scsi_scan_host(struct ata_port *ap) |
| 2952 | { | 3007 | { |
| 2953 | unsigned int i; | 3008 | unsigned int i; |
| @@ -3224,21 +3279,21 @@ struct ata_port *ata_sas_port_alloc(struct ata_host *host, | |||
| 3224 | struct ata_port_info *port_info, | 3279 | struct ata_port_info *port_info, |
| 3225 | struct Scsi_Host *shost) | 3280 | struct Scsi_Host *shost) |
| 3226 | { | 3281 | { |
| 3227 | struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL); | 3282 | struct ata_port *ap; |
| 3228 | struct ata_probe_ent *ent; | ||
| 3229 | 3283 | ||
| 3284 | ap = ata_port_alloc(host); | ||
| 3230 | if (!ap) | 3285 | if (!ap) |
| 3231 | return NULL; | 3286 | return NULL; |
| 3232 | 3287 | ||
| 3233 | ent = ata_probe_ent_alloc(host->dev, port_info); | 3288 | ap->port_no = 0; |
| 3234 | if (!ent) { | ||
| 3235 | kfree(ap); | ||
| 3236 | return NULL; | ||
| 3237 | } | ||
| 3238 | |||
| 3239 | ata_port_init(ap, host, ent, 0); | ||
| 3240 | ap->lock = shost->host_lock; | 3289 | ap->lock = shost->host_lock; |
| 3241 | devm_kfree(host->dev, ent); | 3290 | ap->pio_mask = port_info->pio_mask; |
| 3291 | ap->mwdma_mask = port_info->mwdma_mask; | ||
| 3292 | ap->udma_mask = port_info->udma_mask; | ||
| 3293 | ap->flags |= port_info->flags; | ||
| 3294 | ap->ops = port_info->port_ops; | ||
| 3295 | ap->cbl = ATA_CBL_SATA; | ||
| 3296 | |||
| 3242 | return ap; | 3297 | return ap; |
| 3243 | } | 3298 | } |
| 3244 | EXPORT_SYMBOL_GPL(ata_sas_port_alloc); | 3299 | EXPORT_SYMBOL_GPL(ata_sas_port_alloc); |
| @@ -3294,8 +3349,10 @@ int ata_sas_port_init(struct ata_port *ap) | |||
| 3294 | { | 3349 | { |
| 3295 | int rc = ap->ops->port_start(ap); | 3350 | int rc = ap->ops->port_start(ap); |
| 3296 | 3351 | ||
| 3297 | if (!rc) | 3352 | if (!rc) { |
| 3353 | ap->print_id = ata_print_id++; | ||
| 3298 | rc = ata_bus_probe(ap); | 3354 | rc = ata_bus_probe(ap); |
| 3355 | } | ||
| 3299 | 3356 | ||
| 3300 | return rc; | 3357 | return rc; |
| 3301 | } | 3358 | } |
