Lines Matching +full:srp +full:- +full:capable

1 // SPDX-License-Identifier: GPL-2.0-or-later
11 * Copyright (C) 1998 - 2014 Douglas Gilbert
19 * - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
89 readable via /proc/sys/kernel/sg-big-buff if the sg driver is built into
91 static int def_reserved_size = -1; /* picks up init parameter */
112 unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */
113 unsigned sglist_len; /* size of malloc'd scatter-gather list ++ */
117 char dio_in_use; /* 0->indirect IO (or mmap), 1->dio */
126 struct sg_fd *parentfp; /* NULL -> not in use */
130 char res_used; /* 1 -> using reserve buffer, 0 -> not ... */
131 char orphan; /* 1 -> drop on sight, 0 -> normal */
132 char sg_io_owned; /* 1 -> packet belongs to SG_IO */
134 char done; /* 0->before bh, 1->before read, 2->read */
151 Sg_request req_arr[SG_MAX_QUEUE]; /* used as singly-linked list */
152 char force_packid; /* 1 -> pack_id input to read(), 0 -> ignored */
153 char cmd_q; /* 1 -> allow command queuing, 0 -> don't */
155 char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
156 char mmap_called; /* 0 -> mmap() never called on this fd */
157 char res_in_use; /* 1 -> 'reserve' array in use */
166 int sg_tablesize; /* adapter's max scatter-gather table size */
170 atomic_t detaching; /* 0->device usable, 1->device detaching */
171 bool exclude; /* 1->open(O_EXCL) succeeded and is active */
173 char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
181 static int sg_start_req(Sg_request *srp, unsigned char *cmd);
182 static int sg_finish_rem_req(Sg_request * srp);
185 Sg_request * srp);
189 static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
191 static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer);
194 static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
195 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
200 static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
210 sdev_prefix_printk(prefix, (sdp)->device, (sdp)->name, fmt, ##a)
226 if (filp->f_cred != current_real_cred()) { in sg_check_file_access()
228 caller, task_tgid_vnr(current), current->comm); in sg_check_file_access()
229 return -EPERM; in sg_check_file_access()
236 struct sg_fd *sfp = filp->private_data; in sg_allow_access()
238 if (sfp->parentdp->device->type == TYPE_SCANNER) in sg_allow_access()
240 if (!scsi_cmd_allowed(cmd, filp->f_mode & FMODE_WRITE)) in sg_allow_access()
241 return -EPERM; in sg_allow_access()
251 while (sdp->open_cnt > 0) { in open_wait()
252 mutex_unlock(&sdp->open_rel_lock); in open_wait()
253 retval = wait_event_interruptible(sdp->open_wait, in open_wait()
254 (atomic_read(&sdp->detaching) || in open_wait()
255 !sdp->open_cnt)); in open_wait()
256 mutex_lock(&sdp->open_rel_lock); in open_wait()
258 if (retval) /* -ERESTARTSYS */ in open_wait()
260 if (atomic_read(&sdp->detaching)) in open_wait()
261 return -ENODEV; in open_wait()
264 while (sdp->exclude) { in open_wait()
265 mutex_unlock(&sdp->open_rel_lock); in open_wait()
266 retval = wait_event_interruptible(sdp->open_wait, in open_wait()
267 (atomic_read(&sdp->detaching) || in open_wait()
268 !sdp->exclude)); in open_wait()
269 mutex_lock(&sdp->open_rel_lock); in open_wait()
271 if (retval) /* -ERESTARTSYS */ in open_wait()
273 if (atomic_read(&sdp->detaching)) in open_wait()
274 return -ENODEV; in open_wait()
286 int flags = filp->f_flags; in sg_open()
295 return -EPERM; /* Can't lock it with read only access */ in sg_open()
305 device = sdp->device; in sg_open()
315 retval = -ENXIO; in sg_open()
320 mutex_lock(&sdp->open_rel_lock); in sg_open()
323 if (sdp->open_cnt > 0) { in sg_open()
324 retval = -EBUSY; in sg_open()
328 if (sdp->exclude) { in sg_open()
329 retval = -EBUSY; in sg_open()
335 if (retval) /* -ERESTARTSYS or -ENODEV */ in sg_open()
341 sdp->exclude = true; in sg_open()
343 if (sdp->open_cnt < 1) { /* no existing opens */ in sg_open()
344 sdp->sgdebug = 0; in sg_open()
345 q = device->request_queue; in sg_open()
346 sdp->sg_tablesize = queue_max_segments(q); in sg_open()
354 filp->private_data = sfp; in sg_open()
355 sdp->open_cnt++; in sg_open()
356 mutex_unlock(&sdp->open_rel_lock); in sg_open()
360 kref_put(&sdp->d_ref, sg_device_destroy); in sg_open()
365 sdp->exclude = false; /* undo if error */ in sg_open()
366 wake_up_interruptible(&sdp->open_wait); in sg_open()
369 mutex_unlock(&sdp->open_rel_lock); in sg_open()
371 kref_put(&sdp->d_ref, sg_device_destroy); in sg_open()
384 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_release()
385 return -ENXIO; in sg_release()
388 mutex_lock(&sdp->open_rel_lock); in sg_release()
389 sdp->open_cnt--; in sg_release()
393 if (sdp->exclude) { in sg_release()
394 sdp->exclude = false; in sg_release()
395 wake_up_interruptible_all(&sdp->open_wait); in sg_release()
396 } else if (0 == sdp->open_cnt) { in sg_release()
397 wake_up_interruptible(&sdp->open_wait); in sg_release()
399 mutex_unlock(&sdp->open_rel_lock); in sg_release()
400 kref_put(&sfp->f_ref, sg_remove_sfp); in sg_release()
411 if (get_user(reply_len, &old_hdr->reply_len)) in get_sg_io_pack_id()
412 return -EFAULT; in get_sg_io_pack_id()
415 return get_user(*pack_id, &old_hdr->pack_id); in get_sg_io_pack_id()
421 return get_user(*pack_id, &hp->pack_id); in get_sg_io_pack_id()
427 return get_user(*pack_id, &hp->pack_id); in get_sg_io_pack_id()
432 *pack_id = -1; in get_sg_io_pack_id()
441 Sg_request *srp; in sg_read() local
442 int req_pack_id = -1; in sg_read()
456 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_read()
457 return -ENXIO; in sg_read()
461 if (sfp->force_packid) in sg_read()
466 srp = sg_get_rq_mark(sfp, req_pack_id, &busy); in sg_read()
467 if (!srp) { /* now wait on packet to arrive */ in sg_read()
468 if (filp->f_flags & O_NONBLOCK) in sg_read()
469 return -EAGAIN; in sg_read()
470 retval = wait_event_interruptible(sfp->read_wait, in sg_read()
471 ((srp = sg_get_rq_mark(sfp, req_pack_id, &busy)) || in sg_read()
472 (!busy && atomic_read(&sdp->detaching)))); in sg_read()
473 if (!srp) in sg_read()
475 return retval ? retval : -ENODEV; in sg_read()
477 if (srp->header.interface_id != '\0') in sg_read()
478 return sg_new_read(sfp, buf, count, srp); in sg_read()
480 hp = &srp->header; in sg_read()
483 return -ENOMEM; in sg_read()
485 old_hdr->reply_len = (int) hp->timeout; in sg_read()
486 old_hdr->pack_len = old_hdr->reply_len; /* old, strange behaviour */ in sg_read()
487 old_hdr->pack_id = hp->pack_id; in sg_read()
488 old_hdr->twelve_byte = in sg_read()
489 ((srp->data.cmd_opcode >= 0xc0) && (12 == hp->cmd_len)) ? 1 : 0; in sg_read()
490 old_hdr->target_status = hp->masked_status; in sg_read()
491 old_hdr->host_status = hp->host_status; in sg_read()
492 old_hdr->driver_status = hp->driver_status; in sg_read()
493 if ((CHECK_CONDITION & hp->masked_status) || in sg_read()
494 (srp->sense_b[0] & 0x70) == 0x70) { in sg_read()
495 old_hdr->driver_status = DRIVER_SENSE; in sg_read()
496 memcpy(old_hdr->sense_buffer, srp->sense_b, in sg_read()
497 sizeof (old_hdr->sense_buffer)); in sg_read()
499 switch (hp->host_status) { in sg_read()
505 old_hdr->result = 0; in sg_read()
510 old_hdr->result = EBUSY; in sg_read()
517 old_hdr->result = EIO; in sg_read()
520 old_hdr->result = (srp->sense_b[0] == 0 && in sg_read()
521 hp->masked_status == GOOD) ? 0 : EIO; in sg_read()
524 old_hdr->result = EIO; in sg_read()
531 retval = -EFAULT; in sg_read()
535 if (count > old_hdr->reply_len) in sg_read()
536 count = old_hdr->reply_len; in sg_read()
538 if (sg_read_oxfer(srp, buf, count - SZ_SG_HEADER)) { in sg_read()
539 retval = -EFAULT; in sg_read()
544 count = (old_hdr->result == 0) ? 0 : -EIO; in sg_read()
545 sg_finish_rem_req(srp); in sg_read()
546 sg_remove_request(sfp, srp); in sg_read()
554 sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp) in sg_new_read() argument
556 sg_io_hdr_t *hp = &srp->header; in sg_new_read()
562 err = -EINVAL; in sg_new_read()
566 err = -EINVAL; in sg_new_read()
569 hp->sb_len_wr = 0; in sg_new_read()
570 if ((hp->mx_sb_len > 0) && hp->sbp) { in sg_new_read()
571 if ((CHECK_CONDITION & hp->masked_status) || in sg_new_read()
572 (srp->sense_b[0] & 0x70) == 0x70) { in sg_new_read()
574 sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len; in sg_new_read()
575 len = 8 + (int) srp->sense_b[7]; /* Additional sense length field */ in sg_new_read()
577 if (copy_to_user(hp->sbp, srp->sense_b, len)) { in sg_new_read()
578 err = -EFAULT; in sg_new_read()
581 hp->driver_status = DRIVER_SENSE; in sg_new_read()
582 hp->sb_len_wr = len; in sg_new_read()
585 if (hp->masked_status || hp->host_status || hp->driver_status) in sg_new_read()
586 hp->info |= SG_INFO_CHECK; in sg_new_read()
589 err2 = sg_finish_rem_req(srp); in sg_new_read()
590 sg_remove_request(sfp, srp); in sg_new_read()
602 Sg_request *srp; in sg_write() local
612 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_write()
613 return -ENXIO; in sg_write()
616 if (atomic_read(&sdp->detaching)) in sg_write()
617 return -ENODEV; in sg_write()
618 if (!((filp->f_flags & O_NONBLOCK) || in sg_write()
619 scsi_block_when_processing_errors(sdp->device))) in sg_write()
620 return -ENXIO; in sg_write()
623 return -EIO; in sg_write()
625 return -EFAULT; in sg_write()
626 blocking = !(filp->f_flags & O_NONBLOCK); in sg_write()
631 return -EIO; /* The minimum scsi command length is 6 bytes. */ in sg_write()
635 return -EFAULT; in sg_write()
637 if (!(srp = sg_add_request(sfp))) { in sg_write()
640 return -EDOM; in sg_write()
642 mutex_lock(&sfp->f_mutex); in sg_write()
643 if (sfp->next_cmd_len > 0) { in sg_write()
644 cmd_size = sfp->next_cmd_len; in sg_write()
645 sfp->next_cmd_len = 0; /* reset so only this write() effected */ in sg_write()
651 mutex_unlock(&sfp->f_mutex); in sg_write()
655 input_size = count - cmd_size; in sg_write()
657 mxsize -= SZ_SG_HEADER; in sg_write()
658 input_size -= SZ_SG_HEADER; in sg_write()
660 sg_remove_request(sfp, srp); in sg_write()
661 return -EIO; /* User did not pass enough bytes for this command. */ in sg_write()
663 hp = &srp->header; in sg_write()
664 hp->interface_id = '\0'; /* indicator of old interface tunnelled */ in sg_write()
665 hp->cmd_len = (unsigned char) cmd_size; in sg_write()
666 hp->iovec_count = 0; in sg_write()
667 hp->mx_sb_len = 0; in sg_write()
669 hp->dxfer_direction = (old_hdr.reply_len > SZ_SG_HEADER) ? in sg_write()
672 hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE; in sg_write()
673 hp->dxfer_len = mxsize; in sg_write()
674 if ((hp->dxfer_direction == SG_DXFER_TO_DEV) || in sg_write()
675 (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV)) in sg_write()
676 hp->dxferp = (char __user *)buf + cmd_size; in sg_write()
678 hp->dxferp = NULL; in sg_write()
679 hp->sbp = NULL; in sg_write()
680 hp->timeout = old_hdr.reply_len; /* structure abuse ... */ in sg_write()
681 hp->flags = input_size; /* structure abuse ... */ in sg_write()
682 hp->pack_id = old_hdr.pack_id; in sg_write()
683 hp->usr_ptr = NULL; in sg_write()
685 sg_remove_request(sfp, srp); in sg_write()
686 return -EFAULT; in sg_write()
691 * is a non-zero input_size, so emit a warning. in sg_write()
693 if (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV) { in sg_write()
696 "for SCSI command 0x%x-- guessing " in sg_write()
699 old_hdr.reply_len - (int)SZ_SG_HEADER, in sg_write()
701 current->comm); in sg_write()
703 k = sg_common_write(sfp, srp, cmnd, sfp->timeout, blocking); in sg_write()
713 Sg_request *srp; in sg_new_write() local
720 return -EINVAL; in sg_new_write()
722 sfp->cmd_q = 1; /* when sg_io_hdr seen, set command queuing on */ in sg_new_write()
723 if (!(srp = sg_add_request(sfp))) { in sg_new_write()
724 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_new_write()
726 return -EDOM; in sg_new_write()
728 srp->sg_io_owned = sg_io_owned; in sg_new_write()
729 hp = &srp->header; in sg_new_write()
731 sg_remove_request(sfp, srp); in sg_new_write()
732 return -EFAULT; in sg_new_write()
734 if (hp->interface_id != 'S') { in sg_new_write()
735 sg_remove_request(sfp, srp); in sg_new_write()
736 return -ENOSYS; in sg_new_write()
738 if (hp->flags & SG_FLAG_MMAP_IO) { in sg_new_write()
739 if (hp->dxfer_len > sfp->reserve.bufflen) { in sg_new_write()
740 sg_remove_request(sfp, srp); in sg_new_write()
741 return -ENOMEM; /* MMAP_IO size must fit in reserve buffer */ in sg_new_write()
743 if (hp->flags & SG_FLAG_DIRECT_IO) { in sg_new_write()
744 sg_remove_request(sfp, srp); in sg_new_write()
745 return -EINVAL; /* either MMAP_IO or DIRECT_IO (not both) */ in sg_new_write()
747 if (sfp->res_in_use) { in sg_new_write()
748 sg_remove_request(sfp, srp); in sg_new_write()
749 return -EBUSY; /* reserve buffer already being used */ in sg_new_write()
752 ul_timeout = msecs_to_jiffies(srp->header.timeout); in sg_new_write()
754 if ((!hp->cmdp) || (hp->cmd_len < 6) || (hp->cmd_len > sizeof (cmnd))) { in sg_new_write()
755 sg_remove_request(sfp, srp); in sg_new_write()
756 return -EMSGSIZE; in sg_new_write()
758 if (copy_from_user(cmnd, hp->cmdp, hp->cmd_len)) { in sg_new_write()
759 sg_remove_request(sfp, srp); in sg_new_write()
760 return -EFAULT; in sg_new_write()
763 sg_remove_request(sfp, srp); in sg_new_write()
764 return -EPERM; in sg_new_write()
766 k = sg_common_write(sfp, srp, cmnd, timeout, blocking); in sg_new_write()
770 *o_srp = srp; in sg_new_write()
775 sg_common_write(Sg_fd * sfp, Sg_request * srp, in sg_common_write() argument
779 Sg_device *sdp = sfp->parentdp; in sg_common_write()
780 sg_io_hdr_t *hp = &srp->header; in sg_common_write()
782 srp->data.cmd_opcode = cmnd[0]; /* hold opcode of command */ in sg_common_write()
783 hp->status = 0; in sg_common_write()
784 hp->masked_status = 0; in sg_common_write()
785 hp->msg_status = 0; in sg_common_write()
786 hp->info = 0; in sg_common_write()
787 hp->host_status = 0; in sg_common_write()
788 hp->driver_status = 0; in sg_common_write()
789 hp->resid = 0; in sg_common_write()
790 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_common_write()
792 (int) cmnd[0], (int) hp->cmd_len)); in sg_common_write()
794 if (hp->dxfer_len >= SZ_256M) { in sg_common_write()
795 sg_remove_request(sfp, srp); in sg_common_write()
796 return -EINVAL; in sg_common_write()
799 k = sg_start_req(srp, cmnd); in sg_common_write()
801 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_common_write()
803 sg_finish_rem_req(srp); in sg_common_write()
804 sg_remove_request(sfp, srp); in sg_common_write()
805 return k; /* probably out of space --> ENOMEM */ in sg_common_write()
807 if (atomic_read(&sdp->detaching)) { in sg_common_write()
808 if (srp->bio) { in sg_common_write()
809 blk_mq_free_request(srp->rq); in sg_common_write()
810 srp->rq = NULL; in sg_common_write()
813 sg_finish_rem_req(srp); in sg_common_write()
814 sg_remove_request(sfp, srp); in sg_common_write()
815 return -ENODEV; in sg_common_write()
818 hp->duration = jiffies_to_msecs(jiffies); in sg_common_write()
819 if (hp->interface_id != '\0' && /* v3 (or later) interface */ in sg_common_write()
820 (SG_FLAG_Q_AT_TAIL & hp->flags)) in sg_common_write()
825 srp->rq->timeout = timeout; in sg_common_write()
826 kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */ in sg_common_write()
827 srp->rq->end_io = sg_rq_end_io; in sg_common_write()
828 blk_execute_rq_nowait(srp->rq, at_head); in sg_common_write()
832 static int srp_done(Sg_fd *sfp, Sg_request *srp) in srp_done() argument
837 read_lock_irqsave(&sfp->rq_list_lock, flags); in srp_done()
838 ret = srp->done; in srp_done()
839 read_unlock_irqrestore(&sfp->rq_list_lock, flags); in srp_done()
855 Sg_request *srp; in sg_fill_request_table() local
860 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_fill_request_table()
863 rinfo[val].req_state = srp->done + 1; in sg_fill_request_table()
865 srp->header.masked_status & in sg_fill_request_table()
866 srp->header.host_status & in sg_fill_request_table()
867 srp->header.driver_status; in sg_fill_request_table()
868 if (srp->done) in sg_fill_request_table()
870 srp->header.duration; in sg_fill_request_table()
874 (ms > srp->header.duration) ? in sg_fill_request_table()
875 (ms - srp->header.duration) : 0; in sg_fill_request_table()
877 rinfo[val].orphan = srp->orphan; in sg_fill_request_table()
878 rinfo[val].sg_io_owned = srp->sg_io_owned; in sg_fill_request_table()
879 rinfo[val].pack_id = srp->header.pack_id; in sg_fill_request_table()
880 rinfo[val].usr_ptr = srp->header.usr_ptr; in sg_fill_request_table()
906 return -EFAULT; in put_compat_request_table()
918 Sg_request *srp; in sg_ioctl_common() local
923 read_only = (O_RDWR != (filp->f_flags & O_ACCMODE)); in sg_ioctl_common()
927 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
928 return -ENODEV; in sg_ioctl_common()
929 if (!scsi_block_when_processing_errors(sdp->device)) in sg_ioctl_common()
930 return -ENXIO; in sg_ioctl_common()
932 1, read_only, 1, &srp); in sg_ioctl_common()
935 result = wait_event_interruptible(sfp->read_wait, in sg_ioctl_common()
936 srp_done(sfp, srp)); in sg_ioctl_common()
937 write_lock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
938 if (srp->done) { in sg_ioctl_common()
939 srp->done = 2; in sg_ioctl_common()
940 write_unlock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
941 result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp); in sg_ioctl_common()
944 srp->orphan = 1; in sg_ioctl_common()
945 write_unlock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
946 return result; /* -ERESTARTSYS because signal hit process */ in sg_ioctl_common()
952 return -EIO; in sg_ioctl_common()
956 sfp->timeout_user = val; in sg_ioctl_common()
957 sfp->timeout = mult_frac(val, HZ, USER_HZ); in sg_ioctl_common()
962 return sfp->timeout_user; in sg_ioctl_common()
976 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
977 return -ENODEV; in sg_ioctl_common()
979 v.host_no = sdp->device->host->host_no; in sg_ioctl_common()
980 v.channel = sdp->device->channel; in sg_ioctl_common()
981 v.scsi_id = sdp->device->id; in sg_ioctl_common()
982 v.lun = sdp->device->lun; in sg_ioctl_common()
983 v.scsi_type = sdp->device->type; in sg_ioctl_common()
984 v.h_cmd_per_lun = sdp->device->host->cmd_per_lun; in sg_ioctl_common()
985 v.d_queue_depth = sdp->device->queue_depth; in sg_ioctl_common()
987 return -EFAULT; in sg_ioctl_common()
994 sfp->force_packid = val ? 1 : 0; in sg_ioctl_common()
997 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
998 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_ioctl_common()
999 if ((1 == srp->done) && (!srp->sg_io_owned)) { in sg_ioctl_common()
1000 read_unlock_irqrestore(&sfp->rq_list_lock, in sg_ioctl_common()
1002 return put_user(srp->header.pack_id, ip); in sg_ioctl_common()
1005 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1006 return put_user(-1, ip); in sg_ioctl_common()
1008 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1010 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_ioctl_common()
1011 if ((1 == srp->done) && (!srp->sg_io_owned)) in sg_ioctl_common()
1014 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1017 return put_user(sdp->sg_tablesize, ip); in sg_ioctl_common()
1023 return -EINVAL; in sg_ioctl_common()
1025 max_sectors_bytes(sdp->device->request_queue)); in sg_ioctl_common()
1026 mutex_lock(&sfp->f_mutex); in sg_ioctl_common()
1027 if (val != sfp->reserve.bufflen) { in sg_ioctl_common()
1028 if (sfp->mmap_called || in sg_ioctl_common()
1029 sfp->res_in_use) { in sg_ioctl_common()
1030 mutex_unlock(&sfp->f_mutex); in sg_ioctl_common()
1031 return -EBUSY; in sg_ioctl_common()
1034 sg_remove_scat(sfp, &sfp->reserve); in sg_ioctl_common()
1037 mutex_unlock(&sfp->f_mutex); in sg_ioctl_common()
1040 val = min_t(int, sfp->reserve.bufflen, in sg_ioctl_common()
1041 max_sectors_bytes(sdp->device->request_queue)); in sg_ioctl_common()
1047 sfp->cmd_q = val ? 1 : 0; in sg_ioctl_common()
1050 return put_user((int) sfp->cmd_q, ip); in sg_ioctl_common()
1055 sfp->keep_orphan = val; in sg_ioctl_common()
1058 return put_user((int) sfp->keep_orphan, ip); in sg_ioctl_common()
1064 return -ENOMEM; in sg_ioctl_common()
1065 sfp->next_cmd_len = (val > 0) ? val : 0; in sg_ioctl_common()
1070 /* faked - we don't have a real access count anymore */ in sg_ioctl_common()
1071 val = (sdp->device ? 1 : 0); in sg_ioctl_common()
1080 return -ENOMEM; in sg_ioctl_common()
1081 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1083 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1091 result = result ? -EFAULT : 0; in sg_ioctl_common()
1096 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1097 return -ENODEV; in sg_ioctl_common()
1098 return put_user(sdp->device->host->hostt->emulated, ip); in sg_ioctl_common()
1100 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1101 return -ENODEV; in sg_ioctl_common()
1102 return scsi_ioctl(sdp->device, filp->f_mode & FMODE_WRITE, in sg_ioctl_common()
1108 sdp->sgdebug = (char) val; in sg_ioctl_common()
1111 return put_user(max_sectors_bytes(sdp->device->request_queue), in sg_ioctl_common()
1114 return blk_trace_setup(sdp->device->request_queue, sdp->name, in sg_ioctl_common()
1115 MKDEV(SCSI_GENERIC_MAJOR, sdp->index), in sg_ioctl_common()
1118 return blk_trace_startstop(sdp->device->request_queue, 1); in sg_ioctl_common()
1120 return blk_trace_startstop(sdp->device->request_queue, 0); in sg_ioctl_common()
1122 return blk_trace_remove(sdp->device->request_queue); in sg_ioctl_common()
1128 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1129 return -ENODEV; in sg_ioctl_common()
1133 return -EPERM; /* don't know so take safe approach */ in sg_ioctl_common()
1137 result = scsi_ioctl_block_when_processing_errors(sdp->device, in sg_ioctl_common()
1138 cmd_in, filp->f_flags & O_NDELAY); in sg_ioctl_common()
1142 return -ENOIOCTLCMD; in sg_ioctl_common()
1153 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_ioctl()
1154 return -ENXIO; in sg_ioctl()
1157 if (ret != -ENOIOCTLCMD) in sg_ioctl()
1159 return scsi_ioctl(sdp->device, filp->f_mode & FMODE_WRITE, cmd_in, p); in sg_ioctl()
1168 Sg_request *srp; in sg_poll() local
1172 sfp = filp->private_data; in sg_poll()
1175 sdp = sfp->parentdp; in sg_poll()
1178 poll_wait(filp, &sfp->read_wait, wait); in sg_poll()
1179 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_poll()
1180 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_poll()
1182 if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned)) in sg_poll()
1186 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_poll()
1188 if (atomic_read(&sdp->detaching)) in sg_poll()
1190 else if (!sfp->cmd_q) { in sg_poll()
1206 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_fasync()
1207 return -ENXIO; in sg_fasync()
1211 return fasync_helper(fd, filp, mode, &sfp->async_qp); in sg_fasync()
1217 struct vm_area_struct *vma = vmf->vma; in sg_vma_fault()
1223 if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data))) in sg_vma_fault()
1225 rsv_schp = &sfp->reserve; in sg_vma_fault()
1226 offset = vmf->pgoff << PAGE_SHIFT; in sg_vma_fault()
1227 if (offset >= rsv_schp->bufflen) in sg_vma_fault()
1229 SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp, in sg_vma_fault()
1231 offset, rsv_schp->k_use_sg)); in sg_vma_fault()
1232 sa = vma->vm_start; in sg_vma_fault()
1233 length = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_vma_fault()
1234 for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) { in sg_vma_fault()
1235 len = vma->vm_end - sa; in sg_vma_fault()
1238 struct page *page = nth_page(rsv_schp->pages[k], in sg_vma_fault()
1241 vmf->page = page; in sg_vma_fault()
1245 offset -= len; in sg_vma_fault()
1264 if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data))) in sg_mmap()
1265 return -ENXIO; in sg_mmap()
1266 req_sz = vma->vm_end - vma->vm_start; in sg_mmap()
1267 SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp, in sg_mmap()
1269 (void *) vma->vm_start, (int) req_sz)); in sg_mmap()
1270 if (vma->vm_pgoff) in sg_mmap()
1271 return -EINVAL; /* want no offset */ in sg_mmap()
1272 rsv_schp = &sfp->reserve; in sg_mmap()
1273 mutex_lock(&sfp->f_mutex); in sg_mmap()
1274 if (req_sz > rsv_schp->bufflen) { in sg_mmap()
1275 ret = -ENOMEM; /* cannot map more than reserved buffer */ in sg_mmap()
1279 sa = vma->vm_start; in sg_mmap()
1280 length = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_mmap()
1281 for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) { in sg_mmap()
1282 len = vma->vm_end - sa; in sg_mmap()
1287 sfp->mmap_called = 1; in sg_mmap()
1289 vma->vm_private_data = sfp; in sg_mmap()
1290 vma->vm_ops = &sg_mmap_vm_ops; in sg_mmap()
1292 mutex_unlock(&sfp->f_mutex); in sg_mmap()
1299 struct sg_request *srp = container_of(work, struct sg_request, ew.work); in sg_rq_end_io_usercontext() local
1300 struct sg_fd *sfp = srp->parentfp; in sg_rq_end_io_usercontext()
1302 sg_finish_rem_req(srp); in sg_rq_end_io_usercontext()
1303 sg_remove_request(sfp, srp); in sg_rq_end_io_usercontext()
1304 kref_put(&sfp->f_ref, sg_remove_sfp); in sg_rq_end_io_usercontext()
1315 struct sg_request *srp = rq->end_io_data; in sg_rq_end_io() local
1323 if (WARN_ON(srp->done != 0)) in sg_rq_end_io()
1326 sfp = srp->parentfp; in sg_rq_end_io()
1330 sdp = sfp->parentdp; in sg_rq_end_io()
1331 if (unlikely(atomic_read(&sdp->detaching))) in sg_rq_end_io()
1334 sense = scmd->sense_buffer; in sg_rq_end_io()
1335 result = scmd->result; in sg_rq_end_io()
1336 resid = scmd->resid_len; in sg_rq_end_io()
1340 srp->header.pack_id, result)); in sg_rq_end_io()
1341 srp->header.resid = resid; in sg_rq_end_io()
1343 srp->header.duration = (ms > srp->header.duration) ? in sg_rq_end_io()
1344 (ms - srp->header.duration) : 0; in sg_rq_end_io()
1348 srp->header.status = 0xff & result; in sg_rq_end_io()
1349 srp->header.masked_status = sg_status_byte(result); in sg_rq_end_io()
1350 srp->header.msg_status = COMMAND_COMPLETE; in sg_rq_end_io()
1351 srp->header.host_status = host_byte(result); in sg_rq_end_io()
1352 srp->header.driver_status = driver_byte(result); in sg_rq_end_io()
1353 if ((sdp->sgdebug > 0) && in sg_rq_end_io()
1354 ((CHECK_CONDITION == srp->header.masked_status) || in sg_rq_end_io()
1355 (COMMAND_TERMINATED == srp->header.masked_status))) in sg_rq_end_io()
1356 __scsi_print_sense(sdp->device, __func__, sense, in sg_rq_end_io()
1364 && sdp->device->removable) { in sg_rq_end_io()
1365 /* Detected possible disc change. Set the bit - this */ in sg_rq_end_io()
1367 sdp->device->changed = 1; in sg_rq_end_io()
1371 if (scmd->sense_len) in sg_rq_end_io()
1372 memcpy(srp->sense_b, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); in sg_rq_end_io()
1374 /* Rely on write phase to clean out srp status values, so no "else" */ in sg_rq_end_io()
1382 srp->rq = NULL; in sg_rq_end_io()
1385 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_rq_end_io()
1386 if (unlikely(srp->orphan)) { in sg_rq_end_io()
1387 if (sfp->keep_orphan) in sg_rq_end_io()
1388 srp->sg_io_owned = 0; in sg_rq_end_io()
1392 srp->done = done; in sg_rq_end_io()
1393 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_rq_end_io()
1399 wake_up_interruptible(&sfp->read_wait); in sg_rq_end_io()
1400 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); in sg_rq_end_io()
1401 kref_put(&sfp->f_ref, sg_remove_sfp); in sg_rq_end_io()
1403 INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext); in sg_rq_end_io()
1404 schedule_work(&srp->ew.work); in sg_rq_end_io()
1431 struct request_queue *q = scsidp->request_queue; in sg_alloc()
1441 return ERR_PTR(-ENOMEM); in sg_alloc()
1449 if (error == -ENOSPC) { in sg_alloc()
1452 scsidp->type, SG_MAX_DEVS - 1); in sg_alloc()
1453 error = -ENODEV; in sg_alloc()
1465 sprintf(sdp->name, "sg%d", k); in sg_alloc()
1466 sdp->device = scsidp; in sg_alloc()
1467 mutex_init(&sdp->open_rel_lock); in sg_alloc()
1468 INIT_LIST_HEAD(&sdp->sfds); in sg_alloc()
1469 init_waitqueue_head(&sdp->open_wait); in sg_alloc()
1470 atomic_set(&sdp->detaching, 0); in sg_alloc()
1471 rwlock_init(&sdp->sfd_lock); in sg_alloc()
1472 sdp->sg_tablesize = queue_max_segments(q); in sg_alloc()
1473 sdp->index = k; in sg_alloc()
1474 kref_init(&sdp->d_ref); in sg_alloc()
1491 struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); in sg_add_device()
1497 if (!blk_get_queue(scsidp->request_queue)) { in sg_add_device()
1499 return -ENODEV; in sg_add_device()
1502 error = -ENOMEM; in sg_add_device()
1508 cdev->owner = THIS_MODULE; in sg_add_device()
1509 cdev->ops = &sg_fops; in sg_add_device()
1518 error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, sdp->index), 1); in sg_add_device()
1522 sdp->cdev = cdev; in sg_add_device()
1526 sg_class_member = device_create(&sg_sysfs_class, cl_dev->parent, in sg_add_device()
1528 sdp->index), in sg_add_device()
1529 sdp, "%s", sdp->name); in sg_add_device()
1535 error = sysfs_create_link(&scsidp->sdev_gendev.kobj, in sg_add_device()
1536 &sg_class_member->kobj, "generic"); in sg_add_device()
1539 "to sg%d\n", __func__, sdp->index); in sg_add_device()
1544 "type %d\n", sdp->index, scsidp->type); in sg_add_device()
1552 idr_remove(&sg_index_idr, sdp->index); in sg_add_device()
1559 blk_put_queue(scsidp->request_queue); in sg_add_device()
1567 struct request_queue *q = sdp->device->request_queue; in sg_device_destroy()
1579 idr_remove(&sg_index_idr, sdp->index); in sg_device_destroy()
1591 struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); in sg_remove_device()
1599 /* want sdp->detaching non-zero as soon as possible */ in sg_remove_device()
1600 val = atomic_inc_return(&sdp->detaching); in sg_remove_device()
1607 read_lock_irqsave(&sdp->sfd_lock, iflags); in sg_remove_device()
1608 list_for_each_entry(sfp, &sdp->sfds, sfd_siblings) { in sg_remove_device()
1609 wake_up_interruptible_all(&sfp->read_wait); in sg_remove_device()
1610 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_HUP); in sg_remove_device()
1612 wake_up_interruptible_all(&sdp->open_wait); in sg_remove_device()
1613 read_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_remove_device()
1615 sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic"); in sg_remove_device()
1616 device_destroy(&sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index)); in sg_remove_device()
1617 cdev_del(sdp->cdev); in sg_remove_device()
1618 sdp->cdev = NULL; in sg_remove_device()
1620 kref_put(&sdp->d_ref, sg_device_destroy); in sg_remove_device()
1644 .procname = "sg-big-buff",
1721 sg_start_req(Sg_request *srp, unsigned char *cmd) in sg_start_req() argument
1725 Sg_fd *sfp = srp->parentfp; in sg_start_req()
1726 sg_io_hdr_t *hp = &srp->header; in sg_start_req()
1727 int dxfer_len = (int) hp->dxfer_len; in sg_start_req()
1728 int dxfer_dir = hp->dxfer_direction; in sg_start_req()
1729 unsigned int iov_count = hp->iovec_count; in sg_start_req()
1730 Sg_scatter_hold *req_schp = &srp->data; in sg_start_req()
1731 Sg_scatter_hold *rsv_schp = &sfp->reserve; in sg_start_req()
1732 struct request_queue *q = sfp->parentdp->device->request_queue; in sg_start_req()
1734 int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? ITER_SOURCE : ITER_DEST; in sg_start_req()
1737 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_start_req()
1744 * With scsi-mq enabled, there are a fixed number of preallocated in sg_start_req()
1745 * requests equal in number to shost->can_queue. If all of the in sg_start_req()
1752 rq = scsi_alloc_request(q, hp->dxfer_direction == SG_DXFER_TO_DEV ? in sg_start_req()
1758 if (hp->cmd_len > sizeof(scmd->cmnd)) { in sg_start_req()
1760 return -EINVAL; in sg_start_req()
1763 memcpy(scmd->cmnd, cmd, hp->cmd_len); in sg_start_req()
1764 scmd->cmd_len = hp->cmd_len; in sg_start_req()
1766 srp->rq = rq; in sg_start_req()
1767 rq->end_io_data = srp; in sg_start_req()
1768 scmd->allowed = SG_DEFAULT_RETRIES; in sg_start_req()
1773 if (sg_allow_dio && hp->flags & SG_FLAG_DIRECT_IO && in sg_start_req()
1775 blk_rq_aligned(q, (unsigned long)hp->dxferp, dxfer_len)) in sg_start_req()
1781 mutex_lock(&sfp->f_mutex); in sg_start_req()
1782 if (dxfer_len <= rsv_schp->bufflen && in sg_start_req()
1783 !sfp->res_in_use) { in sg_start_req()
1784 sfp->res_in_use = 1; in sg_start_req()
1785 sg_link_reserve(sfp, srp, dxfer_len); in sg_start_req()
1786 } else if (hp->flags & SG_FLAG_MMAP_IO) { in sg_start_req()
1787 res = -EBUSY; /* sfp->res_in_use == 1 */ in sg_start_req()
1788 if (dxfer_len > rsv_schp->bufflen) in sg_start_req()
1789 res = -ENOMEM; in sg_start_req()
1790 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1795 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1799 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1801 md->pages = req_schp->pages; in sg_start_req()
1802 md->page_order = req_schp->page_order; in sg_start_req()
1803 md->nr_entries = req_schp->k_use_sg; in sg_start_req()
1804 md->offset = 0; in sg_start_req()
1805 md->null_mapped = hp->dxferp ? 0 : 1; in sg_start_req()
1807 md->from_user = 1; in sg_start_req()
1809 md->from_user = 0; in sg_start_req()
1812 res = blk_rq_map_user_io(rq, md, hp->dxferp, hp->dxfer_len, in sg_start_req()
1815 srp->bio = rq->bio; in sg_start_req()
1818 req_schp->dio_in_use = 1; in sg_start_req()
1819 hp->info |= SG_INFO_DIRECT_IO; in sg_start_req()
1826 sg_finish_rem_req(Sg_request *srp) in sg_finish_rem_req() argument
1830 Sg_fd *sfp = srp->parentfp; in sg_finish_rem_req()
1831 Sg_scatter_hold *req_schp = &srp->data; in sg_finish_rem_req()
1833 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_finish_rem_req()
1835 (int) srp->res_used)); in sg_finish_rem_req()
1836 if (srp->bio) in sg_finish_rem_req()
1837 ret = blk_rq_unmap_user(srp->bio); in sg_finish_rem_req()
1839 if (srp->rq) in sg_finish_rem_req()
1840 blk_mq_free_request(srp->rq); in sg_finish_rem_req()
1842 if (srp->res_used) in sg_finish_rem_req()
1843 sg_unlink_reserve(sfp, srp); in sg_finish_rem_req()
1856 schp->pages = kzalloc(sg_bufflen, gfp_flags); in sg_build_sgat()
1857 if (!schp->pages) in sg_build_sgat()
1858 return -ENOMEM; in sg_build_sgat()
1859 schp->sglist_len = sg_bufflen; in sg_build_sgat()
1867 int sg_tablesize = sfp->parentdp->sg_tablesize; in sg_build_indirect()
1872 return -EFAULT; in sg_build_indirect()
1877 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1884 return mx_sc_elems; /* most likely -ENOMEM */ in sg_build_indirect()
1900 k++, rem_sz -= ret_sz) { in sg_build_indirect()
1905 schp->pages[k] = alloc_pages(gfp_mask, order); in sg_build_indirect()
1906 if (!schp->pages[k]) in sg_build_indirect()
1916 SCSI_LOG_TIMEOUT(5, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1921 schp->page_order = order; in sg_build_indirect()
1922 schp->k_use_sg = k; in sg_build_indirect()
1923 SCSI_LOG_TIMEOUT(5, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1927 schp->bufflen = blk_size; in sg_build_indirect()
1929 return -ENOMEM; in sg_build_indirect()
1933 __free_pages(schp->pages[i], order); in sg_build_indirect()
1935 if (--order >= 0) in sg_build_indirect()
1938 return -ENOMEM; in sg_build_indirect()
1944 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_remove_scat()
1945 "sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg)); in sg_remove_scat()
1946 if (schp->pages && schp->sglist_len > 0) { in sg_remove_scat()
1947 if (!schp->dio_in_use) { in sg_remove_scat()
1950 for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) { in sg_remove_scat()
1952 sg_printk(KERN_INFO, sfp->parentdp, in sg_remove_scat()
1954 k, schp->pages[k])); in sg_remove_scat()
1955 __free_pages(schp->pages[k], schp->page_order); in sg_remove_scat()
1958 kfree(schp->pages); in sg_remove_scat()
1965 sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer) in sg_read_oxfer() argument
1967 Sg_scatter_hold *schp = &srp->data; in sg_read_oxfer()
1970 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, srp->parentfp->parentdp, in sg_read_oxfer()
1976 num = 1 << (PAGE_SHIFT + schp->page_order); in sg_read_oxfer()
1977 for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) { in sg_read_oxfer()
1979 if (copy_to_user(outp, page_address(schp->pages[k]), in sg_read_oxfer()
1981 return -EFAULT; in sg_read_oxfer()
1984 if (copy_to_user(outp, page_address(schp->pages[k]), in sg_read_oxfer()
1986 return -EFAULT; in sg_read_oxfer()
1987 num_read_xfer -= num; in sg_read_oxfer()
2000 Sg_scatter_hold *schp = &sfp->reserve; in sg_build_reserve()
2002 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_reserve()
2016 sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size) in sg_link_reserve() argument
2018 Sg_scatter_hold *req_schp = &srp->data; in sg_link_reserve()
2019 Sg_scatter_hold *rsv_schp = &sfp->reserve; in sg_link_reserve()
2022 srp->res_used = 1; in sg_link_reserve()
2023 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_link_reserve()
2027 num = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_link_reserve()
2028 for (k = 0; k < rsv_schp->k_use_sg; k++) { in sg_link_reserve()
2030 req_schp->k_use_sg = k + 1; in sg_link_reserve()
2031 req_schp->sglist_len = rsv_schp->sglist_len; in sg_link_reserve()
2032 req_schp->pages = rsv_schp->pages; in sg_link_reserve()
2034 req_schp->bufflen = size; in sg_link_reserve()
2035 req_schp->page_order = rsv_schp->page_order; in sg_link_reserve()
2038 rem -= num; in sg_link_reserve()
2041 if (k >= rsv_schp->k_use_sg) in sg_link_reserve()
2042 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_link_reserve()
2047 sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp) in sg_unlink_reserve() argument
2049 Sg_scatter_hold *req_schp = &srp->data; in sg_unlink_reserve()
2051 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, srp->parentfp->parentdp, in sg_unlink_reserve()
2052 "sg_unlink_reserve: req->k_use_sg=%d\n", in sg_unlink_reserve()
2053 (int) req_schp->k_use_sg)); in sg_unlink_reserve()
2054 req_schp->k_use_sg = 0; in sg_unlink_reserve()
2055 req_schp->bufflen = 0; in sg_unlink_reserve()
2056 req_schp->pages = NULL; in sg_unlink_reserve()
2057 req_schp->page_order = 0; in sg_unlink_reserve()
2058 req_schp->sglist_len = 0; in sg_unlink_reserve()
2059 srp->res_used = 0; in sg_unlink_reserve()
2061 sfp->res_in_use = 0; in sg_unlink_reserve()
2071 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2072 list_for_each_entry(resp, &sfp->rq_list, entry) { in sg_get_rq_mark()
2074 if ((!resp->sg_io_owned) && in sg_get_rq_mark()
2075 ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { in sg_get_rq_mark()
2076 switch (resp->done) { in sg_get_rq_mark()
2081 resp->done = 2; /* guard against other readers */ in sg_get_rq_mark()
2082 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2089 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2099 Sg_request *rp = sfp->req_arr; in sg_add_request()
2101 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_add_request()
2102 if (!list_empty(&sfp->rq_list)) { in sg_add_request()
2103 if (!sfp->cmd_q) in sg_add_request()
2107 if (!rp->parentfp) in sg_add_request()
2114 rp->parentfp = sfp; in sg_add_request()
2115 rp->header.duration = jiffies_to_msecs(jiffies); in sg_add_request()
2116 list_add_tail(&rp->entry, &sfp->rq_list); in sg_add_request()
2117 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_add_request()
2120 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_add_request()
2126 sg_remove_request(Sg_fd * sfp, Sg_request * srp) in sg_remove_request() argument
2131 if (!sfp || !srp || list_empty(&sfp->rq_list)) in sg_remove_request()
2133 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_remove_request()
2134 if (!list_empty(&srp->entry)) { in sg_remove_request()
2135 list_del(&srp->entry); in sg_remove_request()
2136 srp->parentfp = NULL; in sg_remove_request()
2139 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_remove_request()
2144 * return other than -ENODEV. in sg_remove_request()
2146 if (unlikely(atomic_read(&sfp->parentdp->detaching))) in sg_remove_request()
2147 wake_up_interruptible_all(&sfp->read_wait); in sg_remove_request()
2161 return ERR_PTR(-ENOMEM); in sg_add_sfp()
2163 init_waitqueue_head(&sfp->read_wait); in sg_add_sfp()
2164 rwlock_init(&sfp->rq_list_lock); in sg_add_sfp()
2165 INIT_LIST_HEAD(&sfp->rq_list); in sg_add_sfp()
2166 kref_init(&sfp->f_ref); in sg_add_sfp()
2167 mutex_init(&sfp->f_mutex); in sg_add_sfp()
2168 sfp->timeout = SG_DEFAULT_TIMEOUT; in sg_add_sfp()
2169 sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER; in sg_add_sfp()
2170 sfp->force_packid = SG_DEF_FORCE_PACK_ID; in sg_add_sfp()
2171 sfp->cmd_q = SG_DEF_COMMAND_Q; in sg_add_sfp()
2172 sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; in sg_add_sfp()
2173 sfp->parentdp = sdp; in sg_add_sfp()
2174 write_lock_irqsave(&sdp->sfd_lock, iflags); in sg_add_sfp()
2175 if (atomic_read(&sdp->detaching)) { in sg_add_sfp()
2176 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_add_sfp()
2178 return ERR_PTR(-ENODEV); in sg_add_sfp()
2180 list_add_tail(&sfp->sfd_siblings, &sdp->sfds); in sg_add_sfp()
2181 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_add_sfp()
2188 max_sectors_bytes(sdp->device->request_queue)); in sg_add_sfp()
2192 sfp->reserve.bufflen, in sg_add_sfp()
2193 sfp->reserve.k_use_sg)); in sg_add_sfp()
2195 kref_get(&sdp->d_ref); in sg_add_sfp()
2204 struct sg_device *sdp = sfp->parentdp; in sg_remove_sfp_usercontext()
2205 struct scsi_device *device = sdp->device; in sg_remove_sfp_usercontext()
2206 Sg_request *srp; in sg_remove_sfp_usercontext() local
2210 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_remove_sfp_usercontext()
2211 while (!list_empty(&sfp->rq_list)) { in sg_remove_sfp_usercontext()
2212 srp = list_first_entry(&sfp->rq_list, Sg_request, entry); in sg_remove_sfp_usercontext()
2213 sg_finish_rem_req(srp); in sg_remove_sfp_usercontext()
2214 list_del(&srp->entry); in sg_remove_sfp_usercontext()
2215 srp->parentfp = NULL; in sg_remove_sfp_usercontext()
2217 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_remove_sfp_usercontext()
2219 if (sfp->reserve.bufflen > 0) { in sg_remove_sfp_usercontext()
2222 (int) sfp->reserve.bufflen, in sg_remove_sfp_usercontext()
2223 (int) sfp->reserve.k_use_sg)); in sg_remove_sfp_usercontext()
2224 sg_remove_scat(sfp, &sfp->reserve); in sg_remove_sfp_usercontext()
2231 kref_put(&sdp->d_ref, sg_device_destroy); in sg_remove_sfp_usercontext()
2240 struct sg_device *sdp = sfp->parentdp; in sg_remove_sfp()
2243 write_lock_irqsave(&sdp->sfd_lock, iflags); in sg_remove_sfp()
2244 list_del(&sfp->sfd_siblings); in sg_remove_sfp()
2245 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_remove_sfp()
2247 INIT_WORK(&sfp->ew.work, sg_remove_sfp_usercontext); in sg_remove_sfp()
2248 schedule_work(&sfp->ew.work); in sg_remove_sfp()
2266 int k = -1; in sg_last_dev()
2291 sdp = ERR_PTR(-ENXIO); in sg_get_dev()
2292 else if (atomic_read(&sdp->detaching)) { in sg_get_dev()
2293 /* If sdp->detaching, then the refcount may already be 0, in in sg_get_dev()
2296 sdp = ERR_PTR(-ENODEV); in sg_get_dev()
2298 kref_get(&sdp->d_ref); in sg_get_dev()
2380 seq_printf(s, "%d\n", *((int *)s->private)); in sg_proc_seq_show_int()
2396 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) in sg_proc_write_adio()
2397 return -EACCES; in sg_proc_write_adio()
2417 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) in sg_proc_write_dressz()
2418 return -EACCES; in sg_proc_write_dressz()
2427 return -ERANGE; in sg_proc_write_dressz()
2452 s->private = it; in dev_seq_start()
2456 it->index = *pos; in dev_seq_start()
2457 it->max = sg_last_dev(); in dev_seq_start()
2458 if (it->index >= it->max) in dev_seq_start()
2465 struct sg_proc_deviter * it = s->private; in dev_seq_next()
2467 *pos = ++it->index; in dev_seq_next()
2468 return (it->index < it->max) ? it : NULL; in dev_seq_next()
2473 kfree(s->private); in dev_seq_stop()
2484 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_dev()
2485 if ((NULL == sdp) || (NULL == sdp->device) || in sg_proc_seq_show_dev()
2486 (atomic_read(&sdp->detaching))) in sg_proc_seq_show_dev()
2487 seq_puts(s, "-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n"); in sg_proc_seq_show_dev()
2489 scsidp = sdp->device; in sg_proc_seq_show_dev()
2491 scsidp->host->host_no, scsidp->channel, in sg_proc_seq_show_dev()
2492 scsidp->id, scsidp->lun, (int) scsidp->type, in sg_proc_seq_show_dev()
2494 (int) scsidp->queue_depth, in sg_proc_seq_show_dev()
2510 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_devstrs()
2511 scsidp = sdp ? sdp->device : NULL; in sg_proc_seq_show_devstrs()
2512 if (sdp && scsidp && (!atomic_read(&sdp->detaching))) in sg_proc_seq_show_devstrs()
2514 scsidp->vendor, scsidp->model, scsidp->rev); in sg_proc_seq_show_devstrs()
2525 Sg_request *srp; in sg_proc_debug_helper() local
2532 list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { in sg_proc_debug_helper()
2534 read_lock(&fp->rq_list_lock); /* irqs already disabled */ in sg_proc_debug_helper()
2537 jiffies_to_msecs(fp->timeout), in sg_proc_debug_helper()
2538 fp->reserve.bufflen, in sg_proc_debug_helper()
2539 (int) fp->reserve.k_use_sg, 0); in sg_proc_debug_helper()
2541 (int) fp->cmd_q, (int) fp->force_packid, in sg_proc_debug_helper()
2542 (int) fp->keep_orphan); in sg_proc_debug_helper()
2543 list_for_each_entry(srp, &fp->rq_list, entry) { in sg_proc_debug_helper()
2544 hp = &srp->header; in sg_proc_debug_helper()
2545 new_interface = (hp->interface_id == '\0') ? 0 : 1; in sg_proc_debug_helper()
2546 if (srp->res_used) { in sg_proc_debug_helper()
2548 (SG_FLAG_MMAP_IO & hp->flags)) in sg_proc_debug_helper()
2553 if (SG_INFO_DIRECT_IO_MASK & hp->info) in sg_proc_debug_helper()
2559 blen = srp->data.bufflen; in sg_proc_debug_helper()
2560 usg = srp->data.k_use_sg; in sg_proc_debug_helper()
2561 seq_puts(s, srp->done ? in sg_proc_debug_helper()
2562 ((1 == srp->done) ? "rcv:" : "fin:") in sg_proc_debug_helper()
2565 srp->header.pack_id, blen); in sg_proc_debug_helper()
2566 if (srp->done) in sg_proc_debug_helper()
2567 seq_printf(s, " dur=%d", hp->duration); in sg_proc_debug_helper()
2571 (new_interface ? hp->timeout : in sg_proc_debug_helper()
2572 jiffies_to_msecs(fp->timeout)), in sg_proc_debug_helper()
2573 (ms > hp->duration ? ms - hp->duration : 0)); in sg_proc_debug_helper()
2576 (int) srp->data.cmd_opcode); in sg_proc_debug_helper()
2578 if (list_empty(&fp->rq_list)) in sg_proc_debug_helper()
2580 read_unlock(&fp->rq_list_lock); in sg_proc_debug_helper()
2590 if (it && (0 == it->index)) in sg_proc_seq_show_debug()
2592 (int)it->max, sg_big_buff); in sg_proc_seq_show_debug()
2595 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_debug()
2598 read_lock(&sdp->sfd_lock); in sg_proc_seq_show_debug()
2599 if (!list_empty(&sdp->sfds)) { in sg_proc_seq_show_debug()
2600 seq_printf(s, " >>> device=%s ", sdp->name); in sg_proc_seq_show_debug()
2601 if (atomic_read(&sdp->detaching)) in sg_proc_seq_show_debug()
2603 else if (sdp->device) { in sg_proc_seq_show_debug()
2604 struct scsi_device *scsidp = sdp->device; in sg_proc_seq_show_debug()
2607 scsidp->host->host_no, in sg_proc_seq_show_debug()
2608 scsidp->channel, scsidp->id, in sg_proc_seq_show_debug()
2609 scsidp->lun, in sg_proc_seq_show_debug()
2610 scsidp->host->hostt->emulated); in sg_proc_seq_show_debug()
2613 sdp->sg_tablesize, sdp->exclude, sdp->open_cnt); in sg_proc_seq_show_debug()
2616 read_unlock(&sdp->sfd_lock); in sg_proc_seq_show_debug()