diff options
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r-- | drivers/scsi/sg.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index cf0e71db9e51..0419c2298eab 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -828,6 +828,39 @@ static int max_sectors_bytes(struct request_queue *q) | |||
828 | return max_sectors << 9; | 828 | return max_sectors << 9; |
829 | } | 829 | } |
830 | 830 | ||
831 | static void | ||
832 | sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo) | ||
833 | { | ||
834 | Sg_request *srp; | ||
835 | int val; | ||
836 | unsigned int ms; | ||
837 | |||
838 | val = 0; | ||
839 | list_for_each_entry(srp, &sfp->rq_list, entry) { | ||
840 | if (val > SG_MAX_QUEUE) | ||
841 | break; | ||
842 | rinfo[val].req_state = srp->done + 1; | ||
843 | rinfo[val].problem = | ||
844 | srp->header.masked_status & | ||
845 | srp->header.host_status & | ||
846 | srp->header.driver_status; | ||
847 | if (srp->done) | ||
848 | rinfo[val].duration = | ||
849 | srp->header.duration; | ||
850 | else { | ||
851 | ms = jiffies_to_msecs(jiffies); | ||
852 | rinfo[val].duration = | ||
853 | (ms > srp->header.duration) ? | ||
854 | (ms - srp->header.duration) : 0; | ||
855 | } | ||
856 | rinfo[val].orphan = srp->orphan; | ||
857 | rinfo[val].sg_io_owned = srp->sg_io_owned; | ||
858 | rinfo[val].pack_id = srp->header.pack_id; | ||
859 | rinfo[val].usr_ptr = srp->header.usr_ptr; | ||
860 | val++; | ||
861 | } | ||
862 | } | ||
863 | |||
831 | static long | 864 | static long |
832 | sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) | 865 | sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) |
833 | { | 866 | { |
@@ -1012,38 +1045,13 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) | |||
1012 | return -EFAULT; | 1045 | return -EFAULT; |
1013 | else { | 1046 | else { |
1014 | sg_req_info_t *rinfo; | 1047 | sg_req_info_t *rinfo; |
1015 | unsigned int ms; | ||
1016 | 1048 | ||
1017 | rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, | 1049 | rinfo = kzalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, |
1018 | GFP_KERNEL); | 1050 | GFP_KERNEL); |
1019 | if (!rinfo) | 1051 | if (!rinfo) |
1020 | return -ENOMEM; | 1052 | return -ENOMEM; |
1021 | read_lock_irqsave(&sfp->rq_list_lock, iflags); | 1053 | read_lock_irqsave(&sfp->rq_list_lock, iflags); |
1022 | val = 0; | 1054 | sg_fill_request_table(sfp, rinfo); |
1023 | list_for_each_entry(srp, &sfp->rq_list, entry) { | ||
1024 | if (val >= SG_MAX_QUEUE) | ||
1025 | break; | ||
1026 | memset(&rinfo[val], 0, SZ_SG_REQ_INFO); | ||
1027 | rinfo[val].req_state = srp->done + 1; | ||
1028 | rinfo[val].problem = | ||
1029 | srp->header.masked_status & | ||
1030 | srp->header.host_status & | ||
1031 | srp->header.driver_status; | ||
1032 | if (srp->done) | ||
1033 | rinfo[val].duration = | ||
1034 | srp->header.duration; | ||
1035 | else { | ||
1036 | ms = jiffies_to_msecs(jiffies); | ||
1037 | rinfo[val].duration = | ||
1038 | (ms > srp->header.duration) ? | ||
1039 | (ms - srp->header.duration) : 0; | ||
1040 | } | ||
1041 | rinfo[val].orphan = srp->orphan; | ||
1042 | rinfo[val].sg_io_owned = srp->sg_io_owned; | ||
1043 | rinfo[val].pack_id = srp->header.pack_id; | ||
1044 | rinfo[val].usr_ptr = srp->header.usr_ptr; | ||
1045 | val++; | ||
1046 | } | ||
1047 | read_unlock_irqrestore(&sfp->rq_list_lock, iflags); | 1055 | read_unlock_irqrestore(&sfp->rq_list_lock, iflags); |
1048 | result = __copy_to_user(p, rinfo, | 1056 | result = __copy_to_user(p, rinfo, |
1049 | SZ_SG_REQ_INFO * SG_MAX_QUEUE); | 1057 | SZ_SG_REQ_INFO * SG_MAX_QUEUE); |