diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 57a43649a461..b578b11caa7b 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -190,6 +190,85 @@ static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) | |||
190 | scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); | 190 | scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); |
191 | } | 191 | } |
192 | 192 | ||
193 | static ssize_t | ||
194 | ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, | ||
195 | const char *buf, size_t count) | ||
196 | { | ||
197 | struct Scsi_Host *shost = class_to_shost(dev); | ||
198 | struct ata_port *ap = ata_shost_to_port(shost); | ||
199 | if (ap->ops->em_store && (ap->flags & ATA_FLAG_EM)) | ||
200 | return ap->ops->em_store(ap, buf, count); | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | |||
204 | static ssize_t | ||
205 | ata_scsi_em_message_show(struct device *dev, struct device_attribute *attr, | ||
206 | char *buf) | ||
207 | { | ||
208 | struct Scsi_Host *shost = class_to_shost(dev); | ||
209 | struct ata_port *ap = ata_shost_to_port(shost); | ||
210 | |||
211 | if (ap->ops->em_show && (ap->flags & ATA_FLAG_EM)) | ||
212 | return ap->ops->em_show(ap, buf); | ||
213 | return -EINVAL; | ||
214 | } | ||
215 | DEVICE_ATTR(em_message, S_IRUGO | S_IWUGO, | ||
216 | ata_scsi_em_message_show, ata_scsi_em_message_store); | ||
217 | EXPORT_SYMBOL_GPL(dev_attr_em_message); | ||
218 | |||
219 | static ssize_t | ||
220 | ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, | ||
221 | char *buf) | ||
222 | { | ||
223 | struct Scsi_Host *shost = class_to_shost(dev); | ||
224 | struct ata_port *ap = ata_shost_to_port(shost); | ||
225 | |||
226 | return snprintf(buf, 23, "%d\n", ap->em_message_type); | ||
227 | } | ||
228 | DEVICE_ATTR(em_message_type, S_IRUGO, | ||
229 | ata_scsi_em_message_type_show, NULL); | ||
230 | EXPORT_SYMBOL_GPL(dev_attr_em_message_type); | ||
231 | |||
232 | static ssize_t | ||
233 | ata_scsi_activity_show(struct device *dev, struct device_attribute *attr, | ||
234 | char *buf) | ||
235 | { | ||
236 | struct scsi_device *sdev = to_scsi_device(dev); | ||
237 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
238 | struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); | ||
239 | |||
240 | if (ap->ops->sw_activity_show && (ap->flags & ATA_FLAG_SW_ACTIVITY)) | ||
241 | return ap->ops->sw_activity_show(atadev, buf); | ||
242 | return -EINVAL; | ||
243 | } | ||
244 | |||
245 | static ssize_t | ||
246 | ata_scsi_activity_store(struct device *dev, struct device_attribute *attr, | ||
247 | const char *buf, size_t count) | ||
248 | { | ||
249 | struct scsi_device *sdev = to_scsi_device(dev); | ||
250 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
251 | struct ata_device *atadev = ata_scsi_find_dev(ap, sdev); | ||
252 | enum sw_activity val; | ||
253 | int rc; | ||
254 | |||
255 | if (ap->ops->sw_activity_store && (ap->flags & ATA_FLAG_SW_ACTIVITY)) { | ||
256 | val = simple_strtoul(buf, NULL, 0); | ||
257 | switch (val) { | ||
258 | case OFF: case BLINK_ON: case BLINK_OFF: | ||
259 | rc = ap->ops->sw_activity_store(atadev, val); | ||
260 | if (!rc) | ||
261 | return count; | ||
262 | else | ||
263 | return rc; | ||
264 | } | ||
265 | } | ||
266 | return -EINVAL; | ||
267 | } | ||
268 | DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show, | ||
269 | ata_scsi_activity_store); | ||
270 | EXPORT_SYMBOL_GPL(dev_attr_sw_activity); | ||
271 | |||
193 | static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, | 272 | static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, |
194 | void (*done)(struct scsi_cmnd *)) | 273 | void (*done)(struct scsi_cmnd *)) |
195 | { | 274 | { |