首页|社区论坛|iTePub书库|在线阅读|电图引擎|技术文档|图书查询|光盘刻录 |

返回首页 我的控制台 会员登陆 免费注册 最后更新 高级搜索 我要投稿 退出登陆 联系我们
操作系统
计算机应用技术
解决方案
精彩书评
开发语言
认证考试
软件工程
数据库
算法与数据结构
网络技术与安全
网站制作
移动通信
电子图书籍下载:会员文档首页 / 操作系统 / linux / Linux深入技术 / 硬盘容量的修改要
硬盘容量的修改要
2004-10-30       linuxbyte    点击: 1059
硬盘容量的修改要
以下是SEAGATE的一段升级程序(局部),现在应该还可以使用。从这段程序里s.scsi_command[0]= 0x3B……0x05……0x07可以看到,升级的过程实际是一个传送过程,先把代码送到BUFFER里执行,后面的指令就是状态监视。

对硬盘来说是需要专门的方式进行传送升级代码的,不然,你的代码会被硬盘当成DATA写到了盘片上。

编译环境是使用IP *Works! C++Linux Edition

声明:当年很多和SEAGATE硬盘相关的软件大都使用或借鉴这段程序,所以运行的流程在一定程度上和其他的软件有相似的地方,甚至窗口位置都一样。升级FIRMWARE的过程特别简单.
该程序具有版权,请大家不要原封不动的抄,理解了后可以变换变换,除非得到授权才能照抄发布自己的东西。

代码:
void download_firmware()
{
SCSI *dl;
int w, key, fh, choice, org_asa, new_asa, n= 0, off= 0;
unsigned bufsize= 8*1024, rv;
char *filename, *p;
long l, j, i, jj, offset;

if (!is_seagate_disk(inq))
message("WARNING !rn"
"rn"
"Download firmware is only tested with Seagate disk drives.");

filename= calloc(1, 128);
if (!filename)
{
printf("Error allocating %u bytes of memoryn", 128);
exit(0);
}

strcpy(filename, config->download_file);
key= edit_string_window(filename, 70, "Enter firmware file to download");
if (key== KEY_ENTER)
{
fh= open(filename, O_RDONLY|O_BINARY);
if (fh!= -1)
{
w= window_create(-1, 9, 60, 18, BLUEs.host_adapter= inq->s.host_adapter;
dl->s.target_id= inq->s.target_id;
dl->s.lun= inq->s.lun;

dl->s.scsi_command[0]= 0x3B;
if (off== 0)
{
p= farmalloc(l);
if (p== NULL)
{
message("Error allocating %lu bytes", l);
einde(-1);
}

dl->s.scsi_command[1]= 0x05;
dl->s.data_buffer= p;
dl->s.data_buffer_length= l;
}
else
dl->s.scsi_command[1]= 0x07;

*(unsigned long *)&dl->s.scsi_command[5]=
swaplong(dl->s.data_buffer_length);

if (off== 1)
{
offset= 0;
j= l / bufsize;
jj= l % bufsize;
gotoxy(1,3);
cprintf("%lu blocks of %uK and %lu bytesrn",
j, (bufsize >> 10), jj);
cprintf("Block:");
for (i= 0; i s.data_buffer, bufsize, &rv);
*(unsigned long *)&dl->s.scsi_command[2]=
swaplong(offset);
if (rv== bufsize)
scsi_execute(dl, 1);
else
{
message("Error while reading firmware file");
einde(-1);
}

gotoxy(8,4);
cprintf("%lu", i);
offset+= rv;
}

if (jj)
{
gotoxy(20,3);
_dos_read(fh, dl->s.data_buffer, jj, &rv);
*(unsigned long *)&dl->s.scsi_command[2]=
swaplong(offset);
*(unsigned long *)&dl->s.scsi_command[5]=
swaplong(rv);
if (rv== jj)
scsi_execute_bg(dl);
else
{
message("Error while reading firmware file");
einde(-1);
}

gotoxy(26,4);
cprintf("%u", i);
offset+= rv;
}
}
else
{
cprintf("Reading file %s, %lu KB", filename, l >> 10);
rv= file_read_into_memory(fh, p, l);
if (rv)
{
message("Error while reading firmware file");
einde(-1);
}
scsi_execute_bg(dl);
}

gotoxy(1,4);
clreol();
cprintf("Download status :");

n= 0;
while(dl->s.status== 0)
{
gotoxy(18,4);
putch(wiekje[n++]);
if (!wiekje[n]) n= 0;
gotoxy(19,4);
cprintf("%-10.10s", aspi_status_name(dl->s.status));
delay(250);
}

gotoxy(18,4);
putch(' ');
gotoxy(19,4);
cprintf("%-10.10s", aspi_status_name(dl->s.status));

if (dl->s.status!= 1)
{
gotoxy(1,5);
print_sense_info_short(dl);
}
else
{
gotoxy(1,6);
cprintf("Waiting for unit");
wait_unit_ready(inq);

new_asa= seagate_asa_level(inq);
gotoxy(1,6);
clreol();
cprintf("New ASA level is ASA%u", new_asa);

if (org_asa!= new_asa)
{
message("You upgraded your drive to a newrn"
"ASA level, drive needs low level format !rn"
/*大家注意这点,升级是有风险的,这个信息只是其中一个很小的风险,由于ASA级别的改变,需要你低级格式化硬盘,哈哈数据没啦!
SEAGATE厂的ASA为2。其他计算机大厂的ASA有的为0有的为1……,自己找些资料参考吧。
*/
"rn"
"%s", fortune(fun_message));
}
}

if (off== 0)
{
dl->s.data_buffer= NULL;
dl->s.data_buffer_length= 0;
farfree(p);
}
scsi_destroy(dl);

pause();
}
}

close(fh);
window_destroy(w);
strcpy(config->download_file, filename);
cfg_save();
}
else
message("Error opening file %snr->%s", filename, sys_errlist[errno]);
}


free(filename);
SEAGATE ST336607的部分模式页在这里,自己修改响应的值再写回去就可以了。
04 3c d9 40 00 00 02 00
01 0a c8 0b ff 00 00 00 05 00 27 10
02 0e 00 00 00 0a 00 00 00 00 00 00 10 00 00 00
03 16 11 aa 00 00 00 08 00 00 02 d0 02 00 00 01 00 66 00 66 40 00 00 00
04 16 00 c2 bf 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00
07 0a 08 0b ff 00 00 00 00 00 27 10
08 12 10 00 ff ff 00 00 ff ff ff ff 00 10 00 00 00 00 00 00
0a 0a 00 00 00 00 00 00 00 00 03 00
19 06 01 00 ff ff 00 00
1a 0a 00 03 00 00 00 01 00 00 00 04
1c 0a 88 04 00 00 8c a0 00 00 00 00
下面给你一段参考汇编程序,希自己的硬盘改成自己的名字望对你有用。

代码:

.MODEL large, C
.DATA

.CODE

extrn AspiEntryPoint:dword
public SRBexec

SRBexec PROC C, segm:WORD, ofs:WORD

mov ax, segm
push ax
mov ax, ofs
push ax
call DWORD PTR [AspiEntryPoint]
add sp, 4
ret
SRBexec ENDP

public swaplong

swaplong PROC C, long1,long2:WORD

mov ax, long2
xchg al, ah
mov dx, long1
xchg dl, dh

ret
swaplong ENDP

public swapint

swapint PROC C, int1:WORD

mov ax, int1
xchg al, ah

ret
swapint ENDP

end


有个文件名叫sgdskfl.c,是INTEL的工程师Andy cress写的,算法上和SEAGATE的大致相同,另外还包括很多其他可移动SCSI设备和流SCSI设备的方案。

Andy Cress的编程风格很好,具有很多注释,大家应该很容易看懂。不过由于页面显示程序的缘故,所有程序代码左边的空格均无效了,因此全靠左显示,给大家浏览带来了不便。如果希望浏览更好看的代码,请访问[STOL]存储社区

代码:

/*--------------------------------------------------------------------------
Filename : sgdskfl.c
Abstract : SCSI Generic Disk Firmware Load tool
Operation System: Linux 2.2 or greater
Copyright ? Intel Corporation 2001
Author: Andy Cress
----------- Change History -----------------------------------------------
05/01/01 v0.70 ARCress created
07/17/01 v0.91 ARCress added code to download servo also
added write_buffers code to do multi-part dl.
08/08/01 v0.92 ARCress fixed write_buffers logic for IBM disks.
09/05/01 v0.93 ARCress message cleanup
09/28/01 v0.94 ARCress turn off sg_debug in afterdl
10/15/01 v0.95 ARCress fixed IBM chunk size
10/30/01 v1.0 ARCress cleanup includes & indent -kr
11/09/01 v1.0 ARCress enlarged devstat2 from 80 to 120 for overrun
11/14/01 v1.0 ARCress added default directory for image files.
04/11/02 v1.1 ARCress path changes for log & image files,
set do_numeric=1 default
05/08/02 v1.3 ARCress tune sg_debug level down to 5 by default
08/15/02 v1.4 ARCress moved common subroutines to sgcommon
added more usage messages
09/03/02 v1.5 ARCress streamline display for errors in get_scsi_info
01/08/03 v1.6 ARCress include Quantum in getimage:fscanmodel.
----------- Des cription --------------------------------------------------
sgdskfl
Sequence of events for this utility:
* List each device on the system with firmware versions.
* User selects a device for firmware load (automatic if using -m)
* Read the firmware image file for the selected disk and verify that it is
valid.
* Verify that the disk is present and ready
* Close all open files, flush the adapter, sync any data to the SCSI disks.
* Write the firmware image to the disk using a 'write buffer' SCSI command
with large reserved buffer or scatter/gather.
* Wait 5 (or specified number) seconds
* Verify that the disk comes ready again using SCSI test_unit_ready commands,
and start_unit or scsi_reset to recover if not.
* If the '-m' option was used, repeat writing the firmware for each disk of
this model.
sgdskfl [-e -m diskmodel -f imagefile -t secdelay -x]
Options:
-e Do not write to any files. Usually a log file (sgdskfl.log) is created
and written to, up until the firmware download begins on root.
-m Automatically download all drives that match this model string.
Note that this option will initiate a reboot after it is done,
unless option u is also specified.
-f Specify this filename for the firmware image. Normally, this option is
not used and the filename is formed using the first 8 characters of the
model, with the ".lod" extension. For example: "st39140w.lod".
Note that this utility uses the raw firmware image without any added
headers.
-t Specifies the number of seconds to delay after the firmware is written
and the program attempts to test if the unit is ready again.
Default is 10 seconds.
-r Recover a non-ready drive by updating its firmware.
Don't test if the drive is ready or not.
-x Outputs extra debug messages
-d Specify a unix device name
----------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------
Copyright ? 2002, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
a.. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
b.. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
c.. Neither the name of Intel Corporation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "sgsub.h"
#include "sgcommon.h"

/* External Functions prototypes */
extern void setbuf(FILE * stream, char *buf);
extern int errno;
extern char fdebugsub; /* used in sgsub.c */
extern FILE *dbgout; /* used in sgsub.c */

#define EBUFF_LEN 80
#define MAX_ERRORS 4

/* Global data definitions */
char progver[] = "1.6"; /* program version */
char *progname = "sgdskfl"; /* program name */
char logfile[] = "/var/log/sgdskfl.log"; /* log filename */
char fwsufx[] = ".lod"; /* suffix for firmware image filenames */
char model[20] = ""; /* default model string */
char fsetfile = 0;
char fwfile[20] = "default"; /* default firmware filename (8.lod) */
char defdir[30] = "/usr/share/scsirastools/"; /*default directory for fw files*/
char devname[80] = "/dev/sda"; /* UNIX device name (w path) */
char svfile[20] = "default"; /* default servo filename (8.tms) */
int sdelay = 10; /* num sec to delay before TUR */
FILE *fdlog = NULL; /* log file des criptor */
FILE *fdmsg; /* file des criptor for messages */
char fautomodel = 0; /* =1 to automatically do all of a model */
char filesok = 1; /* =1 if ok to write to files */
char fdebug = 0; /* =1 for debug messages */
char fdoreset = 0; /* =1 if need to do reset for this drive */
char flogopen = 0; /* =1 if log file is open */
char fnotur = 0; /* =1 to not try TUR */
char fdevname = 0; /* =1 if device name specified */
int do_numeric = 1; /* NUMERIC_SCAN_DEF; */
uchar sense_buffer[80]; /* buffer for sense data */
char output[132]; /* message output buffer */
char output2[80]; /* extra message output buffer */
uchar devstat[80]; /* used for inquiry & device status */
uchar devstat2[120]; /* used for Seagate inquiry2 & Mylex stat */
uchar disk_buffer[0x200]; /* 512 bytes, used for misc scsi data */
uchar *image_buffer; /* malloc'd firmware image buffer */
uchar *servo_buffer; /* malloc'd servo buffer */
int idev = 0;
int ndev = 0;
DEVLIST_TYPE devlist[32];
char *devtype_array[11] = {
"Disk ",
"Tape ",
"Printer",
"Procesr",
"WORM ",
"CD-ROM ",
"Scanner",
"Optical",
"Med Chg",
"Comm ",
"Unknown"
};

/* Local subroutines */
int writeimage(int idx, uchar * imgbuf, ulong len, char fservo);
ulong getimage(int idx, uchar ** pbuf, char fservo);
int beforedl(int idx, int *pnumrdy);
int afterdl(void);

int main(int argc, char **argv)
{
int i, c, idx;
char response = 0;
ulong size; /* size of fw */
ulong size_sv; /* size of servo */
int runl;
short sts, rc;
ulong ltime1;
char fname[64];
char ebuff[EBUFF_LEN];
int sg_fd;
int flags;
int res, k;
int eacces_err = 0;
int num_errors = 0;
DEVFS_LIST devfs_components = {0,0,0,0,0};

// progname = argv[0];
fdmsg = stdout; /* set default fdmsg */
while ((c = getopt(argc, argv, "enxrf:m:t:d:?")) != EOF)
switch ? {
case 'e':
filesok = 0;
break;
case 'x':
fdebug = 1;
break;
case 'r':
fnotur = 1;
break;
case 'n':
do_numeric = 0;
break;
case 'f':
strcpy(fwfile, optarg);
fsetfile = 1;
break;
case 'm':
fautomodel = 1; /* automatically do all of this model */
strcpy(model, optarg);
break;
case 't':
sdelay = atoi(optarg); /* time to delay */
break;
case 'd':
strcpy(devname, optarg); /* specify a unix device name */
fdevname = 1;
break;
case '?':
default:
printf("Usage: %s [-m diskmodel -f imagefile -t secdelay -enrx]n",
progname);
printf(" -m Automatically download all drives that match this model stringn");
printf(" -f Specify filename for firmware image instead of defaultn");
printf(" -t Time in seconds to delay after the firmware is written, default 10n");
printf(" -n Turn off Numeric, use alpha device names insteadn");
printf(" -e Do not write to any files, so don't use the log filen");
printf(" -r Recover a non-ready drive by updating its firmwaren");
printf(" -x Outputs extra debug messagesn");
exit(1);
}
/* only run this as superuser */
i = geteuid();
if (i > 1) {
printf("Not superuser (%d)n", i);
exit(1);
}
/* check for run-level 1 */
{
runl = 1;
/* how to check this? */
if (fdebug) {
/*DEBUG*/ printf("sdelay = %d secn", sdelay);
printf("run-level = %dn", runl);
}
}
if (runl != 1) { /* show warning if not run level 1 */
printf
("Warning: Make sure disks are inactive during firmware downloadn");
// dont exit, just give a warning.
}
/* open log file */
if (filesok)
fdlog = fopen(logfile, "a+");
if (fdlog == NULL) {
flogopen = 0;
filesok = 0;
fdlog = stderr;
} else { /* logfile open successful */
flogopen = 1;
time((time_t *) & ltime1);
fprintf(fdlog, "n--- %s v%s log started at %s", progname, progver,
ctime((long *) fprintf(fdlog, "model: %sn", model);
fprintf(fdlog, "fw file: %sn", fwfile);
}
fdebugsub = fdebug;
dbgout = fdlog;
/* loop to display disk choices and do downloads */
while (1) {
/* display header */
printf("n");
printf(" %s utility v%s for SCSI disksn",
progname, progver);
printf
(" ******************************************n");
if (flogopen)
printf("Log file %s is open, debug=%dn", logfile, fdebug);
printf
("nNum Name [bus:ch:id:lun] Type Vendor Device_Model FW__ Serial#_ Servo___n");
/* get SCSI Device Info */
idev = 0;
flags = O_RDWR; /* could use OPEN_FLAG if read-only. */
num_errors = 0;
for (k = 0; (k 0) {
res = close(sg_fd);
if (res vendorid,
"SEAGATE", 7) != 0)
fservo = 3; /* Seagate tapes use split buffer method 3 */
/* Tecmar, Travan, Wangtek, WangDAT tapes use method 2 */
else
fservo = 2; /* use split buffer method 2 */
}
else
if (
(strncmp
((char *) scsi_inq->vendorid, "IBM",
3) == 0)
&&
(strncmp
((char *) scsi_inq->productid, "ST",
2) != 0))
/* for all IBM disks, except Seagate OEM */
fservo = 4; /* IBM disks use split buffer method X */
else
fservo = 0; /* normal, all one buffer */
if (size > 0) { /* flash firmware */
rc =
writeimage(i, image_buffer, size,
fservo);
free(image_buffer); /*allocated in getimage() */
if (fdebug && rc != 0) {
showit((char *) disk_buffer); /*writes saved messages */
quit(rc);
}
}
if (size_sv > 0) { /* flash servo */
rc =
writeimage(i, servo_buffer, size_sv,
1);
free(servo_buffer); /*allocated in getimage() */
}
}
if (!fautomodel)
i = ndev; /* only do one if interactive */
} /*endfor each disk */
rc = afterdl();
} /*endif image ok */
} /*end else index ok */
} /*end else do download */
else { /* response not d or q */
printf("Invalid input [%c], enter 'd' or 'q'.n", response);
}
if (fautomodel) { /* then done */
if (0) { /* if root is down and likely to hang otherwise, */
printf("Rebooting ...n");
sleep(3);
// /* do reboot without shutdown */
} else
quit(0); /* normal exit, successful */
} else { /* interactive, go to menu again */
do_pause();
}
} /*end while(1) */
} /*end main() */

ulong getimage(int idx, uchar ** pbuf, char fservo)
{
ulong filsz;
FILE *fdimg;
struct stat statbuf;
struct SCSI_INQUIRY *scsi_inq;
char modelx[20];
char *filenm;
char fullfilenm[80];
char *buf;
int i, rc;
*pbuf = NULL;
scsi_inq = (struct SCSI_INQUIRY *) devlist[idx].inq;
if (fautomodel)
strncpy(modelx, model, strlen(model));
else
strncpy(modelx, (char *) scsi_inq->productid, 16);
for (i = 0; i vendorid);
showit(output);
}
if (!fsetfile) { /* build the default filename */
for (i = 0; i vendorid, "SEAGATE", 7) == 0) {
if (modelx[7] == 'W')
modelx[7] = 'N'; /*always match with narrow */
modelx[8] = 0; /* truncate to 8 chars for search */
fscanmodel = 1;
} else if (strncmp((char *) scsi_inq->vendorid, "IBM", 3) == 0)
fscanmodel = 1;
else if (strncmp((char *) scsi_inq->vendorid, "MAXTOR", 6) == 0)
fscanmodel = 1;
else if (strncmp((char *) scsi_inq->vendorid, "QUANTUM", 7) == 0)
fscanmodel = 1;
/* HITACHI and FUJITSU only have partial model strings to match */
if (fscanmodel) { /* scan image buffer for model(productid) */
/* A variable offset in the file has a list of the target models. */
rc = findmatch(buf, filsz, modelx, strlen(modelx), 1); /*also ignore case */
if (rc == -1) {
sprintf(output, "Image does not match model %sn", modelx);
showit(output);
fclose(fdimg);
free(buf);
return (0); /* size = 0 */
}
if (fdebug) {
sprintf(output, "Image file matches model %sn", modelx);
showit(output);
}
} /*endif scanmodel */
}
/*endif not servo */
*pbuf = buf;
fclose(fdimg);
return (filsz);
} /*end getimage() */

int write_buffers(int sgfd, uchar * buf, ulong len, uchar fservo)
{
int sts;
ulong j, sz_left;
ulong max_chunk;
uchar save_mode;
uchar bufid;
uchar ebuf[20];
if (fservo >= 2) {
if (fservo == 3) { /* Seagate tapes */
max_chunk = 0x4000;
save_mode = 0x07;
} else if (fservo == 2) { /* other tapes */
max_chunk = 0x8000;
save_mode = 0x05;
} else // if (fservo == 4) { /* IBM disks */
{
max_chunk = 0x8000; /* get this from mode page C7, bytes 16-18 */
save_mode = 0x05;
if (fdebug)
fprintf(fdlog, "IBM split buffer mode, chunk size = %ldn",
max_chunk);
j = 0;
sz_left = len;
bufid = 0;
while (sz_left > max_chunk) {
/* Note that it uses mode 05 for every chunk, not just last one */
sts =
write_buffer(sgfd, &buf[j], max_chunk, save_mode,
bufid);
if (sts != 0) {
unsigned int k, a, q;
int rc;
rc = get_sense(sts, ebuf);
k = ebuf[2] & 0x0f; /*Sense Key */
a = ebuf[12];
/*ASC*/ q = ebuf[13];
/*ASCQ*/
sprintf(output, "wb sense error: %x/%x/%xn", k, a,
q);
showit(output);
if (k == 03 && a == 0x30)
printf("Overlay upload errorn");
else if ((k == 2 || k == 3 || k == 4) &&
(a == 0x40 && q max_chunk) {
sts = write_buffer(sgfd, &buf[j], max_chunk, 0x04, bufid);
if (sts != 0)
return (sts);
sz_left -= max_chunk;
j += max_chunk;
}
sts = write_buffer(sgfd, &buf[j], sz_left, save_mode, bufid);
}
/*endif split buffer scheme */
else { /* fservo == 0, or fservo == 1 */
/* Send it all as one big buffer */
sts = write_buffer(sgfd, buf, len, 0x05, 0L);
}
return (sts);
} /* end write_buffers() */


int writeimage(int idx, uchar * imgbuf, ulong len, char fservo)
{
int sts;
int devfd;
int isave;
ulong ltime, ltime1, ltime2;
ulong ltime3;
int i, rc, rcdl;
int k, a, q;
char *tag;
uchar ch, dv;
isave = idx;
rcdl = 0;
/* Download firmware to this disk */
{
rcdl = 0;
fdoreset = 0;
if (!fautomodel)
idx = isave; /* only do selected disk */
devfd = devlist[idx].sgfd;
ch = devlist[idx].chn;
dv = devlist[idx].tgt;
if (devlist[idx].fdoit == 1) {
if (fautomodel) {
/* Sometimes next device may have a unit attention/reset check
* condition pending, so clear that first before the write_buffer.
*/
sts = test_unit_ready(devfd, 0);
if (fdebug)
fprintf(fdlog, "Extra test_unit_ready sts = %xn",
sts);
}
time((time_t *) & ltime1); // get the start time
/* start the firmware download */
if (fservo == 1)
tag = "Servo";
else
tag = "Firmware";
sprintf(output, "Downloading %s image to disk %d %s",
tag, idx, ctime((long *) // ctime outputs a 'n' at end
showit(output);
sts = write_buffers(devfd, imgbuf, len, fservo);
if (sts) {
rcdl = sts;
sprintf(output, "[%d] Error %d in writing buffern", idx,
sts);
showit(output); // fdlog closed
if (fdebug || !fautomodel) {
return (rcdl); // (only if debug on)
}
}
if (fautomodel && rcdl != 0) {
/* Save error for logging later */
sprintf(output, "[%d] %s download error, status = 0x%xn",
idx, tag, rcdl);
strcat((char *) disk_buffer, output);
/* Try to restart the drive, even if the download failed. */
return (rcdl); /*skip to next one if error */
}
// Test if Unit is Ready again
sprintf(output, "Waiting for disk to come ready again ");
showit(output);
sleep(sdelay); /* wait for the drive to reset and come ready */
for (i = 0; i productid, 8);
model[8] = 0; /*stringify */
}
for (idx = 0; idx productid, 8) == 0) { /* do only ones of the same disk product id */
sts = test_unit_ready(sgfd, 0);
if (sts == SCHECK_CND) { /* not ready initially, try to make it ready */
i = get_sense(sts, sense_buffer);
k = sense_buffer[2] & 0x0f; /*Sense Key */
a = sense_buffer[12];
/*ASC*/ q = sense_buffer[13];
/*ASCQ*/ if (k == 2 && a == 4 && q == 2) {
/* 02-04-02 means it needs a start command, so issue it. */
sts = start_unit(sgfd);
if (fdebug) {
/*DEBUG*/ printf("nStart Unit: sts=%d, ", sts);
if (sts == SCHECK_CND) {
rc = get_sense(sts, sense_buffer);
printf("sense data: %x %x %xn",
sense_buffer[2] & 0x0f,
sense_buffer[12], sense_buffer[13]);
}
}
} /*endif 02-04-02 */
sts = test_unit_ready(sgfd, 1); /* try again */
}
if (sts) {
sprintf(output, "[%d] Error %d from Test Unit Readyn",
idx, sts);
showit(output);
devlist[idx].fdoit = 0;
if (fnotur) {
devlist[idx].fdoit = 1;
nrdy++;
}
} else {
devlist[idx].fdoit = 1;
sprintf(output, "Device [%d] is ready for downloadn",
idx);
showit(output);
nrdy++; /* number ready to download */
}
} else
devlist[idx].fdoit = 0; /* not same product id */
if (!fautomodel)
idx = ndev; /* end loop */
} /* end for devlist TUR loop */
*pnumrdy = nrdy; /* set return value */
if (nrdy == 0) {
sprintf(output, "There are no ready devices for model %s.n",
model);
showit(output);
return (sts);
} else {
if (nrdy > 1)
pl = "s";
else
pl = "";
sprintf(output, "Starting download process for %d disk%s.n", nrdy,
pl);
showit(output);
}
closelog(); /* sets flogopen to false */
filesok = 0; /* allows files to be opened again */
fflush(fdmsg); /* flush stdout/stderr for messages */
setbuf(fdmsg, NULL); /* set for unbuffered writes */
sync();
sync(); /* write all UNIX buffers to disk */
sleep(2);
/* can't have any more disk IOs from here on */
if (0) { /* fumntroot) *//* unmount root by default, skip it if user says not to. */
fprintf(fdmsg, "Unmounting root ...");
// rc = uadmin(4, 128, 0); /* unmount root fs */
if (rc == 0)
fprintf(fdmsg, "donen");
else
fprintf(fdmsg, "rc = %dn", rc);
// frootdown = 1;
}
/* Take all drives offline first if specified. */
disk_buffer[0] = 0; /* used for messages later */
return (rcdl);
} /*end beforedl() */


int afterdl(void)
{
int i, sts;
sts = 0;
/* Bring all drives online again if raid */
/* done, all drives should be ready now */
filesok = 1; /* allows files to be opened again */
showit((char *) disk_buffer); /* writes saved messages */
for (i = 0; i 0) {
sts = set_sg_debug(devlist[I.sgfd, 0);
if (sts && fdebug)
fprintf(fdlog, "[%d] cant clear debug flag, sts=%d errno=%dn",
i, sts, errno);
close(devlist[I.sgfd); /*opened in beforedl() */
devlist[I.sgfd = 0;
}
}
return (sts);
} /*end afterdl() */

/* end sgdskfl.c */


在调用的时候,使用21号中断得到入口另外说明一点,GLIST是可以读取(0X37)清除(格式化)的,但是清楚以后故障还会存在。

再放一段程序便于你们理解。

代码:

int glist(SCSI *sp)
{
SCSI *s;
int al= 8, retval= -1, rv, format;
char format_mask[]= { 0x00, 0x04, 0x05, 0 };
int format_size[]= { 4,8,8,0 };

s= scsi_init(al);
idcpy(s, sp);

s->s.scsi_command[0]= 0x37;
s->s.scsi_command[2]= 0x08;
*(unsigned int *) &s->s.scsi_command[7]= swapint(al);

for (rv= 0, format= 0; format s.scsi_command[2]&= 0xf8;
s->s.scsi_command[2]|= format_mask[format];
rv= scsi_execute(s, 0);
}
format--;

if (rv== 1)
{
retval= swapint(*(unsigned int *)&s->s.data_buffer[2])
format_size[format];
}

scsi_destroy(s);
return(retval);
}


还有南桥芯片中都会有一个256字节的CMOS RAM芯片,它就是用来存储BIOS的设置信息。你可以去看看VIA的VT82C586B、VT82C686A、VT82C686B和最新的几款南桥以及Intel的82371AB(用于440系列家族)、82801AA、82801BA等ICH(用于8xx系列家族)的技术说明文档
责任编辑: sky_walker
发表评论 查看评论 加入收藏 Email给朋友 打印本文
如果你想对该文章评分, 请先登陆, 如果你仍未注册,请点击注册链接注册成为本站会员.
平均得分 0, 共 0 人评分
1 2 3 4 5 6 7 8 9 10

  Copyright © 2002 - 2005 iTePub.Group All Rights Reserved