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()
294 return -EPERM; /* Can't lock it with read only access */ in sg_open()
304 retval = scsi_device_get(sdp->device); in sg_open()
308 retval = scsi_autopm_get_device(sdp->device); in sg_open()
316 scsi_block_when_processing_errors(sdp->device))) { in sg_open()
317 retval = -ENXIO; in sg_open()
322 mutex_lock(&sdp->open_rel_lock); in sg_open()
325 if (sdp->open_cnt > 0) { in sg_open()
326 retval = -EBUSY; in sg_open()
330 if (sdp->exclude) { in sg_open()
331 retval = -EBUSY; in sg_open()
337 if (retval) /* -ERESTARTSYS or -ENODEV */ in sg_open()
343 sdp->exclude = true; in sg_open()
345 if (sdp->open_cnt < 1) { /* no existing opens */ in sg_open()
346 sdp->sgdebug = 0; in sg_open()
347 q = sdp->device->request_queue; in sg_open()
348 sdp->sg_tablesize = queue_max_segments(q); in sg_open()
356 filp->private_data = sfp; in sg_open()
357 sdp->open_cnt++; in sg_open()
358 mutex_unlock(&sdp->open_rel_lock); in sg_open()
362 kref_put(&sdp->d_ref, sg_device_destroy); in sg_open()
367 sdp->exclude = false; /* undo if error */ in sg_open()
368 wake_up_interruptible(&sdp->open_wait); in sg_open()
371 mutex_unlock(&sdp->open_rel_lock); in sg_open()
373 scsi_autopm_put_device(sdp->device); in sg_open()
375 scsi_device_put(sdp->device); in sg_open()
387 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_release()
388 return -ENXIO; in sg_release()
391 mutex_lock(&sdp->open_rel_lock); in sg_release()
392 scsi_autopm_put_device(sdp->device); in sg_release()
393 kref_put(&sfp->f_ref, sg_remove_sfp); in sg_release()
394 sdp->open_cnt--; in sg_release()
398 if (sdp->exclude) { in sg_release()
399 sdp->exclude = false; in sg_release()
400 wake_up_interruptible_all(&sdp->open_wait); in sg_release()
401 } else if (0 == sdp->open_cnt) { in sg_release()
402 wake_up_interruptible(&sdp->open_wait); in sg_release()
404 mutex_unlock(&sdp->open_rel_lock); in sg_release()
415 if (get_user(reply_len, &old_hdr->reply_len)) in get_sg_io_pack_id()
416 return -EFAULT; in get_sg_io_pack_id()
419 return get_user(*pack_id, &old_hdr->pack_id); in get_sg_io_pack_id()
425 return get_user(*pack_id, &hp->pack_id); in get_sg_io_pack_id()
431 return get_user(*pack_id, &hp->pack_id); in get_sg_io_pack_id()
436 *pack_id = -1; in get_sg_io_pack_id()
445 Sg_request *srp; in sg_read() local
446 int req_pack_id = -1; in sg_read()
460 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_read()
461 return -ENXIO; in sg_read()
465 if (sfp->force_packid) in sg_read()
470 srp = sg_get_rq_mark(sfp, req_pack_id, &busy); in sg_read()
471 if (!srp) { /* now wait on packet to arrive */ in sg_read()
472 if (filp->f_flags & O_NONBLOCK) in sg_read()
473 return -EAGAIN; in sg_read()
474 retval = wait_event_interruptible(sfp->read_wait, in sg_read()
475 ((srp = sg_get_rq_mark(sfp, req_pack_id, &busy)) || in sg_read()
476 (!busy && atomic_read(&sdp->detaching)))); in sg_read()
477 if (!srp) in sg_read()
479 return retval ? retval : -ENODEV; in sg_read()
481 if (srp->header.interface_id != '\0') in sg_read()
482 return sg_new_read(sfp, buf, count, srp); in sg_read()
484 hp = &srp->header; in sg_read()
487 return -ENOMEM; in sg_read()
489 old_hdr->reply_len = (int) hp->timeout; in sg_read()
490 old_hdr->pack_len = old_hdr->reply_len; /* old, strange behaviour */ in sg_read()
491 old_hdr->pack_id = hp->pack_id; in sg_read()
492 old_hdr->twelve_byte = in sg_read()
493 ((srp->data.cmd_opcode >= 0xc0) && (12 == hp->cmd_len)) ? 1 : 0; in sg_read()
494 old_hdr->target_status = hp->masked_status; in sg_read()
495 old_hdr->host_status = hp->host_status; in sg_read()
496 old_hdr->driver_status = hp->driver_status; in sg_read()
497 if ((CHECK_CONDITION & hp->masked_status) || in sg_read()
498 (srp->sense_b[0] & 0x70) == 0x70) { in sg_read()
499 old_hdr->driver_status = DRIVER_SENSE; in sg_read()
500 memcpy(old_hdr->sense_buffer, srp->sense_b, in sg_read()
501 sizeof (old_hdr->sense_buffer)); in sg_read()
503 switch (hp->host_status) { in sg_read()
509 old_hdr->result = 0; in sg_read()
514 old_hdr->result = EBUSY; in sg_read()
521 old_hdr->result = EIO; in sg_read()
524 old_hdr->result = (srp->sense_b[0] == 0 && in sg_read()
525 hp->masked_status == GOOD) ? 0 : EIO; in sg_read()
528 old_hdr->result = EIO; in sg_read()
535 retval = -EFAULT; in sg_read()
539 if (count > old_hdr->reply_len) in sg_read()
540 count = old_hdr->reply_len; in sg_read()
542 if (sg_read_oxfer(srp, buf, count - SZ_SG_HEADER)) { in sg_read()
543 retval = -EFAULT; in sg_read()
548 count = (old_hdr->result == 0) ? 0 : -EIO; in sg_read()
549 sg_finish_rem_req(srp); in sg_read()
550 sg_remove_request(sfp, srp); in sg_read()
558 sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp) in sg_new_read() argument
560 sg_io_hdr_t *hp = &srp->header; in sg_new_read()
566 err = -EINVAL; in sg_new_read()
570 err = -EINVAL; in sg_new_read()
573 hp->sb_len_wr = 0; in sg_new_read()
574 if ((hp->mx_sb_len > 0) && hp->sbp) { in sg_new_read()
575 if ((CHECK_CONDITION & hp->masked_status) || in sg_new_read()
576 (srp->sense_b[0] & 0x70) == 0x70) { in sg_new_read()
578 sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len; in sg_new_read()
579 len = 8 + (int) srp->sense_b[7]; /* Additional sense length field */ in sg_new_read()
581 if (copy_to_user(hp->sbp, srp->sense_b, len)) { in sg_new_read()
582 err = -EFAULT; in sg_new_read()
585 hp->driver_status = DRIVER_SENSE; in sg_new_read()
586 hp->sb_len_wr = len; in sg_new_read()
589 if (hp->masked_status || hp->host_status || hp->driver_status) in sg_new_read()
590 hp->info |= SG_INFO_CHECK; in sg_new_read()
593 err2 = sg_finish_rem_req(srp); in sg_new_read()
594 sg_remove_request(sfp, srp); in sg_new_read()
606 Sg_request *srp; in sg_write() local
616 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_write()
617 return -ENXIO; in sg_write()
620 if (atomic_read(&sdp->detaching)) in sg_write()
621 return -ENODEV; in sg_write()
622 if (!((filp->f_flags & O_NONBLOCK) || in sg_write()
623 scsi_block_when_processing_errors(sdp->device))) in sg_write()
624 return -ENXIO; in sg_write()
627 return -EIO; in sg_write()
629 return -EFAULT; in sg_write()
630 blocking = !(filp->f_flags & O_NONBLOCK); in sg_write()
635 return -EIO; /* The minimum scsi command length is 6 bytes. */ in sg_write()
639 return -EFAULT; in sg_write()
641 if (!(srp = sg_add_request(sfp))) { in sg_write()
644 return -EDOM; in sg_write()
646 mutex_lock(&sfp->f_mutex); in sg_write()
647 if (sfp->next_cmd_len > 0) { in sg_write()
648 cmd_size = sfp->next_cmd_len; in sg_write()
649 sfp->next_cmd_len = 0; /* reset so only this write() effected */ in sg_write()
655 mutex_unlock(&sfp->f_mutex); in sg_write()
659 input_size = count - cmd_size; in sg_write()
661 mxsize -= SZ_SG_HEADER; in sg_write()
662 input_size -= SZ_SG_HEADER; in sg_write()
664 sg_remove_request(sfp, srp); in sg_write()
665 return -EIO; /* User did not pass enough bytes for this command. */ in sg_write()
667 hp = &srp->header; in sg_write()
668 hp->interface_id = '\0'; /* indicator of old interface tunnelled */ in sg_write()
669 hp->cmd_len = (unsigned char) cmd_size; in sg_write()
670 hp->iovec_count = 0; in sg_write()
671 hp->mx_sb_len = 0; in sg_write()
673 hp->dxfer_direction = (old_hdr.reply_len > SZ_SG_HEADER) ? in sg_write()
676 hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE; in sg_write()
677 hp->dxfer_len = mxsize; in sg_write()
678 if ((hp->dxfer_direction == SG_DXFER_TO_DEV) || in sg_write()
679 (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV)) in sg_write()
680 hp->dxferp = (char __user *)buf + cmd_size; in sg_write()
682 hp->dxferp = NULL; in sg_write()
683 hp->sbp = NULL; in sg_write()
684 hp->timeout = old_hdr.reply_len; /* structure abuse ... */ in sg_write()
685 hp->flags = input_size; /* structure abuse ... */ in sg_write()
686 hp->pack_id = old_hdr.pack_id; in sg_write()
687 hp->usr_ptr = NULL; in sg_write()
689 sg_remove_request(sfp, srp); in sg_write()
690 return -EFAULT; in sg_write()
695 * is a non-zero input_size, so emit a warning. in sg_write()
697 if (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV) { in sg_write()
700 "for SCSI command 0x%x-- guessing " in sg_write()
703 old_hdr.reply_len - (int)SZ_SG_HEADER, in sg_write()
705 current->comm); in sg_write()
707 k = sg_common_write(sfp, srp, cmnd, sfp->timeout, blocking); in sg_write()
717 Sg_request *srp; in sg_new_write() local
724 return -EINVAL; in sg_new_write()
726 sfp->cmd_q = 1; /* when sg_io_hdr seen, set command queuing on */ in sg_new_write()
727 if (!(srp = sg_add_request(sfp))) { in sg_new_write()
728 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_new_write()
730 return -EDOM; in sg_new_write()
732 srp->sg_io_owned = sg_io_owned; in sg_new_write()
733 hp = &srp->header; in sg_new_write()
735 sg_remove_request(sfp, srp); in sg_new_write()
736 return -EFAULT; in sg_new_write()
738 if (hp->interface_id != 'S') { in sg_new_write()
739 sg_remove_request(sfp, srp); in sg_new_write()
740 return -ENOSYS; in sg_new_write()
742 if (hp->flags & SG_FLAG_MMAP_IO) { in sg_new_write()
743 if (hp->dxfer_len > sfp->reserve.bufflen) { in sg_new_write()
744 sg_remove_request(sfp, srp); in sg_new_write()
745 return -ENOMEM; /* MMAP_IO size must fit in reserve buffer */ in sg_new_write()
747 if (hp->flags & SG_FLAG_DIRECT_IO) { in sg_new_write()
748 sg_remove_request(sfp, srp); in sg_new_write()
749 return -EINVAL; /* either MMAP_IO or DIRECT_IO (not both) */ in sg_new_write()
751 if (sfp->res_in_use) { in sg_new_write()
752 sg_remove_request(sfp, srp); in sg_new_write()
753 return -EBUSY; /* reserve buffer already being used */ in sg_new_write()
756 ul_timeout = msecs_to_jiffies(srp->header.timeout); in sg_new_write()
758 if ((!hp->cmdp) || (hp->cmd_len < 6) || (hp->cmd_len > sizeof (cmnd))) { in sg_new_write()
759 sg_remove_request(sfp, srp); in sg_new_write()
760 return -EMSGSIZE; in sg_new_write()
762 if (copy_from_user(cmnd, hp->cmdp, hp->cmd_len)) { in sg_new_write()
763 sg_remove_request(sfp, srp); in sg_new_write()
764 return -EFAULT; in sg_new_write()
767 sg_remove_request(sfp, srp); in sg_new_write()
768 return -EPERM; in sg_new_write()
770 k = sg_common_write(sfp, srp, cmnd, timeout, blocking); in sg_new_write()
774 *o_srp = srp; in sg_new_write()
779 sg_common_write(Sg_fd * sfp, Sg_request * srp, in sg_common_write() argument
783 Sg_device *sdp = sfp->parentdp; in sg_common_write()
784 sg_io_hdr_t *hp = &srp->header; in sg_common_write()
786 srp->data.cmd_opcode = cmnd[0]; /* hold opcode of command */ in sg_common_write()
787 hp->status = 0; in sg_common_write()
788 hp->masked_status = 0; in sg_common_write()
789 hp->msg_status = 0; in sg_common_write()
790 hp->info = 0; in sg_common_write()
791 hp->host_status = 0; in sg_common_write()
792 hp->driver_status = 0; in sg_common_write()
793 hp->resid = 0; in sg_common_write()
794 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_common_write()
796 (int) cmnd[0], (int) hp->cmd_len)); in sg_common_write()
798 if (hp->dxfer_len >= SZ_256M) { in sg_common_write()
799 sg_remove_request(sfp, srp); in sg_common_write()
800 return -EINVAL; in sg_common_write()
803 k = sg_start_req(srp, cmnd); in sg_common_write()
805 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_common_write()
807 sg_finish_rem_req(srp); in sg_common_write()
808 sg_remove_request(sfp, srp); in sg_common_write()
809 return k; /* probably out of space --> ENOMEM */ in sg_common_write()
811 if (atomic_read(&sdp->detaching)) { in sg_common_write()
812 if (srp->bio) { in sg_common_write()
813 blk_mq_free_request(srp->rq); in sg_common_write()
814 srp->rq = NULL; in sg_common_write()
817 sg_finish_rem_req(srp); in sg_common_write()
818 sg_remove_request(sfp, srp); in sg_common_write()
819 return -ENODEV; in sg_common_write()
822 hp->duration = jiffies_to_msecs(jiffies); in sg_common_write()
823 if (hp->interface_id != '\0' && /* v3 (or later) interface */ in sg_common_write()
824 (SG_FLAG_Q_AT_TAIL & hp->flags)) in sg_common_write()
829 srp->rq->timeout = timeout; in sg_common_write()
830 kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */ in sg_common_write()
831 srp->rq->end_io = sg_rq_end_io; in sg_common_write()
832 blk_execute_rq_nowait(srp->rq, at_head); in sg_common_write()
836 static int srp_done(Sg_fd *sfp, Sg_request *srp) in srp_done() argument
841 read_lock_irqsave(&sfp->rq_list_lock, flags); in srp_done()
842 ret = srp->done; in srp_done()
843 read_unlock_irqrestore(&sfp->rq_list_lock, flags); in srp_done()
859 Sg_request *srp; in sg_fill_request_table() local
864 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_fill_request_table()
867 rinfo[val].req_state = srp->done + 1; in sg_fill_request_table()
869 srp->header.masked_status & in sg_fill_request_table()
870 srp->header.host_status & in sg_fill_request_table()
871 srp->header.driver_status; in sg_fill_request_table()
872 if (srp->done) in sg_fill_request_table()
874 srp->header.duration; in sg_fill_request_table()
878 (ms > srp->header.duration) ? in sg_fill_request_table()
879 (ms - srp->header.duration) : 0; in sg_fill_request_table()
881 rinfo[val].orphan = srp->orphan; in sg_fill_request_table()
882 rinfo[val].sg_io_owned = srp->sg_io_owned; in sg_fill_request_table()
883 rinfo[val].pack_id = srp->header.pack_id; in sg_fill_request_table()
884 rinfo[val].usr_ptr = srp->header.usr_ptr; in sg_fill_request_table()
910 return -EFAULT; in put_compat_request_table()
922 Sg_request *srp; in sg_ioctl_common() local
927 read_only = (O_RDWR != (filp->f_flags & O_ACCMODE)); in sg_ioctl_common()
931 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
932 return -ENODEV; in sg_ioctl_common()
933 if (!scsi_block_when_processing_errors(sdp->device)) in sg_ioctl_common()
934 return -ENXIO; in sg_ioctl_common()
936 1, read_only, 1, &srp); in sg_ioctl_common()
939 result = wait_event_interruptible(sfp->read_wait, in sg_ioctl_common()
940 srp_done(sfp, srp)); in sg_ioctl_common()
941 write_lock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
942 if (srp->done) { in sg_ioctl_common()
943 srp->done = 2; in sg_ioctl_common()
944 write_unlock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
945 result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp); in sg_ioctl_common()
948 srp->orphan = 1; in sg_ioctl_common()
949 write_unlock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
950 return result; /* -ERESTARTSYS because signal hit process */ in sg_ioctl_common()
956 return -EIO; in sg_ioctl_common()
960 sfp->timeout_user = val; in sg_ioctl_common()
961 sfp->timeout = mult_frac(val, HZ, USER_HZ); in sg_ioctl_common()
966 return sfp->timeout_user; in sg_ioctl_common()
980 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
981 return -ENODEV; in sg_ioctl_common()
983 v.host_no = sdp->device->host->host_no; in sg_ioctl_common()
984 v.channel = sdp->device->channel; in sg_ioctl_common()
985 v.scsi_id = sdp->device->id; in sg_ioctl_common()
986 v.lun = sdp->device->lun; in sg_ioctl_common()
987 v.scsi_type = sdp->device->type; in sg_ioctl_common()
988 v.h_cmd_per_lun = sdp->device->host->cmd_per_lun; in sg_ioctl_common()
989 v.d_queue_depth = sdp->device->queue_depth; in sg_ioctl_common()
991 return -EFAULT; in sg_ioctl_common()
998 sfp->force_packid = val ? 1 : 0; in sg_ioctl_common()
1001 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1002 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_ioctl_common()
1003 if ((1 == srp->done) && (!srp->sg_io_owned)) { in sg_ioctl_common()
1004 read_unlock_irqrestore(&sfp->rq_list_lock, in sg_ioctl_common()
1006 return put_user(srp->header.pack_id, ip); in sg_ioctl_common()
1009 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1010 return put_user(-1, ip); in sg_ioctl_common()
1012 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1014 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_ioctl_common()
1015 if ((1 == srp->done) && (!srp->sg_io_owned)) in sg_ioctl_common()
1018 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1021 return put_user(sdp->sg_tablesize, ip); in sg_ioctl_common()
1027 return -EINVAL; in sg_ioctl_common()
1029 max_sectors_bytes(sdp->device->request_queue)); in sg_ioctl_common()
1030 mutex_lock(&sfp->f_mutex); in sg_ioctl_common()
1031 if (val != sfp->reserve.bufflen) { in sg_ioctl_common()
1032 if (sfp->mmap_called || in sg_ioctl_common()
1033 sfp->res_in_use) { in sg_ioctl_common()
1034 mutex_unlock(&sfp->f_mutex); in sg_ioctl_common()
1035 return -EBUSY; in sg_ioctl_common()
1038 sg_remove_scat(sfp, &sfp->reserve); in sg_ioctl_common()
1041 mutex_unlock(&sfp->f_mutex); in sg_ioctl_common()
1044 val = min_t(int, sfp->reserve.bufflen, in sg_ioctl_common()
1045 max_sectors_bytes(sdp->device->request_queue)); in sg_ioctl_common()
1051 sfp->cmd_q = val ? 1 : 0; in sg_ioctl_common()
1054 return put_user((int) sfp->cmd_q, ip); in sg_ioctl_common()
1059 sfp->keep_orphan = val; in sg_ioctl_common()
1062 return put_user((int) sfp->keep_orphan, ip); in sg_ioctl_common()
1068 return -ENOMEM; in sg_ioctl_common()
1069 sfp->next_cmd_len = (val > 0) ? val : 0; in sg_ioctl_common()
1074 /* faked - we don't have a real access count anymore */ in sg_ioctl_common()
1075 val = (sdp->device ? 1 : 0); in sg_ioctl_common()
1084 return -ENOMEM; in sg_ioctl_common()
1085 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1087 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1095 result = result ? -EFAULT : 0; in sg_ioctl_common()
1100 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1101 return -ENODEV; in sg_ioctl_common()
1102 return put_user(sdp->device->host->hostt->emulated, ip); in sg_ioctl_common()
1104 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1105 return -ENODEV; in sg_ioctl_common()
1106 return scsi_ioctl(sdp->device, filp->f_mode & FMODE_WRITE, in sg_ioctl_common()
1112 sdp->sgdebug = (char) val; in sg_ioctl_common()
1115 return put_user(max_sectors_bytes(sdp->device->request_queue), in sg_ioctl_common()
1118 return blk_trace_setup(sdp->device->request_queue, sdp->name, in sg_ioctl_common()
1119 MKDEV(SCSI_GENERIC_MAJOR, sdp->index), in sg_ioctl_common()
1122 return blk_trace_startstop(sdp->device->request_queue, 1); in sg_ioctl_common()
1124 return blk_trace_startstop(sdp->device->request_queue, 0); in sg_ioctl_common()
1126 return blk_trace_remove(sdp->device->request_queue); in sg_ioctl_common()
1132 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1133 return -ENODEV; in sg_ioctl_common()
1137 return -EPERM; /* don't know so take safe approach */ in sg_ioctl_common()
1141 result = scsi_ioctl_block_when_processing_errors(sdp->device, in sg_ioctl_common()
1142 cmd_in, filp->f_flags & O_NDELAY); in sg_ioctl_common()
1146 return -ENOIOCTLCMD; in sg_ioctl_common()
1157 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_ioctl()
1158 return -ENXIO; in sg_ioctl()
1161 if (ret != -ENOIOCTLCMD) in sg_ioctl()
1163 return scsi_ioctl(sdp->device, filp->f_mode & FMODE_WRITE, cmd_in, p); in sg_ioctl()
1172 Sg_request *srp; in sg_poll() local
1176 sfp = filp->private_data; in sg_poll()
1179 sdp = sfp->parentdp; in sg_poll()
1182 poll_wait(filp, &sfp->read_wait, wait); in sg_poll()
1183 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_poll()
1184 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_poll()
1186 if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned)) in sg_poll()
1190 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_poll()
1192 if (atomic_read(&sdp->detaching)) in sg_poll()
1194 else if (!sfp->cmd_q) { in sg_poll()
1210 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_fasync()
1211 return -ENXIO; in sg_fasync()
1215 return fasync_helper(fd, filp, mode, &sfp->async_qp); in sg_fasync()
1221 struct vm_area_struct *vma = vmf->vma; in sg_vma_fault()
1227 if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data))) in sg_vma_fault()
1229 rsv_schp = &sfp->reserve; in sg_vma_fault()
1230 offset = vmf->pgoff << PAGE_SHIFT; in sg_vma_fault()
1231 if (offset >= rsv_schp->bufflen) in sg_vma_fault()
1233 SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp, in sg_vma_fault()
1235 offset, rsv_schp->k_use_sg)); in sg_vma_fault()
1236 sa = vma->vm_start; in sg_vma_fault()
1237 length = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_vma_fault()
1238 for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) { in sg_vma_fault()
1239 len = vma->vm_end - sa; in sg_vma_fault()
1242 struct page *page = nth_page(rsv_schp->pages[k], in sg_vma_fault()
1245 vmf->page = page; in sg_vma_fault()
1249 offset -= len; in sg_vma_fault()
1268 if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data))) in sg_mmap()
1269 return -ENXIO; in sg_mmap()
1270 req_sz = vma->vm_end - vma->vm_start; in sg_mmap()
1271 SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp, in sg_mmap()
1273 (void *) vma->vm_start, (int) req_sz)); in sg_mmap()
1274 if (vma->vm_pgoff) in sg_mmap()
1275 return -EINVAL; /* want no offset */ in sg_mmap()
1276 rsv_schp = &sfp->reserve; in sg_mmap()
1277 mutex_lock(&sfp->f_mutex); in sg_mmap()
1278 if (req_sz > rsv_schp->bufflen) { in sg_mmap()
1279 ret = -ENOMEM; /* cannot map more than reserved buffer */ in sg_mmap()
1283 sa = vma->vm_start; in sg_mmap()
1284 length = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_mmap()
1285 for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) { in sg_mmap()
1286 len = vma->vm_end - sa; in sg_mmap()
1291 sfp->mmap_called = 1; in sg_mmap()
1293 vma->vm_private_data = sfp; in sg_mmap()
1294 vma->vm_ops = &sg_mmap_vm_ops; in sg_mmap()
1296 mutex_unlock(&sfp->f_mutex); in sg_mmap()
1303 struct sg_request *srp = container_of(work, struct sg_request, ew.work); in sg_rq_end_io_usercontext() local
1304 struct sg_fd *sfp = srp->parentfp; in sg_rq_end_io_usercontext()
1306 sg_finish_rem_req(srp); in sg_rq_end_io_usercontext()
1307 sg_remove_request(sfp, srp); in sg_rq_end_io_usercontext()
1308 kref_put(&sfp->f_ref, sg_remove_sfp); in sg_rq_end_io_usercontext()
1319 struct sg_request *srp = rq->end_io_data; in sg_rq_end_io() local
1327 if (WARN_ON(srp->done != 0)) in sg_rq_end_io()
1330 sfp = srp->parentfp; in sg_rq_end_io()
1334 sdp = sfp->parentdp; in sg_rq_end_io()
1335 if (unlikely(atomic_read(&sdp->detaching))) in sg_rq_end_io()
1338 sense = scmd->sense_buffer; in sg_rq_end_io()
1339 result = scmd->result; in sg_rq_end_io()
1340 resid = scmd->resid_len; in sg_rq_end_io()
1344 srp->header.pack_id, result)); in sg_rq_end_io()
1345 srp->header.resid = resid; in sg_rq_end_io()
1347 srp->header.duration = (ms > srp->header.duration) ? in sg_rq_end_io()
1348 (ms - srp->header.duration) : 0; in sg_rq_end_io()
1352 srp->header.status = 0xff & result; in sg_rq_end_io()
1353 srp->header.masked_status = sg_status_byte(result); in sg_rq_end_io()
1354 srp->header.msg_status = COMMAND_COMPLETE; in sg_rq_end_io()
1355 srp->header.host_status = host_byte(result); in sg_rq_end_io()
1356 srp->header.driver_status = driver_byte(result); in sg_rq_end_io()
1357 if ((sdp->sgdebug > 0) && in sg_rq_end_io()
1358 ((CHECK_CONDITION == srp->header.masked_status) || in sg_rq_end_io()
1359 (COMMAND_TERMINATED == srp->header.masked_status))) in sg_rq_end_io()
1360 __scsi_print_sense(sdp->device, __func__, sense, in sg_rq_end_io()
1368 && sdp->device->removable) { in sg_rq_end_io()
1369 /* Detected possible disc change. Set the bit - this */ in sg_rq_end_io()
1371 sdp->device->changed = 1; in sg_rq_end_io()
1375 if (scmd->sense_len) in sg_rq_end_io()
1376 memcpy(srp->sense_b, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); in sg_rq_end_io()
1378 /* Rely on write phase to clean out srp status values, so no "else" */ in sg_rq_end_io()
1386 srp->rq = NULL; in sg_rq_end_io()
1389 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_rq_end_io()
1390 if (unlikely(srp->orphan)) { in sg_rq_end_io()
1391 if (sfp->keep_orphan) in sg_rq_end_io()
1392 srp->sg_io_owned = 0; in sg_rq_end_io()
1396 srp->done = done; in sg_rq_end_io()
1397 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_rq_end_io()
1403 wake_up_interruptible(&sfp->read_wait); in sg_rq_end_io()
1404 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); in sg_rq_end_io()
1405 kref_put(&sfp->f_ref, sg_remove_sfp); in sg_rq_end_io()
1407 INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext); in sg_rq_end_io()
1408 schedule_work(&srp->ew.work); in sg_rq_end_io()
1434 struct request_queue *q = scsidp->request_queue; in sg_alloc()
1444 return ERR_PTR(-ENOMEM); in sg_alloc()
1452 if (error == -ENOSPC) { in sg_alloc()
1455 scsidp->type, SG_MAX_DEVS - 1); in sg_alloc()
1456 error = -ENODEV; in sg_alloc()
1468 sprintf(sdp->name, "sg%d", k); in sg_alloc()
1469 sdp->device = scsidp; in sg_alloc()
1470 mutex_init(&sdp->open_rel_lock); in sg_alloc()
1471 INIT_LIST_HEAD(&sdp->sfds); in sg_alloc()
1472 init_waitqueue_head(&sdp->open_wait); in sg_alloc()
1473 atomic_set(&sdp->detaching, 0); in sg_alloc()
1474 rwlock_init(&sdp->sfd_lock); in sg_alloc()
1475 sdp->sg_tablesize = queue_max_segments(q); in sg_alloc()
1476 sdp->index = k; in sg_alloc()
1477 kref_init(&sdp->d_ref); in sg_alloc()
1494 struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); in sg_add_device()
1500 if (!blk_get_queue(scsidp->request_queue)) { in sg_add_device()
1502 return -ENODEV; in sg_add_device()
1505 error = -ENOMEM; in sg_add_device()
1511 cdev->owner = THIS_MODULE; in sg_add_device()
1512 cdev->ops = &sg_fops; in sg_add_device()
1521 error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, sdp->index), 1); in sg_add_device()
1525 sdp->cdev = cdev; in sg_add_device()
1529 sg_class_member = device_create(sg_sysfs_class, cl_dev->parent, in sg_add_device()
1531 sdp->index), in sg_add_device()
1532 sdp, "%s", sdp->name); in sg_add_device()
1538 error = sysfs_create_link(&scsidp->sdev_gendev.kobj, in sg_add_device()
1539 &sg_class_member->kobj, "generic"); in sg_add_device()
1542 "to sg%d\n", __func__, sdp->index); in sg_add_device()
1547 "type %d\n", sdp->index, scsidp->type); in sg_add_device()
1555 idr_remove(&sg_index_idr, sdp->index); in sg_add_device()
1562 blk_put_queue(scsidp->request_queue); in sg_add_device()
1570 struct request_queue *q = sdp->device->request_queue; in sg_device_destroy()
1582 idr_remove(&sg_index_idr, sdp->index); in sg_device_destroy()
1594 struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); in sg_remove_device()
1602 /* want sdp->detaching non-zero as soon as possible */ in sg_remove_device()
1603 val = atomic_inc_return(&sdp->detaching); in sg_remove_device()
1610 read_lock_irqsave(&sdp->sfd_lock, iflags); in sg_remove_device()
1611 list_for_each_entry(sfp, &sdp->sfds, sfd_siblings) { in sg_remove_device()
1612 wake_up_interruptible_all(&sfp->read_wait); in sg_remove_device()
1613 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_HUP); in sg_remove_device()
1615 wake_up_interruptible_all(&sdp->open_wait); in sg_remove_device()
1616 read_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_remove_device()
1618 sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic"); in sg_remove_device()
1619 device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index)); in sg_remove_device()
1620 cdev_del(sdp->cdev); in sg_remove_device()
1621 sdp->cdev = NULL; in sg_remove_device()
1623 kref_put(&sdp->d_ref, sg_device_destroy); in sg_remove_device()
1647 .procname = "sg-big-buff",
1727 sg_start_req(Sg_request *srp, unsigned char *cmd) in sg_start_req() argument
1731 Sg_fd *sfp = srp->parentfp; in sg_start_req()
1732 sg_io_hdr_t *hp = &srp->header; in sg_start_req()
1733 int dxfer_len = (int) hp->dxfer_len; in sg_start_req()
1734 int dxfer_dir = hp->dxfer_direction; in sg_start_req()
1735 unsigned int iov_count = hp->iovec_count; in sg_start_req()
1736 Sg_scatter_hold *req_schp = &srp->data; in sg_start_req()
1737 Sg_scatter_hold *rsv_schp = &sfp->reserve; in sg_start_req()
1738 struct request_queue *q = sfp->parentdp->device->request_queue; in sg_start_req()
1740 int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? ITER_SOURCE : ITER_DEST; in sg_start_req()
1743 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_start_req()
1750 * With scsi-mq enabled, there are a fixed number of preallocated in sg_start_req()
1751 * requests equal in number to shost->can_queue. If all of the in sg_start_req()
1758 rq = scsi_alloc_request(q, hp->dxfer_direction == SG_DXFER_TO_DEV ? in sg_start_req()
1764 if (hp->cmd_len > sizeof(scmd->cmnd)) { in sg_start_req()
1766 return -EINVAL; in sg_start_req()
1769 memcpy(scmd->cmnd, cmd, hp->cmd_len); in sg_start_req()
1770 scmd->cmd_len = hp->cmd_len; in sg_start_req()
1772 srp->rq = rq; in sg_start_req()
1773 rq->end_io_data = srp; in sg_start_req()
1774 scmd->allowed = SG_DEFAULT_RETRIES; in sg_start_req()
1779 if (sg_allow_dio && hp->flags & SG_FLAG_DIRECT_IO && in sg_start_req()
1781 blk_rq_aligned(q, (unsigned long)hp->dxferp, dxfer_len)) in sg_start_req()
1787 mutex_lock(&sfp->f_mutex); in sg_start_req()
1788 if (dxfer_len <= rsv_schp->bufflen && in sg_start_req()
1789 !sfp->res_in_use) { in sg_start_req()
1790 sfp->res_in_use = 1; in sg_start_req()
1791 sg_link_reserve(sfp, srp, dxfer_len); in sg_start_req()
1792 } else if (hp->flags & SG_FLAG_MMAP_IO) { in sg_start_req()
1793 res = -EBUSY; /* sfp->res_in_use == 1 */ in sg_start_req()
1794 if (dxfer_len > rsv_schp->bufflen) in sg_start_req()
1795 res = -ENOMEM; in sg_start_req()
1796 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1801 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1805 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1807 md->pages = req_schp->pages; in sg_start_req()
1808 md->page_order = req_schp->page_order; in sg_start_req()
1809 md->nr_entries = req_schp->k_use_sg; in sg_start_req()
1810 md->offset = 0; in sg_start_req()
1811 md->null_mapped = hp->dxferp ? 0 : 1; in sg_start_req()
1813 md->from_user = 1; in sg_start_req()
1815 md->from_user = 0; in sg_start_req()
1818 res = blk_rq_map_user_io(rq, md, hp->dxferp, hp->dxfer_len, in sg_start_req()
1821 srp->bio = rq->bio; in sg_start_req()
1824 req_schp->dio_in_use = 1; in sg_start_req()
1825 hp->info |= SG_INFO_DIRECT_IO; in sg_start_req()
1832 sg_finish_rem_req(Sg_request *srp) in sg_finish_rem_req() argument
1836 Sg_fd *sfp = srp->parentfp; in sg_finish_rem_req()
1837 Sg_scatter_hold *req_schp = &srp->data; in sg_finish_rem_req()
1839 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_finish_rem_req()
1841 (int) srp->res_used)); in sg_finish_rem_req()
1842 if (srp->bio) in sg_finish_rem_req()
1843 ret = blk_rq_unmap_user(srp->bio); in sg_finish_rem_req()
1845 if (srp->rq) in sg_finish_rem_req()
1846 blk_mq_free_request(srp->rq); in sg_finish_rem_req()
1848 if (srp->res_used) in sg_finish_rem_req()
1849 sg_unlink_reserve(sfp, srp); in sg_finish_rem_req()
1862 schp->pages = kzalloc(sg_bufflen, gfp_flags); in sg_build_sgat()
1863 if (!schp->pages) in sg_build_sgat()
1864 return -ENOMEM; in sg_build_sgat()
1865 schp->sglist_len = sg_bufflen; in sg_build_sgat()
1873 int sg_tablesize = sfp->parentdp->sg_tablesize; in sg_build_indirect()
1878 return -EFAULT; in sg_build_indirect()
1883 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1890 return mx_sc_elems; /* most likely -ENOMEM */ in sg_build_indirect()
1906 k++, rem_sz -= ret_sz) { in sg_build_indirect()
1911 schp->pages[k] = alloc_pages(gfp_mask, order); in sg_build_indirect()
1912 if (!schp->pages[k]) in sg_build_indirect()
1922 SCSI_LOG_TIMEOUT(5, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1927 schp->page_order = order; in sg_build_indirect()
1928 schp->k_use_sg = k; in sg_build_indirect()
1929 SCSI_LOG_TIMEOUT(5, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1933 schp->bufflen = blk_size; in sg_build_indirect()
1935 return -ENOMEM; in sg_build_indirect()
1939 __free_pages(schp->pages[i], order); in sg_build_indirect()
1941 if (--order >= 0) in sg_build_indirect()
1944 return -ENOMEM; in sg_build_indirect()
1950 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_remove_scat()
1951 "sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg)); in sg_remove_scat()
1952 if (schp->pages && schp->sglist_len > 0) { in sg_remove_scat()
1953 if (!schp->dio_in_use) { in sg_remove_scat()
1956 for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) { in sg_remove_scat()
1958 sg_printk(KERN_INFO, sfp->parentdp, in sg_remove_scat()
1960 k, schp->pages[k])); in sg_remove_scat()
1961 __free_pages(schp->pages[k], schp->page_order); in sg_remove_scat()
1964 kfree(schp->pages); in sg_remove_scat()
1971 sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer) in sg_read_oxfer() argument
1973 Sg_scatter_hold *schp = &srp->data; in sg_read_oxfer()
1976 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, srp->parentfp->parentdp, in sg_read_oxfer()
1982 num = 1 << (PAGE_SHIFT + schp->page_order); in sg_read_oxfer()
1983 for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) { in sg_read_oxfer()
1985 if (copy_to_user(outp, page_address(schp->pages[k]), in sg_read_oxfer()
1987 return -EFAULT; in sg_read_oxfer()
1990 if (copy_to_user(outp, page_address(schp->pages[k]), in sg_read_oxfer()
1992 return -EFAULT; in sg_read_oxfer()
1993 num_read_xfer -= num; in sg_read_oxfer()
2006 Sg_scatter_hold *schp = &sfp->reserve; in sg_build_reserve()
2008 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_reserve()
2022 sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size) in sg_link_reserve() argument
2024 Sg_scatter_hold *req_schp = &srp->data; in sg_link_reserve()
2025 Sg_scatter_hold *rsv_schp = &sfp->reserve; in sg_link_reserve()
2028 srp->res_used = 1; in sg_link_reserve()
2029 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_link_reserve()
2033 num = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_link_reserve()
2034 for (k = 0; k < rsv_schp->k_use_sg; k++) { in sg_link_reserve()
2036 req_schp->k_use_sg = k + 1; in sg_link_reserve()
2037 req_schp->sglist_len = rsv_schp->sglist_len; in sg_link_reserve()
2038 req_schp->pages = rsv_schp->pages; in sg_link_reserve()
2040 req_schp->bufflen = size; in sg_link_reserve()
2041 req_schp->page_order = rsv_schp->page_order; in sg_link_reserve()
2044 rem -= num; in sg_link_reserve()
2047 if (k >= rsv_schp->k_use_sg) in sg_link_reserve()
2048 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_link_reserve()
2053 sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp) in sg_unlink_reserve() argument
2055 Sg_scatter_hold *req_schp = &srp->data; in sg_unlink_reserve()
2057 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, srp->parentfp->parentdp, in sg_unlink_reserve()
2058 "sg_unlink_reserve: req->k_use_sg=%d\n", in sg_unlink_reserve()
2059 (int) req_schp->k_use_sg)); in sg_unlink_reserve()
2060 req_schp->k_use_sg = 0; in sg_unlink_reserve()
2061 req_schp->bufflen = 0; in sg_unlink_reserve()
2062 req_schp->pages = NULL; in sg_unlink_reserve()
2063 req_schp->page_order = 0; in sg_unlink_reserve()
2064 req_schp->sglist_len = 0; in sg_unlink_reserve()
2065 srp->res_used = 0; in sg_unlink_reserve()
2067 sfp->res_in_use = 0; in sg_unlink_reserve()
2077 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2078 list_for_each_entry(resp, &sfp->rq_list, entry) { in sg_get_rq_mark()
2080 if ((!resp->sg_io_owned) && in sg_get_rq_mark()
2081 ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { in sg_get_rq_mark()
2082 switch (resp->done) { in sg_get_rq_mark()
2087 resp->done = 2; /* guard against other readers */ in sg_get_rq_mark()
2088 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2095 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2105 Sg_request *rp = sfp->req_arr; in sg_add_request()
2107 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_add_request()
2108 if (!list_empty(&sfp->rq_list)) { in sg_add_request()
2109 if (!sfp->cmd_q) in sg_add_request()
2113 if (!rp->parentfp) in sg_add_request()
2120 rp->parentfp = sfp; in sg_add_request()
2121 rp->header.duration = jiffies_to_msecs(jiffies); in sg_add_request()
2122 list_add_tail(&rp->entry, &sfp->rq_list); in sg_add_request()
2123 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_add_request()
2126 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_add_request()
2132 sg_remove_request(Sg_fd * sfp, Sg_request * srp) in sg_remove_request() argument
2137 if (!sfp || !srp || list_empty(&sfp->rq_list)) in sg_remove_request()
2139 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_remove_request()
2140 if (!list_empty(&srp->entry)) { in sg_remove_request()
2141 list_del(&srp->entry); in sg_remove_request()
2142 srp->parentfp = NULL; in sg_remove_request()
2145 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_remove_request()
2150 * return other than -ENODEV. in sg_remove_request()
2152 if (unlikely(atomic_read(&sfp->parentdp->detaching))) in sg_remove_request()
2153 wake_up_interruptible_all(&sfp->read_wait); in sg_remove_request()
2167 return ERR_PTR(-ENOMEM); in sg_add_sfp()
2169 init_waitqueue_head(&sfp->read_wait); in sg_add_sfp()
2170 rwlock_init(&sfp->rq_list_lock); in sg_add_sfp()
2171 INIT_LIST_HEAD(&sfp->rq_list); in sg_add_sfp()
2172 kref_init(&sfp->f_ref); in sg_add_sfp()
2173 mutex_init(&sfp->f_mutex); in sg_add_sfp()
2174 sfp->timeout = SG_DEFAULT_TIMEOUT; in sg_add_sfp()
2175 sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER; in sg_add_sfp()
2176 sfp->force_packid = SG_DEF_FORCE_PACK_ID; in sg_add_sfp()
2177 sfp->cmd_q = SG_DEF_COMMAND_Q; in sg_add_sfp()
2178 sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; in sg_add_sfp()
2179 sfp->parentdp = sdp; in sg_add_sfp()
2180 write_lock_irqsave(&sdp->sfd_lock, iflags); in sg_add_sfp()
2181 if (atomic_read(&sdp->detaching)) { in sg_add_sfp()
2182 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_add_sfp()
2184 return ERR_PTR(-ENODEV); in sg_add_sfp()
2186 list_add_tail(&sfp->sfd_siblings, &sdp->sfds); in sg_add_sfp()
2187 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_add_sfp()
2194 max_sectors_bytes(sdp->device->request_queue)); in sg_add_sfp()
2198 sfp->reserve.bufflen, in sg_add_sfp()
2199 sfp->reserve.k_use_sg)); in sg_add_sfp()
2201 kref_get(&sdp->d_ref); in sg_add_sfp()
2210 struct sg_device *sdp = sfp->parentdp; in sg_remove_sfp_usercontext()
2211 Sg_request *srp; in sg_remove_sfp_usercontext() local
2215 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_remove_sfp_usercontext()
2216 while (!list_empty(&sfp->rq_list)) { in sg_remove_sfp_usercontext()
2217 srp = list_first_entry(&sfp->rq_list, Sg_request, entry); in sg_remove_sfp_usercontext()
2218 sg_finish_rem_req(srp); in sg_remove_sfp_usercontext()
2219 list_del(&srp->entry); in sg_remove_sfp_usercontext()
2220 srp->parentfp = NULL; in sg_remove_sfp_usercontext()
2222 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_remove_sfp_usercontext()
2224 if (sfp->reserve.bufflen > 0) { in sg_remove_sfp_usercontext()
2227 (int) sfp->reserve.bufflen, in sg_remove_sfp_usercontext()
2228 (int) sfp->reserve.k_use_sg)); in sg_remove_sfp_usercontext()
2229 sg_remove_scat(sfp, &sfp->reserve); in sg_remove_sfp_usercontext()
2236 scsi_device_put(sdp->device); in sg_remove_sfp_usercontext()
2237 kref_put(&sdp->d_ref, sg_device_destroy); in sg_remove_sfp_usercontext()
2245 struct sg_device *sdp = sfp->parentdp; in sg_remove_sfp()
2248 write_lock_irqsave(&sdp->sfd_lock, iflags); in sg_remove_sfp()
2249 list_del(&sfp->sfd_siblings); in sg_remove_sfp()
2250 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_remove_sfp()
2252 INIT_WORK(&sfp->ew.work, sg_remove_sfp_usercontext); in sg_remove_sfp()
2253 schedule_work(&sfp->ew.work); in sg_remove_sfp()
2271 int k = -1; in sg_last_dev()
2296 sdp = ERR_PTR(-ENXIO); in sg_get_dev()
2297 else if (atomic_read(&sdp->detaching)) { in sg_get_dev()
2298 /* If sdp->detaching, then the refcount may already be 0, in in sg_get_dev()
2301 sdp = ERR_PTR(-ENODEV); in sg_get_dev()
2303 kref_get(&sdp->d_ref); in sg_get_dev()
2385 seq_printf(s, "%d\n", *((int *)s->private)); in sg_proc_seq_show_int()
2401 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) in sg_proc_write_adio()
2402 return -EACCES; in sg_proc_write_adio()
2422 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) in sg_proc_write_dressz()
2423 return -EACCES; in sg_proc_write_dressz()
2432 return -ERANGE; in sg_proc_write_dressz()
2457 s->private = it; in dev_seq_start()
2461 it->index = *pos; in dev_seq_start()
2462 it->max = sg_last_dev(); in dev_seq_start()
2463 if (it->index >= it->max) in dev_seq_start()
2470 struct sg_proc_deviter * it = s->private; in dev_seq_next()
2472 *pos = ++it->index; in dev_seq_next()
2473 return (it->index < it->max) ? it : NULL; in dev_seq_next()
2478 kfree(s->private); in dev_seq_stop()
2489 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_dev()
2490 if ((NULL == sdp) || (NULL == sdp->device) || in sg_proc_seq_show_dev()
2491 (atomic_read(&sdp->detaching))) in sg_proc_seq_show_dev()
2492 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()
2494 scsidp = sdp->device; in sg_proc_seq_show_dev()
2496 scsidp->host->host_no, scsidp->channel, in sg_proc_seq_show_dev()
2497 scsidp->id, scsidp->lun, (int) scsidp->type, in sg_proc_seq_show_dev()
2499 (int) scsidp->queue_depth, in sg_proc_seq_show_dev()
2515 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_devstrs()
2516 scsidp = sdp ? sdp->device : NULL; in sg_proc_seq_show_devstrs()
2517 if (sdp && scsidp && (!atomic_read(&sdp->detaching))) in sg_proc_seq_show_devstrs()
2519 scsidp->vendor, scsidp->model, scsidp->rev); in sg_proc_seq_show_devstrs()
2530 Sg_request *srp; in sg_proc_debug_helper() local
2537 list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { in sg_proc_debug_helper()
2539 read_lock(&fp->rq_list_lock); /* irqs already disabled */ in sg_proc_debug_helper()
2542 jiffies_to_msecs(fp->timeout), in sg_proc_debug_helper()
2543 fp->reserve.bufflen, in sg_proc_debug_helper()
2544 (int) fp->reserve.k_use_sg, 0); in sg_proc_debug_helper()
2546 (int) fp->cmd_q, (int) fp->force_packid, in sg_proc_debug_helper()
2547 (int) fp->keep_orphan); in sg_proc_debug_helper()
2548 list_for_each_entry(srp, &fp->rq_list, entry) { in sg_proc_debug_helper()
2549 hp = &srp->header; in sg_proc_debug_helper()
2550 new_interface = (hp->interface_id == '\0') ? 0 : 1; in sg_proc_debug_helper()
2551 if (srp->res_used) { in sg_proc_debug_helper()
2553 (SG_FLAG_MMAP_IO & hp->flags)) in sg_proc_debug_helper()
2558 if (SG_INFO_DIRECT_IO_MASK & hp->info) in sg_proc_debug_helper()
2564 blen = srp->data.bufflen; in sg_proc_debug_helper()
2565 usg = srp->data.k_use_sg; in sg_proc_debug_helper()
2566 seq_puts(s, srp->done ? in sg_proc_debug_helper()
2567 ((1 == srp->done) ? "rcv:" : "fin:") in sg_proc_debug_helper()
2570 srp->header.pack_id, blen); in sg_proc_debug_helper()
2571 if (srp->done) in sg_proc_debug_helper()
2572 seq_printf(s, " dur=%d", hp->duration); in sg_proc_debug_helper()
2576 (new_interface ? hp->timeout : in sg_proc_debug_helper()
2577 jiffies_to_msecs(fp->timeout)), in sg_proc_debug_helper()
2578 (ms > hp->duration ? ms - hp->duration : 0)); in sg_proc_debug_helper()
2581 (int) srp->data.cmd_opcode); in sg_proc_debug_helper()
2583 if (list_empty(&fp->rq_list)) in sg_proc_debug_helper()
2585 read_unlock(&fp->rq_list_lock); in sg_proc_debug_helper()
2595 if (it && (0 == it->index)) in sg_proc_seq_show_debug()
2597 (int)it->max, sg_big_buff); in sg_proc_seq_show_debug()
2600 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_debug()
2603 read_lock(&sdp->sfd_lock); in sg_proc_seq_show_debug()
2604 if (!list_empty(&sdp->sfds)) { in sg_proc_seq_show_debug()
2605 seq_printf(s, " >>> device=%s ", sdp->name); in sg_proc_seq_show_debug()
2606 if (atomic_read(&sdp->detaching)) in sg_proc_seq_show_debug()
2608 else if (sdp->device) { in sg_proc_seq_show_debug()
2609 struct scsi_device *scsidp = sdp->device; in sg_proc_seq_show_debug()
2612 scsidp->host->host_no, in sg_proc_seq_show_debug()
2613 scsidp->channel, scsidp->id, in sg_proc_seq_show_debug()
2614 scsidp->lun, in sg_proc_seq_show_debug()
2615 scsidp->host->hostt->emulated); in sg_proc_seq_show_debug()
2618 sdp->sg_tablesize, sdp->exclude, sdp->open_cnt); in sg_proc_seq_show_debug()
2621 read_unlock(&sdp->sfd_lock); in sg_proc_seq_show_debug()