diff options
author | Oliver Neukum <oliver@neukum.org> | 2012-01-14 18:16:51 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:08:51 -0500 |
commit | 46a243f72de931aad2632a0f3de3612534212ae9 (patch) | |
tree | 34a73f00f3785ce9d2d0b96ab594843bf22e6b88 /drivers/scsi/st.c | |
parent | fea6d607e154cf96ab22254ccb48addfd43d4cb5 (diff) |
[SCSI] st: implement PM
This implements basic power management for SCSI tapes.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Acked-by: Kai Mäkisara <kai.makisara@kolumbus.fi>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r-- | drivers/scsi/st.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 9b28f39bac26..9262cdfa4b23 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -1177,6 +1177,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) | |||
1177 | static int st_open(struct inode *inode, struct file *filp) | 1177 | static int st_open(struct inode *inode, struct file *filp) |
1178 | { | 1178 | { |
1179 | int i, retval = (-EIO); | 1179 | int i, retval = (-EIO); |
1180 | int resumed = 0; | ||
1180 | struct scsi_tape *STp; | 1181 | struct scsi_tape *STp; |
1181 | struct st_partstat *STps; | 1182 | struct st_partstat *STps; |
1182 | int dev = TAPE_NR(inode); | 1183 | int dev = TAPE_NR(inode); |
@@ -1211,6 +1212,11 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1211 | write_unlock(&st_dev_arr_lock); | 1212 | write_unlock(&st_dev_arr_lock); |
1212 | STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0; | 1213 | STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0; |
1213 | 1214 | ||
1215 | if (scsi_autopm_get_device(STp->device) < 0) { | ||
1216 | retval = -EIO; | ||
1217 | goto err_out; | ||
1218 | } | ||
1219 | resumed = 1; | ||
1214 | if (!scsi_block_when_processing_errors(STp->device)) { | 1220 | if (!scsi_block_when_processing_errors(STp->device)) { |
1215 | retval = (-ENXIO); | 1221 | retval = (-ENXIO); |
1216 | goto err_out; | 1222 | goto err_out; |
@@ -1258,6 +1264,8 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1258 | normalize_buffer(STp->buffer); | 1264 | normalize_buffer(STp->buffer); |
1259 | STp->in_use = 0; | 1265 | STp->in_use = 0; |
1260 | scsi_tape_put(STp); | 1266 | scsi_tape_put(STp); |
1267 | if (resumed) | ||
1268 | scsi_autopm_put_device(STp->device); | ||
1261 | mutex_unlock(&st_mutex); | 1269 | mutex_unlock(&st_mutex); |
1262 | return retval; | 1270 | return retval; |
1263 | 1271 | ||
@@ -1391,6 +1399,7 @@ static int st_release(struct inode *inode, struct file *filp) | |||
1391 | write_lock(&st_dev_arr_lock); | 1399 | write_lock(&st_dev_arr_lock); |
1392 | STp->in_use = 0; | 1400 | STp->in_use = 0; |
1393 | write_unlock(&st_dev_arr_lock); | 1401 | write_unlock(&st_dev_arr_lock); |
1402 | scsi_autopm_put_device(STp->device); | ||
1394 | scsi_tape_put(STp); | 1403 | scsi_tape_put(STp); |
1395 | 1404 | ||
1396 | return result; | 1405 | return result; |
@@ -4154,6 +4163,7 @@ static int st_probe(struct device *dev) | |||
4154 | if (error) | 4163 | if (error) |
4155 | goto out_free_tape; | 4164 | goto out_free_tape; |
4156 | } | 4165 | } |
4166 | scsi_autopm_put_device(SDp); | ||
4157 | 4167 | ||
4158 | sdev_printk(KERN_NOTICE, SDp, | 4168 | sdev_printk(KERN_NOTICE, SDp, |
4159 | "Attached scsi tape %s\n", tape_name(tpnt)); | 4169 | "Attached scsi tape %s\n", tape_name(tpnt)); |
@@ -4201,6 +4211,7 @@ static int st_remove(struct device *dev) | |||
4201 | struct scsi_tape *tpnt; | 4211 | struct scsi_tape *tpnt; |
4202 | int i, j, mode; | 4212 | int i, j, mode; |
4203 | 4213 | ||
4214 | scsi_autopm_get_device(SDp); | ||
4204 | write_lock(&st_dev_arr_lock); | 4215 | write_lock(&st_dev_arr_lock); |
4205 | for (i = 0; i < st_dev_max; i++) { | 4216 | for (i = 0; i < st_dev_max; i++) { |
4206 | tpnt = scsi_tapes[i]; | 4217 | tpnt = scsi_tapes[i]; |