Deleted Added
full compact
scsi_target.c (167082) scsi_target.c (168752)
1/*-
2 * Generic SCSI Target Kernel Mode Driver
3 *
4 * Copyright (c) 2002 Nate Lawson.
5 * Copyright (c) 1998, 1999, 2001, 2002 Justin T. Gibbs.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Generic SCSI Target Kernel Mode Driver
3 *
4 * Copyright (c) 2002 Nate Lawson.
5 * Copyright (c) 1998, 1999, 2001, 2002 Justin T. Gibbs.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_target.c 167082 2007-02-27 17:15:39Z jhb $");
31__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_target.c 168752 2007-04-15 08:49:19Z scottl $");
32
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/kernel.h>
37#include <sys/conf.h>
38#include <sys/malloc.h>
39#include <sys/poll.h>
40#include <sys/vnode.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/devicestat.h>
44#include <sys/proc.h>
45
46#include <cam/cam.h>
47#include <cam/cam_ccb.h>
48#include <cam/cam_periph.h>
49#include <cam/cam_xpt_periph.h>
32
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/kernel.h>
37#include <sys/conf.h>
38#include <sys/malloc.h>
39#include <sys/poll.h>
40#include <sys/vnode.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/devicestat.h>
44#include <sys/proc.h>
45
46#include <cam/cam.h>
47#include <cam/cam_ccb.h>
48#include <cam/cam_periph.h>
49#include <cam/cam_xpt_periph.h>
50#include <cam/cam_sim.h>
50#include <cam/scsi/scsi_targetio.h>
51
52/* Transaction information attached to each CCB sent by the user */
53struct targ_cmd_descr {
54 struct cam_periph_map_info mapinfo;
55 TAILQ_ENTRY(targ_cmd_descr) tqe;
56 union ccb *user_ccb;
57 int priority;

--- 97 unchanged lines hidden (view full) ---

155{
156 targinit, "targ",
157 TAILQ_HEAD_INITIALIZER(targdriver.units), /* generation */ 0
158};
159PERIPHDRIVER_DECLARE(targ, targdriver);
160
161static MALLOC_DEFINE(M_TARG, "TARG", "TARG data");
162
51#include <cam/scsi/scsi_targetio.h>
52
53/* Transaction information attached to each CCB sent by the user */
54struct targ_cmd_descr {
55 struct cam_periph_map_info mapinfo;
56 TAILQ_ENTRY(targ_cmd_descr) tqe;
57 union ccb *user_ccb;
58 int priority;

--- 97 unchanged lines hidden (view full) ---

156{
157 targinit, "targ",
158 TAILQ_HEAD_INITIALIZER(targdriver.units), /* generation */ 0
159};
160PERIPHDRIVER_DECLARE(targ, targdriver);
161
162static MALLOC_DEFINE(M_TARG, "TARG", "TARG data");
163
163/* Create softc and initialize it. Only one proc can open each targ device. */
164/*
165 * Create softc and initialize it. Only one proc can open each targ device.
166 * There is no locking here because a periph doesn't get created until an
167 * ioctl is issued to do so, and that can't happen until this method returns.
168 */
164static int
165targopen(struct cdev *dev, int flags, int fmt, struct thread *td)
166{
167 struct targ_softc *softc;
168
169 if (dev->si_drv1 != 0) {
170 return (EBUSY);
171 }

--- 22 unchanged lines hidden (view full) ---

194 return (0);
195}
196
197/* Disable LUN if enabled and teardown softc */
198static int
199targclose(struct cdev *dev, int flag, int fmt, struct thread *td)
200{
201 struct targ_softc *softc;
169static int
170targopen(struct cdev *dev, int flags, int fmt, struct thread *td)
171{
172 struct targ_softc *softc;
173
174 if (dev->si_drv1 != 0) {
175 return (EBUSY);
176 }

--- 22 unchanged lines hidden (view full) ---

199 return (0);
200}
201
202/* Disable LUN if enabled and teardown softc */
203static int
204targclose(struct cdev *dev, int flag, int fmt, struct thread *td)
205{
206 struct targ_softc *softc;
207 struct cam_periph *periph;
202 int error;
203
204 softc = (struct targ_softc *)dev->si_drv1;
208 int error;
209
210 softc = (struct targ_softc *)dev->si_drv1;
211 if ((softc->periph == NULL) ||
212 (softc->state & TARG_STATE_LUN_ENABLED) == 0) {
213 destroy_dev(dev);
214 FREE(softc, M_TARG);
215 return (0);
216 }
217
218 /*
219 * Acquire a hold on the periph so that it doesn't go away before
220 * we are ready at the end of the function.
221 */
222 periph = softc->periph;
223 cam_periph_acquire(periph);
224 cam_periph_lock(periph);
205 error = targdisable(softc);
206 if (error == CAM_REQ_CMP) {
207 dev->si_drv1 = 0;
208 if (softc->periph != NULL) {
209 cam_periph_invalidate(softc->periph);
210 softc->periph = NULL;
211 }
212 destroy_dev(dev);
213 FREE(softc, M_TARG);
214 }
225 error = targdisable(softc);
226 if (error == CAM_REQ_CMP) {
227 dev->si_drv1 = 0;
228 if (softc->periph != NULL) {
229 cam_periph_invalidate(softc->periph);
230 softc->periph = NULL;
231 }
232 destroy_dev(dev);
233 FREE(softc, M_TARG);
234 }
235 cam_periph_unlock(periph);
236 cam_periph_release(periph);
237
215 return (error);
216}
217
218/* Enable/disable LUNs, set debugging level */
219static int
220targioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
221{
222 struct targ_softc *softc;
223 cam_status status;
224
225 softc = (struct targ_softc *)dev->si_drv1;
226
227 switch (cmd) {
228 case TARGIOCENABLE:
229 {
230 struct ioc_enable_lun *new_lun;
231 struct cam_path *path;
238 return (error);
239}
240
241/* Enable/disable LUNs, set debugging level */
242static int
243targioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
244{
245 struct targ_softc *softc;
246 cam_status status;
247
248 softc = (struct targ_softc *)dev->si_drv1;
249
250 switch (cmd) {
251 case TARGIOCENABLE:
252 {
253 struct ioc_enable_lun *new_lun;
254 struct cam_path *path;
255 struct cam_sim *sim;
232
233 new_lun = (struct ioc_enable_lun *)addr;
256
257 new_lun = (struct ioc_enable_lun *)addr;
234 status = xpt_create_path(&path, /*periph*/NULL,
235 new_lun->path_id,
236 new_lun->target_id,
237 new_lun->lun_id);
258 status = xpt_create_path_unlocked(&path, /*periph*/NULL,
259 new_lun->path_id,
260 new_lun->target_id,
261 new_lun->lun_id);
238 if (status != CAM_REQ_CMP) {
239 printf("Couldn't create path, status %#x\n", status);
240 break;
241 }
262 if (status != CAM_REQ_CMP) {
263 printf("Couldn't create path, status %#x\n", status);
264 break;
265 }
266 sim = xpt_path_sim(path);
267 mtx_lock(sim->mtx);
242 status = targenable(softc, path, new_lun->grp6_len,
243 new_lun->grp7_len);
244 xpt_free_path(path);
268 status = targenable(softc, path, new_lun->grp6_len,
269 new_lun->grp7_len);
270 xpt_free_path(path);
271 mtx_unlock(sim->mtx);
245 break;
246 }
247 case TARGIOCDISABLE:
272 break;
273 }
274 case TARGIOCDISABLE:
275 if (softc->periph == NULL) {
276 status = CAM_DEV_NOT_THERE;
277 break;
278 }
279 cam_periph_lock(softc->periph);
248 status = targdisable(softc);
280 status = targdisable(softc);
281 cam_periph_unlock(softc->periph);
249 break;
250 case TARGIOCDEBUG:
251 {
252#ifdef CAMDEBUG
253 struct ccb_debug cdbg;
254
282 break;
283 case TARGIOCDEBUG:
284 {
285#ifdef CAMDEBUG
286 struct ccb_debug cdbg;
287
288 /* If no periph available, disallow debugging changes */
289 if ((softc->state & TARG_STATE_LUN_ENABLED) == 0) {
290 status = CAM_DEV_NOT_THERE;
291 break;
292 }
255 bzero(&cdbg, sizeof cdbg);
256 if (*((int *)addr) != 0)
257 cdbg.flags = CAM_DEBUG_PERIPH;
258 else
259 cdbg.flags = CAM_DEBUG_NONE;
293 bzero(&cdbg, sizeof cdbg);
294 if (*((int *)addr) != 0)
295 cdbg.flags = CAM_DEBUG_PERIPH;
296 else
297 cdbg.flags = CAM_DEBUG_NONE;
298 cam_periph_lock(softc->periph);
260 xpt_setup_ccb(&cdbg.ccb_h, softc->path, /*priority*/0);
261 cdbg.ccb_h.func_code = XPT_DEBUG;
262 cdbg.ccb_h.cbfcnp = targdone;
263
299 xpt_setup_ccb(&cdbg.ccb_h, softc->path, /*priority*/0);
300 cdbg.ccb_h.func_code = XPT_DEBUG;
301 cdbg.ccb_h.cbfcnp = targdone;
302
264 /* If no periph available, disallow debugging changes */
265 if ((softc->state & TARG_STATE_LUN_ENABLED) == 0) {
266 status = CAM_DEV_NOT_THERE;
267 break;
268 }
269 xpt_action((union ccb *)&cdbg);
303 xpt_action((union ccb *)&cdbg);
304 cam_periph_unlock(softc->periph);
270 status = cdbg.ccb_h.status & CAM_STATUS_MASK;
271#else
272 status = CAM_FUNC_NOTAVAIL;
273#endif
274 break;
275 }
276 default:
277 status = CAM_PROVIDE_FAIL;

--- 11 unchanged lines hidden (view full) ---

289 int revents;
290
291 softc = (struct targ_softc *)dev->si_drv1;
292
293 /* Poll for write() is always ok. */
294 revents = poll_events & (POLLOUT | POLLWRNORM);
295 if ((poll_events & (POLLIN | POLLRDNORM)) != 0) {
296 /* Poll for read() depends on user and abort queues. */
305 status = cdbg.ccb_h.status & CAM_STATUS_MASK;
306#else
307 status = CAM_FUNC_NOTAVAIL;
308#endif
309 break;
310 }
311 default:
312 status = CAM_PROVIDE_FAIL;

--- 11 unchanged lines hidden (view full) ---

324 int revents;
325
326 softc = (struct targ_softc *)dev->si_drv1;
327
328 /* Poll for write() is always ok. */
329 revents = poll_events & (POLLOUT | POLLWRNORM);
330 if ((poll_events & (POLLIN | POLLRDNORM)) != 0) {
331 /* Poll for read() depends on user and abort queues. */
332 cam_periph_lock(softc->periph);
297 if (!TAILQ_EMPTY(&softc->user_ccb_queue) ||
298 !TAILQ_EMPTY(&softc->abort_queue)) {
299 revents |= poll_events & (POLLIN | POLLRDNORM);
300 }
333 if (!TAILQ_EMPTY(&softc->user_ccb_queue) ||
334 !TAILQ_EMPTY(&softc->abort_queue)) {
335 revents |= poll_events & (POLLIN | POLLRDNORM);
336 }
337 cam_periph_unlock(softc->periph);
301 /* Only sleep if the user didn't poll for write. */
302 if (revents == 0)
303 selrecord(td, &softc->read_select);
304 }
305
306 return (revents);
307}
308

--- 21 unchanged lines hidden (view full) ---

330/* Notify the user's kqueue when the user queue or abort queue gets a CCB */
331static int
332targreadfilt(struct knote *kn, long hint)
333{
334 struct targ_softc *softc;
335 int retval;
336
337 softc = (struct targ_softc *)kn->kn_hook;
338 /* Only sleep if the user didn't poll for write. */
339 if (revents == 0)
340 selrecord(td, &softc->read_select);
341 }
342
343 return (revents);
344}
345

--- 21 unchanged lines hidden (view full) ---

367/* Notify the user's kqueue when the user queue or abort queue gets a CCB */
368static int
369targreadfilt(struct knote *kn, long hint)
370{
371 struct targ_softc *softc;
372 int retval;
373
374 softc = (struct targ_softc *)kn->kn_hook;
375 cam_periph_lock(softc->periph);
338 retval = !TAILQ_EMPTY(&softc->user_ccb_queue) ||
339 !TAILQ_EMPTY(&softc->abort_queue);
376 retval = !TAILQ_EMPTY(&softc->user_ccb_queue) ||
377 !TAILQ_EMPTY(&softc->abort_queue);
378 cam_periph_unlock(softc->periph);
340 return (retval);
341}
342
343/* Send the HBA the enable/disable message */
344static cam_status
345targendislun(struct cam_path *path, int enable, int grp6_len, int grp7_len)
346{
347 struct ccb_en_lun en_ccb;

--- 179 unchanged lines hidden (view full) ---

527 if (priority == -1) {
528 error = EINVAL;
529 break;
530 }
531 func_code = fuword32(&user_ccb->ccb_h.func_code);
532 switch (func_code) {
533 case XPT_ACCEPT_TARGET_IO:
534 case XPT_IMMED_NOTIFY:
379 return (retval);
380}
381
382/* Send the HBA the enable/disable message */
383static cam_status
384targendislun(struct cam_path *path, int enable, int grp6_len, int grp7_len)
385{
386 struct ccb_en_lun en_ccb;

--- 179 unchanged lines hidden (view full) ---

566 if (priority == -1) {
567 error = EINVAL;
568 break;
569 }
570 func_code = fuword32(&user_ccb->ccb_h.func_code);
571 switch (func_code) {
572 case XPT_ACCEPT_TARGET_IO:
573 case XPT_IMMED_NOTIFY:
574 cam_periph_lock(softc->periph);
535 ccb = targgetccb(softc, func_code, priority);
536 descr = (struct targ_cmd_descr *)ccb->ccb_h.targ_descr;
537 descr->user_ccb = user_ccb;
538 descr->func_code = func_code;
539 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
540 ("Sent ATIO/INOT (%p)\n", user_ccb));
541 xpt_action(ccb);
542 TAILQ_INSERT_TAIL(&softc->pending_ccb_queue,
543 &ccb->ccb_h,
544 periph_links.tqe);
575 ccb = targgetccb(softc, func_code, priority);
576 descr = (struct targ_cmd_descr *)ccb->ccb_h.targ_descr;
577 descr->user_ccb = user_ccb;
578 descr->func_code = func_code;
579 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
580 ("Sent ATIO/INOT (%p)\n", user_ccb));
581 xpt_action(ccb);
582 TAILQ_INSERT_TAIL(&softc->pending_ccb_queue,
583 &ccb->ccb_h,
584 periph_links.tqe);
585 cam_periph_unlock(softc->periph);
545 break;
546 default:
586 break;
587 default:
588 cam_periph_lock(softc->periph);
547 if ((func_code & XPT_FC_QUEUED) != 0) {
548 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
549 ("Sending queued ccb %#x (%p)\n",
550 func_code, user_ccb));
551 descr = targgetdescr(softc);
552 descr->user_ccb = user_ccb;
553 descr->priority = priority;
554 descr->func_code = func_code;

--- 9 unchanged lines hidden (view full) ---

564 ccb->ccb_h.targ_descr;
565 descr->user_ccb = user_ccb;
566 descr->priority = priority;
567 descr->func_code = func_code;
568 if (targusermerge(softc, descr, ccb) != EFAULT)
569 targsendccb(softc, ccb, descr);
570 targreturnccb(softc, ccb);
571 }
589 if ((func_code & XPT_FC_QUEUED) != 0) {
590 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
591 ("Sending queued ccb %#x (%p)\n",
592 func_code, user_ccb));
593 descr = targgetdescr(softc);
594 descr->user_ccb = user_ccb;
595 descr->priority = priority;
596 descr->func_code = func_code;

--- 9 unchanged lines hidden (view full) ---

606 ccb->ccb_h.targ_descr;
607 descr->user_ccb = user_ccb;
608 descr->priority = priority;
609 descr->func_code = func_code;
610 if (targusermerge(softc, descr, ccb) != EFAULT)
611 targsendccb(softc, ccb, descr);
612 targreturnccb(softc, ccb);
613 }
614 cam_periph_unlock(softc->periph);
572 break;
573 }
574 write_len += sizeof(user_ccb);
575 }
576
577 /*
578 * If we've successfully taken in some amount of
579 * data, return success for that data first. If

--- 211 unchanged lines hidden (view full) ---

791 struct descr_queue *abort_queue;
792 struct targ_cmd_descr *user_descr;
793 struct targ_softc *softc;
794 struct ccb_queue *user_queue;
795 struct ccb_hdr *ccb_h;
796 union ccb *user_ccb;
797 int read_len, error;
798
615 break;
616 }
617 write_len += sizeof(user_ccb);
618 }
619
620 /*
621 * If we've successfully taken in some amount of
622 * data, return success for that data first. If

--- 211 unchanged lines hidden (view full) ---

834 struct descr_queue *abort_queue;
835 struct targ_cmd_descr *user_descr;
836 struct targ_softc *softc;
837 struct ccb_queue *user_queue;
838 struct ccb_hdr *ccb_h;
839 union ccb *user_ccb;
840 int read_len, error;
841
799 mtx_lock(&Giant);
800
801 error = 0;
802 read_len = 0;
803 softc = (struct targ_softc *)dev->si_drv1;
804 user_queue = &softc->user_ccb_queue;
805 abort_queue = &softc->abort_queue;
806 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("targread\n"));
807
808 /* If no data is available, wait or return immediately */
842 error = 0;
843 read_len = 0;
844 softc = (struct targ_softc *)dev->si_drv1;
845 user_queue = &softc->user_ccb_queue;
846 abort_queue = &softc->abort_queue;
847 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("targread\n"));
848
849 /* If no data is available, wait or return immediately */
850 cam_periph_lock(softc->periph);
809 ccb_h = TAILQ_FIRST(user_queue);
810 user_descr = TAILQ_FIRST(abort_queue);
811 while (ccb_h == NULL && user_descr == NULL) {
812 if ((ioflag & IO_NDELAY) == 0) {
851 ccb_h = TAILQ_FIRST(user_queue);
852 user_descr = TAILQ_FIRST(abort_queue);
853 while (ccb_h == NULL && user_descr == NULL) {
854 if ((ioflag & IO_NDELAY) == 0) {
813 error = tsleep(user_queue,
855 error = msleep(user_queue, softc->periph->sim->mtx,
814 PRIBIO | PCATCH, "targrd", 0);
815 ccb_h = TAILQ_FIRST(user_queue);
816 user_descr = TAILQ_FIRST(abort_queue);
817 if (error != 0) {
818 if (error == ERESTART) {
819 continue;
820 } else {
821 goto read_fail;
822 }
823 }
824 } else {
856 PRIBIO | PCATCH, "targrd", 0);
857 ccb_h = TAILQ_FIRST(user_queue);
858 user_descr = TAILQ_FIRST(abort_queue);
859 if (error != 0) {
860 if (error == ERESTART) {
861 continue;
862 } else {
863 goto read_fail;
864 }
865 }
866 } else {
825 mtx_unlock(&Giant);
867 cam_periph_unlock(softc->periph);
826 return (EAGAIN);
827 }
828 }
829
830 /* Data is available so fill the user's buffer */
831 while (ccb_h != NULL) {
832 struct targ_cmd_descr *descr;
833
834 if (uio->uio_resid < sizeof(user_ccb))
835 break;
836 TAILQ_REMOVE(user_queue, ccb_h, periph_links.tqe);
837 descr = (struct targ_cmd_descr *)ccb_h->targ_descr;
838 user_ccb = descr->user_ccb;
839 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
840 ("targread ccb %p (%p)\n", ccb_h, user_ccb));
841 error = targreturnccb(softc, (union ccb *)ccb_h);
842 if (error != 0)
843 goto read_fail;
868 return (EAGAIN);
869 }
870 }
871
872 /* Data is available so fill the user's buffer */
873 while (ccb_h != NULL) {
874 struct targ_cmd_descr *descr;
875
876 if (uio->uio_resid < sizeof(user_ccb))
877 break;
878 TAILQ_REMOVE(user_queue, ccb_h, periph_links.tqe);
879 descr = (struct targ_cmd_descr *)ccb_h->targ_descr;
880 user_ccb = descr->user_ccb;
881 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
882 ("targread ccb %p (%p)\n", ccb_h, user_ccb));
883 error = targreturnccb(softc, (union ccb *)ccb_h);
884 if (error != 0)
885 goto read_fail;
886 cam_periph_unlock(softc->periph);
844 error = uiomove((caddr_t)&user_ccb, sizeof(user_ccb), uio);
887 error = uiomove((caddr_t)&user_ccb, sizeof(user_ccb), uio);
888 cam_periph_lock(softc->periph);
845 if (error != 0)
846 goto read_fail;
847 read_len += sizeof(user_ccb);
848
849 ccb_h = TAILQ_FIRST(user_queue);
850 }
851
852 /* Flush out any aborted descriptors */
853 while (user_descr != NULL) {
854 if (uio->uio_resid < sizeof(user_ccb))
855 break;
856 TAILQ_REMOVE(abort_queue, user_descr, tqe);
857 user_ccb = user_descr->user_ccb;
858 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
859 ("targread aborted descr %p (%p)\n",
860 user_descr, user_ccb));
861 suword(&user_ccb->ccb_h.status, CAM_REQ_ABORTED);
889 if (error != 0)
890 goto read_fail;
891 read_len += sizeof(user_ccb);
892
893 ccb_h = TAILQ_FIRST(user_queue);
894 }
895
896 /* Flush out any aborted descriptors */
897 while (user_descr != NULL) {
898 if (uio->uio_resid < sizeof(user_ccb))
899 break;
900 TAILQ_REMOVE(abort_queue, user_descr, tqe);
901 user_ccb = user_descr->user_ccb;
902 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
903 ("targread aborted descr %p (%p)\n",
904 user_descr, user_ccb));
905 suword(&user_ccb->ccb_h.status, CAM_REQ_ABORTED);
906 cam_periph_unlock(softc->periph);
862 error = uiomove((caddr_t)&user_ccb, sizeof(user_ccb), uio);
907 error = uiomove((caddr_t)&user_ccb, sizeof(user_ccb), uio);
908 cam_periph_lock(softc->periph);
863 if (error != 0)
864 goto read_fail;
865 read_len += sizeof(user_ccb);
866
867 user_descr = TAILQ_FIRST(abort_queue);
868 }
869
870 /*
871 * If we've successfully read some amount of data, don't report an
872 * error. If the error is persistent, it will be reported on the
873 * next read().
874 */
875 if (read_len == 0 && uio->uio_resid != 0)
876 error = ENOSPC;
877
878read_fail:
909 if (error != 0)
910 goto read_fail;
911 read_len += sizeof(user_ccb);
912
913 user_descr = TAILQ_FIRST(abort_queue);
914 }
915
916 /*
917 * If we've successfully read some amount of data, don't report an
918 * error. If the error is persistent, it will be reported on the
919 * next read().
920 */
921 if (read_len == 0 && uio->uio_resid != 0)
922 error = ENOSPC;
923
924read_fail:
879 mtx_unlock(&Giant);
925 cam_periph_unlock(softc->periph);
880 return (error);
881}
882
883/* Copy completed ccb back to the user */
884static int
885targreturnccb(struct targ_softc *softc, union ccb *ccb)
886{
887 struct targ_cmd_descr *descr;

--- 112 unchanged lines hidden (view full) ---

1000
1001/* Cancel all pending requests and CCBs awaiting work. */
1002static void
1003abort_all_pending(struct targ_softc *softc)
1004{
1005 struct targ_cmd_descr *descr;
1006 struct ccb_abort cab;
1007 struct ccb_hdr *ccb_h;
926 return (error);
927}
928
929/* Copy completed ccb back to the user */
930static int
931targreturnccb(struct targ_softc *softc, union ccb *ccb)
932{
933 struct targ_cmd_descr *descr;

--- 112 unchanged lines hidden (view full) ---

1046
1047/* Cancel all pending requests and CCBs awaiting work. */
1048static void
1049abort_all_pending(struct targ_softc *softc)
1050{
1051 struct targ_cmd_descr *descr;
1052 struct ccb_abort cab;
1053 struct ccb_hdr *ccb_h;
1054 struct cam_sim *sim;
1008
1009 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("abort_all_pending\n"));
1010
1011 /* First abort the descriptors awaiting resources */
1012 while ((descr = TAILQ_FIRST(&softc->work_queue)) != NULL) {
1013 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
1014 ("Aborting descr from workq %p\n", descr));
1015 TAILQ_REMOVE(&softc->work_queue, descr, tqe);

--- 16 unchanged lines hidden (view full) ---

1032 xpt_print(cab.ccb_h.path,
1033 "Unable to abort CCB, status %#x\n",
1034 cab.ccb_h.status);
1035 }
1036 }
1037
1038 /* If we aborted at least one pending CCB ok, wait for it. */
1039 if (cab.ccb_h.status == CAM_REQ_CMP) {
1055
1056 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("abort_all_pending\n"));
1057
1058 /* First abort the descriptors awaiting resources */
1059 while ((descr = TAILQ_FIRST(&softc->work_queue)) != NULL) {
1060 CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH,
1061 ("Aborting descr from workq %p\n", descr));
1062 TAILQ_REMOVE(&softc->work_queue, descr, tqe);

--- 16 unchanged lines hidden (view full) ---

1079 xpt_print(cab.ccb_h.path,
1080 "Unable to abort CCB, status %#x\n",
1081 cab.ccb_h.status);
1082 }
1083 }
1084
1085 /* If we aborted at least one pending CCB ok, wait for it. */
1086 if (cab.ccb_h.status == CAM_REQ_CMP) {
1040 tsleep(&softc->pending_ccb_queue,
1087 sim = xpt_path_sim(softc->path);
1088 msleep(&softc->pending_ccb_queue, sim->mtx,
1041 PRIBIO | PCATCH, "tgabrt", 0);
1042 }
1043
1044 /* If we aborted anything from the work queue, wakeup user. */
1045 if (!TAILQ_EMPTY(&softc->user_ccb_queue)
1046 || !TAILQ_EMPTY(&softc->abort_queue))
1047 notify_user(softc);
1048}

--- 91 unchanged lines hidden ---
1089 PRIBIO | PCATCH, "tgabrt", 0);
1090 }
1091
1092 /* If we aborted anything from the work queue, wakeup user. */
1093 if (!TAILQ_EMPTY(&softc->user_ccb_queue)
1094 || !TAILQ_EMPTY(&softc->abort_queue))
1095 notify_user(softc);
1096}

--- 91 unchanged lines hidden ---