scd.c (10910) | scd.c (11872) |
---|---|
1/*- 2 * Copyright (c) 1995 Mikael Hybsch 3 * All rights reserved. 4 * 5 * Portions of this file are copied from mcd.c 6 * which has the following copyrights: 7 * 8 * Copyright 1993 by Holger Veit (data part) --- 27 unchanged lines hidden (view full) --- 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 */ 42 43 | 1/*- 2 * Copyright (c) 1995 Mikael Hybsch 3 * All rights reserved. 4 * 5 * Portions of this file are copied from mcd.c 6 * which has the following copyrights: 7 * 8 * Copyright 1993 by Holger Veit (data part) --- 27 unchanged lines hidden (view full) --- 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 */ 42 43 |
44/* $Id: scd.c,v 1.6 1995/09/08 11:07:55 bde Exp $ */ | 44/* $Id: scd.c,v 1.7 1995/09/19 18:55:15 bde Exp $ */ |
45 46/* Please send any comments to micke@dynas.se */ 47 48#define SCD_DEBUG 0 49 50#include "scd.h" 51#if NSCD > 0 52#include <sys/types.h> --- 42 unchanged lines hidden (view full) --- 95#define SCD_S_WAITPARAM 6 96 97#define RDELAY_WAIT 300 98#define RDELAY_WAITREAD 300 99 100#define SCDBLKSIZE 2048 101 102#ifdef SCD_DEBUG | 45 46/* Please send any comments to micke@dynas.se */ 47 48#define SCD_DEBUG 0 49 50#include "scd.h" 51#if NSCD > 0 52#include <sys/types.h> --- 42 unchanged lines hidden (view full) --- 95#define SCD_S_WAITPARAM 6 96 97#define RDELAY_WAIT 300 98#define RDELAY_WAITREAD 300 99 100#define SCDBLKSIZE 2048 101 102#ifdef SCD_DEBUG |
103 int scd_debuglevel = SCD_DEBUG; | 103 static int scd_debuglevel = SCD_DEBUG; |
104# define XDEBUG(level, data) {if (scd_debuglevel >= level) printf data;} 105#else 106# define XDEBUG(level, data) 107#endif 108 109struct scd_mbx { 110 short unit; 111 short port; 112 short retry; 113 short nblk; 114 int sz; 115 u_long skip; 116 struct buf *bp; 117 int p_offset; 118 short count; 119}; 120 | 104# define XDEBUG(level, data) {if (scd_debuglevel >= level) printf data;} 105#else 106# define XDEBUG(level, data) 107#endif 108 109struct scd_mbx { 110 short unit; 111 short port; 112 short retry; 113 short nblk; 114 int sz; 115 u_long skip; 116 struct buf *bp; 117 int p_offset; 118 short count; 119}; 120 |
121struct scd_data { | 121static struct scd_data { |
122 int iobase; 123 char double_speed; 124 char *name; 125 short flags; 126 int blksize; 127 u_long disksize; 128 struct disklabel dlabel; 129 int openflag; --- 21 unchanged lines hidden (view full) --- 151static int bcd2bin(bcd_t b); 152static bcd_t bin2bcd(int b); 153static void hsg2msf(int hsg, bcd_t *msf); 154static int msf2hsg(bcd_t *msf); 155 156static void process_attention(unsigned unit); 157static inline void write_control(unsigned port, unsigned data); 158static int waitfor_status_bits(int unit, int bits_set, int bits_clear); | 122 int iobase; 123 char double_speed; 124 char *name; 125 short flags; 126 int blksize; 127 u_long disksize; 128 struct disklabel dlabel; 129 int openflag; --- 21 unchanged lines hidden (view full) --- 151static int bcd2bin(bcd_t b); 152static bcd_t bin2bcd(int b); 153static void hsg2msf(int hsg, bcd_t *msf); 154static int msf2hsg(bcd_t *msf); 155 156static void process_attention(unsigned unit); 157static inline void write_control(unsigned port, unsigned data); 158static int waitfor_status_bits(int unit, int bits_set, int bits_clear); |
159static int waitfor_attention(int unit); | |
160static int send_cmd(u_int unit, u_char cmd, u_int nargs, ...); 161static void init_drive(unsigned unit); 162static int spin_up(unsigned unit); 163static int read_toc(dev_t dev); 164static int get_result(u_int unit, int result_len, u_char *result); 165static void print_error(int unit, int errcode); 166 167static void scd_start(int unit); --- 11 unchanged lines hidden (view full) --- 179 180/* for xcdplayer */ 181static int scd_toc_header(int unit, struct ioc_toc_header *th); 182static int scd_toc_entrys(int unit, struct ioc_read_toc_entry *te); 183#define SCD_LASTPLUS1 170 /* don't ask, xcdplayer passes this in */ 184 185extern int hz; 186 | 159static int send_cmd(u_int unit, u_char cmd, u_int nargs, ...); 160static void init_drive(unsigned unit); 161static int spin_up(unsigned unit); 162static int read_toc(dev_t dev); 163static int get_result(u_int unit, int result_len, u_char *result); 164static void print_error(int unit, int errcode); 165 166static void scd_start(int unit); --- 11 unchanged lines hidden (view full) --- 178 179/* for xcdplayer */ 180static int scd_toc_header(int unit, struct ioc_toc_header *th); 181static int scd_toc_entrys(int unit, struct ioc_read_toc_entry *te); 182#define SCD_LASTPLUS1 170 /* don't ask, xcdplayer passes this in */ 183 184extern int hz; 185 |
187int scd_probe(struct isa_device *dev); 188int scd_attach(struct isa_device *dev); | 186static int scd_probe(struct isa_device *dev); 187static int scd_attach(struct isa_device *dev); |
189struct isa_driver scddriver = { scd_probe, scd_attach, "scd" }; 190 191static struct kern_devconf kdc_scd[NSCD] = { { 192 0, 0, 0, /* filled in by dev_attach */ 193 "scd", 0, { MDDT_ISA, 0, "bio" }, 194 isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, 195 &kdc_isa0, /* parent */ 196 0, /* parentdata */ --- 10 unchanged lines hidden (view full) --- 207 kdc_scd[id->id_unit].kdc_unit = id->id_unit; 208 kdc_scd[id->id_unit].kdc_isa = id; 209 dev_attach(&kdc_scd[id->id_unit]); 210} 211 212int scd_attach(struct isa_device *dev) 213{ 214 struct scd_data *cd = scd_data + dev->id_unit; | 188struct isa_driver scddriver = { scd_probe, scd_attach, "scd" }; 189 190static struct kern_devconf kdc_scd[NSCD] = { { 191 0, 0, 0, /* filled in by dev_attach */ 192 "scd", 0, { MDDT_ISA, 0, "bio" }, 193 isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, 194 &kdc_isa0, /* parent */ 195 0, /* parentdata */ --- 10 unchanged lines hidden (view full) --- 206 kdc_scd[id->id_unit].kdc_unit = id->id_unit; 207 kdc_scd[id->id_unit].kdc_isa = id; 208 dev_attach(&kdc_scd[id->id_unit]); 209} 210 211int scd_attach(struct isa_device *dev) 212{ 213 struct scd_data *cd = scd_data + dev->id_unit; |
215 int i; | |
216 217 cd->iobase = dev->id_iobase; /* Already set by probe, but ... */ 218 219 kdc_scd[dev->id_unit].kdc_state = DC_IDLE; 220 /* name filled in probe */ 221 kdc_scd[dev->id_unit].kdc_description = scd_data[dev->id_unit].name; 222 printf("scd%d: <%s>\n", dev->id_unit, scd_data[dev->id_unit].name); 223 --- 58 unchanged lines hidden (view full) --- 282 return 0; 283} 284 285int 286scdclose(dev_t dev, int flags, int fmt, struct proc *p) 287{ 288 int unit,part,phys; 289 struct scd_data *cd; | 214 215 cd->iobase = dev->id_iobase; /* Already set by probe, but ... */ 216 217 kdc_scd[dev->id_unit].kdc_state = DC_IDLE; 218 /* name filled in probe */ 219 kdc_scd[dev->id_unit].kdc_description = scd_data[dev->id_unit].name; 220 printf("scd%d: <%s>\n", dev->id_unit, scd_data[dev->id_unit].name); 221 --- 58 unchanged lines hidden (view full) --- 280 return 0; 281} 282 283int 284scdclose(dev_t dev, int flags, int fmt, struct proc *p) 285{ 286 int unit,part,phys; 287 struct scd_data *cd; |
290 int rlen; 291 char rdata[10]; | |
292 293 unit = scd_unit(dev); 294 if (unit >= NSCD) 295 return ENXIO; 296 297 cd = scd_data + unit; 298 part = scd_part(dev); 299 phys = scd_phys(dev); --- 81 unchanged lines hidden (view full) --- 381} 382 383static void 384scd_start(int unit) 385{ 386 struct scd_data *cd = scd_data + unit; 387 struct buf *bp, *qp = &cd->head; 388 struct partition *p; | 288 289 unit = scd_unit(dev); 290 if (unit >= NSCD) 291 return ENXIO; 292 293 cd = scd_data + unit; 294 part = scd_part(dev); 295 phys = scd_phys(dev); --- 81 unchanged lines hidden (view full) --- 377} 378 379static void 380scd_start(int unit) 381{ 382 struct scd_data *cd = scd_data + unit; 383 struct buf *bp, *qp = &cd->head; 384 struct partition *p; |
389 int part; | |
390 register s = splbio(); 391 392 if (cd->flags & SCDMBXBSY) { 393 splx(s); 394 return; 395 } 396 397 if ((bp = qp->b_actf) != 0) { --- 108 unchanged lines hidden (view full) --- 506 507static int 508scd_playtracks(int unit, struct ioc_play_track *pt) 509{ 510 struct scd_data *cd = scd_data + unit; 511 struct ioc_play_msf msf; 512 int a = pt->start_track; 513 int z = pt->end_track; | 385 register s = splbio(); 386 387 if (cd->flags & SCDMBXBSY) { 388 splx(s); 389 return; 390 } 391 392 if ((bp = qp->b_actf) != 0) { --- 108 unchanged lines hidden (view full) --- 501 502static int 503scd_playtracks(int unit, struct ioc_play_track *pt) 504{ 505 struct scd_data *cd = scd_data + unit; 506 struct ioc_play_msf msf; 507 int a = pt->start_track; 508 int z = pt->end_track; |
514 int rc, i; | 509 int rc; |
515 516 if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { 517 if (rc == -ERR_NOT_SPINNING) { 518 if (spin_up(unit) != 0) 519 return EIO; 520 rc = read_toc(unit); 521 } 522 if (rc != 0) { --- 110 unchanged lines hidden (view full) --- 633 return EINVAL; 634 return scd_play(unit, &scd_data[unit].last_play); 635} 636 637static int 638scd_eject(int unit) 639{ 640 struct scd_data *cd = scd_data + unit; | 510 511 if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { 512 if (rc == -ERR_NOT_SPINNING) { 513 if (spin_up(unit) != 0) 514 return EIO; 515 rc = read_toc(unit); 516 } 517 if (rc != 0) { --- 110 unchanged lines hidden (view full) --- 628 return EINVAL; 629 return scd_play(unit, &scd_data[unit].last_play); 630} 631 632static int 633scd_eject(int unit) 634{ 635 struct scd_data *cd = scd_data + unit; |
641 int port = cd->iobase; | |
642 643 cd->audio_status = CD_AS_AUDIO_INVALID; 644 cd->flags &= ~(SCDSPINNING|SCDTOC); 645 646 if (send_cmd(unit, CMD_STOP_AUDIO, 0) != 0 || 647 send_cmd(unit, CMD_SPIN_DOWN, 0) != 0 || 648 send_cmd(unit, CMD_EJECT, 0) != 0) 649 { --- 139 unchanged lines hidden (view full) --- 789static void 790scd_doread(int state, struct scd_mbx *mbxin) 791{ 792 struct scd_mbx *mbx = (state!=SCD_S_BEGIN) ? mbxsave : mbxin; 793 int unit = mbx->unit; 794 int port = mbx->port; 795 struct buf *bp = mbx->bp; 796 struct scd_data *cd = scd_data + unit; | 636 637 cd->audio_status = CD_AS_AUDIO_INVALID; 638 cd->flags &= ~(SCDSPINNING|SCDTOC); 639 640 if (send_cmd(unit, CMD_STOP_AUDIO, 0) != 0 || 641 send_cmd(unit, CMD_SPIN_DOWN, 0) != 0 || 642 send_cmd(unit, CMD_EJECT, 0) != 0) 643 { --- 139 unchanged lines hidden (view full) --- 783static void 784scd_doread(int state, struct scd_mbx *mbxin) 785{ 786 struct scd_mbx *mbx = (state!=SCD_S_BEGIN) ? mbxsave : mbxin; 787 int unit = mbx->unit; 788 int port = mbx->port; 789 struct buf *bp = mbx->bp; 790 struct scd_data *cd = scd_data + unit; |
797 int reg,i,k,c; | 791 int reg,i; |
798 int blknum; 799 caddr_t addr; | 792 int blknum; 793 caddr_t addr; |
800 char rdata[10]; | |
801 static char sdata[3]; /* Must be preserved between calls to this function */ 802 803loop: 804 switch (state) { 805 case SCD_S_BEGIN: 806 mbx = mbxsave = mbxin; 807 808 case SCD_S_BEGIN1: --- 22 unchanged lines hidden (view full) --- 831 /* reject, if audio active */ 832 if (cd->audio_status & CD_AS_PLAY_IN_PROGRESS) { 833 printf("scd%d: audio is active\n",unit); 834 goto harderr; 835 } 836 837 mbx->sz = cd->blksize; 838 | 794 static char sdata[3]; /* Must be preserved between calls to this function */ 795 796loop: 797 switch (state) { 798 case SCD_S_BEGIN: 799 mbx = mbxsave = mbxin; 800 801 case SCD_S_BEGIN1: --- 22 unchanged lines hidden (view full) --- 824 /* reject, if audio active */ 825 if (cd->audio_status & CD_AS_PLAY_IN_PROGRESS) { 826 printf("scd%d: audio is active\n",unit); 827 goto harderr; 828 } 829 830 mbx->sz = cd->blksize; 831 |
839firstblock: | |
840 /* for first block */ 841 mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; 842 mbx->skip = 0; 843 844nextblock: 845 if (!(cd->flags & SCDVALID)) 846 goto changed; 847 --- 240 unchanged lines hidden (view full) --- 1088} 1089 1090static void 1091process_attention(unsigned unit) 1092{ 1093 unsigned port = scd_data[unit].iobase; 1094 unsigned char code; 1095 int count = 0; | 832 /* for first block */ 833 mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; 834 mbx->skip = 0; 835 836nextblock: 837 if (!(cd->flags & SCDVALID)) 838 goto changed; 839 --- 240 unchanged lines hidden (view full) --- 1080} 1081 1082static void 1083process_attention(unsigned unit) 1084{ 1085 unsigned port = scd_data[unit].iobase; 1086 unsigned char code; 1087 int count = 0; |
1096 int i; | |
1097 1098 while (IS_ATTENTION(port) && count++ < 30) { 1099 write_control(port, CBIT_ATTENTION_CLEAR); 1100 code = inb(port+IREG_RESULT); 1101 1102#if SCD_DEBUG 1103 if (scd_debuglevel > 0) { 1104 if (count == 1) --- 204 unchanged lines hidden (view full) --- 1309} 1310 1311/* Returns 0 or errno */ 1312static int 1313get_result(u_int unit, int result_len, u_char *result) 1314{ 1315 unsigned int port = scd_data[unit].iobase; 1316 unsigned int res_reg = port + IREG_RESULT; | 1088 1089 while (IS_ATTENTION(port) && count++ < 30) { 1090 write_control(port, CBIT_ATTENTION_CLEAR); 1091 code = inb(port+IREG_RESULT); 1092 1093#if SCD_DEBUG 1094 if (scd_debuglevel > 0) { 1095 if (count == 1) --- 204 unchanged lines hidden (view full) --- 1300} 1301 1302/* Returns 0 or errno */ 1303static int 1304get_result(u_int unit, int result_len, u_char *result) 1305{ 1306 unsigned int port = scd_data[unit].iobase; 1307 unsigned int res_reg = port + IREG_RESULT; |
1317 unsigned char c; | |
1318 int loop_index = 2; /* send_cmd() reads two bytes ... */ 1319 1320 XDEBUG(1, ("scd%d: DEBUG: get_result: bytes=%d\n", unit, result_len)); 1321 1322 while (result_len-- > 0) { 1323 if (loop_index++ >= 10) { 1324 loop_index = 1; 1325 if (waitfor_status_bits(unit, SBIT_RESULT_READY, 0)) --- 44 unchanged lines hidden (view full) --- 1370 outb(reg, c); 1371 XDEBUG(1, (",{0x%x}", c)); 1372 } 1373 va_end(ap); 1374 XDEBUG(1, ("\n")); 1375 1376 outb(port+OREG_COMMAND, cmd); 1377 | 1308 int loop_index = 2; /* send_cmd() reads two bytes ... */ 1309 1310 XDEBUG(1, ("scd%d: DEBUG: get_result: bytes=%d\n", unit, result_len)); 1311 1312 while (result_len-- > 0) { 1313 if (loop_index++ >= 10) { 1314 loop_index = 1; 1315 if (waitfor_status_bits(unit, SBIT_RESULT_READY, 0)) --- 44 unchanged lines hidden (view full) --- 1360 outb(reg, c); 1361 XDEBUG(1, (",{0x%x}", c)); 1362 } 1363 va_end(ap); 1364 XDEBUG(1, ("\n")); 1365 1366 outb(port+OREG_COMMAND, cmd); 1367 |
1378 if (rc = waitfor_status_bits(unit, SBIT_RESULT_READY, SBIT_BUSY)) | 1368 rc = waitfor_status_bits(unit, SBIT_RESULT_READY, SBIT_BUSY); 1369 if (rc) |
1379 return -0x100; 1380 1381 reg = port + IREG_RESULT; 1382 write_control(port, CBIT_RESULT_READY_CLEAR); 1383 switch ((rc = inb(reg)) & 0xf0) { 1384 case 0x20: 1385 rc = inb(reg); 1386 /* FALL TROUGH */ --- 151 unchanged lines hidden --- | 1370 return -0x100; 1371 1372 reg = port + IREG_RESULT; 1373 write_control(port, CBIT_RESULT_READY_CLEAR); 1374 switch ((rc = inb(reg)) & 0xf0) { 1375 case 0x20: 1376 rc = inb(reg); 1377 /* FALL TROUGH */ --- 151 unchanged lines hidden --- |