hdparm.c 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * hdparm implementation for busybox
  4. *
  5. * Copyright (C) [2003] by [Matteo Croce] <3297627799@wind.it>
  6. * Hacked by Tito <farmatito@tiscali.it> for size optimization.
  7. *
  8. * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
  9. *
  10. * This program is based on the source code of hdparm: see below...
  11. * hdparm.c - Command line interface to get/set hard disk parameters
  12. * - by Mark Lord (C) 1994-2002 -- freely distributable
  13. */
  14. #include "libbb.h"
  15. #include <linux/hdreg.h>
  16. /* device types */
  17. /* ------------ */
  18. #define NO_DEV 0xffff
  19. #define ATA_DEV 0x0000
  20. #define ATAPI_DEV 0x0001
  21. /* word definitions */
  22. /* ---------------- */
  23. #define GEN_CONFIG 0 /* general configuration */
  24. #define LCYLS 1 /* number of logical cylinders */
  25. #define CONFIG 2 /* specific configuration */
  26. #define LHEADS 3 /* number of logical heads */
  27. #define TRACK_BYTES 4 /* number of bytes/track (ATA-1) */
  28. #define SECT_BYTES 5 /* number of bytes/sector (ATA-1) */
  29. #define LSECTS 6 /* number of logical sectors/track */
  30. #define START_SERIAL 10 /* ASCII serial number */
  31. #define LENGTH_SERIAL 10 /* 10 words (20 bytes or characters) */
  32. #define BUF_TYPE 20 /* buffer type (ATA-1) */
  33. #define BUFFER__SIZE 21 /* buffer size (ATA-1) */
  34. #define RW_LONG 22 /* extra bytes in R/W LONG cmd ( < ATA-4)*/
  35. #define START_FW_REV 23 /* ASCII firmware revision */
  36. #define LENGTH_FW_REV 4 /* 4 words (8 bytes or characters) */
  37. #define START_MODEL 27 /* ASCII model number */
  38. #define LENGTH_MODEL 20 /* 20 words (40 bytes or characters) */
  39. #define SECTOR_XFER_MAX 47 /* r/w multiple: max sectors xfered */
  40. #define DWORD_IO 48 /* can do double-word IO (ATA-1 only) */
  41. #define CAPAB_0 49 /* capabilities */
  42. #define CAPAB_1 50
  43. #define PIO_MODE 51 /* max PIO mode supported (obsolete)*/
  44. #define DMA_MODE 52 /* max Singleword DMA mode supported (obs)*/
  45. #define WHATS_VALID 53 /* what fields are valid */
  46. #define LCYLS_CUR 54 /* current logical cylinders */
  47. #define LHEADS_CUR 55 /* current logical heads */
  48. #define LSECTS_CUR 56 /* current logical sectors/track */
  49. #define CAPACITY_LSB 57 /* current capacity in sectors */
  50. #define CAPACITY_MSB 58
  51. #define SECTOR_XFER_CUR 59 /* r/w multiple: current sectors xfered */
  52. #define LBA_SECTS_LSB 60 /* LBA: total number of user */
  53. #define LBA_SECTS_MSB 61 /* addressable sectors */
  54. #define SINGLE_DMA 62 /* singleword DMA modes */
  55. #define MULTI_DMA 63 /* multiword DMA modes */
  56. #define ADV_PIO_MODES 64 /* advanced PIO modes supported */
  57. /* multiword DMA xfer cycle time: */
  58. #define DMA_TIME_MIN 65 /* - minimum */
  59. #define DMA_TIME_NORM 66 /* - manufacturer's recommended */
  60. /* minimum PIO xfer cycle time: */
  61. #define PIO_NO_FLOW 67 /* - without flow control */
  62. #define PIO_FLOW 68 /* - with IORDY flow control */
  63. #define PKT_REL 71 /* typical #ns from PKT cmd to bus rel */
  64. #define SVC_NBSY 72 /* typical #ns from SERVICE cmd to !BSY */
  65. #define CDR_MAJOR 73 /* CD ROM: major version number */
  66. #define CDR_MINOR 74 /* CD ROM: minor version number */
  67. #define QUEUE_DEPTH 75 /* queue depth */
  68. #define MAJOR 80 /* major version number */
  69. #define MINOR 81 /* minor version number */
  70. #define CMDS_SUPP_0 82 /* command/feature set(s) supported */
  71. #define CMDS_SUPP_1 83
  72. #define CMDS_SUPP_2 84
  73. #define CMDS_EN_0 85 /* command/feature set(s) enabled */
  74. #define CMDS_EN_1 86
  75. #define CMDS_EN_2 87
  76. #define ULTRA_DMA 88 /* ultra DMA modes */
  77. /* time to complete security erase */
  78. #define ERASE_TIME 89 /* - ordinary */
  79. #define ENH_ERASE_TIME 90 /* - enhanced */
  80. #define ADV_PWR 91 /* current advanced power management level
  81. in low byte, 0x40 in high byte. */
  82. #define PSWD_CODE 92 /* master password revision code */
  83. #define HWRST_RSLT 93 /* hardware reset result */
  84. #define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
  85. #define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
  86. #define LBA_MID 101 /* bits are used, but addr 103 */
  87. #define LBA_48_MSB 102 /* has been reserved for LBA in */
  88. #define LBA_64_MSB 103 /* the future. */
  89. #define RM_STAT 127 /* removable media status notification feature set support */
  90. #define SECU_STATUS 128 /* security status */
  91. #define CFA_PWR_MODE 160 /* CFA power mode 1 */
  92. #define START_MEDIA 176 /* media serial number */
  93. #define LENGTH_MEDIA 20 /* 20 words (40 bytes or characters)*/
  94. #define START_MANUF 196 /* media manufacturer I.D. */
  95. #define LENGTH_MANUF 10 /* 10 words (20 bytes or characters) */
  96. #define INTEGRITY 255 /* integrity word */
  97. /* bit definitions within the words */
  98. /* -------------------------------- */
  99. /* many words are considered valid if bit 15 is 0 and bit 14 is 1 */
  100. #define VALID 0xc000
  101. #define VALID_VAL 0x4000
  102. /* many words are considered invalid if they are either all-0 or all-1 */
  103. #define NOVAL_0 0x0000
  104. #define NOVAL_1 0xffff
  105. /* word 0: gen_config */
  106. #define NOT_ATA 0x8000
  107. #define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
  108. #define MEDIA_REMOVABLE 0x0080
  109. #define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
  110. #define INCOMPLETE 0x0004
  111. #define CFA_SUPPORT_VAL 0x848a /* 848a=CFA feature set support */
  112. #define DRQ_RESPONSE_TIME 0x0060
  113. #define DRQ_3MS_VAL 0x0000
  114. #define DRQ_INTR_VAL 0x0020
  115. #define DRQ_50US_VAL 0x0040
  116. #define PKT_SIZE_SUPPORTED 0x0003
  117. #define PKT_SIZE_12_VAL 0x0000
  118. #define PKT_SIZE_16_VAL 0x0001
  119. #define EQPT_TYPE 0x1f00
  120. #define SHIFT_EQPT 8
  121. #define CDROM 0x0005
  122. /* word 1: number of logical cylinders */
  123. #define LCYLS_MAX 0x3fff /* maximum allowable value */
  124. /* word 2: specific configuration
  125. * (a) require SET FEATURES to spin-up
  126. * (b) require spin-up to fully reply to IDENTIFY DEVICE
  127. */
  128. #define STBY_NID_VAL 0x37c8 /* (a) and (b) */
  129. #define STBY_ID_VAL 0x738c /* (a) and not (b) */
  130. #define PWRD_NID_VAL 0x8c73 /* not (a) and (b) */
  131. #define PWRD_ID_VAL 0xc837 /* not (a) and not (b) */
  132. /* words 47 & 59: sector_xfer_max & sector_xfer_cur */
  133. #define SECTOR_XFER 0x00ff /* sectors xfered on r/w multiple cmds*/
  134. #define MULTIPLE_SETTING_VALID 0x0100 /* 1=multiple sector setting is valid */
  135. /* word 49: capabilities 0 */
  136. #define STD_STBY 0x2000 /* 1=standard values supported (ATA); 0=vendor specific values */
  137. #define IORDY_SUP 0x0800 /* 1=support; 0=may be supported */
  138. #define IORDY_OFF 0x0400 /* 1=may be disabled */
  139. #define LBA_SUP 0x0200 /* 1=Logical Block Address support */
  140. #define DMA_SUP 0x0100 /* 1=Direct Memory Access support */
  141. #define DMA_IL_SUP 0x8000 /* 1=interleaved DMA support (ATAPI) */
  142. #define CMD_Q_SUP 0x4000 /* 1=command queuing support (ATAPI) */
  143. #define OVLP_SUP 0x2000 /* 1=overlap operation support (ATAPI) */
  144. #define SWRST_REQ 0x1000 /* 1=ATA SW reset required (ATAPI, obsolete */
  145. /* word 50: capabilities 1 */
  146. #define MIN_STANDBY_TIMER 0x0001 /* 1=device specific standby timer value minimum */
  147. /* words 51 & 52: PIO & DMA cycle times */
  148. #define MODE 0xff00 /* the mode is in the MSBs */
  149. /* word 53: whats_valid */
  150. #define OK_W88 0x0004 /* the ultra_dma info is valid */
  151. #define OK_W64_70 0x0002 /* see above for word descriptions */
  152. #define OK_W54_58 0x0001 /* current cyl, head, sector, cap. info valid */
  153. /*word 63,88: dma_mode, ultra_dma_mode*/
  154. #define MODE_MAX 7 /* bit definitions force udma <=7 (when
  155. * udma >=8 comes out it'll have to be
  156. * defined in a new dma_mode word!) */
  157. /* word 64: PIO transfer modes */
  158. #define PIO_SUP 0x00ff /* only bits 0 & 1 are used so far, */
  159. #define PIO_MODE_MAX 8 /* but all 8 bits are defined */
  160. /* word 75: queue_depth */
  161. #define DEPTH_BITS 0x001f /* bits used for queue depth */
  162. /* words 80-81: version numbers */
  163. /* NOVAL_0 or NOVAL_1 means device does not report version */
  164. /* word 81: minor version number */
  165. #define MINOR_MAX 0x22
  166. /* words 82-84: cmds/feats supported */
  167. #define CMDS_W82 0x77ff /* word 82: defined command locations*/
  168. #define CMDS_W83 0x3fff /* word 83: defined command locations*/
  169. #define CMDS_W84 0x002f /* word 83: defined command locations*/
  170. #define SUPPORT_48_BIT 0x0400
  171. #define NUM_CMD_FEAT_STR 48
  172. /* words 85-87: cmds/feats enabled */
  173. /* use cmd_feat_str[] to display what commands and features have
  174. * been enabled with words 85-87
  175. */
  176. /* words 89, 90, SECU ERASE TIME */
  177. #define ERASE_BITS 0x00ff
  178. /* word 92: master password revision */
  179. /* NOVAL_0 or NOVAL_1 means no support for master password revision */
  180. /* word 93: hw reset result */
  181. #define CBLID 0x2000 /* CBLID status */
  182. #define RST0 0x0001 /* 1=reset to device #0 */
  183. #define DEV_DET 0x0006 /* how device num determined */
  184. #define JUMPER_VAL 0x0002 /* device num determined by jumper */
  185. #define CSEL_VAL 0x0004 /* device num determined by CSEL_VAL */
  186. /* word 127: removable media status notification feature set support */
  187. #define RM_STAT_BITS 0x0003
  188. #define RM_STAT_SUP 0x0001
  189. /* word 128: security */
  190. #define SECU_ENABLED 0x0002
  191. #define SECU_LEVEL 0x0010
  192. #define NUM_SECU_STR 6
  193. /* word 160: CFA power mode */
  194. #define VALID_W160 0x8000 /* 1=word valid */
  195. #define PWR_MODE_REQ 0x2000 /* 1=CFA power mode req'd by some cmds*/
  196. #define PWR_MODE_OFF 0x1000 /* 1=CFA power moded disabled */
  197. #define MAX_AMPS 0x0fff /* value = max current in ma */
  198. /* word 255: integrity */
  199. #define SIG 0x00ff /* signature location */
  200. #define SIG_VAL 0x00a5 /* signature value */
  201. #define TIMING_BUF_MB 1
  202. #define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
  203. #undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
  204. enum { fd = 3 };
  205. struct globals {
  206. smallint get_identity, get_geom;
  207. smallint do_flush;
  208. smallint do_ctimings, do_timings;
  209. smallint reread_partn;
  210. smallint set_piomode, noisy_piomode;
  211. smallint set_readahead, get_readahead;
  212. smallint set_readonly, get_readonly;
  213. smallint set_unmask, get_unmask;
  214. smallint set_mult, get_mult;
  215. smallint set_dma_q, get_dma_q;
  216. smallint set_nowerr, get_nowerr;
  217. smallint set_keep, get_keep;
  218. smallint set_io32bit, get_io32bit;
  219. int piomode;
  220. unsigned long Xreadahead;
  221. unsigned long readonly;
  222. unsigned long unmask;
  223. unsigned long mult;
  224. unsigned long dma_q;
  225. unsigned long nowerr;
  226. unsigned long keep;
  227. unsigned long io32bit;
  228. #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
  229. unsigned long dma;
  230. smallint set_dma, get_dma;
  231. #endif
  232. #ifdef HDIO_DRIVE_CMD
  233. smallint set_xfermode, get_xfermode;
  234. smallint set_dkeep, get_dkeep;
  235. smallint set_standby, get_standby;
  236. smallint set_lookahead, get_lookahead;
  237. smallint set_prefetch, get_prefetch;
  238. smallint set_defects, get_defects;
  239. smallint set_wcache, get_wcache;
  240. smallint set_doorlock, get_doorlock;
  241. smallint set_seagate, get_seagate;
  242. smallint set_standbynow, get_standbynow;
  243. smallint set_sleepnow, get_sleepnow;
  244. smallint get_powermode;
  245. smallint set_apmmode, get_apmmode;
  246. int xfermode_requested;
  247. unsigned long dkeep;
  248. unsigned long standby_requested;
  249. unsigned long lookahead;
  250. unsigned long prefetch;
  251. unsigned long defects;
  252. unsigned long wcache;
  253. unsigned long doorlock;
  254. unsigned long apmmode;
  255. #endif
  256. USE_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;)
  257. USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint set_busstate, get_busstate;)
  258. USE_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;)
  259. USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;)
  260. USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;)
  261. USE_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;)
  262. USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;)
  263. USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;)
  264. USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;)
  265. #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
  266. unsigned long hwif_data;
  267. unsigned long hwif_ctrl;
  268. unsigned long hwif_irq;
  269. #endif
  270. #ifdef DO_FLUSHCACHE
  271. unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 };
  272. #endif
  273. };
  274. #define G (*(struct globals*)&bb_common_bufsiz1)
  275. struct BUG_G_too_big {
  276. char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
  277. };
  278. #define get_identity (G.get_identity )
  279. #define get_geom (G.get_geom )
  280. #define do_flush (G.do_flush )
  281. #define do_ctimings (G.do_ctimings )
  282. #define do_timings (G.do_timings )
  283. #define reread_partn (G.reread_partn )
  284. #define set_piomode (G.set_piomode )
  285. #define noisy_piomode (G.noisy_piomode )
  286. #define set_readahead (G.set_readahead )
  287. #define get_readahead (G.get_readahead )
  288. #define set_readonly (G.set_readonly )
  289. #define get_readonly (G.get_readonly )
  290. #define set_unmask (G.set_unmask )
  291. #define get_unmask (G.get_unmask )
  292. #define set_mult (G.set_mult )
  293. #define get_mult (G.get_mult )
  294. #define set_dma_q (G.set_dma_q )
  295. #define get_dma_q (G.get_dma_q )
  296. #define set_nowerr (G.set_nowerr )
  297. #define get_nowerr (G.get_nowerr )
  298. #define set_keep (G.set_keep )
  299. #define get_keep (G.get_keep )
  300. #define set_io32bit (G.set_io32bit )
  301. #define get_io32bit (G.get_io32bit )
  302. #define piomode (G.piomode )
  303. #define Xreadahead (G.Xreadahead )
  304. #define readonly (G.readonly )
  305. #define unmask (G.unmask )
  306. #define mult (G.mult )
  307. #define dma_q (G.dma_q )
  308. #define nowerr (G.nowerr )
  309. #define keep (G.keep )
  310. #define io32bit (G.io32bit )
  311. #define dma (G.dma )
  312. #define set_dma (G.set_dma )
  313. #define get_dma (G.get_dma )
  314. #define set_xfermode (G.set_xfermode )
  315. #define get_xfermode (G.get_xfermode )
  316. #define set_dkeep (G.set_dkeep )
  317. #define get_dkeep (G.get_dkeep )
  318. #define set_standby (G.set_standby )
  319. #define get_standby (G.get_standby )
  320. #define set_lookahead (G.set_lookahead )
  321. #define get_lookahead (G.get_lookahead )
  322. #define set_prefetch (G.set_prefetch )
  323. #define get_prefetch (G.get_prefetch )
  324. #define set_defects (G.set_defects )
  325. #define get_defects (G.get_defects )
  326. #define set_wcache (G.set_wcache )
  327. #define get_wcache (G.get_wcache )
  328. #define set_doorlock (G.set_doorlock )
  329. #define get_doorlock (G.get_doorlock )
  330. #define set_seagate (G.set_seagate )
  331. #define get_seagate (G.get_seagate )
  332. #define set_standbynow (G.set_standbynow )
  333. #define get_standbynow (G.get_standbynow )
  334. #define set_sleepnow (G.set_sleepnow )
  335. #define get_sleepnow (G.get_sleepnow )
  336. #define get_powermode (G.get_powermode )
  337. #define set_apmmode (G.set_apmmode )
  338. #define get_apmmode (G.get_apmmode )
  339. #define xfermode_requested (G.xfermode_requested )
  340. #define dkeep (G.dkeep )
  341. #define standby_requested (G.standby_requested )
  342. #define lookahead (G.lookahead )
  343. #define prefetch (G.prefetch )
  344. #define defects (G.defects )
  345. #define wcache (G.wcache )
  346. #define doorlock (G.doorlock )
  347. #define apmmode (G.apmmode )
  348. #define get_IDentity (G.get_IDentity )
  349. #define set_busstate (G.set_busstate )
  350. #define get_busstate (G.get_busstate )
  351. #define perform_reset (G.perform_reset )
  352. #define perform_tristate (G.perform_tristate )
  353. #define unregister_hwif (G.unregister_hwif )
  354. #define scan_hwif (G.scan_hwif )
  355. #define busstate (G.busstate )
  356. #define tristate (G.tristate )
  357. #define hwif (G.hwif )
  358. #define hwif_data (G.hwif_data )
  359. #define hwif_ctrl (G.hwif_ctrl )
  360. #define hwif_irq (G.hwif_irq )
  361. /* Busybox messages and functions */
  362. #if ENABLE_IOCTL_HEX2STR_ERROR
  363. static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt, const char *string)
  364. {
  365. if (!ioctl(fd, cmd, args))
  366. return 0;
  367. args[0] = alt;
  368. return bb_ioctl_or_warn(fd, cmd, args, string);
  369. }
  370. #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt,#cmd)
  371. #else
  372. static int ioctl_alt_func(/*int fd,*/ int cmd, unsigned char *args, int alt)
  373. {
  374. if (!ioctl(fd, cmd, args))
  375. return 0;
  376. args[0] = alt;
  377. return bb_ioctl_or_warn(fd, cmd, args);
  378. }
  379. #define ioctl_alt_or_warn(cmd,args,alt) ioctl_alt_func(cmd,args,alt)
  380. #endif
  381. static void on_off(int value)
  382. {
  383. puts(value ? " (on)" : " (off)");
  384. }
  385. static void print_flag_on_off(int get_arg, const char *s, unsigned long arg)
  386. {
  387. if (get_arg) {
  388. printf(" setting %s to %ld", s, arg);
  389. on_off(arg);
  390. }
  391. }
  392. static void print_value_on_off(const char *str, unsigned long argp)
  393. {
  394. printf(" %s\t= %2ld", str, argp);
  395. on_off(argp != 0);
  396. }
  397. #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
  398. static void print_ascii(const char *p, int length)
  399. {
  400. #if BB_BIG_ENDIAN
  401. #define LE_ONLY(x)
  402. enum { ofs = 0 };
  403. #else
  404. #define LE_ONLY(x) x
  405. /* every 16bit word is big-endian (i.e. inverted) */
  406. /* accessing bytes in 1,0, 3,2, 5,4... sequence */
  407. int ofs = 1;
  408. #endif
  409. length *= 2;
  410. /* find first non-space & print it */
  411. while (length && p[ofs] != ' ') {
  412. p++;
  413. LE_ONLY(ofs = -ofs;)
  414. length--;
  415. }
  416. while (length && p[ofs]) {
  417. bb_putchar(p[ofs]);
  418. p++;
  419. LE_ONLY(ofs = -ofs;)
  420. length--;
  421. }
  422. bb_putchar('\n');
  423. #undef LE_ONLY
  424. }
  425. static void xprint_ascii(uint16_t *val, int i, const char *string, int n)
  426. {
  427. if (val[i]) {
  428. printf("\t%-20s", string);
  429. print_ascii((void*)&val[i], n);
  430. }
  431. }
  432. static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
  433. {
  434. uint16_t ii;
  435. uint8_t err_dma = 0;
  436. for (ii = 0; ii <= MODE_MAX; ii++) {
  437. if (mode_sel & 0x0001) {
  438. printf("*%cdma%u ", cc, ii);
  439. if (*have_mode)
  440. err_dma = 1;
  441. *have_mode = 1;
  442. } else if (mode_sup & 0x0001)
  443. printf("%cdma%u ", cc, ii);
  444. mode_sup >>= 1;
  445. mode_sel >>= 1;
  446. }
  447. return err_dma;
  448. }
  449. static const char pkt_str[] ALIGN1 =
  450. "Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
  451. "Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
  452. "Printer" "\0" /* word 0, bits 12-8 = 02 */
  453. "Processor" "\0" /* word 0, bits 12-8 = 03 */
  454. "Write-once device" "\0" /* word 0, bits 12-8 = 04 */
  455. "CD-ROM" "\0" /* word 0, bits 12-8 = 05 */
  456. "Scanner" "\0" /* word 0, bits 12-8 = 06 */
  457. "Optical memory" "\0" /* word 0, bits 12-8 = 07 */
  458. "Medium changer" "\0" /* word 0, bits 12-8 = 08 */
  459. "Communications device" "\0" /* word 0, bits 12-8 = 09 */
  460. "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0a */
  461. "ACS-IT8 device" "\0" /* word 0, bits 12-8 = 0b */
  462. "Array controller" "\0" /* word 0, bits 12-8 = 0c */
  463. "Enclosure services" "\0" /* word 0, bits 12-8 = 0d */
  464. "Reduced block command device" "\0" /* word 0, bits 12-8 = 0e */
  465. "Optical card reader/writer" "\0" /* word 0, bits 12-8 = 0f */
  466. ;
  467. static const char ata1_cfg_str[] ALIGN1 = /* word 0 in ATA-1 mode */
  468. "reserved" "\0" /* bit 0 */
  469. "hard sectored" "\0" /* bit 1 */
  470. "soft sectored" "\0" /* bit 2 */
  471. "not MFM encoded " "\0" /* bit 3 */
  472. "head switch time > 15us" "\0" /* bit 4 */
  473. "spindle motor control option" "\0" /* bit 5 */
  474. "fixed drive" "\0" /* bit 6 */
  475. "removable drive" "\0" /* bit 7 */
  476. "disk xfer rate <= 5Mbs" "\0" /* bit 8 */
  477. "disk xfer rate > 5Mbs, <= 10Mbs" "\0" /* bit 9 */
  478. "disk xfer rate > 5Mbs" "\0" /* bit 10 */
  479. "rotational speed tol." "\0" /* bit 11 */
  480. "data strobe offset option" "\0" /* bit 12 */
  481. "track offset option" "\0" /* bit 13 */
  482. "format speed tolerance gap reqd" "\0" /* bit 14 */
  483. "ATAPI" /* bit 14 */
  484. ;
  485. static const char minor_str[] ALIGN1 =
  486. /* word 81 value: */
  487. "Unspecified" "\0" /* 0x0000 */
  488. "ATA-1 X3T9.2 781D prior to rev.4" "\0" /* 0x0001 */
  489. "ATA-1 published, ANSI X3.221-1994" "\0" /* 0x0002 */
  490. "ATA-1 X3T9.2 781D rev.4" "\0" /* 0x0003 */
  491. "ATA-2 published, ANSI X3.279-1996" "\0" /* 0x0004 */
  492. "ATA-2 X3T10 948D prior to rev.2k" "\0" /* 0x0005 */
  493. "ATA-3 X3T10 2008D rev.1" "\0" /* 0x0006 */
  494. "ATA-2 X3T10 948D rev.2k" "\0" /* 0x0007 */
  495. "ATA-3 X3T10 2008D rev.0" "\0" /* 0x0008 */
  496. "ATA-2 X3T10 948D rev.3" "\0" /* 0x0009 */
  497. "ATA-3 published, ANSI X3.298-199x" "\0" /* 0x000a */
  498. "ATA-3 X3T10 2008D rev.6" "\0" /* 0x000b */
  499. "ATA-3 X3T13 2008D rev.7 and 7a" "\0" /* 0x000c */
  500. "ATA/ATAPI-4 X3T13 1153D rev.6" "\0" /* 0x000d */
  501. "ATA/ATAPI-4 T13 1153D rev.13" "\0" /* 0x000e */
  502. "ATA/ATAPI-4 X3T13 1153D rev.7" "\0" /* 0x000f */
  503. "ATA/ATAPI-4 T13 1153D rev.18" "\0" /* 0x0010 */
  504. "ATA/ATAPI-4 T13 1153D rev.15" "\0" /* 0x0011 */
  505. "ATA/ATAPI-4 published, ANSI INCITS 317-1998" "\0" /* 0x0012 */
  506. "ATA/ATAPI-5 T13 1321D rev.3" "\0" /* 0x0013 */
  507. "ATA/ATAPI-4 T13 1153D rev.14" "\0" /* 0x0014 */
  508. "ATA/ATAPI-5 T13 1321D rev.1" "\0" /* 0x0015 */
  509. "ATA/ATAPI-5 published, ANSI INCITS 340-2000" "\0" /* 0x0016 */
  510. "ATA/ATAPI-4 T13 1153D rev.17" "\0" /* 0x0017 */
  511. "ATA/ATAPI-6 T13 1410D rev.0" "\0" /* 0x0018 */
  512. "ATA/ATAPI-6 T13 1410D rev.3a" "\0" /* 0x0019 */
  513. "ATA/ATAPI-7 T13 1532D rev.1" "\0" /* 0x001a */
  514. "ATA/ATAPI-6 T13 1410D rev.2" "\0" /* 0x001b */
  515. "ATA/ATAPI-6 T13 1410D rev.1" "\0" /* 0x001c */
  516. "ATA/ATAPI-7 published, ANSI INCITS 397-2005" "\0" /* 0x001d */
  517. "ATA/ATAPI-7 T13 1532D rev.0" "\0" /* 0x001e */
  518. "reserved" "\0" /* 0x001f */
  519. "reserved" "\0" /* 0x0020 */
  520. "ATA/ATAPI-7 T13 1532D rev.4a" "\0" /* 0x0021 */
  521. "ATA/ATAPI-6 published, ANSI INCITS 361-2002" "\0" /* 0x0022 */
  522. "reserved" /* 0x0023-0xfffe */
  523. ;
  524. static const char actual_ver[MINOR_MAX + 2] ALIGN1 = {
  525. /* word 81 value: */
  526. 0, /* 0x0000 WARNING: actual_ver[] array */
  527. 1, /* 0x0001 WARNING: corresponds */
  528. 1, /* 0x0002 WARNING: *exactly* */
  529. 1, /* 0x0003 WARNING: to the ATA/ */
  530. 2, /* 0x0004 WARNING: ATAPI version */
  531. 2, /* 0x0005 WARNING: listed in */
  532. 3, /* 0x0006 WARNING: the */
  533. 2, /* 0x0007 WARNING: minor_str */
  534. 3, /* 0x0008 WARNING: array */
  535. 2, /* 0x0009 WARNING: above. */
  536. 3, /* 0x000a WARNING: */
  537. 3, /* 0x000b WARNING: If you change */
  538. 3, /* 0x000c WARNING: that one, */
  539. 4, /* 0x000d WARNING: change this one */
  540. 4, /* 0x000e WARNING: too!!! */
  541. 4, /* 0x000f */
  542. 4, /* 0x0010 */
  543. 4, /* 0x0011 */
  544. 4, /* 0x0012 */
  545. 5, /* 0x0013 */
  546. 4, /* 0x0014 */
  547. 5, /* 0x0015 */
  548. 5, /* 0x0016 */
  549. 4, /* 0x0017 */
  550. 6, /* 0x0018 */
  551. 6, /* 0x0019 */
  552. 7, /* 0x001a */
  553. 6, /* 0x001b */
  554. 6, /* 0x001c */
  555. 7, /* 0x001d */
  556. 7, /* 0x001e */
  557. 0, /* 0x001f */
  558. 0, /* 0x0020 */
  559. 7, /* 0x0021 */
  560. 6, /* 0x0022 */
  561. 0 /* 0x0023-0xfffe */
  562. };
  563. static const char cmd_feat_str[] ALIGN1 =
  564. "" "\0" /* word 82 bit 15: obsolete */
  565. "NOP cmd" "\0" /* word 82 bit 14 */
  566. "READ BUFFER cmd" "\0" /* word 82 bit 13 */
  567. "WRITE BUFFER cmd" "\0" /* word 82 bit 12 */
  568. "" "\0" /* word 82 bit 11: obsolete */
  569. "Host Protected Area feature set" "\0" /* word 82 bit 10 */
  570. "DEVICE RESET cmd" "\0" /* word 82 bit 9 */
  571. "SERVICE interrupt" "\0" /* word 82 bit 8 */
  572. "Release interrupt" "\0" /* word 82 bit 7 */
  573. "Look-ahead" "\0" /* word 82 bit 6 */
  574. "Write cache" "\0" /* word 82 bit 5 */
  575. "PACKET command feature set" "\0" /* word 82 bit 4 */
  576. "Power Management feature set" "\0" /* word 82 bit 3 */
  577. "Removable Media feature set" "\0" /* word 82 bit 2 */
  578. "Security Mode feature set" "\0" /* word 82 bit 1 */
  579. "SMART feature set" "\0" /* word 82 bit 0 */
  580. /* -------------- */
  581. "" "\0" /* word 83 bit 15: !valid bit */
  582. "" "\0" /* word 83 bit 14: valid bit */
  583. "FLUSH CACHE EXT cmd" "\0" /* word 83 bit 13 */
  584. "Mandatory FLUSH CACHE cmd " "\0" /* word 83 bit 12 */
  585. "Device Configuration Overlay feature set " "\0"
  586. "48-bit Address feature set " "\0" /* word 83 bit 10 */
  587. "" "\0"
  588. "SET MAX security extension" "\0" /* word 83 bit 8 */
  589. "Address Offset Reserved Area Boot" "\0" /* word 83 bit 7 */
  590. "SET FEATURES subcommand required to spinup after power up" "\0"
  591. "Power-Up In Standby feature set" "\0" /* word 83 bit 5 */
  592. "Removable Media Status Notification feature set" "\0"
  593. "Adv. Power Management feature set" "\0" /* word 83 bit 3 */
  594. "CFA feature set" "\0" /* word 83 bit 2 */
  595. "READ/WRITE DMA QUEUED" "\0" /* word 83 bit 1 */
  596. "DOWNLOAD MICROCODE cmd" "\0" /* word 83 bit 0 */
  597. /* -------------- */
  598. "" "\0" /* word 84 bit 15: !valid bit */
  599. "" "\0" /* word 84 bit 14: valid bit */
  600. "" "\0" /* word 84 bit 13: reserved */
  601. "" "\0" /* word 84 bit 12: reserved */
  602. "" "\0" /* word 84 bit 11: reserved */
  603. "" "\0" /* word 84 bit 10: reserved */
  604. "" "\0" /* word 84 bit 9: reserved */
  605. "" "\0" /* word 84 bit 8: reserved */
  606. "" "\0" /* word 84 bit 7: reserved */
  607. "" "\0" /* word 84 bit 6: reserved */
  608. "General Purpose Logging feature set" "\0" /* word 84 bit 5 */
  609. "" "\0" /* word 84 bit 4: reserved */
  610. "Media Card Pass Through Command feature set " "\0"
  611. "Media serial number " "\0" /* word 84 bit 2 */
  612. "SMART self-test " "\0" /* word 84 bit 1 */
  613. "SMART error logging " /* word 84 bit 0 */
  614. ;
  615. static const char secu_str[] ALIGN1 =
  616. "supported" "\0" /* word 128, bit 0 */
  617. "enabled" "\0" /* word 128, bit 1 */
  618. "locked" "\0" /* word 128, bit 2 */
  619. "frozen" "\0" /* word 128, bit 3 */
  620. "expired: security count" "\0" /* word 128, bit 4 */
  621. "supported: enhanced erase" /* word 128, bit 5 */
  622. ;
  623. // Parse 512 byte disk identification block and print much crap.
  624. static void identify(uint16_t *val) ATTRIBUTE_NORETURN;
  625. static void identify(uint16_t *val)
  626. {
  627. uint16_t ii, jj, kk;
  628. uint16_t like_std = 1, std = 0, min_std = 0xffff;
  629. uint16_t dev = NO_DEV, eqpt = NO_DEV;
  630. uint8_t have_mode = 0, err_dma = 0;
  631. uint8_t chksum = 0;
  632. uint32_t ll, mm, nn, oo;
  633. uint64_t bbbig; /* (:) */
  634. const char *strng;
  635. #if BB_BIG_ENDIAN
  636. uint16_t buf[256];
  637. // Adjust for endianness
  638. swab(val, buf, sizeof(buf));
  639. val = buf;
  640. #endif
  641. /* check if we recognise the device type */
  642. bb_putchar('\n');
  643. if (!(val[GEN_CONFIG] & NOT_ATA)) {
  644. dev = ATA_DEV;
  645. printf("ATA device, with ");
  646. } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) {
  647. dev = ATA_DEV;
  648. like_std = 4;
  649. printf("CompactFlash ATA device, with ");
  650. } else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
  651. dev = ATAPI_DEV;
  652. eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
  653. printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
  654. like_std = 3;
  655. } else
  656. /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
  657. bb_error_msg_and_die("unknown device type");
  658. printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
  659. /* Info from the specific configuration word says whether or not the
  660. * ID command completed correctly. It is only defined, however in
  661. * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
  662. * standards. Since the values allowed for this word are extremely
  663. * specific, it should be safe to check it now, even though we don't
  664. * know yet what standard this device is using.
  665. */
  666. if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)
  667. || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL)
  668. ) {
  669. like_std = 5;
  670. if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL))
  671. printf("powers-up in standby; SET FEATURES subcmd spins-up.\n");
  672. if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE))
  673. printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
  674. }
  675. /* output the model and serial numbers and the fw revision */
  676. xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
  677. xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
  678. xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
  679. xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
  680. xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
  681. /* major & minor standards version number (Note: these words were not
  682. * defined until ATA-3 & the CDROM std uses different words.) */
  683. printf("Standards:");
  684. if (eqpt != CDROM) {
  685. if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
  686. if (like_std < 3) like_std = 3;
  687. std = actual_ver[val[MINOR]];
  688. if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
  689. }
  690. /* looks like when they up-issue the std, they obsolete one;
  691. * thus, only the newest 4 issues need be supported. (That's
  692. * what "kk" and "min_std" are all about.) */
  693. if (val[MAJOR] && (val[MAJOR] != NOVAL_1)) {
  694. printf("\n\tSupported: ");
  695. jj = val[MAJOR] << 1;
  696. kk = like_std >4 ? like_std-4: 0;
  697. for (ii = 14; (ii >0)&&(ii>kk); ii--) {
  698. if (jj & 0x8000) {
  699. printf("%u ", ii);
  700. if (like_std < ii) {
  701. like_std = ii;
  702. kk = like_std >4 ? like_std-4: 0;
  703. }
  704. if (min_std > ii) min_std = ii;
  705. }
  706. jj <<= 1;
  707. }
  708. if (like_std < 3) like_std = 3;
  709. }
  710. /* Figure out what standard the device is using if it hasn't told
  711. * us. If we know the std, check if the device is using any of
  712. * the words from the next level up. It happens.
  713. */
  714. if (like_std < std) like_std = std;
  715. if (((std == 5) || (!std && (like_std < 6))) &&
  716. ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
  717. (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
  718. ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
  719. ( val[CMDS_SUPP_2] & CMDS_W84) ) )
  720. ) {
  721. like_std = 6;
  722. } else if (((std == 4) || (!std && (like_std < 5))) &&
  723. ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
  724. (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
  725. ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
  726. (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
  727. {
  728. like_std = 5;
  729. } else if (((std == 3) || (!std && (like_std < 4))) &&
  730. ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
  731. ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
  732. (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
  733. (( val[CAPAB_1] & VALID) == VALID_VAL) ||
  734. (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
  735. (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) )
  736. ) {
  737. like_std = 4;
  738. } else if (((std == 2) || (!std && (like_std < 3)))
  739. && ((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
  740. ) {
  741. like_std = 3;
  742. } else if (((std == 1) || (!std && (like_std < 2))) &&
  743. ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
  744. (val[WHATS_VALID] & OK_W64_70)) )
  745. {
  746. like_std = 2;
  747. }
  748. if (!std)
  749. printf("\n\tLikely used: %u\n", like_std);
  750. else if (like_std > std)
  751. printf("& some of %u\n", like_std);
  752. else
  753. bb_putchar('\n');
  754. } else {
  755. /* TBD: do CDROM stuff more thoroughly. For now... */
  756. kk = 0;
  757. if (val[CDR_MINOR] == 9) {
  758. kk = 1;
  759. printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
  760. }
  761. if (val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) {
  762. kk = 1;
  763. printf("\n\tSupported: CD-ROM ATAPI");
  764. jj = val[CDR_MAJOR] >> 1;
  765. for (ii = 1; ii < 15; ii++) {
  766. if (jj & 0x0001) printf("-%u ", ii);
  767. jj >>= 1;
  768. }
  769. }
  770. puts(kk ? "" : "\n\tLikely used CD-ROM ATAPI-1");
  771. /* the cdrom stuff is more like ATA-2 than anything else, so: */
  772. like_std = 2;
  773. }
  774. if (min_std == 0xffff)
  775. min_std = like_std > 4 ? like_std - 3 : 1;
  776. printf("Configuration:\n");
  777. /* more info from the general configuration word */
  778. if ((eqpt != CDROM) && (like_std == 1)) {
  779. jj = val[GEN_CONFIG] >> 1;
  780. for (ii = 1; ii < 15; ii++) {
  781. if (jj & 0x0001)
  782. printf("\t%s\n", nth_string(ata1_cfg_str, ii));
  783. jj >>=1;
  784. }
  785. }
  786. if (dev == ATAPI_DEV) {
  787. if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_3MS_VAL)
  788. strng = "3ms";
  789. else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL)
  790. strng = "<=10ms with INTRQ";
  791. else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL)
  792. strng ="50us";
  793. else
  794. strng = "unknown";
  795. printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */
  796. if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_12_VAL)
  797. strng = "12 bytes";
  798. else if ((val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) == PKT_SIZE_16_VAL)
  799. strng = "16 bytes";
  800. else
  801. strng = "unknown";
  802. puts(strng);
  803. } else {
  804. /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
  805. ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
  806. mm = 0; bbbig = 0;
  807. if ((ll > 0x00FBFC10) && (!val[LCYLS]))
  808. printf("\tCHS addressing not supported\n");
  809. else {
  810. jj = val[WHATS_VALID] & OK_W54_58;
  811. printf("\tLogical\t\tmax\tcurrent\n\tcylinders\t%u\t%u\n\theads\t\t%u\t%u\n\tsectors/track\t%u\t%u\n\t--\n",
  812. val[LCYLS],jj?val[LCYLS_CUR]:0, val[LHEADS],jj?val[LHEADS_CUR]:0, val[LSECTS],jj?val[LSECTS_CUR]:0);
  813. if ((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES]))
  814. printf("\tbytes/track: %u\tbytes/sector: %u\n", val[TRACK_BYTES], val[SECT_BYTES]);
  815. if (jj) {
  816. mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
  817. if (like_std < 3) {
  818. /* check Endian of capacity bytes */
  819. nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
  820. oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
  821. if (abs(mm - nn) > abs(oo - nn))
  822. mm = oo;
  823. }
  824. printf("\tCHS current addressable sectors:%11u\n", mm);
  825. }
  826. }
  827. /* LBA addressing */
  828. printf("\tLBA user addressable sectors:%11u\n", ll);
  829. if (((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
  830. && (val[CMDS_SUPP_1] & SUPPORT_48_BIT)
  831. ) {
  832. bbbig = (uint64_t)val[LBA_64_MSB] << 48 |
  833. (uint64_t)val[LBA_48_MSB] << 32 |
  834. (uint64_t)val[LBA_MID] << 16 |
  835. val[LBA_LSB];
  836. printf("\tLBA48 user addressable sectors:%11"PRIu64"\n", bbbig);
  837. }
  838. if (!bbbig)
  839. bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */
  840. printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11);
  841. bbbig = (bbbig << 9) / 1000000;
  842. printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig);
  843. if (bbbig > 1000)
  844. printf("(%"PRIu64" GB)\n", bbbig/1000);
  845. else
  846. bb_putchar('\n');
  847. }
  848. /* hw support of commands (capabilities) */
  849. printf("Capabilities:\n\t");
  850. if (dev == ATAPI_DEV) {
  851. if (eqpt != CDROM && (val[CAPAB_0] & CMD_Q_SUP)) printf("Cmd queuing, ");
  852. if (val[CAPAB_0] & OVLP_SUP) printf("Cmd overlap, ");
  853. }
  854. if (val[CAPAB_0] & LBA_SUP) printf("LBA, ");
  855. if (like_std != 1) {
  856. printf("IORDY%s(can%s be disabled)\n",
  857. !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "",
  858. (val[CAPAB_0] & IORDY_OFF) ? "" :"not");
  859. } else
  860. printf("no IORDY\n");
  861. if ((like_std == 1) && val[BUF_TYPE]) {
  862. printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE],
  863. (val[BUF_TYPE] < 2) ? "single port, single-sector" : "dual port, multi-sector",
  864. (val[BUF_TYPE] > 2) ? " with read caching ability" : "");
  865. }
  866. if ((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) {
  867. printf("\tBuffer size: %.1fkB\n", (float)val[BUFFER__SIZE]/2);
  868. }
  869. if ((min_std < 4) && (val[RW_LONG])) {
  870. printf("\tbytes avail on r/w long: %u\n", val[RW_LONG]);
  871. }
  872. if ((eqpt != CDROM) && (like_std > 3)) {
  873. printf("\tQueue depth: %u\n", (val[QUEUE_DEPTH] & DEPTH_BITS) + 1);
  874. }
  875. if (dev == ATA_DEV) {
  876. if (like_std == 1)
  877. printf("\tCan%s perform double-word IO\n", (!val[DWORD_IO]) ? "not" : "");
  878. else {
  879. printf("\tStandby timer values: spec'd by %s", (val[CAPAB_0] & STD_STBY) ? "Standard" : "Vendor");
  880. if ((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
  881. printf(", %s device specific minimum\n", (val[CAPAB_1] & MIN_STANDBY_TIMER) ? "with" : "no");
  882. else
  883. bb_putchar('\n');
  884. }
  885. printf("\tR/W multiple sector transfer: ");
  886. if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
  887. printf("not supported\n");
  888. else {
  889. printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER);
  890. if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID)
  891. printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER);
  892. else
  893. printf("?\n");
  894. }
  895. if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
  896. /* We print out elsewhere whether the APM feature is enabled or
  897. not. If it's not enabled, let's not repeat the info; just print
  898. nothing here. */
  899. printf("\tAdvancedPM level: ");
  900. if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
  901. uint8_t apm_level = val[ADV_PWR] & 0x00FF;
  902. printf("%u (0x%x)\n", apm_level, apm_level);
  903. }
  904. else
  905. printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
  906. }
  907. if (like_std > 5 && val[ACOUSTIC]) {
  908. printf("\tRecommended acoustic management value: %u, current value: %u\n",
  909. (val[ACOUSTIC] >> 8) & 0x00ff, val[ACOUSTIC] & 0x00ff);
  910. }
  911. } else {
  912. /* ATAPI */
  913. if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
  914. printf("\tATA sw reset required\n");
  915. if (val[PKT_REL] || val[SVC_NBSY]) {
  916. printf("\tOverlap support:");
  917. if (val[PKT_REL]) printf(" %uus to release bus.", val[PKT_REL]);
  918. if (val[SVC_NBSY]) printf(" %uus to clear BSY after SERVICE cmd.", val[SVC_NBSY]);
  919. bb_putchar('\n');
  920. }
  921. }
  922. /* DMA stuff. Check that only one DMA mode is selected. */
  923. printf("\tDMA: ");
  924. if (!(val[CAPAB_0] & DMA_SUP))
  925. printf("not supported\n");
  926. else {
  927. if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA])
  928. printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8);
  929. if (val[SINGLE_DMA]) {
  930. jj = val[SINGLE_DMA];
  931. kk = val[SINGLE_DMA] >> 8;
  932. err_dma += mode_loop(jj, kk, 's', &have_mode);
  933. }
  934. if (val[MULTI_DMA]) {
  935. jj = val[MULTI_DMA];
  936. kk = val[MULTI_DMA] >> 8;
  937. err_dma += mode_loop(jj, kk, 'm', &have_mode);
  938. }
  939. if ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) {
  940. jj = val[ULTRA_DMA];
  941. kk = val[ULTRA_DMA] >> 8;
  942. err_dma += mode_loop(jj, kk, 'u', &have_mode);
  943. }
  944. if (err_dma || !have_mode) printf("(?)");
  945. bb_putchar('\n');
  946. if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP))
  947. printf("\t\tInterleaved DMA support\n");
  948. if ((val[WHATS_VALID] & OK_W64_70)
  949. && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])
  950. ) {
  951. printf("\t\tCycle time:");
  952. if (val[DMA_TIME_MIN]) printf(" min=%uns", val[DMA_TIME_MIN]);
  953. if (val[DMA_TIME_NORM]) printf(" recommended=%uns", val[DMA_TIME_NORM]);
  954. bb_putchar('\n');
  955. }
  956. }
  957. /* Programmed IO stuff */
  958. printf("\tPIO: ");
  959. /* If a drive supports mode n (e.g. 3), it also supports all modes less
  960. * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
  961. if ((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) {
  962. jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
  963. for (ii = 0; ii <= PIO_MODE_MAX; ii++) {
  964. if (jj & 0x0001) printf("pio%d ", ii);
  965. jj >>=1;
  966. }
  967. bb_putchar('\n');
  968. } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) {
  969. for (ii = 0; ii <= val[PIO_MODE]>>8; ii++)
  970. printf("pio%d ", ii);
  971. bb_putchar('\n');
  972. } else
  973. puts("unknown");
  974. if (val[WHATS_VALID] & OK_W64_70) {
  975. if (val[PIO_NO_FLOW] || val[PIO_FLOW]) {
  976. printf("\t\tCycle time:");
  977. if (val[PIO_NO_FLOW]) printf(" no flow control=%uns", val[PIO_NO_FLOW]);
  978. if (val[PIO_FLOW]) printf(" IORDY flow control=%uns", val[PIO_FLOW]);
  979. bb_putchar('\n');
  980. }
  981. }
  982. if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) {
  983. printf("Commands/features:\n\tEnabled\tSupported:\n");
  984. jj = val[CMDS_SUPP_0];
  985. kk = val[CMDS_EN_0];
  986. for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
  987. const char *feat_str = nth_string(cmd_feat_str, ii);
  988. if ((jj & 0x8000) && (*feat_str != '\0')) {
  989. printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
  990. }
  991. jj <<= 1;
  992. kk <<= 1;
  993. if (ii % 16 == 15) {
  994. jj = val[CMDS_SUPP_0+1+(ii/16)];
  995. kk = val[CMDS_EN_0+1+(ii/16)];
  996. }
  997. if (ii == 31) {
  998. if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
  999. ii +=16;
  1000. }
  1001. }
  1002. }
  1003. /* Removable Media Status Notification feature set */
  1004. if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
  1005. printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
  1006. /* security */
  1007. if ((eqpt != CDROM) && (like_std > 3)
  1008. && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])
  1009. ) {
  1010. printf("Security:\n");
  1011. if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1))
  1012. printf("\tMaster password revision code = %u\n", val[PSWD_CODE]);
  1013. jj = val[SECU_STATUS];
  1014. if (jj) {
  1015. for (ii = 0; ii < NUM_SECU_STR; ii++) {
  1016. printf("\t%s\t%s\n", (!(jj & 0x0001)) ? "not" : "", nth_string(secu_str, ii));
  1017. jj >>=1;
  1018. }
  1019. if (val[SECU_STATUS] & SECU_ENABLED) {
  1020. printf("\tSecurity level %s\n", (val[SECU_STATUS] & SECU_LEVEL) ? "maximum" : "high");
  1021. }
  1022. }
  1023. jj = val[ERASE_TIME] & ERASE_BITS;
  1024. kk = val[ENH_ERASE_TIME] & ERASE_BITS;
  1025. if (jj || kk) {
  1026. printf("\t");
  1027. if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
  1028. if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
  1029. bb_putchar('\n');
  1030. }
  1031. }
  1032. /* reset result */
  1033. jj = val[HWRST_RSLT];
  1034. if ((jj & VALID) == VALID_VAL) {
  1035. if (!(oo = (jj & RST0)))
  1036. jj >>= 8;
  1037. if ((jj & DEV_DET) == JUMPER_VAL)
  1038. strng = " determined by the jumper";
  1039. else if ((jj & DEV_DET) == CSEL_VAL)
  1040. strng = " determined by CSEL";
  1041. else
  1042. strng = "";
  1043. printf("HW reset results:\n\tCBLID- %s Vih\n\tDevice num = %i%s\n",
  1044. (val[HWRST_RSLT] & CBLID) ? "above" : "below", !(oo), strng);
  1045. }
  1046. /* more stuff from std 5 */
  1047. if ((like_std > 4) && (eqpt != CDROM)) {
  1048. if (val[CFA_PWR_MODE] & VALID_W160) {
  1049. printf("CFA power mode 1:\n\t%s%s\n", (val[CFA_PWR_MODE] & PWR_MODE_OFF) ? "disabled" : "enabled",
  1050. (val[CFA_PWR_MODE] & PWR_MODE_REQ) ? " and required by some commands" : "");
  1051. if (val[CFA_PWR_MODE] & MAX_AMPS)
  1052. printf("\tMaximum current = %uma\n", val[CFA_PWR_MODE] & MAX_AMPS);
  1053. }
  1054. if ((val[INTEGRITY] & SIG) == SIG_VAL) {
  1055. printf("Checksum: %scorrect\n", chksum ? "in" : "");
  1056. }
  1057. }
  1058. exit(EXIT_SUCCESS);
  1059. }
  1060. #endif
  1061. // Historically, if there was no HDIO_OBSOLETE_IDENTITY, then
  1062. // then the HDIO_GET_IDENTITY only returned 142 bytes.
  1063. // Otherwise, HDIO_OBSOLETE_IDENTITY returns 142 bytes,
  1064. // and HDIO_GET_IDENTITY returns 512 bytes. But the latest
  1065. // 2.5.xx kernels no longer define HDIO_OBSOLETE_IDENTITY
  1066. // (which they should, but they should just return -EINVAL).
  1067. //
  1068. // So.. we must now assume that HDIO_GET_IDENTITY returns 512 bytes.
  1069. // On a really old system, it will not, and we will be confused.
  1070. // Too bad, really.
  1071. #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
  1072. static const char cfg_str[] ALIGN1 =
  1073. """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
  1074. "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
  1075. "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
  1076. "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
  1077. ;
  1078. static const char BuffType[] ALIGN1 =
  1079. "unknown""\0" "1Sect""\0" "DualPort""\0" "DualPortCache"
  1080. ;
  1081. static void dump_identity(const struct hd_driveid *id)
  1082. {
  1083. int i;
  1084. const unsigned short int *id_regs = (const void*) id;
  1085. printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
  1086. id->model, id->fw_rev, id->serial_no);
  1087. for (i = 0; i <= 15; i++) {
  1088. if (id->config & (1<<i))
  1089. printf(" %s", nth_string(cfg_str, i));
  1090. }
  1091. printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
  1092. " BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
  1093. id->cyls, id->heads, id->sectors, id->track_bytes,
  1094. id->sector_bytes, id->ecc_bytes,
  1095. id->buf_type, nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
  1096. id->buf_size/2, id->max_multsect);
  1097. if (id->max_multsect) {
  1098. printf(", MultSect=");
  1099. if (!(id->multsect_valid & 1))
  1100. printf("?%u?", id->multsect);
  1101. else if (id->multsect)
  1102. printf("%u", id->multsect);
  1103. else
  1104. printf("off");
  1105. }
  1106. bb_putchar('\n');
  1107. if (!(id->field_valid & 1))
  1108. printf(" (maybe):");
  1109. printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s", id->cur_cyls, id->cur_heads,
  1110. id->cur_sectors,
  1111. (BB_BIG_ENDIAN) ?
  1112. (unsigned long)(id->cur_capacity0 << 16) | id->cur_capacity1 :
  1113. (unsigned long)(id->cur_capacity1 << 16) | id->cur_capacity0,
  1114. ((id->capability&2) == 0) ? "no" : "yes");
  1115. if (id->capability & 2)
  1116. printf(", LBAsects=%u", id->lba_capacity);
  1117. printf("\n IORDY=%s", (id->capability & 8) ? (id->capability & 4) ? "on/off" : "yes" : "no");
  1118. if (((id->capability & 8) || (id->field_valid & 2)) && (id->field_valid & 2))
  1119. printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
  1120. if ((id->capability & 1) && (id->field_valid & 2))
  1121. printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
  1122. printf("\n PIO modes: ");
  1123. if (id->tPIO <= 5) {
  1124. printf("pio0 ");
  1125. if (id->tPIO >= 1) printf("pio1 ");
  1126. if (id->tPIO >= 2) printf("pio2 ");
  1127. }
  1128. if (id->field_valid & 2) {
  1129. if (id->eide_pio_modes & 1) printf("pio3 ");
  1130. if (id->eide_pio_modes & 2) printf("pio4 ");
  1131. if (id->eide_pio_modes &~3) printf("pio? ");
  1132. }
  1133. if (id->capability & 1) {
  1134. if (id->dma_1word | id->dma_mword) {
  1135. printf("\n DMA modes: ");
  1136. if (id->dma_1word & 0x100) printf("*");
  1137. if (id->dma_1word & 1) printf("sdma0 ");
  1138. if (id->dma_1word & 0x200) printf("*");
  1139. if (id->dma_1word & 2) printf("sdma1 ");
  1140. if (id->dma_1word & 0x400) printf("*");
  1141. if (id->dma_1word & 4) printf("sdma2 ");
  1142. if (id->dma_1word & 0xf800) printf("*");
  1143. if (id->dma_1word & 0xf8) printf("sdma? ");
  1144. if (id->dma_mword & 0x100) printf("*");
  1145. if (id->dma_mword & 1) printf("mdma0 ");
  1146. if (id->dma_mword & 0x200) printf("*");
  1147. if (id->dma_mword & 2) printf("mdma1 ");
  1148. if (id->dma_mword & 0x400) printf("*");
  1149. if (id->dma_mword & 4) printf("mdma2 ");
  1150. if (id->dma_mword & 0xf800) printf("*");
  1151. if (id->dma_mword & 0xf8) printf("mdma? ");
  1152. }
  1153. }
  1154. if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
  1155. printf("\n UDMA modes: ");
  1156. if (id->dma_ultra & 0x100) printf("*");
  1157. if (id->dma_ultra & 0x001) printf("udma0 ");
  1158. if (id->dma_ultra & 0x200) printf("*");
  1159. if (id->dma_ultra & 0x002) printf("udma1 ");
  1160. if (id->dma_ultra & 0x400) printf("*");
  1161. if (id->dma_ultra & 0x004) printf("udma2 ");
  1162. #ifdef __NEW_HD_DRIVE_ID
  1163. if (id->hw_config & 0x2000) {
  1164. #else /* !__NEW_HD_DRIVE_ID */
  1165. if (id->word93 & 0x2000) {
  1166. #endif /* __NEW_HD_DRIVE_ID */
  1167. if (id->dma_ultra & 0x0800) printf("*");
  1168. if (id->dma_ultra & 0x0008) printf("udma3 ");
  1169. if (id->dma_ultra & 0x1000) printf("*");
  1170. if (id->dma_ultra & 0x0010) printf("udma4 ");
  1171. if (id->dma_ultra & 0x2000) printf("*");
  1172. if (id->dma_ultra & 0x0020) printf("udma5 ");
  1173. if (id->dma_ultra & 0x4000) printf("*");
  1174. if (id->dma_ultra & 0x0040) printf("udma6 ");
  1175. if (id->dma_ultra & 0x8000) printf("*");
  1176. if (id->dma_ultra & 0x0080) printf("udma7 ");
  1177. }
  1178. }
  1179. printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
  1180. if (id_regs[83] & 8) {
  1181. if (!(id_regs[86] & 8))
  1182. printf(": disabled (255)");
  1183. else if ((id_regs[91] & 0xFF00) != 0x4000)
  1184. printf(": unknown setting");
  1185. else
  1186. printf(": mode=0x%02X (%u)", id_regs[91] & 0xFF, id_regs[91] & 0xFF);
  1187. }
  1188. if (id_regs[82] & 0x20)
  1189. printf(" WriteCache=%s", (id_regs[85] & 0x20) ? "enabled" : "disabled");
  1190. #ifdef __NEW_HD_DRIVE_ID
  1191. if ((id->minor_rev_num && id->minor_rev_num <= 31)
  1192. || (id->major_rev_num && id->minor_rev_num <= 31)
  1193. ) {
  1194. printf("\n Drive conforms to: %s: ", (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
  1195. if (id->major_rev_num != 0x0000 && /* NOVAL_0 */
  1196. id->major_rev_num != 0xFFFF) { /* NOVAL_1 */
  1197. for (i = 0; i <= 15; i++) {
  1198. if (id->major_rev_num & (1<<i))
  1199. printf(" ATA/ATAPI-%u", i);
  1200. }
  1201. }
  1202. }
  1203. #endif /* __NEW_HD_DRIVE_ID */
  1204. printf("\n\n * current active mode\n\n");
  1205. }
  1206. #endif
  1207. static void flush_buffer_cache(/*int fd*/ void)
  1208. {
  1209. fsync(fd); /* flush buffers */
  1210. ioctl_or_warn(fd, BLKFLSBUF, NULL); /* do it again, big time */
  1211. #ifdef HDIO_DRIVE_CMD
  1212. sleep(1);
  1213. if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
  1214. if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
  1215. bb_perror_msg("HDIO_DRIVE_CMD");
  1216. else
  1217. bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
  1218. }
  1219. #endif
  1220. }
  1221. static void seek_to_zero(/*int fd*/ void)
  1222. {
  1223. xlseek(fd, (off_t) 0, SEEK_SET);
  1224. }
  1225. static void read_big_block(/*int fd,*/ char *buf)
  1226. {
  1227. int i;
  1228. xread(fd, buf, TIMING_BUF_BYTES);
  1229. /* access all sectors of buf to ensure the read fully completed */
  1230. for (i = 0; i < TIMING_BUF_BYTES; i += 512)
  1231. buf[i] &= 1;
  1232. }
  1233. static unsigned dev_size_mb(/*int fd*/ void)
  1234. {
  1235. union {
  1236. unsigned long long blksize64;
  1237. unsigned blksize32;
  1238. } u;
  1239. if (0 == ioctl(fd, BLKGETSIZE64, &u.blksize64)) { // bytes
  1240. u.blksize64 /= (1024 * 1024);
  1241. } else {
  1242. xioctl(fd, BLKGETSIZE, &u.blksize32); // sectors
  1243. u.blksize64 = u.blksize32 / (2 * 1024);
  1244. }
  1245. if (u.blksize64 > UINT_MAX)
  1246. return UINT_MAX;
  1247. return u.blksize64;
  1248. }
  1249. static void print_timing(unsigned m, unsigned elapsed_us)
  1250. {
  1251. unsigned sec = elapsed_us / 1000000;
  1252. unsigned hs = (elapsed_us % 1000000) / 10000;
  1253. printf("%5u MB in %u.%02u seconds = %u kB/s\n",
  1254. m, sec, hs,
  1255. /* "| 1" prevents div-by-0 */
  1256. (unsigned) ((unsigned long long)m * (1024 * 1000000) / (elapsed_us | 1))
  1257. // ~= (m * 1024) / (elapsed_us / 1000000)
  1258. // = kb / elapsed_sec
  1259. );
  1260. }
  1261. static void do_time(int cache /*,int fd*/)
  1262. /* cache=1: time cache: repeatedly read N MB at offset 0
  1263. * cache=0: time device: linear read, starting at offset 0
  1264. */
  1265. {
  1266. unsigned max_iterations, iterations;
  1267. unsigned start; /* doesn't need to be long long */
  1268. unsigned elapsed, elapsed2;
  1269. unsigned total_MB;
  1270. char *buf = xmalloc(TIMING_BUF_BYTES);
  1271. if (mlock(buf, TIMING_BUF_BYTES))
  1272. bb_perror_msg_and_die("mlock");
  1273. /* Clear out the device request queues & give them time to complete.
  1274. * NB: *small* delay. User is expected to have a clue and to not run
  1275. * heavy io in parallel with measurements. */
  1276. sync();
  1277. sleep(1);
  1278. if (cache) { /* Time cache */
  1279. seek_to_zero();
  1280. read_big_block(buf);
  1281. printf("Timing buffer-cache reads: ");
  1282. } else { /* Time device */
  1283. printf("Timing buffered disk reads:");
  1284. }
  1285. fflush(stdout);
  1286. /* Now do the timing */
  1287. iterations = 0;
  1288. /* Max time to run (small for cache, avoids getting
  1289. * huge total_MB which can overlow unsigned type) */
  1290. elapsed2 = 510000; /* cache */
  1291. max_iterations = UINT_MAX;
  1292. if (!cache) {
  1293. elapsed2 = 3000000; /* not cache */
  1294. /* Don't want to read past the end! */
  1295. max_iterations = dev_size_mb() / TIMING_BUF_MB;
  1296. }
  1297. start = monotonic_us();
  1298. do {
  1299. if (cache)
  1300. seek_to_zero();
  1301. read_big_block(buf);
  1302. elapsed = (unsigned)monotonic_us() - start;
  1303. ++iterations;
  1304. } while (elapsed < elapsed2 && iterations < max_iterations);
  1305. total_MB = iterations * TIMING_BUF_MB;
  1306. //printf(" elapsed:%u iterations:%u ", elapsed, iterations);
  1307. if (cache) {
  1308. /* Cache: remove lseek() and monotonic_us() overheads
  1309. * from elapsed */
  1310. start = monotonic_us();
  1311. do {
  1312. seek_to_zero();
  1313. elapsed2 = (unsigned)monotonic_us() - start;
  1314. } while (--iterations);
  1315. //printf(" elapsed2:%u ", elapsed2);
  1316. elapsed -= elapsed2;
  1317. total_MB *= 2; // BUFCACHE_FACTOR (why?)
  1318. flush_buffer_cache();
  1319. }
  1320. print_timing(total_MB, elapsed);
  1321. munlock(buf, TIMING_BUF_BYTES);
  1322. free(buf);
  1323. }
  1324. #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
  1325. static void bus_state_value(unsigned value)
  1326. {
  1327. if (value == BUSSTATE_ON)
  1328. on_off(1);
  1329. else if (value == BUSSTATE_OFF)
  1330. on_off(0);
  1331. else if (value == BUSSTATE_TRISTATE)
  1332. printf(" (tristate)\n");
  1333. else
  1334. printf(" (unknown: %d)\n", value);
  1335. }
  1336. #endif
  1337. #ifdef HDIO_DRIVE_CMD
  1338. static void interpret_standby(unsigned standby)
  1339. {
  1340. unsigned t;
  1341. printf(" (");
  1342. if (standby == 0)
  1343. printf("off");
  1344. else if (standby == 252)
  1345. printf("21 minutes");
  1346. else if (standby == 253)
  1347. printf("vendor-specific");
  1348. else if (standby == 254)
  1349. printf("reserved");
  1350. else if (standby == 255)
  1351. printf("21 minutes + 15 seconds");
  1352. else if (standby <= 240) {
  1353. t = standby * 5;
  1354. printf("%u minutes + %u seconds", t / 60, t % 60);
  1355. } else if (standby <= 251) {
  1356. t = (standby - 240) * 30;
  1357. printf("%u hours + %u minutes", t / 60, t % 60);
  1358. } else
  1359. printf("illegal value");
  1360. printf(")\n");
  1361. }
  1362. static const uint8_t xfermode_val[] ALIGN1 = {
  1363. 8, 9, 10, 11, 12, 13, 14, 15,
  1364. 16, 17, 18, 19, 20, 21, 22, 23,
  1365. 32, 33, 34, 35, 36, 37, 38, 39,
  1366. 64, 65, 66, 67, 68, 69, 70, 71
  1367. };
  1368. /* NB: we save size by _not_ storing terninating NUL! */
  1369. static const char xfermode_name[][5] ALIGN1 = {
  1370. "pio0", "pio1", "pio2", "pio3", "pio4", "pio5", "pio6", "pio7",
  1371. "sdma0","sdma1","sdma2","sdma3","sdma4","sdma5","sdma6","sdma7",
  1372. "mdma0","mdma1","mdma2","mdma3","mdma4","mdma5","mdma6","mdma7",
  1373. "udma0","udma1","udma2","udma3","udma4","udma5","udma6","udma7"
  1374. };
  1375. static int translate_xfermode(const char *name)
  1376. {
  1377. int val, i;
  1378. for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
  1379. if (!strncmp(name, xfermode_name[i], 5))
  1380. if (strlen(name) <= 5)
  1381. return xfermode_val[i];
  1382. }
  1383. /* Negative numbers are invalid and are caught later */
  1384. val = bb_strtoi(name, NULL, 10);
  1385. if (!errno)
  1386. return val;
  1387. return -1;
  1388. }
  1389. static void interpret_xfermode(unsigned xfermode)
  1390. {
  1391. printf(" (");
  1392. if (xfermode == 0)
  1393. printf("default PIO mode");
  1394. else if (xfermode == 1)
  1395. printf("default PIO mode, disable IORDY");
  1396. else if (xfermode >= 8 && xfermode <= 15)
  1397. printf("PIO flow control mode%u", xfermode - 8);
  1398. else if (xfermode >= 16 && xfermode <= 23)
  1399. printf("singleword DMA mode%u", xfermode - 16);
  1400. else if (xfermode >= 32 && xfermode <= 39)
  1401. printf("multiword DMA mode%u", xfermode - 32);
  1402. else if (xfermode >= 64 && xfermode <= 71)
  1403. printf("UltraDMA mode%u", xfermode - 64);
  1404. else
  1405. printf("unknown");
  1406. printf(")\n");
  1407. }
  1408. #endif /* HDIO_DRIVE_CMD */
  1409. static void print_flag(int flag, const char *s, unsigned long value)
  1410. {
  1411. if (flag)
  1412. printf(" setting %s to %ld\n", s, value);
  1413. }
  1414. static void process_dev(char *devname)
  1415. {
  1416. /*int fd;*/
  1417. long parm, multcount;
  1418. #ifndef HDIO_DRIVE_CMD
  1419. int force_operation = 0;
  1420. #endif
  1421. /* Please restore args[n] to these values after each ioctl
  1422. except for args[2] */
  1423. unsigned char args[4] = { WIN_SETFEATURES, 0, 0, 0 };
  1424. const char *fmt = " %s\t= %2ld";
  1425. /*fd = xopen(devname, O_RDONLY | O_NONBLOCK);*/
  1426. xmove_fd(xopen(devname, O_RDONLY | O_NONBLOCK), fd);
  1427. printf("\n%s:\n", devname);
  1428. if (set_readahead) {
  1429. print_flag(get_readahead, "fs readahead", Xreadahead);
  1430. ioctl_or_warn(fd, BLKRASET, (int *)Xreadahead);
  1431. }
  1432. #if ENABLE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
  1433. if (unregister_hwif) {
  1434. printf(" attempting to unregister hwif#%lu\n", hwif);
  1435. ioctl_or_warn(fd, HDIO_UNREGISTER_HWIF, (int *)(unsigned long)hwif);
  1436. }
  1437. #endif
  1438. #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
  1439. if (scan_hwif) {
  1440. printf(" attempting to scan hwif (0x%lx, 0x%lx, %lu)\n", hwif_data, hwif_ctrl, hwif_irq);
  1441. args[0] = hwif_data;
  1442. args[1] = hwif_ctrl;
  1443. args[2] = hwif_irq;
  1444. ioctl_or_warn(fd, HDIO_SCAN_HWIF, args);
  1445. args[0] = WIN_SETFEATURES;
  1446. args[1] = 0;
  1447. }
  1448. #endif
  1449. if (set_piomode) {
  1450. if (noisy_piomode) {
  1451. printf(" attempting to ");
  1452. if (piomode == 255)
  1453. printf("auto-tune PIO mode\n");
  1454. else if (piomode < 100)
  1455. printf("set PIO mode to %d\n", piomode);
  1456. else if (piomode < 200)
  1457. printf("set MDMA mode to %d\n", (piomode-100));
  1458. else
  1459. printf("set UDMA mode to %d\n", (piomode-200));
  1460. }
  1461. ioctl_or_warn(fd, HDIO_SET_PIO_MODE, (int *)(unsigned long)piomode);
  1462. }
  1463. if (set_io32bit) {
  1464. print_flag(get_io32bit, "32-bit IO_support flag", io32bit);
  1465. ioctl_or_warn(fd, HDIO_SET_32BIT, (int *)io32bit);
  1466. }
  1467. if (set_mult) {
  1468. print_flag(get_mult, "multcount", mult);
  1469. #ifdef HDIO_DRIVE_CMD
  1470. ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult);
  1471. #else
  1472. force_operation |= (!ioctl_or_warn(fd, HDIO_SET_MULTCOUNT, (void *)mult));
  1473. #endif
  1474. }
  1475. if (set_readonly) {
  1476. print_flag_on_off(get_readonly, "readonly", readonly);
  1477. ioctl_or_warn(fd, BLKROSET, &readonly);
  1478. }
  1479. if (set_unmask) {
  1480. print_flag_on_off(get_unmask, "unmaskirq", unmask);
  1481. ioctl_or_warn(fd, HDIO_SET_UNMASKINTR, (int *)unmask);
  1482. }
  1483. #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
  1484. if (set_dma) {
  1485. print_flag_on_off(get_dma, "using_dma", dma);
  1486. ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
  1487. }
  1488. #endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
  1489. if (set_dma_q) {
  1490. print_flag_on_off(get_dma_q, "DMA queue_depth", dma_q);
  1491. ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
  1492. }
  1493. if (set_nowerr) {
  1494. print_flag_on_off(get_nowerr, "nowerr", nowerr);
  1495. ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
  1496. }
  1497. if (set_keep) {
  1498. print_flag_on_off(get_keep, "keep_settings", keep);
  1499. ioctl_or_warn(fd, HDIO_SET_KEEPSETTINGS, (int *)keep);
  1500. }
  1501. #ifdef HDIO_DRIVE_CMD
  1502. if (set_doorlock) {
  1503. args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
  1504. args[2] = 0;
  1505. print_flag_on_off(get_doorlock, "drive doorlock", doorlock);
  1506. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1507. args[0] = WIN_SETFEATURES;
  1508. }
  1509. if (set_dkeep) {
  1510. /* lock/unlock the drive's "feature" settings */
  1511. print_flag_on_off(get_dkeep, "drive keep features", dkeep);
  1512. args[2] = dkeep ? 0x66 : 0xcc;
  1513. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1514. }
  1515. if (set_defects) {
  1516. args[2] = defects ? 0x04 : 0x84;
  1517. print_flag(get_defects, "drive defect-mgmt", defects);
  1518. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1519. }
  1520. if (set_prefetch) {
  1521. args[1] = prefetch;
  1522. args[2] = 0xab;
  1523. print_flag(get_prefetch, "drive prefetch", prefetch);
  1524. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1525. args[1] = 0;
  1526. }
  1527. if (set_xfermode) {
  1528. args[1] = xfermode_requested;
  1529. args[2] = 3;
  1530. if (get_xfermode) {
  1531. print_flag(1, "xfermode", xfermode_requested);
  1532. interpret_xfermode(xfermode_requested);
  1533. }
  1534. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1535. args[1] = 0;
  1536. }
  1537. if (set_lookahead) {
  1538. args[2] = lookahead ? 0xaa : 0x55;
  1539. print_flag_on_off(get_lookahead, "drive read-lookahead", lookahead);
  1540. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1541. }
  1542. if (set_apmmode) {
  1543. args[2] = (apmmode == 255) ? 0x85 /* disable */ : 0x05 /* set */; /* feature register */
  1544. args[1] = apmmode; /* sector count register 1-255 */
  1545. if (get_apmmode)
  1546. printf(" setting APM level to %s 0x%02lX (%ld)\n", (apmmode == 255) ? "disabled" : "", apmmode, apmmode);
  1547. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1548. args[1] = 0;
  1549. }
  1550. if (set_wcache) {
  1551. #ifdef DO_FLUSHCACHE
  1552. #ifndef WIN_FLUSHCACHE
  1553. #define WIN_FLUSHCACHE 0xe7
  1554. #endif
  1555. #endif /* DO_FLUSHCACHE */
  1556. args[2] = wcache ? 0x02 : 0x82;
  1557. print_flag_on_off(get_wcache, "drive write-caching", wcache);
  1558. #ifdef DO_FLUSHCACHE
  1559. if (!wcache)
  1560. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
  1561. #endif /* DO_FLUSHCACHE */
  1562. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1563. #ifdef DO_FLUSHCACHE
  1564. if (!wcache)
  1565. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &flushcache);
  1566. #endif /* DO_FLUSHCACHE */
  1567. }
  1568. /* In code below, we do not preserve args[0], but the rest
  1569. is preserved, including args[2] */
  1570. args[2] = 0;
  1571. if (set_standbynow) {
  1572. #ifndef WIN_STANDBYNOW1
  1573. #define WIN_STANDBYNOW1 0xE0
  1574. #endif
  1575. #ifndef WIN_STANDBYNOW2
  1576. #define WIN_STANDBYNOW2 0x94
  1577. #endif
  1578. if (get_standbynow) printf(" issuing standby command\n");
  1579. args[0] = WIN_STANDBYNOW1;
  1580. ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2);
  1581. }
  1582. if (set_sleepnow) {
  1583. #ifndef WIN_SLEEPNOW1
  1584. #define WIN_SLEEPNOW1 0xE6
  1585. #endif
  1586. #ifndef WIN_SLEEPNOW2
  1587. #define WIN_SLEEPNOW2 0x99
  1588. #endif
  1589. if (get_sleepnow) printf(" issuing sleep command\n");
  1590. args[0] = WIN_SLEEPNOW1;
  1591. ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2);
  1592. }
  1593. if (set_seagate) {
  1594. args[0] = 0xfb;
  1595. if (get_seagate) printf(" disabling Seagate auto powersaving mode\n");
  1596. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1597. }
  1598. if (set_standby) {
  1599. args[0] = WIN_SETIDLE1;
  1600. args[1] = standby_requested;
  1601. if (get_standby) {
  1602. print_flag(1, "standby", standby_requested);
  1603. interpret_standby(standby_requested);
  1604. }
  1605. ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args);
  1606. args[1] = 0;
  1607. }
  1608. #else /* HDIO_DRIVE_CMD */
  1609. if (force_operation) {
  1610. char buf[512];
  1611. flush_buffer_cache();
  1612. if (-1 == read(fd, buf, sizeof(buf)))
  1613. bb_perror_msg("read(%d bytes) failed (rc=-1)", sizeof(buf));
  1614. }
  1615. #endif /* HDIO_DRIVE_CMD */
  1616. if (get_mult || get_identity) {
  1617. multcount = -1;
  1618. if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
  1619. if (get_mult && ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn. */
  1620. bb_perror_msg("HDIO_GET_MULTCOUNT");
  1621. else
  1622. bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
  1623. } else if (get_mult) {
  1624. printf(fmt, "multcount", multcount);
  1625. on_off(multcount != 0);
  1626. }
  1627. }
  1628. if (get_io32bit) {
  1629. if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) {
  1630. printf(" IO_support\t=%3ld (", parm);
  1631. if (parm == 0)
  1632. printf("default 16-bit)\n");
  1633. else if (parm == 2)
  1634. printf("16-bit)\n");
  1635. else if (parm == 1)
  1636. printf("32-bit)\n");
  1637. else if (parm == 3)
  1638. printf("32-bit w/sync)\n");
  1639. else if (parm == 8)
  1640. printf("Request-Queue-Bypass)\n");
  1641. else
  1642. printf("\?\?\?)\n");
  1643. }
  1644. }
  1645. if (get_unmask) {
  1646. if(!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, (unsigned long *)parm))
  1647. print_value_on_off("unmaskirq", parm);
  1648. }
  1649. #if ENABLE_FEATURE_HDPARM_HDIO_GETSET_DMA
  1650. if (get_dma) {
  1651. if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) {
  1652. printf(fmt, "using_dma", parm);
  1653. if (parm == 8)
  1654. printf(" (DMA-Assisted-PIO)\n");
  1655. else
  1656. on_off(parm != 0);
  1657. }
  1658. }
  1659. #endif
  1660. if (get_dma_q) {
  1661. if(!ioctl_or_warn(fd, HDIO_GET_QDMA, (unsigned long *)parm))
  1662. print_value_on_off("queue_depth", parm);
  1663. }
  1664. if (get_keep) {
  1665. if(!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, (unsigned long *)parm))
  1666. print_value_on_off("keepsettings", parm);
  1667. }
  1668. if (get_nowerr) {
  1669. if(!ioctl_or_warn(fd, HDIO_GET_NOWERR, (unsigned long *)parm))
  1670. print_value_on_off("nowerr", parm);
  1671. }
  1672. if (get_readonly) {
  1673. if(!ioctl_or_warn(fd, BLKROGET, (unsigned long *)parm))
  1674. print_value_on_off("readonly", parm);
  1675. }
  1676. if (get_readahead) {
  1677. if(!ioctl_or_warn(fd, BLKRAGET, (unsigned long *)parm))
  1678. print_value_on_off("readahead", parm);
  1679. }
  1680. if (get_geom) {
  1681. if (!ioctl_or_warn(fd, BLKGETSIZE, &parm)) {
  1682. struct hd_geometry g;
  1683. if (!ioctl_or_warn(fd, HDIO_GETGEO, &g))
  1684. printf(" geometry\t= %u/%u/%u, sectors = %ld, start = %ld\n",
  1685. g.cylinders, g.heads, g.sectors, parm, g.start);
  1686. }
  1687. }
  1688. #ifdef HDIO_DRIVE_CMD
  1689. if (get_powermode) {
  1690. #ifndef WIN_CHECKPOWERMODE1
  1691. #define WIN_CHECKPOWERMODE1 0xE5
  1692. #endif
  1693. #ifndef WIN_CHECKPOWERMODE2
  1694. #define WIN_CHECKPOWERMODE2 0x98
  1695. #endif
  1696. const char *state;
  1697. args[0] = WIN_CHECKPOWERMODE1;
  1698. if (ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_CHECKPOWERMODE2)) {
  1699. if (errno != EIO || args[0] != 0 || args[1] != 0)
  1700. state = "unknown";
  1701. else
  1702. state = "sleeping";
  1703. } else
  1704. state = (args[2] == 255) ? "active/idle" : "standby";
  1705. args[1] = args[2] = 0;
  1706. printf(" drive state is: %s\n", state);
  1707. }
  1708. #endif
  1709. #if ENABLE_FEATURE_HDPARM_HDIO_DRIVE_RESET
  1710. if (perform_reset) {
  1711. ioctl_or_warn(fd, HDIO_DRIVE_RESET, NULL);
  1712. }
  1713. #endif /* FEATURE_HDPARM_HDIO_DRIVE_RESET */
  1714. #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
  1715. if (perform_tristate) {
  1716. args[0] = 0;
  1717. args[1] = tristate;
  1718. ioctl_or_warn(fd, HDIO_TRISTATE_HWIF, &args);
  1719. }
  1720. #endif /* FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
  1721. #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
  1722. if (get_identity) {
  1723. struct hd_driveid id;
  1724. if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {
  1725. if (multcount != -1) {
  1726. id.multsect = multcount;
  1727. id.multsect_valid |= 1;
  1728. } else
  1729. id.multsect_valid &= ~1;
  1730. dump_identity(&id);
  1731. } else if (errno == -ENOMSG)
  1732. printf(" no identification info available\n");
  1733. else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
  1734. bb_perror_msg("HDIO_GET_IDENTITY");
  1735. else
  1736. bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
  1737. }
  1738. if (get_IDentity) {
  1739. unsigned char args1[4+512]; /* = { ... } will eat 0.5k of rodata! */
  1740. memset(args1, 0, sizeof(args1));
  1741. args1[0] = WIN_IDENTIFY;
  1742. args1[3] = 1;
  1743. if (!ioctl_alt_or_warn(HDIO_DRIVE_CMD, args1, WIN_PIDENTIFY))
  1744. identify((void *)(args1 + 4));
  1745. }
  1746. #endif
  1747. #if ENABLE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
  1748. if (set_busstate) {
  1749. if (get_busstate) {
  1750. print_flag(1, "bus state", busstate);
  1751. bus_state_value(busstate);
  1752. }
  1753. ioctl_or_warn(fd, HDIO_SET_BUSSTATE, (int *)(unsigned long)busstate);
  1754. }
  1755. if (get_busstate) {
  1756. if (!ioctl_or_warn(fd, HDIO_GET_BUSSTATE, &parm)) {
  1757. printf(fmt, "bus state", parm);
  1758. bus_state_value(parm);
  1759. }
  1760. }
  1761. #endif
  1762. if (reread_partn)
  1763. ioctl_or_warn(fd, BLKRRPART, NULL);
  1764. if (do_ctimings)
  1765. do_time(1 /*,fd*/); /* time cache */
  1766. if (do_timings)
  1767. do_time(0 /*,fd*/); /* time device */
  1768. if (do_flush)
  1769. flush_buffer_cache();
  1770. close(fd);
  1771. }
  1772. #if ENABLE_FEATURE_HDPARM_GET_IDENTITY
  1773. static int fromhex(unsigned char c)
  1774. {
  1775. if (isdigit(c))
  1776. return (c - '0');
  1777. if (c >= 'a' && c <= 'f')
  1778. return (c - ('a' - 10));
  1779. bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
  1780. }
  1781. static void identify_from_stdin(void) ATTRIBUTE_NORETURN;
  1782. static void identify_from_stdin(void)
  1783. {
  1784. uint16_t sbuf[256];
  1785. unsigned char buf[1280];
  1786. unsigned char *b = (unsigned char *)buf;
  1787. int i;
  1788. xread(0, buf, 1280);
  1789. // Convert the newline-separated hex data into an identify block.
  1790. for (i = 0; i < 256; i++) {
  1791. int j;
  1792. for (j = 0; j < 4; j++)
  1793. sbuf[i] = (sbuf[i] << 4) + fromhex(*(b++));
  1794. }
  1795. // Parse the data.
  1796. identify(sbuf);
  1797. }
  1798. #else
  1799. void identify_from_stdin(void);
  1800. #endif
  1801. /* busybox specific stuff */
  1802. static void parse_opts(smallint *get, smallint *set, unsigned long *value, int min, int max)
  1803. {
  1804. if (get) {
  1805. *get = 1;
  1806. }
  1807. if (optarg) {
  1808. *set = 1;
  1809. *value = xatol_range(optarg, min, max);
  1810. }
  1811. }
  1812. static void parse_xfermode(int flag, smallint *get, smallint *set, int *value)
  1813. {
  1814. if (flag) {
  1815. *get = 1;
  1816. if (optarg) {
  1817. *value = translate_xfermode(optarg);
  1818. *set = (*value > -1);
  1819. }
  1820. }
  1821. }
  1822. /*------- getopt short options --------*/
  1823. static const char hdparm_options[] ALIGN1 =
  1824. "gfu::n::p:r::m::c::k::a::B:tT"
  1825. USE_FEATURE_HDPARM_GET_IDENTITY("iI")
  1826. USE_FEATURE_HDPARM_HDIO_GETSET_DMA("d::")
  1827. #ifdef HDIO_DRIVE_CMD
  1828. "S:D:P:X:K:A:L:W:CyYzZ"
  1829. #endif
  1830. USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:")
  1831. #ifdef HDIO_GET_QDMA
  1832. #ifdef HDIO_SET_QDMA
  1833. "Q:"
  1834. #else
  1835. "Q"
  1836. #endif
  1837. #endif
  1838. USE_FEATURE_HDPARM_HDIO_DRIVE_RESET("w")
  1839. USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:")
  1840. USE_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:");
  1841. /*-------------------------------------*/
  1842. /* our main() routine: */
  1843. int hdparm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  1844. int hdparm_main(int argc, char **argv)
  1845. {
  1846. int c;
  1847. int flagcount = 0;
  1848. while ((c = getopt(argc, argv, hdparm_options)) >= 0) {
  1849. flagcount++;
  1850. USE_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I'));
  1851. USE_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i'));
  1852. get_geom |= (c == 'g');
  1853. do_flush |= (c == 'f');
  1854. if (c == 'u') parse_opts(&get_unmask, &set_unmask, &unmask, 0, 1);
  1855. USE_FEATURE_HDPARM_HDIO_GETSET_DMA(if (c == 'd') parse_opts(&get_dma, &set_dma, &dma, 0, 9));
  1856. if (c == 'n') parse_opts(&get_nowerr, &set_nowerr, &nowerr, 0, 1);
  1857. parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode);
  1858. if (c == 'r') parse_opts(&get_readonly, &set_readonly, &readonly, 0, 1);
  1859. if (c == 'm') parse_opts(&get_mult, &set_mult, &mult, 0, INT_MAX /*32*/);
  1860. if (c == 'c') parse_opts(&get_io32bit, &set_io32bit, &io32bit, 0, INT_MAX /*8*/);
  1861. if (c == 'k') parse_opts(&get_keep, &set_keep, &keep, 0, 1);
  1862. if (c == 'a') parse_opts(&get_readahead, &set_readahead, &Xreadahead, 0, INT_MAX);
  1863. if (c == 'B') parse_opts(&get_apmmode, &set_apmmode, &apmmode, 1, 255);
  1864. do_flush |= do_timings |= (c == 't');
  1865. do_flush |= do_ctimings |= (c == 'T');
  1866. #ifdef HDIO_DRIVE_CMD
  1867. if (c == 'S') parse_opts(&get_standby, &set_standby, &standby_requested, 0, INT_MAX);
  1868. if (c == 'D') parse_opts(&get_defects, &set_defects, &defects, 0, INT_MAX);
  1869. if (c == 'P') parse_opts(&get_prefetch, &set_prefetch, &prefetch, 0, INT_MAX);
  1870. parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);
  1871. if (c == 'K') parse_opts(&get_dkeep, &set_dkeep, &prefetch, 0, 1);
  1872. if (c == 'A') parse_opts(&get_lookahead, &set_lookahead, &lookahead, 0, 1);
  1873. if (c == 'L') parse_opts(&get_doorlock, &set_doorlock, &doorlock, 0, 1);
  1874. if (c == 'W') parse_opts(&get_wcache, &set_wcache, &wcache, 0, 1);
  1875. get_powermode |= (c == 'C');
  1876. get_standbynow = set_standbynow |= (c == 'y');
  1877. get_sleepnow = set_sleepnow |= (c == 'Y');
  1878. reread_partn |= (c == 'z');
  1879. get_seagate = set_seagate |= (c == 'Z');
  1880. #endif
  1881. USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') parse_opts(NULL, &unregister_hwif, &hwif, 0, INT_MAX));
  1882. #ifdef HDIO_GET_QDMA
  1883. if (c == 'Q') {
  1884. #ifdef HDIO_SET_QDMA
  1885. parse_opts(&get_dma_q, &set_dma_q, &dma_q, 0, INT_MAX);
  1886. #else
  1887. parse_opts(&get_dma_q, NULL, NULL, 0, 0);
  1888. #endif
  1889. }
  1890. #endif
  1891. USE_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r'));
  1892. USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') parse_opts(NULL, &perform_tristate, &tristate, 0, 1));
  1893. USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') parse_opts(&get_busstate, &set_busstate, &busstate, 0, 2));
  1894. #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
  1895. if (c == 'R') {
  1896. parse_opts(NULL, &scan_hwif, &hwif_data, 0, INT_MAX);
  1897. hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : "");
  1898. hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : "");
  1899. /* Move past the 2 additional arguments */
  1900. argv += 2;
  1901. argc -= 2;
  1902. }
  1903. #endif
  1904. }
  1905. /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */
  1906. if (!flagcount) {
  1907. get_mult = get_io32bit = get_unmask = get_keep = get_readonly = get_readahead = get_geom = 1;
  1908. USE_FEATURE_HDPARM_HDIO_GETSET_DMA(get_dma = 1);
  1909. }
  1910. argv += optind;
  1911. if (!*argv) {
  1912. if (ENABLE_FEATURE_HDPARM_GET_IDENTITY && !isatty(STDIN_FILENO))
  1913. identify_from_stdin(); /* EXIT */
  1914. bb_show_usage();
  1915. }
  1916. do {
  1917. process_dev(*argv++);
  1918. } while (*argv);
  1919. return EXIT_SUCCESS;
  1920. }