1/* 2 * Copyright (c) 1997 Justin T. Gibbs. 3 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Kenneth D. Merry. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 32 unchanged lines hidden (view full) --- 41 * functioning of this software in any circumstances. 42 * 43 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 44 * 45 * from: cd.c,v 1.83 1997/05/04 15:24:22 joerg Exp $ 46 */ 47 48#include <sys/cdefs.h> |
49__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_cd.c 125975 2004-02-18 21:36:53Z phk $"); |
50 51#include "opt_cd.h" 52 53#include <sys/param.h> 54#include <sys/systm.h> 55#include <sys/kernel.h> 56#include <sys/bio.h> 57#include <sys/conf.h> --- 96 unchanged lines hidden (view full) --- 154 struct cam_periph *periph; 155 int minimum_command_size; 156 int outstanding_cmds; 157 struct task sysctl_task; 158 struct sysctl_ctx_list sysctl_ctx; 159 struct sysctl_oid *sysctl_tree; 160 STAILQ_HEAD(, cd_mode_params) mode_queue; 161 struct cd_tocdata toc; |
162 struct disk *disk; |
163}; 164 165struct cd_page_sizes { 166 int page; 167 int page_size; 168}; 169 170static struct cd_page_sizes cd_page_size_table[] = --- 322 unchanged lines hidden (view full) --- 493 494 STAILQ_REMOVE(&changerq, softc->changer, cdchanger, 495 changer_links); 496 xpt_print_path(periph->path); 497 printf("removing changer entry\n"); 498 free(softc->changer, M_DEVBUF); 499 num_changers--; 500 } |
501 disk_destroy(softc->disk); |
502 free(softc, M_DEVBUF); 503 splx(s); 504} 505 506static void 507cdasync(void *callback_arg, u_int32_t code, 508 struct cam_path *path, void *arg) 509{ --- 221 unchanged lines hidden (view full) --- 731 * yet. Unlike other SCSI peripheral drivers, we explicitly set 732 * the device type here to be CDROM, rather than just ORing in 733 * the device type. This is because this driver can attach to either 734 * CDROM or WORM devices, and we want this peripheral driver to 735 * show up in the devstat list as a CD peripheral driver, not a 736 * WORM peripheral driver. WORM drives will also have the WORM 737 * driver attached to them. 738 */ |
739 softc->disk = disk_alloc(); 740 softc->disk->d_devstat = devstat_new_entry("cd", |
741 periph->unit_number, 0, 742 DEVSTAT_BS_UNAVAILABLE, 743 DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_SCSI, 744 DEVSTAT_PRIORITY_CD); |
745 softc->disk->d_open = cdopen; 746 softc->disk->d_close = cdclose; 747 softc->disk->d_strategy = cdstrategy; 748 softc->disk->d_ioctl = cdioctl; 749 softc->disk->d_name = "cd"; 750 softc->disk->d_unit = periph->unit_number; 751 softc->disk->d_drv1 = periph; 752 softc->disk->d_flags = DISKFLAG_NEEDSGIANT; 753 disk_create(softc->disk, DISK_VERSION); |
754 755 /* 756 * Add an async callback so that we get 757 * notified if this device goes away. 758 */ 759 xpt_setup_ccb(&csa.ccb_h, periph->path, 760 /* priority */ 5); 761 csa.ccb_h.func_code = XPT_SASYNC_CB; --- 295 unchanged lines hidden (view full) --- 1057 1058 if ((softc->flags & CD_FLAG_DISC_REMOVABLE) != 0) 1059 cdprevent(periph, PR_ALLOW); 1060 1061 /* 1062 * Since we're closing this CD, mark the blocksize as unavailable. 1063 * It will be marked as available when the CD is opened again. 1064 */ |
1065 softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE; |
1066 1067 /* 1068 * We'll check the media and toc again at the next open(). 1069 */ 1070 softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC); 1071 1072 cam_periph_unlock(periph); 1073 cam_periph_release(periph); --- 277 unchanged lines hidden (view full) --- 1351 struct cd_softc *softc; 1352 struct cam_periph *periph; 1353 int error; 1354 1355 periph = xpt_path_periph(ccb->ccb_h.path); 1356 softc = (struct cd_softc *)periph->softc; 1357 1358 error = cam_periph_runccb(ccb, error_routine, cam_flags, sense_flags, |
1359 softc->disk->d_devstat); |
1360 1361 if (softc->flags & CD_FLAG_CHANGER) 1362 cdchangerschedule(softc); 1363 1364 return(error); 1365} 1366 1367static union ccb * --- 139 unchanged lines hidden (view full) --- 1507 splx(s); 1508 wakeup(&periph->ccb_list); 1509 } else if (bp == NULL) { 1510 splx(s); 1511 xpt_release_ccb(start_ccb); 1512 } else { 1513 bioq_remove(&softc->bio_queue, bp); 1514 |
1515 devstat_start_transaction_bio(softc->disk->d_devstat, bp); |
1516 1517 scsi_read_write(&start_ccb->csio, 1518 /*retries*/4, 1519 /* cbfcnp */ cddone, 1520 MSG_SIMPLE_Q_TAG, 1521 /* read */bp->bio_cmd == BIO_READ, 1522 /* byte2 */ 0, 1523 /* minimum_cmd_size */ 10, --- 139 unchanged lines hidden (view full) --- 1663 oldspl = splcam(); 1664 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); 1665 softc->outstanding_cmds--; 1666 splx(oldspl); 1667 1668 if (softc->flags & CD_FLAG_CHANGER) 1669 cdchangerschedule(softc); 1670 |
1671 biofinish(bp, softc->disk->d_devstat, 0); |
1672 break; 1673 } 1674 case CD_CCB_PROBE: 1675 { 1676 struct scsi_read_capacity_data *rdcap; 1677 char announce_buf[120]; /* 1678 * Currently (9/30/97) the 1679 * longest possible announce --- 1037 unchanged lines hidden (view full) --- 2717 struct ioc_toc_header *toch; 2718 struct cd_toc_single leadout; 2719 u_int32_t size, toclen; 2720 int error, num_entries, cdindex; 2721 2722 softc = (struct cd_softc *)periph->softc; 2723 2724 cdprevent(periph, PR_PREVENT); |
2725 softc->disk->d_maxsize = DFLTPHYS; 2726 softc->disk->d_sectorsize = 0; 2727 softc->disk->d_mediasize = 0; |
2728 2729 /* 2730 * Get the disc size and block size. If we can't get it, we don't 2731 * have media, most likely. 2732 */ 2733 if ((error = cdsize(periph, &size)) != 0) { 2734 softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC); 2735 cdprevent(periph, PR_ALLOW); --- 83 unchanged lines hidden (view full) --- 2819 if (softc->quirks & CD_Q_BCD_TRACKS) { 2820 for (cdindex = 0; cdindex < num_entries - 1; cdindex++) { 2821 softc->toc.entries[cdindex].track = 2822 bcd2bin(softc->toc.entries[cdindex].track); 2823 } 2824 } 2825 2826 softc->flags |= CD_FLAG_VALID_TOC; |
2827 softc->disk->d_maxsize = DFLTPHYS; 2828 softc->disk->d_sectorsize = softc->params.blksize; 2829 softc->disk->d_mediasize = |
2830 (off_t)softc->params.blksize * softc->params.disksize; 2831 2832bailout: 2833 2834 /* 2835 * We unconditionally (re)set the blocksize each time the 2836 * CD device is opened. This is because the CD can change, 2837 * and therefore the blocksize might change. 2838 * XXX problems here if some slice or partition is still 2839 * open with the old size? 2840 */ |
2841 if ((softc->disk->d_devstat->flags & DEVSTAT_BS_UNAVAILABLE) != 0) 2842 softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE; 2843 softc->disk->d_devstat->block_size = softc->params.blksize; |
2844 2845 return (error); 2846} 2847 2848static int 2849cdsize(struct cam_periph *periph, u_int32_t *size) 2850{ 2851 struct cd_softc *softc; --- 1369 unchanged lines hidden --- |