⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbpcd.c.txt

📁 Linux块设备驱动分析与模拟实现
💻 TXT
📖 第 1 页 / 共 5 页
字号:
1204   u_char chan0,vol0,chan1,vol1;
1205 
1206   DS[d].diskstate_flags &= ~volume_bit;
1207   clr_cmdbuf();
1208   if (new_drive)
1209     {
1210       drvcmd[0]=0x84;
1211       drvcmd[1]=0x05;
1212       response_count=5;
1213       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1214     }
1215   else
1216     {
1217       drvcmd[0]=0x85;
1218       drvcmd[1]=0x03;
1219       response_count=2;
1220       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1221     }
1222   i=cmd_out();
1223   if (i<0) return (i);
1224   if (new_drive)
1225     {
1226       chan0=infobuf[1]&0x0F;
1227       vol0=infobuf[2];
1228       chan1=infobuf[3]&0x0F;
1229       vol1=infobuf[4];
1230       if (chan0==0)
1231         {
1232           chan0=1;
1233           vol0=0;
1234         }
1235       if (chan1==0)
1236         {
1237           chan1=2;
1238           vol1=0;
1239         }
1240       chan0 >>= 1;
1241       chan1 >>= 1;
1242     }
1243   else
1244     {
1245       chan0=0;
1246       chan1=1;
1247       vol0=vol1=infobuf[1];
1248       if (DS[d].drv_type>=drv_201)
1249         {
1250           if (DS[d].drv_type<drv_300)
1251             {
1252               switches=infobuf[0];
1253               if ((switches&0x80)!=0) vol0=0;
1254               if ((switches&0x40)!=0) vol1=0;
1255               if (DS[d].drv_type>=drv_211)
1256                 {
1257                   if ((switches&0x20)!=0) chan0=1;
1258                   if ((switches&0x10)!=0) chan1=0;
1259                 }
1260             }
1261           else
1262             {
1263               vol0=infobuf[0];
1264               if ((vol0&0x01)!=0) chan0=1;
1265               if ((vol1&0x01)==0) chan1=0;
1266               vol0 &= 0xFC;
1267               vol1 &= 0xFC;
1268               if (vol0!=0) vol0 += 3;
1269               if (vol1!=0) vol1 += 3;
1270             }
1271         }
1272     }
1273   DS[d].vol_chan0=chan0;
1274   DS[d].vol_ctrl0=vol0;
1275   DS[d].vol_chan1=chan1;
1276   DS[d].vol_ctrl1=vol1;
1277   DS[d].vol_chan2=2;
1278   DS[d].vol_ctrl2=0xFF;
1279   DS[d].vol_chan3=3;
1280   DS[d].vol_ctrl3=0xFF;
1281   DS[d].diskstate_flags |= volume_bit;
1282   return (0);
1283 }
1284 #endif
1285 /*==========================================================================*/
1286 static int xx_ReadCapacity(void)
1287 {
1288   int i;
1289 
1290   DS[d].diskstate_flags &= ~cd_size_bit;
1291   clr_cmdbuf();
1292   if (new_drive)
1293     {
1294       drvcmd[0]=0x85;
1295       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1296     }
1297   else
1298     {
1299       drvcmd[0]=0x88;
1300       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1301     }
1302   response_count=5;
1303   i=cmd_out();
1304   if (i<0) return (i);
1305   DS[d].CDsize_blk=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
1306   if (new_drive) DS[d].CDsize_blk=msf2blk(DS[d].CDsize_blk);
1307   DS[d].CDsize_frm = (DS[d].CDsize_blk * make16(infobuf[3],infobuf[4])) / CD_FRAMESIZE;
1308   DS[d].CDsize_blk += 151;
1309   DS[d].diskstate_flags |= cd_size_bit;
1310   return (0);
1311 }
1312 /*==========================================================================*/
1313 static int xx_ReadTocDescr(void)
1314 {
1315   int i;
1316 
1317   DS[d].diskstate_flags &= ~toc_bit;
1318   clr_cmdbuf();
1319   if (new_drive)
1320     {
1321       drvcmd[0]=0x8B;
1322       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1323     }
1324   else
1325     {
1326       drvcmd[0]=0x8B;
1327       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1328     }
1329   response_count=6;
1330   i=cmd_out();
1331   if (i<0) return (i);
1332   DS[d].xa_byte=infobuf[0];
1333   DS[d].n_first_track=infobuf[1];
1334   DS[d].n_last_track=infobuf[2];
1335   DS[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
1336   DS[d].size_blk=msf2blk(DS[d].size_msf);
1337   DS[d].diskstate_flags |= toc_bit;
1338   DPRINTF((DBG_TOC,"SBPCD: TocDesc: %02X %02X %02X %08X\n",
1339          DS[d].xa_byte,DS[d].n_first_track,DS[d].n_last_track,DS[d].size_msf));
1340   return (0);
1341 }
1342 /*==========================================================================*/
1343 static int xx_ReadTocEntry(int num)
1344 {
1345   int i;
1346 
1347   clr_cmdbuf();
1348   if (new_drive)
1349     {
1350       drvcmd[0]=0x8C;
1351       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1352     }
1353   else
1354     {
1355       drvcmd[0]=0x8C;
1356       drvcmd[1]=0x02;
1357       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1358     }
1359   drvcmd[2]=num;
1360   response_count=8;
1361   i=cmd_out();
1362   if (i<0) return (i);
1363   DS[d].TocEnt_nixbyte=infobuf[0];
1364   DS[d].TocEnt_ctl_adr=swap_nibbles(infobuf[1]);
1365   DS[d].TocEnt_number=infobuf[2];
1366   DS[d].TocEnt_format=infobuf[3];
1367   if (new_drive) i=4;
1368   else i=5;
1369   DS[d].TocEnt_address=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2]));
1370   DPRINTF((DBG_TOC,"SBPCD: TocEntry: %02X %02X %02X %02X %08X\n",
1371            DS[d].TocEnt_nixbyte,DS[d].TocEnt_ctl_adr,DS[d].TocEnt_number,
1372            DS[d].TocEnt_format,DS[d].TocEnt_address));
1373   return (0);
1374 }
1375 /*==========================================================================*/
1376 static int xx_ReadPacket(void)
1377 {
1378   int i;
1379 
1380   clr_cmdbuf();
1381   drvcmd[0]=0x8E;
1382   drvcmd[1]=response_count;
1383   flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1384   i=cmd_out();
1385   return (i);
1386 }
1387 /*==========================================================================*/
1388 static int convert_UPC(u_char *p)
1389 {
1390   int i;
1391 
1392   p++;
1393   if (!new_drive) p[13]=0;
1394   for (i=0;i<7;i++)
1395     {
1396       if (new_drive) DS[d].UPC_buf[i]=swap_nibbles(*p++);
1397       else
1398         {
1399           DS[d].UPC_buf[i]=((*p++)<<4)&0xFF;
1400           DS[d].UPC_buf[i] |= *p++;
1401         }
1402     }
1403   DS[d].UPC_buf[6] &= 0xF0;
1404   return (0);
1405 }
1406 /*==========================================================================*/
1407 static int xx_ReadUPC(void)
1408 {
1409   int i;
1410 
1411   DS[d].diskstate_flags &= ~upc_bit;
1412   clr_cmdbuf();
1413   if (new_drive)
1414     {
1415       drvcmd[0]=0x88;
1416       response_count=8;
1417       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1418     }
1419   else
1420     {
1421       drvcmd[0]=0x08;
1422       response_count=0;
1423       flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1424     }
1425   i=cmd_out();
1426   if (i<0) return (i);
1427   if (!new_drive)
1428     {
1429       response_count=16;
1430       i=xx_ReadPacket();
1431       if (i<0) return (i);
1432     }
1433   DS[d].UPC_ctl_adr=0;
1434   if (new_drive) i=0;
1435   else i=2;
1436   if ((infobuf[i]&0x80)!=0)
1437     {
1438       convert_UPC(&infobuf[i]);
1439       DS[d].UPC_ctl_adr &= 0xF0;
1440       DS[d].UPC_ctl_adr |= 0x02;
1441     }
1442   DS[d].diskstate_flags |= upc_bit;
1443   return (0);
1444 }
1445 /*==========================================================================*/
1446 static int yy_CheckMultiSession(void)
1447 {
1448   int i;
1449 
1450   DS[d].diskstate_flags &= ~multisession_bit;
1451   DS[d].f_multisession=0;
1452   clr_cmdbuf();
1453   if (new_drive)
1454     {
1455       drvcmd[0]=0x8D;
1456       response_count=6;
1457       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1458       i=cmd_out();
1459       if (i<0) return (i);
1460       if ((infobuf[0]&0x80)!=0)
1461         {
1462           DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X\n",
1463                          infobuf[0], infobuf[1], infobuf[2],
1464                          infobuf[3], infobuf[4], infobuf[5]));
1465           DS[d].f_multisession=1;
1466           DS[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
1467                                    make16(infobuf[2],infobuf[3])));
1468         }
1469     }
1470   DS[d].diskstate_flags |= multisession_bit;
1471   return (0);
1472 }
1473 /*==========================================================================*/
1474 static void check_datarate(void)
1475 {
1476 #ifdef CDMKE
1477   int i=0;
1478 
1479   timed_out=0;
1480   datarate=0;
1481 
1482   /* set a timer to make (timed_out!=0) after 1.1 seconds */
1483 
1484   DPRINTF((DBG_TIM,"SBPCD: timer started (110).\n"));
1485   sti(); /* to avoid possible "printf" bug */
1486 
1487   SET_TIMER(mark_timeout,110);
1488   do
1489     {
1490       i=inb(CDi_status);
1491       datarate++;
1492 
1493 #if 00000
1494       if (datarate>0x0FFFFFFF) break;
1495 #endif 00000
1496 
1497     }
1498   while (!timed_out); /* originally looping for 1.1 seconds */
1499   CLEAR_TIMER;
1500   DPRINTF((DBG_TIM,"SBPCD: datarate: %d\n", datarate));
1501   if (datarate<65536) datarate=65536;
1502 
1503   maxtim16=datarate*16;
1504   maxtim04=datarate*4;
1505   maxtim02=datarate*2;
1506   maxtim_8=datarate/32;
1507 #if MANY_SESSION
1508   maxtim_data=datarate/100;
1509 #else
1510   maxtim_data=datarate/300;
1511 #endif MANY_SESSION
1512   DPRINTF((DBG_TIM,"SBPCD: maxtim_8 %d, maxtim_data %d.\n",
1513            maxtim_8, maxtim_data));
1514 #endif CDMKE
1515 }
1516 /*==========================================================================*/
1517 static int check_version(void)
1518 {
1519   int i, j;
1520 
1521   /* clear any pending error state */
1522   clr_cmdbuf();
1523   drvcmd[0]=0x82;
1524   response_count=9;
1525   flags_cmd_out=f_putcmd;
1526   cmd_out();
1527 
1528   /* read drive version */
1529   clr_cmdbuf();
1530   for (i=0;i<12;i++) infobuf[i]=0;
1531   drvcmd[0]=0x83;
1532   response_count=12;
1533   flags_cmd_out=f_putcmd;
1534   i=cmd_out();
1535   if (i<0) DPRINTF((DBG_INI,"SBPCD: cmd_83 returns %d\n",i));
1536 
1537   DPRINTF((DBG_INI,"SBPCD: infobuf = \""));
1538   for (i=0;i<12;i++) DPRINTF((DBG_INI,"%c",infobuf[i]));
1539   DPRINTF((DBG_INI,"\"\n"));
1540 
1541   for (i=0;i<4;i++) if (infobuf[i]!=drive_family[i]) break;
1542   if (i==4)
1543     {
1544       DS[d].drive_model[0]=infobuf[i++];
1545       DS[d].drive_model[1]=infobuf[i++];
1546       DS[d].drive_model[2]='-';
1547       DS[d].drive_model[3]='x';
1548       DS[d].drv_type=drv_new;
1549     }
1550   else
1551     {
1552       for (i=0;i<8;i++) if (infobuf[i]!=drive_vendor[i]) break;
1553       if (i!=8) return (-1);
1554       DS[d].drive_model[0]='2';
1555       DS[d].drive_model[1]='x';
1556       DS[d].drive_model[2]='-';
1557       DS[d].drive_model[3]='x';
1558       DS[d].drv_type=drv_old;
1559     }
1560   for (j=0;j<4;j++) DS[d].firmware_version[j]=infobuf[i+j];
1561   j = (DS[d].firmware_version[0] & 0x0F) * 100 +
1562       (DS[d].firmware_version[2] & 0x0F) *10 +
1563       (DS[d].firmware_version[3] & 0x0F);
1564   if (new_drive)
1565     {
1566       if (j<100) DS[d].drv_type=drv_099;
1567       else DS[d].drv_type=drv_100;
1568     }
1569   else if (j<200) DS[d].drv_type=drv_199;
1570   else if (j<201) DS[d].drv_type=drv_200;
1571   else if (j<210) DS[d].drv_type=drv_201;
1572   else if (j<211) DS[d].drv_type=drv_210;
1573   else if (j<300) DS[d].drv_type=drv_211;
1574   else DS[d].drv_type=drv_300;
1575   return (0);
1576 }
1577 /*==========================================================================*/
1578 static int switch_drive(int num)
1579 {
1580   int i;
1581 
1582   d=num;
1583 
1584   i=num;
1585   if (sbpro_type) i=(i&0x01)<<1|(i&0x02)>>1;
1586   OUT(CDo_enable,i);
1587   DPRINTF((DBG_DID,"SBPCD: switch_drive: drive %d activated.\n",DS[d].drv_minor));
1588   return (0);
1589 }
1590 /*==========================================================================*/
1591 /*
1592  * probe for the presence of drives on the selected controller
1593  */
1594 static int check_drives(void)
1595 {
1596   int i, j;
1597   char *printk_header="";
1598 
1599   DPRINTF((DBG_INI,"SBPCD: check_drives entered.\n"));
1600 
1601   ndrives=0;
1602   for (j=0;j<NR_SBPCD;j++)
1603     {
1604       DS[j].drv_minor=j;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -