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 --- |