aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/st.c
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2012-01-14 18:16:51 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 09:08:51 -0500
commit46a243f72de931aad2632a0f3de3612534212ae9 (patch)
tree34a73f00f3785ce9d2d0b96ab594843bf22e6b88 /drivers/scsi/st.c
parentfea6d607e154cf96ab22254ccb48addfd43d4cb5 (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.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 9b28f39bac2..9262cdfa4b2 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)
1177static int st_open(struct inode *inode, struct file *filp) 1177static 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];