projects
/
linux-2.6-block.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6-block.git]
/
drivers
/
scsi
/
sd.c
diff --git
a/drivers/scsi/sd.c
b/drivers/scsi/sd.c
index 37df8bbe7f462b3c74228abef8f9ed71a6e6e731..0c63947d8a9d8fce2b4fa6240d9847036289f3b2 100644
(file)
--- a/
drivers/scsi/sd.c
+++ b/
drivers/scsi/sd.c
@@
-58,8
+58,8
@@
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsicam.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsicam.h>
-#include <scsi/sd.h>
+#include "sd.h"
#include "scsi_logging.h"
MODULE_AUTHOR("Eric Youngdale");
#include "scsi_logging.h"
MODULE_AUTHOR("Eric Youngdale");
@@
-95,7
+95,7
@@
static int sd_resume(struct device *);
static void sd_rescan(struct device *);
static int sd_done(struct scsi_cmnd *);
static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
static void sd_rescan(struct device *);
static int sd_done(struct scsi_cmnd *);
static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
-static void scsi_disk_release(struct
class_
device *cdev);
+static void scsi_disk_release(struct device *cdev);
static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
static void sd_print_result(struct scsi_disk *, int);
static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
static void sd_print_result(struct scsi_disk *, int);
@@
-112,11
+112,12
@@
static const char *sd_cache_types[] = {
"write back, no read (daft)"
};
"write back, no read (daft)"
};
-static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
- size_t count)
+static ssize_t
+sd_store_cache_type(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
int i, ct = -1, rcd, wce, sp;
{
int i, ct = -1, rcd, wce, sp;
- struct scsi_disk *sdkp = to_scsi_disk(
c
dev);
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
char buffer[64];
char *buffer_data;
struct scsi_device *sdp = sdkp->device;
char buffer[64];
char *buffer_data;
@@
-163,10
+164,11
@@
static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
return count;
}
return count;
}
-static ssize_t sd_store_manage_start_stop(struct class_device *cdev,
- const char *buf, size_t count)
+static ssize_t
+sd_store_manage_start_stop(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
{
- struct scsi_disk *sdkp = to_scsi_disk(
c
dev);
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
if (!capable(CAP_SYS_ADMIN))
struct scsi_device *sdp = sdkp->device;
if (!capable(CAP_SYS_ADMIN))
@@
-177,10
+179,11
@@
static ssize_t sd_store_manage_start_stop(struct class_device *cdev,
return count;
}
return count;
}
-static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf,
- size_t count)
+static ssize_t
+sd_store_allow_restart(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
{
- struct scsi_disk *sdkp = to_scsi_disk(
c
dev);
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
if (!capable(CAP_SYS_ADMIN))
struct scsi_device *sdp = sdkp->device;
if (!capable(CAP_SYS_ADMIN))
@@
-194,37
+197,44
@@
static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf
return count;
}
return count;
}
-static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf)
+static ssize_t
+sd_show_cache_type(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
{
- struct scsi_disk *sdkp = to_scsi_disk(
c
dev);
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
int ct = sdkp->RCD + 2*sdkp->WCE;
return snprintf(buf, 40, "%s\n", sd_cache_types[ct]);
}
int ct = sdkp->RCD + 2*sdkp->WCE;
return snprintf(buf, 40, "%s\n", sd_cache_types[ct]);
}
-static ssize_t sd_show_fua(struct class_device *cdev, char *buf)
+static ssize_t
+sd_show_fua(struct device *dev, struct device_attribute *attr, char *buf)
{
{
- struct scsi_disk *sdkp = to_scsi_disk(
c
dev);
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
}
return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
}
-static ssize_t sd_show_manage_start_stop(struct class_device *cdev, char *buf)
+static ssize_t
+sd_show_manage_start_stop(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
{
- struct scsi_disk *sdkp = to_scsi_disk(
c
dev);
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
return snprintf(buf, 20, "%u\n", sdp->manage_start_stop);
}
struct scsi_device *sdp = sdkp->device;
return snprintf(buf, 20, "%u\n", sdp->manage_start_stop);
}
-static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf)
+static ssize_t
+sd_show_allow_restart(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
{
- struct scsi_disk *sdkp = to_scsi_disk(
c
dev);
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart);
}
return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart);
}
-static struct
class_
device_attribute sd_disk_attrs[] = {
+static struct device_attribute sd_disk_attrs[] = {
__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
sd_store_cache_type),
__ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
sd_store_cache_type),
__ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
@@
-238,8
+248,8
@@
static struct class_device_attribute sd_disk_attrs[] = {
static struct class sd_disk_class = {
.name = "scsi_disk",
.owner = THIS_MODULE,
static struct class sd_disk_class = {
.name = "scsi_disk",
.owner = THIS_MODULE,
- .
release
= scsi_disk_release,
- .
class_dev_attrs
= sd_disk_attrs,
+ .
dev_release
= scsi_disk_release,
+ .
dev_attrs
= sd_disk_attrs,
};
static struct scsi_driver sd_template = {
};
static struct scsi_driver sd_template = {
@@
-285,11
+295,6
@@
static int sd_major(int major_idx)
}
}
}
}
-static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
-{
- return container_of(disk->private_data, struct scsi_disk, driver);
-}
-
static struct scsi_disk *__scsi_disk_get(struct gendisk *disk)
{
struct scsi_disk *sdkp = NULL;
static struct scsi_disk *__scsi_disk_get(struct gendisk *disk)
{
struct scsi_disk *sdkp = NULL;
@@
-297,7
+302,7
@@
static struct scsi_disk *__scsi_disk_get(struct gendisk *disk)
if (disk->private_data) {
sdkp = scsi_disk(disk);
if (scsi_device_get(sdkp->device) == 0)
if (disk->private_data) {
sdkp = scsi_disk(disk);
if (scsi_device_get(sdkp->device) == 0)
-
class_device_get(&sdkp->c
dev);
+
get_device(&sdkp->
dev);
else
sdkp = NULL;
}
else
sdkp = NULL;
}
@@
-331,7
+336,7
@@
static void scsi_disk_put(struct scsi_disk *sdkp)
struct scsi_device *sdev = sdkp->device;
mutex_lock(&sd_ref_mutex);
struct scsi_device *sdev = sdkp->device;
mutex_lock(&sd_ref_mutex);
-
class_device_put(&sdkp->c
dev);
+
put_device(&sdkp->
dev);
scsi_device_put(sdev);
mutex_unlock(&sd_ref_mutex);
}
scsi_device_put(sdev);
mutex_unlock(&sd_ref_mutex);
}
@@
-850,7
+855,6
@@
static int sd_sync_cache(struct scsi_disk *sdkp)
static void sd_prepare_flush(struct request_queue *q, struct request *rq)
{
static void sd_prepare_flush(struct request_queue *q, struct request *rq)
{
- memset(rq->cmd, 0, sizeof(rq->cmd));
rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = SD_TIMEOUT;
rq->cmd[0] = SYNCHRONIZE_CACHE;
rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = SD_TIMEOUT;
rq->cmd[0] = SYNCHRONIZE_CACHE;
@@
-1115,6
+1119,8
@@
sd_spinup_disk(struct scsi_disk *sdkp)
cmd[1] = 1; /* Return immediately */
memset((void *) &cmd[2], 0, 8);
cmd[4] = 1; /* Start spin cycle */
cmd[1] = 1; /* Return immediately */
memset((void *) &cmd[2], 0, 8);
cmd[4] = 1; /* Start spin cycle */
+ if (sdkp->device->start_stop_pwr_cond)
+ cmd[4] |= 1 << 4;
scsi_execute_req(sdkp->device, cmd, DMA_NONE,
NULL, 0, &sshdr,
SD_TIMEOUT, SD_MAX_RETRIES);
scsi_execute_req(sdkp->device, cmd, DMA_NONE,
NULL, 0, &sshdr,
SD_TIMEOUT, SD_MAX_RETRIES);
@@
-1654,6
+1660,7
@@
static int sd_probe(struct device *dev)
sdkp->disk = gd;
sdkp->index = index;
sdkp->openers = 0;
sdkp->disk = gd;
sdkp->index = index;
sdkp->openers = 0;
+ sdkp->previous_state = 1;
if (!sdp->timeout) {
if (sdp->type != TYPE_MOD)
if (!sdp->timeout) {
if (sdp->type != TYPE_MOD)
@@
-1662,12
+1669,12
@@
static int sd_probe(struct device *dev)
sdp->timeout = SD_MOD_TIMEOUT;
}
sdp->timeout = SD_MOD_TIMEOUT;
}
-
class_device_initialize(&sdkp->c
dev);
- sdkp->
cdev.dev
= &sdp->sdev_gendev;
- sdkp->
c
dev.class = &sd_disk_class;
- strncpy(sdkp->
cdev.clas
s_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
+
device_initialize(&sdkp->
dev);
+ sdkp->
dev.parent
= &sdp->sdev_gendev;
+ sdkp->dev.class = &sd_disk_class;
+ strncpy(sdkp->
dev.bu
s_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
- if (
class_device_add(&sdkp->c
dev))
+ if (
device_add(&sdkp->
dev))
goto out_put;
get_device(&sdp->sdev_gendev);
goto out_put;
get_device(&sdp->sdev_gendev);
@@
-1733,13
+1740,13
@@
static int sd_remove(struct device *dev)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
-
class_device_del(&sdkp->c
dev);
+
device_del(&sdkp->
dev);
del_gendisk(sdkp->disk);
sd_shutdown(dev);
mutex_lock(&sd_ref_mutex);
dev_set_drvdata(dev, NULL);
del_gendisk(sdkp->disk);
sd_shutdown(dev);
mutex_lock(&sd_ref_mutex);
dev_set_drvdata(dev, NULL);
-
class_device_put(&sdkp->c
dev);
+
put_device(&sdkp->
dev);
mutex_unlock(&sd_ref_mutex);
return 0;
mutex_unlock(&sd_ref_mutex);
return 0;
@@
-1747,16
+1754,16
@@
static int sd_remove(struct device *dev)
/**
* scsi_disk_release - Called to free the scsi_disk structure
/**
* scsi_disk_release - Called to free the scsi_disk structure
- * @
c
dev: pointer to embedded class device
+ * @dev: pointer to embedded class device
*
* sd_ref_mutex must be held entering this routine. Because it is
* called on last put, you should always use the scsi_disk_get()
* scsi_disk_put() helpers which manipulate the semaphore directly
*
* sd_ref_mutex must be held entering this routine. Because it is
* called on last put, you should always use the scsi_disk_get()
* scsi_disk_put() helpers which manipulate the semaphore directly
- * and never do a direct
class_device_put()
.
+ * and never do a direct
put_device
.
**/
**/
-static void scsi_disk_release(struct
class_device *c
dev)
+static void scsi_disk_release(struct
device *
dev)
{
{
- struct scsi_disk *sdkp = to_scsi_disk(
c
dev);
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
struct gendisk *disk = sdkp->disk;
spin_lock(&sd_index_lock);
struct gendisk *disk = sdkp->disk;
spin_lock(&sd_index_lock);
@@
-1780,6
+1787,9
@@
static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
if (start)
cmd[4] |= 1; /* START */
if (start)
cmd[4] |= 1; /* START */
+ if (sdp->start_stop_pwr_cond)
+ cmd[4] |= start ? 1 << 4 : 3 << 4; /* Active or Standby */
+
if (!scsi_device_online(sdp))
return -ENODEV;
if (!scsi_device_online(sdp))
return -ENODEV;
@@
-1835,8
+1845,7
@@
static int sd_suspend(struct device *dev, pm_message_t mesg)
goto done;
}
goto done;
}
- if (mesg.event == PM_EVENT_SUSPEND &&
- sdkp->device->manage_start_stop) {
+ if ((mesg.event & PM_EVENT_SLEEP) && sdkp->device->manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
ret = sd_start_stop_device(sdkp, 0);
}
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
ret = sd_start_stop_device(sdkp, 0);
}