• Home
  • Raw
  • Download

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
84 readable via /proc/sys/kernel/sg-big-buff if the sg driver is built into
86 static int def_reserved_size = -1; /* picks up init parameter */
107 unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */
108 unsigned sglist_len; /* size of malloc'd scatter-gather list ++ */
112 char dio_in_use; /* 0->indirect IO (or mmap), 1->dio */
121 struct sg_fd *parentfp; /* NULL -> not in use */
125 char res_used; /* 1 -> using reserve buffer, 0 -> not ... */
126 char orphan; /* 1 -> drop on sight, 0 -> normal */
127 char sg_io_owned; /* 1 -> packet belongs to SG_IO */
129 char done; /* 0->before bh, 1->before read, 2->read */
146 Sg_request req_arr[SG_MAX_QUEUE]; /* used as singly-linked list */
147 char force_packid; /* 1 -> pack_id input to read(), 0 -> ignored */
148 char cmd_q; /* 1 -> allow command queuing, 0 -> don't */
150 char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
151 char mmap_called; /* 0 -> mmap() never called on this fd */
152 char res_in_use; /* 1 -> 'reserve' array in use */
161 int sg_tablesize; /* adapter's max scatter-gather table size */
165 atomic_t detaching; /* 0->device usable, 1->device detaching */
166 bool exclude; /* 1->open(O_EXCL) succeeded and is active */
168 char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
176 static int sg_start_req(Sg_request *srp, unsigned char *cmd);
177 static int sg_finish_rem_req(Sg_request * srp);
180 Sg_request * srp);
184 static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
186 static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer);
189 static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
190 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
195 static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
205 sdev_prefix_printk(prefix, (sdp)->device, \
206 (sdp)->disk->disk_name, fmt, ##a)
222 if (filp->f_cred != current_real_cred()) { in sg_check_file_access()
224 caller, task_tgid_vnr(current), current->comm); in sg_check_file_access()
225 return -EPERM; in sg_check_file_access()
229 caller, task_tgid_vnr(current), current->comm); in sg_check_file_access()
230 return -EACCES; in sg_check_file_access()
237 struct sg_fd *sfp = filp->private_data; in sg_allow_access()
239 if (sfp->parentdp->device->type == TYPE_SCANNER) in sg_allow_access()
242 return blk_verify_command(cmd, filp->f_mode); 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 (DRIVER_SENSE & hp->driver_status)) in sg_read()
499 memcpy(old_hdr->sense_buffer, srp->sense_b, in sg_read()
500 sizeof (old_hdr->sense_buffer)); in sg_read()
501 switch (hp->host_status) { in sg_read()
507 old_hdr->result = 0; in sg_read()
512 old_hdr->result = EBUSY; in sg_read()
519 old_hdr->result = EIO; in sg_read()
522 old_hdr->result = (srp->sense_b[0] == 0 && in sg_read()
523 hp->masked_status == GOOD) ? 0 : EIO; in sg_read()
526 old_hdr->result = EIO; in sg_read()
533 retval = -EFAULT; in sg_read()
537 if (count > old_hdr->reply_len) in sg_read()
538 count = old_hdr->reply_len; in sg_read()
540 if (sg_read_oxfer(srp, buf, count - SZ_SG_HEADER)) { in sg_read()
541 retval = -EFAULT; in sg_read()
546 count = (old_hdr->result == 0) ? 0 : -EIO; in sg_read()
547 sg_finish_rem_req(srp); in sg_read()
548 sg_remove_request(sfp, srp); in sg_read()
556 sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp) in sg_new_read() argument
558 sg_io_hdr_t *hp = &srp->header; in sg_new_read()
564 err = -EINVAL; in sg_new_read()
568 err = -EINVAL; in sg_new_read()
571 hp->sb_len_wr = 0; in sg_new_read()
572 if ((hp->mx_sb_len > 0) && hp->sbp) { in sg_new_read()
573 if ((CHECK_CONDITION & hp->masked_status) || in sg_new_read()
574 (DRIVER_SENSE & hp->driver_status)) { in sg_new_read()
576 sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len; in sg_new_read()
577 len = 8 + (int) srp->sense_b[7]; /* Additional sense length field */ in sg_new_read()
579 if (copy_to_user(hp->sbp, srp->sense_b, len)) { in sg_new_read()
580 err = -EFAULT; in sg_new_read()
583 hp->sb_len_wr = len; in sg_new_read()
586 if (hp->masked_status || hp->host_status || hp->driver_status) in sg_new_read()
587 hp->info |= SG_INFO_CHECK; in sg_new_read()
590 err2 = sg_finish_rem_req(srp); in sg_new_read()
591 sg_remove_request(sfp, srp); in sg_new_read()
603 Sg_request *srp; in sg_write() local
613 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_write()
614 return -ENXIO; in sg_write()
617 if (atomic_read(&sdp->detaching)) in sg_write()
618 return -ENODEV; in sg_write()
619 if (!((filp->f_flags & O_NONBLOCK) || in sg_write()
620 scsi_block_when_processing_errors(sdp->device))) in sg_write()
621 return -ENXIO; in sg_write()
624 return -EIO; in sg_write()
626 return -EFAULT; in sg_write()
627 blocking = !(filp->f_flags & O_NONBLOCK); in sg_write()
632 return -EIO; /* The minimum scsi command length is 6 bytes. */ in sg_write()
636 return -EFAULT; in sg_write()
638 if (!(srp = sg_add_request(sfp))) { in sg_write()
641 return -EDOM; in sg_write()
643 mutex_lock(&sfp->f_mutex); in sg_write()
644 if (sfp->next_cmd_len > 0) { in sg_write()
645 cmd_size = sfp->next_cmd_len; in sg_write()
646 sfp->next_cmd_len = 0; /* reset so only this write() effected */ in sg_write()
652 mutex_unlock(&sfp->f_mutex); in sg_write()
656 input_size = count - cmd_size; in sg_write()
658 mxsize -= SZ_SG_HEADER; in sg_write()
659 input_size -= SZ_SG_HEADER; in sg_write()
661 sg_remove_request(sfp, srp); in sg_write()
662 return -EIO; /* User did not pass enough bytes for this command. */ in sg_write()
664 hp = &srp->header; in sg_write()
665 hp->interface_id = '\0'; /* indicator of old interface tunnelled */ in sg_write()
666 hp->cmd_len = (unsigned char) cmd_size; in sg_write()
667 hp->iovec_count = 0; in sg_write()
668 hp->mx_sb_len = 0; in sg_write()
670 hp->dxfer_direction = (old_hdr.reply_len > SZ_SG_HEADER) ? in sg_write()
673 hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE; in sg_write()
674 hp->dxfer_len = mxsize; in sg_write()
675 if ((hp->dxfer_direction == SG_DXFER_TO_DEV) || in sg_write()
676 (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV)) in sg_write()
677 hp->dxferp = (char __user *)buf + cmd_size; in sg_write()
679 hp->dxferp = NULL; in sg_write()
680 hp->sbp = NULL; in sg_write()
681 hp->timeout = old_hdr.reply_len; /* structure abuse ... */ in sg_write()
682 hp->flags = input_size; /* structure abuse ... */ in sg_write()
683 hp->pack_id = old_hdr.pack_id; in sg_write()
684 hp->usr_ptr = NULL; in sg_write()
686 sg_remove_request(sfp, srp); in sg_write()
687 return -EFAULT; in sg_write()
692 * is a non-zero input_size, so emit a warning. in sg_write()
694 if (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV) { in sg_write()
697 "for SCSI command 0x%x-- guessing " in sg_write()
700 old_hdr.reply_len - (int)SZ_SG_HEADER, in sg_write()
702 current->comm); in sg_write()
704 k = sg_common_write(sfp, srp, cmnd, sfp->timeout, blocking); in sg_write()
714 Sg_request *srp; in sg_new_write() local
721 return -EINVAL; in sg_new_write()
723 sfp->cmd_q = 1; /* when sg_io_hdr seen, set command queuing on */ in sg_new_write()
724 if (!(srp = sg_add_request(sfp))) { in sg_new_write()
725 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_new_write()
727 return -EDOM; in sg_new_write()
729 srp->sg_io_owned = sg_io_owned; in sg_new_write()
730 hp = &srp->header; in sg_new_write()
732 sg_remove_request(sfp, srp); in sg_new_write()
733 return -EFAULT; in sg_new_write()
735 if (hp->interface_id != 'S') { in sg_new_write()
736 sg_remove_request(sfp, srp); in sg_new_write()
737 return -ENOSYS; in sg_new_write()
739 if (hp->flags & SG_FLAG_MMAP_IO) { in sg_new_write()
740 if (hp->dxfer_len > sfp->reserve.bufflen) { in sg_new_write()
741 sg_remove_request(sfp, srp); in sg_new_write()
742 return -ENOMEM; /* MMAP_IO size must fit in reserve buffer */ in sg_new_write()
744 if (hp->flags & SG_FLAG_DIRECT_IO) { in sg_new_write()
745 sg_remove_request(sfp, srp); in sg_new_write()
746 return -EINVAL; /* either MMAP_IO or DIRECT_IO (not both) */ in sg_new_write()
748 if (sfp->res_in_use) { in sg_new_write()
749 sg_remove_request(sfp, srp); in sg_new_write()
750 return -EBUSY; /* reserve buffer already being used */ in sg_new_write()
753 ul_timeout = msecs_to_jiffies(srp->header.timeout); in sg_new_write()
755 if ((!hp->cmdp) || (hp->cmd_len < 6) || (hp->cmd_len > sizeof (cmnd))) { in sg_new_write()
756 sg_remove_request(sfp, srp); in sg_new_write()
757 return -EMSGSIZE; in sg_new_write()
759 if (copy_from_user(cmnd, hp->cmdp, hp->cmd_len)) { in sg_new_write()
760 sg_remove_request(sfp, srp); in sg_new_write()
761 return -EFAULT; in sg_new_write()
764 sg_remove_request(sfp, srp); in sg_new_write()
765 return -EPERM; in sg_new_write()
767 k = sg_common_write(sfp, srp, cmnd, timeout, blocking); in sg_new_write()
771 *o_srp = srp; in sg_new_write()
776 sg_common_write(Sg_fd * sfp, Sg_request * srp, in sg_common_write() argument
780 Sg_device *sdp = sfp->parentdp; in sg_common_write()
781 sg_io_hdr_t *hp = &srp->header; in sg_common_write()
783 srp->data.cmd_opcode = cmnd[0]; /* hold opcode of command */ in sg_common_write()
784 hp->status = 0; in sg_common_write()
785 hp->masked_status = 0; in sg_common_write()
786 hp->msg_status = 0; in sg_common_write()
787 hp->info = 0; in sg_common_write()
788 hp->host_status = 0; in sg_common_write()
789 hp->driver_status = 0; in sg_common_write()
790 hp->resid = 0; in sg_common_write()
791 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_common_write()
793 (int) cmnd[0], (int) hp->cmd_len)); in sg_common_write()
795 if (hp->dxfer_len >= SZ_256M) { in sg_common_write()
796 sg_remove_request(sfp, srp); in sg_common_write()
797 return -EINVAL; in sg_common_write()
800 k = sg_start_req(srp, cmnd); in sg_common_write()
802 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_common_write()
804 sg_finish_rem_req(srp); in sg_common_write()
805 sg_remove_request(sfp, srp); in sg_common_write()
806 return k; /* probably out of space --> ENOMEM */ in sg_common_write()
808 if (atomic_read(&sdp->detaching)) { in sg_common_write()
809 if (srp->bio) { in sg_common_write()
810 scsi_req_free_cmd(scsi_req(srp->rq)); in sg_common_write()
811 blk_put_request(srp->rq); in sg_common_write()
812 srp->rq = NULL; in sg_common_write()
815 sg_finish_rem_req(srp); in sg_common_write()
816 sg_remove_request(sfp, srp); in sg_common_write()
817 return -ENODEV; in sg_common_write()
820 hp->duration = jiffies_to_msecs(jiffies); in sg_common_write()
821 if (hp->interface_id != '\0' && /* v3 (or later) interface */ in sg_common_write()
822 (SG_FLAG_Q_AT_TAIL & hp->flags)) in sg_common_write()
827 srp->rq->timeout = timeout; in sg_common_write()
828 kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */ in sg_common_write()
829 blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk, in sg_common_write()
830 srp->rq, at_head, sg_rq_end_io); in sg_common_write()
834 static int srp_done(Sg_fd *sfp, Sg_request *srp) in srp_done() argument
839 read_lock_irqsave(&sfp->rq_list_lock, flags); in srp_done()
840 ret = srp->done; in srp_done()
841 read_unlock_irqrestore(&sfp->rq_list_lock, flags); in srp_done()
857 Sg_request *srp; in sg_fill_request_table() local
862 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_fill_request_table()
865 rinfo[val].req_state = srp->done + 1; in sg_fill_request_table()
867 srp->header.masked_status & in sg_fill_request_table()
868 srp->header.host_status & in sg_fill_request_table()
869 srp->header.driver_status; in sg_fill_request_table()
870 if (srp->done) in sg_fill_request_table()
872 srp->header.duration; in sg_fill_request_table()
876 (ms > srp->header.duration) ? in sg_fill_request_table()
877 (ms - srp->header.duration) : 0; in sg_fill_request_table()
879 rinfo[val].orphan = srp->orphan; in sg_fill_request_table()
880 rinfo[val].sg_io_owned = srp->sg_io_owned; in sg_fill_request_table()
881 rinfo[val].pack_id = srp->header.pack_id; in sg_fill_request_table()
882 rinfo[val].usr_ptr = srp->header.usr_ptr; in sg_fill_request_table()
908 return -EFAULT; in put_compat_request_table()
920 Sg_request *srp; in sg_ioctl_common() local
925 read_only = (O_RDWR != (filp->f_flags & O_ACCMODE)); in sg_ioctl_common()
929 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
930 return -ENODEV; in sg_ioctl_common()
931 if (!scsi_block_when_processing_errors(sdp->device)) in sg_ioctl_common()
932 return -ENXIO; in sg_ioctl_common()
934 1, read_only, 1, &srp); in sg_ioctl_common()
937 result = wait_event_interruptible(sfp->read_wait, in sg_ioctl_common()
938 srp_done(sfp, srp)); in sg_ioctl_common()
939 write_lock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
940 if (srp->done) { in sg_ioctl_common()
941 srp->done = 2; in sg_ioctl_common()
942 write_unlock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
943 result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp); in sg_ioctl_common()
946 srp->orphan = 1; in sg_ioctl_common()
947 write_unlock_irq(&sfp->rq_list_lock); in sg_ioctl_common()
948 return result; /* -ERESTARTSYS because signal hit process */ in sg_ioctl_common()
954 return -EIO; in sg_ioctl_common()
958 sfp->timeout_user = val; in sg_ioctl_common()
959 sfp->timeout = mult_frac(val, HZ, USER_HZ); in sg_ioctl_common()
964 return sfp->timeout_user; in sg_ioctl_common()
973 return put_user((int) sdp->device->host->unchecked_isa_dma, ip); in sg_ioctl_common()
978 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
979 return -ENODEV; in sg_ioctl_common()
981 v.host_no = sdp->device->host->host_no; in sg_ioctl_common()
982 v.channel = sdp->device->channel; in sg_ioctl_common()
983 v.scsi_id = sdp->device->id; in sg_ioctl_common()
984 v.lun = sdp->device->lun; in sg_ioctl_common()
985 v.scsi_type = sdp->device->type; in sg_ioctl_common()
986 v.h_cmd_per_lun = sdp->device->host->cmd_per_lun; in sg_ioctl_common()
987 v.d_queue_depth = sdp->device->queue_depth; in sg_ioctl_common()
989 return -EFAULT; in sg_ioctl_common()
996 sfp->force_packid = val ? 1 : 0; in sg_ioctl_common()
999 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1000 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_ioctl_common()
1001 if ((1 == srp->done) && (!srp->sg_io_owned)) { in sg_ioctl_common()
1002 read_unlock_irqrestore(&sfp->rq_list_lock, in sg_ioctl_common()
1004 return put_user(srp->header.pack_id, ip); in sg_ioctl_common()
1007 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1008 return put_user(-1, ip); in sg_ioctl_common()
1010 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1012 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_ioctl_common()
1013 if ((1 == srp->done) && (!srp->sg_io_owned)) in sg_ioctl_common()
1016 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1019 return put_user(sdp->sg_tablesize, ip); in sg_ioctl_common()
1025 return -EINVAL; in sg_ioctl_common()
1027 max_sectors_bytes(sdp->device->request_queue)); in sg_ioctl_common()
1028 mutex_lock(&sfp->f_mutex); in sg_ioctl_common()
1029 if (val != sfp->reserve.bufflen) { in sg_ioctl_common()
1030 if (sfp->mmap_called || in sg_ioctl_common()
1031 sfp->res_in_use) { in sg_ioctl_common()
1032 mutex_unlock(&sfp->f_mutex); in sg_ioctl_common()
1033 return -EBUSY; in sg_ioctl_common()
1036 sg_remove_scat(sfp, &sfp->reserve); in sg_ioctl_common()
1039 mutex_unlock(&sfp->f_mutex); in sg_ioctl_common()
1042 val = min_t(int, sfp->reserve.bufflen, in sg_ioctl_common()
1043 max_sectors_bytes(sdp->device->request_queue)); in sg_ioctl_common()
1049 sfp->cmd_q = val ? 1 : 0; in sg_ioctl_common()
1052 return put_user((int) sfp->cmd_q, ip); in sg_ioctl_common()
1057 sfp->keep_orphan = val; in sg_ioctl_common()
1060 return put_user((int) sfp->keep_orphan, ip); in sg_ioctl_common()
1066 return -ENOMEM; in sg_ioctl_common()
1067 sfp->next_cmd_len = (val > 0) ? val : 0; in sg_ioctl_common()
1072 /* faked - we don't have a real access count anymore */ in sg_ioctl_common()
1073 val = (sdp->device ? 1 : 0); in sg_ioctl_common()
1082 return -ENOMEM; in sg_ioctl_common()
1083 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1085 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_ioctl_common()
1093 result = result ? -EFAULT : 0; in sg_ioctl_common()
1098 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1099 return -ENODEV; in sg_ioctl_common()
1100 return put_user(sdp->device->host->hostt->emulated, ip); in sg_ioctl_common()
1102 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1103 return -ENODEV; in sg_ioctl_common()
1104 return sg_scsi_ioctl(sdp->device->request_queue, NULL, filp->f_mode, p); in sg_ioctl_common()
1109 sdp->sgdebug = (char) val; in sg_ioctl_common()
1112 return put_user(max_sectors_bytes(sdp->device->request_queue), in sg_ioctl_common()
1115 return blk_trace_setup(sdp->device->request_queue, in sg_ioctl_common()
1116 sdp->disk->disk_name, in sg_ioctl_common()
1117 MKDEV(SCSI_GENERIC_MAJOR, sdp->index), in sg_ioctl_common()
1120 return blk_trace_startstop(sdp->device->request_queue, 1); in sg_ioctl_common()
1122 return blk_trace_startstop(sdp->device->request_queue, 0); in sg_ioctl_common()
1124 return blk_trace_remove(sdp->device->request_queue); in sg_ioctl_common()
1130 if (atomic_read(&sdp->detaching)) in sg_ioctl_common()
1131 return -ENODEV; in sg_ioctl_common()
1135 return -EPERM; /* don't know so take safe approach */ in sg_ioctl_common()
1139 result = scsi_ioctl_block_when_processing_errors(sdp->device, in sg_ioctl_common()
1140 cmd_in, filp->f_flags & O_NDELAY); in sg_ioctl_common()
1144 return -ENOIOCTLCMD; in sg_ioctl_common()
1155 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_ioctl()
1156 return -ENXIO; in sg_ioctl()
1159 if (ret != -ENOIOCTLCMD) in sg_ioctl()
1162 return scsi_ioctl(sdp->device, cmd_in, p); in sg_ioctl()
1173 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_compat_ioctl()
1174 return -ENXIO; in sg_compat_ioctl()
1177 if (ret != -ENOIOCTLCMD) in sg_compat_ioctl()
1180 return scsi_compat_ioctl(sdp->device, cmd_in, p); in sg_compat_ioctl()
1190 Sg_request *srp; in sg_poll() local
1194 sfp = filp->private_data; in sg_poll()
1197 sdp = sfp->parentdp; in sg_poll()
1200 poll_wait(filp, &sfp->read_wait, wait); in sg_poll()
1201 read_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_poll()
1202 list_for_each_entry(srp, &sfp->rq_list, entry) { in sg_poll()
1204 if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned)) in sg_poll()
1208 read_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_poll()
1210 if (atomic_read(&sdp->detaching)) in sg_poll()
1212 else if (!sfp->cmd_q) { in sg_poll()
1228 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) in sg_fasync()
1229 return -ENXIO; in sg_fasync()
1233 return fasync_helper(fd, filp, mode, &sfp->async_qp); in sg_fasync()
1239 struct vm_area_struct *vma = vmf->vma; in sg_vma_fault()
1245 if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data))) in sg_vma_fault()
1247 rsv_schp = &sfp->reserve; in sg_vma_fault()
1248 offset = vmf->pgoff << PAGE_SHIFT; in sg_vma_fault()
1249 if (offset >= rsv_schp->bufflen) in sg_vma_fault()
1251 SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp, in sg_vma_fault()
1253 offset, rsv_schp->k_use_sg)); in sg_vma_fault()
1254 sa = vma->vm_start; in sg_vma_fault()
1255 length = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_vma_fault()
1256 for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) { in sg_vma_fault()
1257 len = vma->vm_end - sa; in sg_vma_fault()
1260 struct page *page = nth_page(rsv_schp->pages[k], in sg_vma_fault()
1263 vmf->page = page; in sg_vma_fault()
1267 offset -= len; in sg_vma_fault()
1286 if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data))) in sg_mmap()
1287 return -ENXIO; in sg_mmap()
1288 req_sz = vma->vm_end - vma->vm_start; in sg_mmap()
1289 SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp, in sg_mmap()
1291 (void *) vma->vm_start, (int) req_sz)); in sg_mmap()
1292 if (vma->vm_pgoff) in sg_mmap()
1293 return -EINVAL; /* want no offset */ in sg_mmap()
1294 rsv_schp = &sfp->reserve; in sg_mmap()
1295 mutex_lock(&sfp->f_mutex); in sg_mmap()
1296 if (req_sz > rsv_schp->bufflen) { in sg_mmap()
1297 ret = -ENOMEM; /* cannot map more than reserved buffer */ in sg_mmap()
1301 sa = vma->vm_start; in sg_mmap()
1302 length = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_mmap()
1303 for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) { in sg_mmap()
1304 len = vma->vm_end - sa; in sg_mmap()
1309 sfp->mmap_called = 1; in sg_mmap()
1310 vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; in sg_mmap()
1311 vma->vm_private_data = sfp; in sg_mmap()
1312 vma->vm_ops = &sg_mmap_vm_ops; in sg_mmap()
1314 mutex_unlock(&sfp->f_mutex); in sg_mmap()
1321 struct sg_request *srp = container_of(work, struct sg_request, ew.work); in sg_rq_end_io_usercontext() local
1322 struct sg_fd *sfp = srp->parentfp; in sg_rq_end_io_usercontext()
1324 sg_finish_rem_req(srp); in sg_rq_end_io_usercontext()
1325 sg_remove_request(sfp, srp); in sg_rq_end_io_usercontext()
1326 kref_put(&sfp->f_ref, sg_remove_sfp); in sg_rq_end_io_usercontext()
1336 struct sg_request *srp = rq->end_io_data; in sg_rq_end_io() local
1345 if (WARN_ON(srp->done != 0)) in sg_rq_end_io()
1348 sfp = srp->parentfp; in sg_rq_end_io()
1352 sdp = sfp->parentdp; in sg_rq_end_io()
1353 if (unlikely(atomic_read(&sdp->detaching))) in sg_rq_end_io()
1356 sense = req->sense; in sg_rq_end_io()
1357 result = req->result; in sg_rq_end_io()
1358 resid = req->resid_len; in sg_rq_end_io()
1362 srp->header.pack_id, result)); in sg_rq_end_io()
1363 srp->header.resid = resid; in sg_rq_end_io()
1365 srp->header.duration = (ms > srp->header.duration) ? in sg_rq_end_io()
1366 (ms - srp->header.duration) : 0; in sg_rq_end_io()
1370 srp->header.status = 0xff & result; in sg_rq_end_io()
1371 srp->header.masked_status = status_byte(result); in sg_rq_end_io()
1372 srp->header.msg_status = msg_byte(result); in sg_rq_end_io()
1373 srp->header.host_status = host_byte(result); in sg_rq_end_io()
1374 srp->header.driver_status = driver_byte(result); in sg_rq_end_io()
1375 if ((sdp->sgdebug > 0) && in sg_rq_end_io()
1376 ((CHECK_CONDITION == srp->header.masked_status) || in sg_rq_end_io()
1377 (COMMAND_TERMINATED == srp->header.masked_status))) in sg_rq_end_io()
1378 __scsi_print_sense(sdp->device, __func__, sense, in sg_rq_end_io()
1386 && sdp->device->removable) { in sg_rq_end_io()
1387 /* Detected possible disc change. Set the bit - this */ in sg_rq_end_io()
1389 sdp->device->changed = 1; in sg_rq_end_io()
1393 if (req->sense_len) in sg_rq_end_io()
1394 memcpy(srp->sense_b, req->sense, SCSI_SENSE_BUFFERSIZE); in sg_rq_end_io()
1396 /* Rely on write phase to clean out srp status values, so no "else" */ in sg_rq_end_io()
1404 srp->rq = NULL; in sg_rq_end_io()
1408 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_rq_end_io()
1409 if (unlikely(srp->orphan)) { in sg_rq_end_io()
1410 if (sfp->keep_orphan) in sg_rq_end_io()
1411 srp->sg_io_owned = 0; in sg_rq_end_io()
1415 srp->done = done; in sg_rq_end_io()
1416 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_rq_end_io()
1422 wake_up_interruptible(&sfp->read_wait); in sg_rq_end_io()
1423 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); in sg_rq_end_io()
1424 kref_put(&sfp->f_ref, sg_remove_sfp); in sg_rq_end_io()
1426 INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext); in sg_rq_end_io()
1427 schedule_work(&srp->ew.work); in sg_rq_end_io()
1454 struct request_queue *q = scsidp->request_queue; in sg_alloc()
1464 return ERR_PTR(-ENOMEM); in sg_alloc()
1472 if (error == -ENOSPC) { in sg_alloc()
1475 scsidp->type, SG_MAX_DEVS - 1); in sg_alloc()
1476 error = -ENODEV; in sg_alloc()
1488 sprintf(disk->disk_name, "sg%d", k); in sg_alloc()
1489 disk->first_minor = k; in sg_alloc()
1490 sdp->disk = disk; in sg_alloc()
1491 sdp->device = scsidp; in sg_alloc()
1492 mutex_init(&sdp->open_rel_lock); in sg_alloc()
1493 INIT_LIST_HEAD(&sdp->sfds); in sg_alloc()
1494 init_waitqueue_head(&sdp->open_wait); in sg_alloc()
1495 atomic_set(&sdp->detaching, 0); in sg_alloc()
1496 rwlock_init(&sdp->sfd_lock); in sg_alloc()
1497 sdp->sg_tablesize = queue_max_segments(q); in sg_alloc()
1498 sdp->index = k; in sg_alloc()
1499 kref_init(&sdp->d_ref); in sg_alloc()
1516 struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); in sg_add_device()
1526 return -ENOMEM; in sg_add_device()
1528 disk->major = SCSI_GENERIC_MAJOR; in sg_add_device()
1530 error = -ENOMEM; in sg_add_device()
1536 cdev->owner = THIS_MODULE; in sg_add_device()
1537 cdev->ops = &sg_fops; in sg_add_device()
1546 error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, sdp->index), 1); in sg_add_device()
1550 sdp->cdev = cdev; in sg_add_device()
1554 sg_class_member = device_create(sg_sysfs_class, cl_dev->parent, in sg_add_device()
1556 sdp->index), in sg_add_device()
1557 sdp, "%s", disk->disk_name); in sg_add_device()
1563 error = sysfs_create_link(&scsidp->sdev_gendev.kobj, in sg_add_device()
1564 &sg_class_member->kobj, "generic"); in sg_add_device()
1567 "to sg%d\n", __func__, sdp->index); in sg_add_device()
1572 "type %d\n", sdp->index, scsidp->type); in sg_add_device()
1580 idr_remove(&sg_index_idr, sdp->index); in sg_add_device()
1603 idr_remove(&sg_index_idr, sdp->index); in sg_device_destroy()
1609 put_disk(sdp->disk); in sg_device_destroy()
1616 struct scsi_device *scsidp = to_scsi_device(cl_dev->parent); in sg_remove_device()
1624 /* want sdp->detaching non-zero as soon as possible */ in sg_remove_device()
1625 val = atomic_inc_return(&sdp->detaching); in sg_remove_device()
1632 read_lock_irqsave(&sdp->sfd_lock, iflags); in sg_remove_device()
1633 list_for_each_entry(sfp, &sdp->sfds, sfd_siblings) { in sg_remove_device()
1634 wake_up_interruptible_all(&sfp->read_wait); in sg_remove_device()
1635 kill_fasync(&sfp->async_qp, SIGPOLL, POLL_HUP); in sg_remove_device()
1637 wake_up_interruptible_all(&sdp->open_wait); in sg_remove_device()
1638 read_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_remove_device()
1640 sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic"); in sg_remove_device()
1641 device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index)); in sg_remove_device()
1642 cdev_del(sdp->cdev); in sg_remove_device()
1643 sdp->cdev = NULL; in sg_remove_device()
1645 kref_put(&sdp->d_ref, sg_device_destroy); in sg_remove_device()
1716 sg_start_req(Sg_request *srp, unsigned char *cmd) in sg_start_req() argument
1721 Sg_fd *sfp = srp->parentfp; in sg_start_req()
1722 sg_io_hdr_t *hp = &srp->header; in sg_start_req()
1723 int dxfer_len = (int) hp->dxfer_len; in sg_start_req()
1724 int dxfer_dir = hp->dxfer_direction; in sg_start_req()
1725 unsigned int iov_count = hp->iovec_count; in sg_start_req()
1726 Sg_scatter_hold *req_schp = &srp->data; in sg_start_req()
1727 Sg_scatter_hold *rsv_schp = &sfp->reserve; in sg_start_req()
1728 struct request_queue *q = sfp->parentdp->device->request_queue; in sg_start_req()
1730 int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ; in sg_start_req()
1733 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_start_req()
1737 if (hp->cmd_len > BLK_MAX_CDB) { in sg_start_req()
1738 long_cmdp = kzalloc(hp->cmd_len, GFP_KERNEL); in sg_start_req()
1740 return -ENOMEM; in sg_start_req()
1746 * With scsi-mq enabled, there are a fixed number of preallocated in sg_start_req()
1747 * requests equal in number to shost->can_queue. If all of the in sg_start_req()
1754 rq = blk_get_request(q, hp->dxfer_direction == SG_DXFER_TO_DEV ? in sg_start_req()
1762 if (hp->cmd_len > BLK_MAX_CDB) in sg_start_req()
1763 req->cmd = long_cmdp; in sg_start_req()
1764 memcpy(req->cmd, cmd, hp->cmd_len); in sg_start_req()
1765 req->cmd_len = hp->cmd_len; in sg_start_req()
1767 srp->rq = rq; in sg_start_req()
1768 rq->end_io_data = srp; in sg_start_req()
1769 req->retries = SG_DEFAULT_RETRIES; in sg_start_req()
1774 if (sg_allow_dio && hp->flags & SG_FLAG_DIRECT_IO && in sg_start_req()
1776 !sfp->parentdp->device->host->unchecked_isa_dma && in sg_start_req()
1777 blk_rq_aligned(q, (unsigned long)hp->dxferp, dxfer_len)) in sg_start_req()
1783 mutex_lock(&sfp->f_mutex); in sg_start_req()
1784 if (dxfer_len <= rsv_schp->bufflen && in sg_start_req()
1785 !sfp->res_in_use) { in sg_start_req()
1786 sfp->res_in_use = 1; in sg_start_req()
1787 sg_link_reserve(sfp, srp, dxfer_len); in sg_start_req()
1788 } else if (hp->flags & SG_FLAG_MMAP_IO) { in sg_start_req()
1789 res = -EBUSY; /* sfp->res_in_use == 1 */ in sg_start_req()
1790 if (dxfer_len > rsv_schp->bufflen) in sg_start_req()
1791 res = -ENOMEM; in sg_start_req()
1792 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1797 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1801 mutex_unlock(&sfp->f_mutex); in sg_start_req()
1803 md->pages = req_schp->pages; in sg_start_req()
1804 md->page_order = req_schp->page_order; in sg_start_req()
1805 md->nr_entries = req_schp->k_use_sg; in sg_start_req()
1806 md->offset = 0; in sg_start_req()
1807 md->null_mapped = hp->dxferp ? 0 : 1; in sg_start_req()
1809 md->from_user = 1; in sg_start_req()
1811 md->from_user = 0; in sg_start_req()
1818 res = import_iovec(rw, hp->dxferp, iov_count, 0, &iov, &i); in sg_start_req()
1822 iov_iter_truncate(&i, hp->dxfer_len); in sg_start_req()
1825 return -EINVAL; in sg_start_req()
1831 res = blk_rq_map_user(q, rq, md, hp->dxferp, in sg_start_req()
1832 hp->dxfer_len, GFP_ATOMIC); in sg_start_req()
1835 srp->bio = rq->bio; in sg_start_req()
1838 req_schp->dio_in_use = 1; in sg_start_req()
1839 hp->info |= SG_INFO_DIRECT_IO; in sg_start_req()
1846 sg_finish_rem_req(Sg_request *srp) in sg_finish_rem_req() argument
1850 Sg_fd *sfp = srp->parentfp; in sg_finish_rem_req()
1851 Sg_scatter_hold *req_schp = &srp->data; in sg_finish_rem_req()
1853 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_finish_rem_req()
1855 (int) srp->res_used)); in sg_finish_rem_req()
1856 if (srp->bio) in sg_finish_rem_req()
1857 ret = blk_rq_unmap_user(srp->bio); in sg_finish_rem_req()
1859 if (srp->rq) { in sg_finish_rem_req()
1860 scsi_req_free_cmd(scsi_req(srp->rq)); in sg_finish_rem_req()
1861 blk_put_request(srp->rq); in sg_finish_rem_req()
1864 if (srp->res_used) in sg_finish_rem_req()
1865 sg_unlink_reserve(sfp, srp); in sg_finish_rem_req()
1878 schp->pages = kzalloc(sg_bufflen, gfp_flags); in sg_build_sgat()
1879 if (!schp->pages) in sg_build_sgat()
1880 return -ENOMEM; in sg_build_sgat()
1881 schp->sglist_len = sg_bufflen; in sg_build_sgat()
1889 int sg_tablesize = sfp->parentdp->sg_tablesize; in sg_build_indirect()
1892 struct sg_device *sdp = sfp->parentdp; in sg_build_indirect()
1895 return -EFAULT; in sg_build_indirect()
1900 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1907 return mx_sc_elems; /* most likely -ENOMEM */ in sg_build_indirect()
1918 if (sdp->device->host->unchecked_isa_dma) in sg_build_indirect()
1926 k++, rem_sz -= ret_sz) { in sg_build_indirect()
1931 schp->pages[k] = alloc_pages(gfp_mask, order); in sg_build_indirect()
1932 if (!schp->pages[k]) in sg_build_indirect()
1942 SCSI_LOG_TIMEOUT(5, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1947 schp->page_order = order; in sg_build_indirect()
1948 schp->k_use_sg = k; in sg_build_indirect()
1949 SCSI_LOG_TIMEOUT(5, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_indirect()
1953 schp->bufflen = blk_size; in sg_build_indirect()
1955 return -ENOMEM; in sg_build_indirect()
1959 __free_pages(schp->pages[i], order); in sg_build_indirect()
1961 if (--order >= 0) in sg_build_indirect()
1964 return -ENOMEM; in sg_build_indirect()
1970 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_remove_scat()
1971 "sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg)); in sg_remove_scat()
1972 if (schp->pages && schp->sglist_len > 0) { in sg_remove_scat()
1973 if (!schp->dio_in_use) { in sg_remove_scat()
1976 for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) { in sg_remove_scat()
1978 sg_printk(KERN_INFO, sfp->parentdp, in sg_remove_scat()
1980 k, schp->pages[k])); in sg_remove_scat()
1981 __free_pages(schp->pages[k], schp->page_order); in sg_remove_scat()
1984 kfree(schp->pages); in sg_remove_scat()
1991 sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer) in sg_read_oxfer() argument
1993 Sg_scatter_hold *schp = &srp->data; in sg_read_oxfer()
1996 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, srp->parentfp->parentdp, in sg_read_oxfer()
2002 num = 1 << (PAGE_SHIFT + schp->page_order); in sg_read_oxfer()
2003 for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) { in sg_read_oxfer()
2005 if (copy_to_user(outp, page_address(schp->pages[k]), in sg_read_oxfer()
2007 return -EFAULT; in sg_read_oxfer()
2010 if (copy_to_user(outp, page_address(schp->pages[k]), in sg_read_oxfer()
2012 return -EFAULT; in sg_read_oxfer()
2013 num_read_xfer -= num; in sg_read_oxfer()
2026 Sg_scatter_hold *schp = &sfp->reserve; in sg_build_reserve()
2028 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_build_reserve()
2042 sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size) in sg_link_reserve() argument
2044 Sg_scatter_hold *req_schp = &srp->data; in sg_link_reserve()
2045 Sg_scatter_hold *rsv_schp = &sfp->reserve; in sg_link_reserve()
2048 srp->res_used = 1; in sg_link_reserve()
2049 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, in sg_link_reserve()
2053 num = 1 << (PAGE_SHIFT + rsv_schp->page_order); in sg_link_reserve()
2054 for (k = 0; k < rsv_schp->k_use_sg; k++) { in sg_link_reserve()
2056 req_schp->k_use_sg = k + 1; in sg_link_reserve()
2057 req_schp->sglist_len = rsv_schp->sglist_len; in sg_link_reserve()
2058 req_schp->pages = rsv_schp->pages; in sg_link_reserve()
2060 req_schp->bufflen = size; in sg_link_reserve()
2061 req_schp->page_order = rsv_schp->page_order; in sg_link_reserve()
2064 rem -= num; in sg_link_reserve()
2067 if (k >= rsv_schp->k_use_sg) in sg_link_reserve()
2068 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp, in sg_link_reserve()
2073 sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp) in sg_unlink_reserve() argument
2075 Sg_scatter_hold *req_schp = &srp->data; in sg_unlink_reserve()
2077 SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, srp->parentfp->parentdp, in sg_unlink_reserve()
2078 "sg_unlink_reserve: req->k_use_sg=%d\n", in sg_unlink_reserve()
2079 (int) req_schp->k_use_sg)); in sg_unlink_reserve()
2080 req_schp->k_use_sg = 0; in sg_unlink_reserve()
2081 req_schp->bufflen = 0; in sg_unlink_reserve()
2082 req_schp->pages = NULL; in sg_unlink_reserve()
2083 req_schp->page_order = 0; in sg_unlink_reserve()
2084 req_schp->sglist_len = 0; in sg_unlink_reserve()
2085 srp->res_used = 0; in sg_unlink_reserve()
2087 sfp->res_in_use = 0; in sg_unlink_reserve()
2097 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2098 list_for_each_entry(resp, &sfp->rq_list, entry) { in sg_get_rq_mark()
2100 if ((!resp->sg_io_owned) && in sg_get_rq_mark()
2101 ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { in sg_get_rq_mark()
2102 switch (resp->done) { in sg_get_rq_mark()
2107 resp->done = 2; /* guard against other readers */ in sg_get_rq_mark()
2108 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2115 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_get_rq_mark()
2125 Sg_request *rp = sfp->req_arr; in sg_add_request()
2127 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_add_request()
2128 if (!list_empty(&sfp->rq_list)) { in sg_add_request()
2129 if (!sfp->cmd_q) in sg_add_request()
2133 if (!rp->parentfp) in sg_add_request()
2140 rp->parentfp = sfp; in sg_add_request()
2141 rp->header.duration = jiffies_to_msecs(jiffies); in sg_add_request()
2142 list_add_tail(&rp->entry, &sfp->rq_list); in sg_add_request()
2143 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_add_request()
2146 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_add_request()
2152 sg_remove_request(Sg_fd * sfp, Sg_request * srp) in sg_remove_request() argument
2157 if (!sfp || !srp || list_empty(&sfp->rq_list)) in sg_remove_request()
2159 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_remove_request()
2160 if (!list_empty(&srp->entry)) { in sg_remove_request()
2161 list_del(&srp->entry); in sg_remove_request()
2162 srp->parentfp = NULL; in sg_remove_request()
2165 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_remove_request()
2170 * return other than -ENODEV. in sg_remove_request()
2172 if (unlikely(atomic_read(&sfp->parentdp->detaching))) in sg_remove_request()
2173 wake_up_interruptible_all(&sfp->read_wait); in sg_remove_request()
2187 return ERR_PTR(-ENOMEM); in sg_add_sfp()
2189 init_waitqueue_head(&sfp->read_wait); in sg_add_sfp()
2190 rwlock_init(&sfp->rq_list_lock); in sg_add_sfp()
2191 INIT_LIST_HEAD(&sfp->rq_list); in sg_add_sfp()
2192 kref_init(&sfp->f_ref); in sg_add_sfp()
2193 mutex_init(&sfp->f_mutex); in sg_add_sfp()
2194 sfp->timeout = SG_DEFAULT_TIMEOUT; in sg_add_sfp()
2195 sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER; in sg_add_sfp()
2196 sfp->force_packid = SG_DEF_FORCE_PACK_ID; in sg_add_sfp()
2197 sfp->cmd_q = SG_DEF_COMMAND_Q; in sg_add_sfp()
2198 sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; in sg_add_sfp()
2199 sfp->parentdp = sdp; in sg_add_sfp()
2200 write_lock_irqsave(&sdp->sfd_lock, iflags); in sg_add_sfp()
2201 if (atomic_read(&sdp->detaching)) { in sg_add_sfp()
2202 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_add_sfp()
2204 return ERR_PTR(-ENODEV); in sg_add_sfp()
2206 list_add_tail(&sfp->sfd_siblings, &sdp->sfds); in sg_add_sfp()
2207 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_add_sfp()
2214 max_sectors_bytes(sdp->device->request_queue)); in sg_add_sfp()
2218 sfp->reserve.bufflen, in sg_add_sfp()
2219 sfp->reserve.k_use_sg)); in sg_add_sfp()
2221 kref_get(&sdp->d_ref); in sg_add_sfp()
2230 struct sg_device *sdp = sfp->parentdp; in sg_remove_sfp_usercontext()
2231 Sg_request *srp; in sg_remove_sfp_usercontext() local
2235 write_lock_irqsave(&sfp->rq_list_lock, iflags); in sg_remove_sfp_usercontext()
2236 while (!list_empty(&sfp->rq_list)) { in sg_remove_sfp_usercontext()
2237 srp = list_first_entry(&sfp->rq_list, Sg_request, entry); in sg_remove_sfp_usercontext()
2238 sg_finish_rem_req(srp); in sg_remove_sfp_usercontext()
2239 list_del(&srp->entry); in sg_remove_sfp_usercontext()
2240 srp->parentfp = NULL; in sg_remove_sfp_usercontext()
2242 write_unlock_irqrestore(&sfp->rq_list_lock, iflags); in sg_remove_sfp_usercontext()
2244 if (sfp->reserve.bufflen > 0) { in sg_remove_sfp_usercontext()
2247 (int) sfp->reserve.bufflen, in sg_remove_sfp_usercontext()
2248 (int) sfp->reserve.k_use_sg)); in sg_remove_sfp_usercontext()
2249 sg_remove_scat(sfp, &sfp->reserve); in sg_remove_sfp_usercontext()
2256 scsi_device_put(sdp->device); in sg_remove_sfp_usercontext()
2257 kref_put(&sdp->d_ref, sg_device_destroy); in sg_remove_sfp_usercontext()
2265 struct sg_device *sdp = sfp->parentdp; in sg_remove_sfp()
2268 write_lock_irqsave(&sdp->sfd_lock, iflags); in sg_remove_sfp()
2269 list_del(&sfp->sfd_siblings); in sg_remove_sfp()
2270 write_unlock_irqrestore(&sdp->sfd_lock, iflags); in sg_remove_sfp()
2272 INIT_WORK(&sfp->ew.work, sg_remove_sfp_usercontext); in sg_remove_sfp()
2273 schedule_work(&sfp->ew.work); in sg_remove_sfp()
2291 int k = -1; in sg_last_dev()
2316 sdp = ERR_PTR(-ENXIO); in sg_get_dev()
2317 else if (atomic_read(&sdp->detaching)) { in sg_get_dev()
2318 /* If sdp->detaching, then the refcount may already be 0, in in sg_get_dev()
2321 sdp = ERR_PTR(-ENODEV); in sg_get_dev()
2323 kref_get(&sdp->d_ref); in sg_get_dev()
2405 seq_printf(s, "%d\n", *((int *)s->private)); in sg_proc_seq_show_int()
2421 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) in sg_proc_write_adio()
2422 return -EACCES; in sg_proc_write_adio()
2442 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) in sg_proc_write_dressz()
2443 return -EACCES; in sg_proc_write_dressz()
2452 return -ERANGE; in sg_proc_write_dressz()
2477 s->private = it; in dev_seq_start()
2481 it->index = *pos; in dev_seq_start()
2482 it->max = sg_last_dev(); in dev_seq_start()
2483 if (it->index >= it->max) in dev_seq_start()
2490 struct sg_proc_deviter * it = s->private; in dev_seq_next()
2492 *pos = ++it->index; in dev_seq_next()
2493 return (it->index < it->max) ? it : NULL; in dev_seq_next()
2498 kfree(s->private); in dev_seq_stop()
2509 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_dev()
2510 if ((NULL == sdp) || (NULL == sdp->device) || in sg_proc_seq_show_dev()
2511 (atomic_read(&sdp->detaching))) in sg_proc_seq_show_dev()
2512 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()
2514 scsidp = sdp->device; in sg_proc_seq_show_dev()
2516 scsidp->host->host_no, scsidp->channel, in sg_proc_seq_show_dev()
2517 scsidp->id, scsidp->lun, (int) scsidp->type, in sg_proc_seq_show_dev()
2519 (int) scsidp->queue_depth, in sg_proc_seq_show_dev()
2520 (int) atomic_read(&scsidp->device_busy), in sg_proc_seq_show_dev()
2535 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_devstrs()
2536 scsidp = sdp ? sdp->device : NULL; in sg_proc_seq_show_devstrs()
2537 if (sdp && scsidp && (!atomic_read(&sdp->detaching))) in sg_proc_seq_show_devstrs()
2539 scsidp->vendor, scsidp->model, scsidp->rev); in sg_proc_seq_show_devstrs()
2550 Sg_request *srp; in sg_proc_debug_helper() local
2557 list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { in sg_proc_debug_helper()
2559 read_lock(&fp->rq_list_lock); /* irqs already disabled */ in sg_proc_debug_helper()
2562 jiffies_to_msecs(fp->timeout), in sg_proc_debug_helper()
2563 fp->reserve.bufflen, in sg_proc_debug_helper()
2564 (int) fp->reserve.k_use_sg, in sg_proc_debug_helper()
2565 (int) sdp->device->host->unchecked_isa_dma); in sg_proc_debug_helper()
2567 (int) fp->cmd_q, (int) fp->force_packid, in sg_proc_debug_helper()
2568 (int) fp->keep_orphan); in sg_proc_debug_helper()
2569 list_for_each_entry(srp, &fp->rq_list, entry) { in sg_proc_debug_helper()
2570 hp = &srp->header; in sg_proc_debug_helper()
2571 new_interface = (hp->interface_id == '\0') ? 0 : 1; in sg_proc_debug_helper()
2572 if (srp->res_used) { in sg_proc_debug_helper()
2574 (SG_FLAG_MMAP_IO & hp->flags)) in sg_proc_debug_helper()
2579 if (SG_INFO_DIRECT_IO_MASK & hp->info) in sg_proc_debug_helper()
2585 blen = srp->data.bufflen; in sg_proc_debug_helper()
2586 usg = srp->data.k_use_sg; in sg_proc_debug_helper()
2587 seq_puts(s, srp->done ? in sg_proc_debug_helper()
2588 ((1 == srp->done) ? "rcv:" : "fin:") in sg_proc_debug_helper()
2591 srp->header.pack_id, blen); in sg_proc_debug_helper()
2592 if (srp->done) in sg_proc_debug_helper()
2593 seq_printf(s, " dur=%d", hp->duration); in sg_proc_debug_helper()
2597 (new_interface ? hp->timeout : in sg_proc_debug_helper()
2598 jiffies_to_msecs(fp->timeout)), in sg_proc_debug_helper()
2599 (ms > hp->duration ? ms - hp->duration : 0)); in sg_proc_debug_helper()
2602 (int) srp->data.cmd_opcode); in sg_proc_debug_helper()
2604 if (list_empty(&fp->rq_list)) in sg_proc_debug_helper()
2606 read_unlock(&fp->rq_list_lock); in sg_proc_debug_helper()
2616 if (it && (0 == it->index)) in sg_proc_seq_show_debug()
2618 (int)it->max, sg_big_buff); in sg_proc_seq_show_debug()
2621 sdp = it ? sg_lookup_dev(it->index) : NULL; in sg_proc_seq_show_debug()
2624 read_lock(&sdp->sfd_lock); in sg_proc_seq_show_debug()
2625 if (!list_empty(&sdp->sfds)) { in sg_proc_seq_show_debug()
2626 seq_printf(s, " >>> device=%s ", sdp->disk->disk_name); in sg_proc_seq_show_debug()
2627 if (atomic_read(&sdp->detaching)) in sg_proc_seq_show_debug()
2629 else if (sdp->device) { in sg_proc_seq_show_debug()
2630 struct scsi_device *scsidp = sdp->device; in sg_proc_seq_show_debug()
2633 scsidp->host->host_no, in sg_proc_seq_show_debug()
2634 scsidp->channel, scsidp->id, in sg_proc_seq_show_debug()
2635 scsidp->lun, in sg_proc_seq_show_debug()
2636 scsidp->host->hostt->emulated); in sg_proc_seq_show_debug()
2639 sdp->sg_tablesize, sdp->exclude, sdp->open_cnt); in sg_proc_seq_show_debug()
2642 read_unlock(&sdp->sfd_lock); in sg_proc_seq_show_debug()