Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
 
22
/***************************************
23
 
24
  CVS :        $Id: idelow.c,v 1.1.1.1 2002-03-29 14:12:49 pj Exp $
25
 
26
  Revision:    $Revision: 1.1.1.1 $
27
 
28
  Last update: $Date: 2002-03-29 14:12:49 $
29
 
30
  This module is responsable of the protocol between the IDE device driver
31
  interface and the host (the computer).
32
 
33
***************************************/
34
 
35
/*
36
 * Copyright (C) 1999,2000 Massimiliano Giorgi
37
 *
38
 * This program is free software; you can redistribute it and/or modify
39
 * it under the terms of the GNU General Public License as published by
40
 * the Free Software Foundation; either version 2 of the License, or
41
 * (at your option) any later version.
42
 *
43
 * This program is distributed in the hope that it will be useful,
44
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
45
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
46
 * GNU General Public License for more details.
47
 *
48
 * You should have received a copy of the GNU General Public License
49
 * along with this program; if not, write to the Free Software
50
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
51
 *
52
 */
53
 
54
#include "glue.h"
55
#include <fs/bdevinit.h>
56
#include <fs/magic.h>
57
#include <fs/assert.h>
58
#include <fs/util.h>
59
#include <fs/maccess.h>
60
 
61
#include "bdev.h"
62
#include "phdsk.h"
63
#include "lodsk.h"
64
#include "ide.h"
65
#include "idereq.h"
66
#include "bqueue.h"
67
 
68
/*+ some kernel depend features implemented +*/
69
#include "ideglue.h"
70
 
71
/*
72
 * TRACER FLAGS
73
 */
74
 
75
/* if defined use tracer user events 1 and 2 before and after blocking
76
 * for synchronization (so we can compute the waiting time for a
77
 * request)
78
 */
79
#define TRACEWAIT
80
#undef TRACEWAIT
81
 
82
#ifdef TRACEWAIT
83
#include <trace/types.h>
84
#include <kernel/trace.h>
85
#endif
86
 
87
/*
88
 * FLAGS
89
 */
90
 
91
/* if defined:
92
 * enable "set features" commands (so we can set features on ide drives).
93
 */
94
#define IDE_ENABLESETFEATURES 1
95
//#undef IDE_ENABLESETFEATURES
96
 
97
/* if defined:
98
 * add a delay into the IRQ handler
99
 * (my old cdrom seems to clear the IRQ at the end of the data in/out
100
 * not when reading the STATUS register)
101
 * PS: if the DEBUG_SERVER is defined this delay isn't required.
102
 */
103
#define IDE_OLDATAPIDELAY 1
104
#undef IDE_OLDATAPIDELAY
105
 
106
/* if defined:
107
 * after the soft reset timeout expired do a soft reset
108
 * also if the device is busy
109
 * (some old cdrom seems not to clear the busy bits ?!?)
110
 */
111
#define IDE_FORCERESET 1
112
//#undef IDE_FORCERESET
113
 
114
/*
115
 * if defined:
116
 * after issuing a command does not test for command in progress
117
 * (does not read the status register!)
118
 * DANGER: need for all TX motherboard
119
 */
120
#define IDE_SKIPSTATUSTEST 1
121
//#undef IDE_SKIPSTATUSTEST
122
 
123
/*
124
 * if defined:
125
 * skip all test when issuing a command!
126
 * (it imply IDE_SKIPSTATUSTEST)
127
 * DANGER: need on some TX motherboard
128
 * on few TX motherboards PIO mode is not safe (DMA must be used)
129
 */
130
#define IDE_SKIPALLTEST 1
131
#undef IDE_SKIPALLTEST
132
 
133
#ifdef IDE_SKIPALLTEST
134
#define IDE_SKIPSTATUSTEST 1
135
#endif
136
 
137
/*
138
 * DEBUG
139
 */
140
 
141
/* show server activity */
142
#define DEBUG_SERVER KERN_DEBUG
143
#undef DEBUG_SERVER
144
 
145
/* show request and result */
146
#define DEBUG_SHOWREQUEST KERN_DEBUG
147
#undef DEBUG_SHOWREQUEST
148
 
149
/* trace soft reset function */
150
#define DEBUG_SOFTRESET KERN_DEBUG
151
#undef DEBUG_SOFTRESET
152
 
153
/* trace REQ_EPILOG (the epilog of every device request) */
154
#define DEBUG_REQEPILOG KERN_DEBUG
155
#undef DEBUG_REQEPILOG
156
 
157
/* trace do_io_request() (WARNIG can cause a deadline miss)*/
158
#define DEBUG_IOREQUEST KERN_DEBUG
159
#undef DEBUG_IOREQUEST
160
 
161
/**/
162
 
163
#ifdef DEBUG_SERVER
164
#define printk0(ideif,fmt,args...) \
165
        printk(DEBUG_SERVER "ide%i server:" fmt,ideif,##args)
166
#else
167
#define printk0(fmt,args...)
168
#endif
169
 
170
#ifdef DEBUG_SHOWREQUEST
171
#define printk1(ideif,fmt,args...) \
172
        printk(DEBUG_SHOWREQUEST "ide%i request:" fmt,ideif,##args)
173
#else
174
#define printk1(fmt,args...)
175
#endif
176
 
177
#ifdef DEBUG_SOFTRESET
178
#define printk2(ideif,fmt,args...) \
179
        printk(DEBUG_SOFTRESET "ide%i soft reset:" fmt,ideif,##args)
180
#else
181
#define printk2(fmt,args...)
182
#endif
183
 
184
#ifdef DEBUG_REQEPILOG
185
#define printk3(ideif,fmt,args...) \
186
        printk(DEBUG_REQEPILOG "ide%i req_epilog:" fmt,ideif,##args)
187
#else
188
#define printk3(fmt,args...)
189
#endif
190
 
191
#ifdef DEBUG_IOREQUEST
192
#define printk4(ideif,fmt,args...) \
193
        printk(DEBUG_IOREQUEST fmt)
194
#else
195
#define printk4(fmt,args...)
196
#endif
197
 
198
/*
199
 *
200
 * REGISTERS
201
 *
202
 */
203
 
204
/*
205
 * from ATA/ATAPI 4 (T13/1153D revision 18)
206
 * paragraph 7.x
207
 */
208
 
209
/* io_port registers (usually on 0x1f0 for first IDE interface) */
210
#define REG_DATA     0x00
211
#define REG_ERROR    0x01
212
#define REG_FEATURES 0x01
213
#define REG_SECCOU   0x02
214
#define REG_SECNUM   0x03
215
#define REG_CYLLOW   0x04
216
#define REG_CYLHIG   0x05
217
#define REG_DEVHEAD  0x06
218
#define REG_STATUS   0x07
219
#define REG_COMMAND  0x07
220
 
221
/* to register the i/o space */
222
#define IOPORT_OFFSET 0
223
#define IOPORT_LEN    8
224
 
225
/* io_port2 registers (usually on 0x3f0 for first IDE interface) */
226
#define REG_ALTSTATUS 0x06
227
#define REG_DEVCTRL   0x06
228
 
229
/* to register the i/o space */
230
#define IOPORT2_OFFSET 6
231
#define IOPORT2_LEN    1
232
 
233
/* to use with VM_in/VM_out */
234
/* for read/write */
235
#define IDE_REG_DATA      (ide[ideif].io_port+REG_DATA)
236
#define IDE_REG_SECCOU    (ide[ideif].io_port+REG_SECCOU)
237
#define IDE_REG_SECNUM    (ide[ideif].io_port+REG_SECNUM)
238
#define IDE_REG_CYLLOW    (ide[ideif].io_port+REG_CYLLOW)
239
#define IDE_REG_CYLHIG    (ide[ideif].io_port+REG_CYLHIG)
240
#define IDE_REG_DEVHEAD   (ide[ideif].io_port+REG_DEVHEAD)
241
/* for read */
242
#define IDE_REG_STATUS    (ide[ideif].io_port+REG_STATUS)
243
#define IDE_REG_ERROR     (ide[ideif].io_port+REG_ERROR)
244
#define IDE_REG_ALTSTATUS (ide[ideif].io_port2+REG_ALTSTATUS)
245
/* for write */
246
#define IDE_REG_COMMAND   (ide[ideif].io_port+REG_COMMAND)
247
#define IDE_REG_FEATURES  (ide[ideif].io_port+REG_ERROR)
248
#define IDE_REG_DEVCTRL   (ide[ideif].io_port2+REG_DEVCTRL)
249
 
250
/* for status & alt_status register */
251
#define STATUS_BUSY        0x80
252
#define STATUS_DRDY        0x40
253
#define STATUS_R_FAULT     0x20
254
#define STATUS_R_SEEKCOM   0x10
255
#define STATUS_DRQ         0x08
256
#define STATUS_R_DWC       0x04
257
#define STATUS_R_CMDPROG   0x02
258
#define STATUS_ERR         0x01
259
 
260
/* for error register */
261
#define ERROR_OBS_BADBLOCK    0x80
262
#define ERROR_OBS_CRCECC      0x40
263
#define ERROR_OBS_IDNOTFOUND  0x10
264
#define ERROR_ABORTCMD        0x04
265
#define ERROR_OBS_TRACK00     0x02
266
#define ERROR_OBS_DAMNOTFOUND 0x01
267
 
268
/* for devhead register */
269
#define DEVHEAD_DEV  0x10
270
 
271
/* for devctrl (device control) register */
272
#define DEVCTRL_SRST  0x04
273
#define DEVCTRL_NIEN  0x02
274
 
275
#define DEVCTRL_SOFTRESET  (DEVCTRL_SRST)
276
#define DEVCTRL_ENABLEINT  (0)
277
#define DEVCTRL_DISABLEINT (DEVCTRL_NIEN)
278
 
279
#define DEVCTRL_NORMALOP   (DEVCTRL_ENABLEINT)
280
 
281
/*
282
 * these are not from ATA specification
283
 */
284
 
285
/* bus master registers */      
286
#define REG_BMICX     0
287
#define REG_BMISX     2
288
#define REG_BMIDTPX   4
289
 
290
/* to use with VM_in/VM_out */
291
#define BM_REG_COMMAND    (ide[ideif].io_bmdma+REG_BMICX)
292
#define BM_REG_STATUS     (ide[ideif].io_bmdma+REG_BMISX)
293
#define BM_REG_PRDADDR    (ide[ideif].io_bmdma+REG_BMIDTPX)
294
 
295
/* to register the i/o space */
296
#define BMDMAPORT_OFFSET 0
297
#define BMDMAPORT_LEN    8
298
 
299
/*
300
 *
301
 *
302
 *
303
 */
304
 
305
static int decode_error_result(int ideif)
306
{
307
 
308
  BYTE error;
309
  error=inp(IDE_REG_ERROR);
310
 
311
  /*
312
   * obsoleted by ATA 4
313
   *
314
  if (error&ERR_BADBLOCK) return IDE_ERR_BADBLOCK;
315
  else if (error&ERR_CRCECC) return IDE_ERR_CRCECC;
316
  else if (error&ERR_IDNOTFOUND) return IDE_ERR_IDNOTFOUND;
317
  else if (error&ERR_ABORTCMD) return IDE_ERR_ABORTCMD;
318
  else if (error&ERR_TRACK00) return IDE_ERR_TRACK00;
319
  else if (error&ERR_DAMNOTFOUND) return IDE_ERR_DAMNOTFOUND;
320
  */
321
 
322
  if (error&ERROR_ABORTCMD) return IDE_ERR_ABORTCMD;
323
  return IDE_ERR_UNKNOWN;
324
}
325
 
326
static void debug_status(char *s,BYTE status,BYTE mask)
327
{
328
  printk(IDEDEBUGLOG "%s: %s\n",s,status&mask?"yes":"no");
329
}
330
 
331
void ide_dump_interface_status(int ideif)
332
{
333
  BYTE status;
334
 
335
  printk(IDEDEBUGLOG "ide%i status\n",ideif);
336
 
337
  status=inp(IDE_REG_ALTSTATUS);
338
 
339
  debug_status("busy               ",status,STATUS_BUSY);
340
  if (status&STATUS_BUSY) return;
341
 
342
  debug_status("ready              ",status,STATUS_DRDY);
343
  //debug_status("write fault        ",status,ST_WRFAULT);
344
  //debug_status("seek complete      ",status,ST_SEEKCOM);
345
  debug_status("data request       ",status,STATUS_DRQ);
346
  //debug_status("data was corrected ",status,ST_DWC);
347
  //debug_status("command in progress",status,ST_CMDPROG);
348
  debug_status("error              ",status,STATUS_ERR);
349
 
350
}
351
 
352
 
353
//#ifndef NDEBUG
354
 
355
/*+ for the IDE_ERR_??? constants +*/
356
char *ide_error_msg[]={
357
  "no error",
358
  "there are too much request pending",
359
  "there was an interrupt but the interface is busy or can not do a command",
360
  "IDE error: bad block",
361
  "IDE error: crc/ecc error",
362
  "IDE error: sector id not found",
363
  "IDE error: abort command",
364
  "IDE error: track00 seek error",
365
  "IDE error: DAM not found",
366
  "generic error",
367
  "there was an interrupt, we aspect data but there is not data",
368
  "there was an interrupt, we do not aspect data but there is data",
369
  "interface not ready for a command",
370
  "a timeout waiting for a reply",
371
  "the interface must be busy but it is not",
372
  "device fault"
373
};
374
 
375
//#endif
376
 
377
/*
378
 *
379
 *
380
 *
381
 */
382
 
383
/* on i386 machine */
384
/* (todo better) */
385
/* done better! */
386
//#define ntohs(x) ((((x)&0xff00)>>8)|(((x)&0x00ff)<<8))
387
 
388
/* Well... the strings reported are swapped so if we have
389
 * a "Maxtor" hard disk the following string is reported: "aMtxro"
390
 */
391
 
392
/* from Linux kernel (modified!) */
393
static void ide_fixstring (BYTE *s, const int bytecount, const int byteswap)
394
{
395
  BYTE *p = s, *end = &s[bytecount & ~1]; /* bytecount must be even */
396
 
397
  if (byteswap) {
398
    /* convert from big-endian to host byte order */
399
    for (p = end ; p != s;) {
400
      WORD *pp = (WORD *) (p -= 2);
401
      *pp = ntohs(*pp);
402
    }
403
  }
404
 
405
  /* strip leading blanks */
406
  while (s != end && *s == ' ')
407
    ++s;
408
 
409
  /* compress internal blanks and strip trailing blanks */
410
  while (s != end && *s) {
411
    if (*s++ != ' ' || (s != end && *s && *s != ' '))
412
      *p++ = *(s-1);
413
  }
414
 
415
  /* wipe out trailing garbage */
416
  while (p != end)
417
    *p++ = '\0';
418
}
419
 
420
static void ide_fixdiskid(struct ata_diskid *ptr)
421
{
422
  ide_fixstring(ptr->firmware,sizeof(ptr->firmware),1);
423
  ptr->firmware[sizeof(ptr->firmware)-1]='\0';
424
  ide_fixstring(ptr->model,sizeof(ptr->model),1);
425
  ptr->model[sizeof(ptr->model)-1]='\0';
426
  ide_fixstring(ptr->serial,sizeof(ptr->serial),1);
427
  ptr->serial[sizeof(ptr->serial)-1]='\0';
428
}
429
 
430
static void ide_fixatapidiskid(struct atapi_diskid *ptr)
431
{
432
  ide_fixstring(ptr->firmware,sizeof(ptr->firmware),1);
433
  ptr->firmware[sizeof(ptr->firmware)-1]='\0';
434
  ide_fixstring(ptr->model,sizeof(ptr->model),1);
435
  ptr->model[sizeof(ptr->model)-1]='\0';
436
  ide_fixstring(ptr->serial,sizeof(ptr->serial),1);
437
  ptr->serial[sizeof(ptr->serial)-1]='\0';
438
}
439
 
440
static void lba2chs(int ideif, int id, DWORD lsector, int req)
441
{
442
 
443
  if (ide[ideif].info[id].use_lba) {
444
    idereq[req].secnum=lsector&0xff;
445
    lsector>>=8;
446
    idereq[req].cyllow=lsector&0xff;
447
    lsector>>=8;
448
    idereq[req].cylhig=lsector&0xff;
449
    lsector>>=8;
450
    idereq[req].devhead=0xe0|(lsector&0x0f)|((id&0x01)<<4);
451
  } else {    
452
    /* for old hard-disk; is this correct? */
453
    int sect,head,cyl,track;
454
    struct dskgeometry *drive=&(ide[ideif].pdisk[id]->pd_phgeom);
455
    track = lsector / drive->sectors;
456
    sect  = lsector % drive->sectors + 1;
457
    idereq[req].secnum=sect;    
458
    head  = track % drive->heads;
459
    cyl   = track / drive->heads;
460
    idereq[req].cyllow=cyl&0xff;
461
    idereq[req].cylhig=(cyl>>8)&0xff;
462
    idereq[req].devhead=0xa0|(head&0x0f)|((id&0x01)<<4);
463
  }
464
}
465
 
466
int ide_register(__uint16_t io_port, __uint16_t io_port2,
467
                 __uint8_t irq,
468
                 __uint8_t dma, __uint16_t io_bmdma)
469
{
470
  //struct phdskinfo    disk;
471
  //MODEL      m=BASE_MODEL;
472
  //int ind;
473
  int ideif;
474
  int res;
475
 
476
  //int req;
477
  //int ret;
478
 
479
  /* find an IDE interface sequential number */
480
  ideif=nextideif();
481
  if (ideif==MAXIDEINTERFACES) {
482
    if (ide_showinfo_flag)
483
      printk(IDELOG "ide: can't register (unavailable space)");
484
    return -1;
485
  }
486
 
487
  /* request to use resources... */
488
  if (!__request_irq(irq)) return -1;
489
  if (!__request_io_space(io_port+IOPORT_OFFSET,IOPORT_LEN)) {
490
    mark_ide_free(ideif);
491
    __release_irq(irq);
492
    return -1;
493
  }
494
  if (!__request_io_space(io_port2+IOPORT2_OFFSET,IOPORT2_LEN)) {
495
    mark_ide_free(ideif);
496
    __release_irq(irq);
497
    __release_io_space(io_port+IOPORT_OFFSET,IOPORT_LEN);
498
    return -1;
499
  }
500
  if (io_bmdma!=0)
501
    if (!__request_io_space(io_bmdma+BMDMAPORT_OFFSET,BMDMAPORT_LEN)) {
502
      mark_ide_free(ideif);
503
      __release_irq(irq);
504
      __release_io_space(io_port+IOPORT_OFFSET,IOPORT_LEN);
505
      __release_io_space(io_port2+IOPORT2_OFFSET,IOPORT2_LEN);
506
      return -1;
507
    }
508
 
509
#ifdef _PARANOIA
510
  ide[ideif].magic=IDE_MAGIC;
511
#endif
512
 
513
  ide[ideif].io_port=io_port;
514
  ide[ideif].io_port2=io_port2;
515
  ide[ideif].irq=irq;
516
  ide[ideif].dma=dma;
517
  ide[ideif].io_bmdma=io_bmdma;
518
  ide[ideif].pdisk[IDE_MASTER]=NULL;
519
  ide[ideif].info[IDE_MASTER].use_lba=0;
520
  ide[ideif].pdisk[IDE_SLAVE]=NULL;
521
  ide[ideif].info[IDE_SLAVE].use_lba=0;
522
  ide[ideif].actreq=-1;
523
  ide[ideif].actdrv=-1;
524
  bqueue_init(&ide[ideif].queue[0]);
525
  bqueue_init(&ide[ideif].queue[1]);
526
 
527
  /*
528
   * glue initialization
529
   */
530
 
531
  res=ide_glue_activate_interface(ideif);
532
  if (res==-1) {
533
    mark_ide_free(ideif);
534
    __release_irq(irq);
535
    __release_io_space(io_port+IOPORT_OFFSET,IOPORT_LEN);
536
    __release_io_space(io_port2+IOPORT2_OFFSET,IOPORT2_LEN);
537
    if (io_bmdma!=0)
538
      __release_io_space(io_bmdma+BMDMAPORT_OFFSET,BMDMAPORT_LEN);
539
    return -1;
540
  }
541
 
542
  return ideif;
543
}
544
 
545
void ide_unregister(int ideif)
546
{
547
 
548
  ide_glue_unactivate_interface(ideif);
549
 
550
  __release_irq(ide[ideif].irq);
551
  __release_io_space(ide[ideif].io_port+IOPORT_OFFSET,IOPORT_LEN);
552
  __release_io_space(ide[ideif].io_port2+IOPORT2_OFFSET,IOPORT2_LEN);
553
 
554
  mark_ide_free(ideif);
555
  //if (ideif!=ideiftail-1) 
556
  //  memcpy(ide+ideif,ide+ideiftail-1,sizeof(ideinfo_t));
557
}
558
 
559
/*
560
 *
561
 *
562
 *
563
 */
564
 
565
/* commands used */
566
#define ATA_READ       0x20
567
#define ATA_WRITE      0x30
568
#define ATA_SEEK       0x70
569
#define ATA_DMAREAD    0xc8
570
#define ATA_DMAWRITE   0xca
571
#define ATA_IDENTIFY   0xec
572
#define ATA_PIDENTIFY  0xa1
573
#define ATA_SETFEATURE 0xef
574
 
575
/* for 'set feature' command */
576
#define ATA_FEATURE_ENABLELOOKAHEAD  0xaa
577
#define ATA_FEATURE_DISABLELOOKAHEAD 0x55
578
#define ATA_FEATURE_SETTRANSFERTMODE 0x03
579
 
580
/* commands type */
581
#define ATA_TYPE_PIOIN   0
582
#define ATA_TYPE_PIOOUT  1
583
#define ATA_TYPE_DMA     2
584
#define ATA_TYPE_NODATA  3
585
 
586
static inline int cmd2type(int cmd)
587
{
588
  switch(cmd) {
589
    case ATA_READ:
590
    case ATA_IDENTIFY:
591
    case ATA_PIDENTIFY:
592
      return ATA_TYPE_PIOIN;
593
    case ATA_WRITE:
594
      return ATA_TYPE_PIOOUT;
595
    case ATA_DMAREAD:
596
    case ATA_DMAWRITE:
597
      return ATA_TYPE_DMA;
598
    case ATA_SEEK:
599
    case ATA_SETFEATURE:
600
      return ATA_TYPE_NODATA;
601
  }
602
  return ATA_TYPE_NODATA;
603
}
604
 
605
#if defined(DEBUG_SERVER)||defined(DEBUG_SHOWREQUEST)
606
static char *cmd2str(int cmd)
607
{
608
  switch(cmd) {
609
    case ATA_READ: return "'read'";
610
    case ATA_WRITE: return "'write'";
611
    case ATA_SEEK: return "'seek'";
612
    case ATA_DMAREAD: return "'dma read'";
613
    case ATA_DMAWRITE: return "'dma write'";
614
    case ATA_IDENTIFY: return "'identify'";
615
    case ATA_PIDENTIFY: return "'packet identify'";
616
    case ATA_SETFEATURE: return "'set feature'";
617
  }
618
  return "'unknown'";
619
}
620
#endif
621
 
622
/*
623
 * from ATA/ATAPI 4 (T13/1153D revision 18)
624
 * paragraph 9.7 (figure 12)
625
 */
626
 
627
#define RETRY 3
628
 
629
 
630
/*from Linux 2.2.13*/
631
/*
632
static int do_io_request(int ideif)
633
{
634
  int req=ide[ideif].reqhead;
635
 
636
  VM_out(IDE_REG_DEVCTRL,DEVCTRL_NORMALOP);
637
  outp(IDE_REG_SECCOU,idereq[req].seccou);  
638
 
639
  outp(IDE_REG_SECNUM,idereq[req].secnum);  
640
  outp(IDE_REG_CYLLOW,idereq[req].cyllow);
641
  outp(IDE_REG_CYLHIG,idereq[req].cylhig);
642
  outp(IDE_REG_DEVHEAD,idereq[req].devhead);
643
 
644
  outp(IDE_REG_COMMAND,idereq[req].cmd);
645
 
646
  return IDE_OK;  
647
}
648
*/
649
 
650
static int do_io_request(int ideif)
651
{
652
  int req;
653
  BYTE status;
654
  int n;
655
  WORD *ptr;
656
#ifndef IDE_SKIPALLTEST
657
  int retries;
658
#endif
659
 
660
  printk4(ideif,"A");
661
 
662
  //outp(IDE_REG_DEVCTRL,DEVCTRL_NORMALOP);
663
  //outp(IDE_REG_SECCOU,idereq[req].seccou);  
664
 
665
  req=first_idereq(ideif);
666
  assertk(req!=NIL);
667
 
668
  /* requirement for some commands */
669
  switch(idereq[req].cmd) {
670
 
671
    /* DRDY must be one */
672
    case ATA_READ:
673
    case ATA_DMAREAD:      
674
    case ATA_WRITE:
675
    case ATA_DMAWRITE:
676
    case ATA_SEEK:
677
    case ATA_IDENTIFY:
678
    case ATA_SETFEATURE:
679
 
680
#ifndef IDE_SKIPALLTEST
681
      retries=RETRY;
682
      while (--retries>=0) {
683
        status=inp(IDE_REG_STATUS);
684
        if ((status&STATUS_DRDY)!=0) break;
685
      }
686
      if (retries<0) return idereq[req].result=IDE_ERR_NOTDRDY;
687
      break;
688
#endif
689
 
690
      /* no requirement */
691
    case ATA_PIDENTIFY:
692
      break;
693
  }
694
 
695
  printk4(ideif,"B");
696
 
697
  /* a command can be issued when BUSY==0 && DRQ==0 */
698
#ifndef IDE_SKIPALLTEST
699
  retries=RETRY;  
700
  while (--retries>=0) {
701
    status=inp(IDE_REG_STATUS);
702
    if ((status&STATUS_BUSY)==0&&(status&STATUS_DRQ)==0) break;
703
  }  
704
  if (retries<0) {    
705
    /* if the ide device is in stand-by the request fail! */      
706
    if (status&STATUS_BUSY) return idereq[req].result=IDE_ERR_BUSY;
707
    else return idereq[req].result=IDE_ERR_NOTREADY;
708
  }
709
#endif
710
 
711
  printk4(ideif,"C");
712
 
713
  /* write "change device" register */
714
  outp(IDE_REG_DEVHEAD,idereq[req].devhead);
715
 
716
  /* to wait for 400ns (I hope) */
717
#ifndef IDE_SKIPALLTEST
718
  inp(IDE_REG_ALTSTATUS);
719
#endif
720
 
721
  /* wait for "change device" to take effect */
722
#ifndef IDE_SKIPALLTEST
723
  retries=RETRY;  
724
  while (--retries>=0) {
725
    status=inp(IDE_REG_STATUS);
726
    if ((status&STATUS_BUSY)==0&&(status&STATUS_DRQ)==0) break;
727
  }
728
  if (retries<0) {
729
    /* Well, if I do a command to a disk that does not exist an
730
     * interrupt is generated... so I MUST report no error
731
     * (the error is manage into the ide server)
732
     */
733
    return IDE_OK;
734
    if (status&STATUS_BUSY) return idereq[req].result=IDE_ERR_BUSY;
735
    else return idereq[req].result=IDE_ERR_NOTREADY;
736
  }
737
#endif
738
 
739
  printk4(ideif,"D");
740
 
741
  /* write all the registers */
742
  outp(IDE_REG_FEATURES,idereq[req].features);  
743
  outp(IDE_REG_SECCOU,idereq[req].seccou);  
744
  outp(IDE_REG_SECNUM,idereq[req].secnum);
745
  outp(IDE_REG_CYLLOW,idereq[req].cyllow);
746
  outp(IDE_REG_CYLHIG,idereq[req].cylhig);
747
  //outp(IDE_REG_DEVHEAD,idereq[req].devhead);
748
 
749
  if (cmd2type(idereq[req].cmd)==ATA_TYPE_DMA) {
750
 
751
    /*
752
     *
753
     * Bus Master DMA commands
754
     *
755
     */
756
 
757
    /* these code come from Linux 2.2.12 (modified!) */
758
 
759
    __uint32_t addr,*ptr;
760
    unsigned int size;
761
    int count;
762
 
763
    /* make PRD table */
764
 
765
    addr=__lin_to_phy(idereq[req].buffer);
766
    if (addr&3) {
767
      /* misaligned buffer */
768
      printk(KERN_ERR "ide do_io_request: misaligned DMA buffer (0x%08lx)",
769
             (long)addr);
770
      return IDE_ERR_UNKNOWN;
771
    }
772
    size=IDE_SECTOR_SIZE; /* for now only 1 sector */
773
 
774
    ptr=ide[ideif].prd;
775
    count=0;
776
    while (size) {
777
      if (++count>=MAXPRDENTRIES) {    
778
        /* table to small for the request */
779
        printk(KERN_ERR "ide do_io_request: PRD table too small");
780
        return IDE_ERR_UNKNOWN;
781
      } else {
782
        unsigned int xcount, bcount = 0x10000 - (addr & 0xffff);       
783
        if (bcount > size)
784
          bcount = size;
785
        *ptr++ = addr;
786
        xcount = bcount & 0xffff;
787
        //if (is_trm290_chipset)
788
          //  xcount = ((xcount >> 2) - 1) << 16;       
789
        *ptr++ = xcount;               
790
        addr += bcount;
791
        size -= bcount;
792
      }
793
    }
794
 
795
    printk4(ideif,"E3");
796
 
797
    /* PRD table */
798
    outpd(BM_REG_PRDADDR,__lin_to_phy(ide[ideif].prd));
799
 
800
    /* specify r/w */
801
    if (idereq[req].cmd==ATA_DMAREAD) outp(BM_REG_COMMAND,1<<3);
802
    else {
803
      /* for default now... read */
804
      /*outp(BM_REG_COMMAND,1<<3);*/
805
      /* for write */
806
      outp(BM_REG_COMMAND,0);
807
    }
808
 
809
    /* clear INTR & ERROR flags */
810
    outp(BM_REG_STATUS,inp(BM_REG_STATUS)|6);
811
 
812
    /* write command*/
813
    outp(IDE_REG_COMMAND,idereq[req].cmd);
814
 
815
    /* start DMA */
816
    outp(BM_REG_COMMAND,inp(BM_REG_COMMAND)|1);
817
 
818
    printk4(ideif,"F3");
819
 
820
    return IDE_OK;    
821
  }
822
 
823
  /*
824
   *
825
   * PIO IN/OUT and NO_DATA commands
826
   *
827
   */
828
 
829
  /* write command*/
830
  outp(IDE_REG_COMMAND,idereq[req].cmd);
831
 
832
  /* to wait for 400ns; I hope */
833
#ifndef  IDE_SKIPSTATUSTEST
834
  inp(IDE_REG_STATUS);
835
#endif
836
 
837
  switch (cmd2type(idereq[req].cmd)) {
838
 
839
    /* for PIO data in commands and NODATA commands */
840
 
841
    case ATA_TYPE_PIOIN:
842
    case ATA_TYPE_NODATA:
843
 
844
      /* Well, the host should set the BUSY flag*/
845
#ifndef IDE_SKIPSTATUSTEST
846
      retries=RETRY;
847
      while (--retries>=0) {
848
        status=inp(IDE_REG_ALTSTATUS);
849
        if ((status&STATUS_BUSY)!=0) break;
850
      }
851
      if (retries<0) return IDE_ERR_NOTBUSY;
852
#endif
853
      printk4(ideif,"E1");
854
 
855
      return IDE_OK;
856
 
857
      /* for PIO data out commands */
858
 
859
    case ATA_TYPE_PIOOUT:
860
 
861
      for (;;) {
862
        /* Well, perhaps a timeout is necessary! */
863
        status=inp(IDE_REG_ALTSTATUS);
864
#ifndef IDE_SKIPALLTEST
865
        if ((status&STATUS_BUSY)!=0) break;
866
#else
867
        break;
868
#endif
869
      }
870
      printk4(ideif,"E2");
871
 
872
      if ((status&STATUS_ERR)||(status&STATUS_R_FAULT)) {
873
        /* an error is detected! */
874
        idereq[req].result=((status&STATUS_ERR)?
875
                            decode_error_result(ideif):IDE_ERR_FAULT
876
                            );
877
        return idereq[req].result;
878
 
879
      }
880
      if (!(status&STATUS_DRQ)) {
881
        /* error,  */
882
        return IDE_ERR_NODATAREQ;
883
      }
884
 
885
      /* Data I/O */
886
      ptr=(WORD*)idereq[req].buffer;
887
      for (n=0;n<IDE_SECTOR_SIZE>>1;n++)
888
        *ptr++=inpw(IDE_REG_DATA);
889
 
890
      /* to wait for 400ns; I hope ;-) */
891
#ifndef IDE_SKIPALLTEST
892
      inp(IDE_REG_ALTSTATUS);
893
#endif
894
 
895
#ifndef IDE_SKIPALLTEST
896
      status=inp(IDE_REG_ALTSTATUS);
897
      if ((status&STATUS_BUSY)==0) return IDE_ERR_NOTBUSY;
898
#endif
899
 
900
      printk4(ideif,"F2");
901
 
902
      return IDE_OK;
903
  }
904
 
905
  return IDE_ERR_UNKNOWN;
906
}
907
 
908
/* (must be 6sec for ATA specs) */
909
#define WAITENDRESET_ELAPSE 200000l
910
 
911
int do_ide_softreset(int ideif)
912
{
913
  unsigned long t;
914
  int flag;
915
  int status;
916
 
917
  printk2(ideif,"START");
918
 
919
  printk2(ideif,"waiting for not busy...");
920
  /* 1 msec */
921
  flag=1;
922
  t=__gettimer()+1000;
923
  while (__gettimer()<t) {
924
    status=inp(IDE_REG_ALTSTATUS);
925
    if (!(status&STATUS_BUSY)) { flag=0; break; }
926
  }
927
  if (flag) {
928
    printk2(ideif,"device is busy!");
929
    #ifndef IDE_FORCERESET
930
    printk2(ideif,"END");
931
    return IDE_ERR_TIMEOUT;
932
    #endif
933
    printk2(ideif,"with FORCERESET");
934
  } else
935
    printk2(ideif,"not busy");
936
 
937
  printk2(ideif,"soft resetting");
938
  outp(IDE_REG_DEVCTRL,DEVCTRL_SOFTRESET);
939
  __delayk(5);
940
  outp(IDE_REG_DEVCTRL,DEVCTRL_NORMALOP);
941
 
942
  __delayk(2000);
943
 
944
  printk2(ideif,"waiting for soft resetting end");
945
  /* 6sec */
946
  flag=1;
947
  t=__gettimer()+WAITENDRESET_ELAPSE;
948
  while (__gettimer()<t) {
949
    status=inp(IDE_REG_ALTSTATUS);
950
    if (!(status&STATUS_BUSY||!(status&STATUS_DRDY))) { flag=0; break; }
951
  }
952
  if (flag) {
953
    printk2(ideif,"not ending!!");
954
    printk2(ideif,"END");
955
    return IDE_ERR_TIMEOUT;
956
  }
957
  printk2(ideif,"resetting end");
958
 
959
  printk2(ideif,"END");
960
  return IDE_OK;
961
}
962
 
963
/*
964
 *
965
 *
966
 *
967
 */
968
 
969
/* abort per i packet */
970
 
971
static int REQ_PROLOG(void)
972
{
973
  int req;
974
 
975
  req=get_idereq();
976
  if (req==NIL)
977
    return IDE_ERR_TOOMUCHREQ;
978
 
979
  /* ide[].resetonerror:
980
   *
981
   * used by calling thread
982
   *    0 -> no soft reset on error
983
   *    1 -> request a soft reset on error
984
   * used by called thread (the server)
985
   *    2 -> the calling thread MUST do a soft reset
986
   */
987
 
988
  /* for safety */
989
  idereq[req].resetonerror=1;
990
 
991
  return req;
992
}
993
 
994
/* elapse for a timeouted request in usec (must be 2sec for ATA spec) */
995
#define TIMED_ELAPSE 80000l
996
 
997
static int __REQ_EPILOG(int ideif, int drv, int req, int timed)
998
{
999
  int res,ret;
1000
  //long num;
1001
 
1002
  printk3(ideif,"START");
1003
 
1004
  ret=insert_idereq(ideif,drv,req);
1005
  if (ret) {
1006
    printk3(ideif,"activating server task");
1007
    ide_glue_send_request(ideif);
1008
  } else
1009
    printk3(ideif,"server task already running");
1010
 
1011
  if (timed) {
1012
    unsigned long timer,timer2,timer3;
1013
    printk3(ideif,"waiting timed server reply");
1014
    res=1;
1015
    timer=__gettimer();
1016
    printk3(ideif,"AA");
1017
    assertk(timer!=0);
1018
    timer+=TIMED_ELAPSE;
1019
    printk3(ideif,"BB");
1020
    timer3=0;
1021
 
1022
    /*
1023
    {
1024
      SYS_FLAGS f;      
1025
      f=kern_fsave();
1026
      kern_frestore(f);
1027
      cprintf("[f=0x%x]",(int)f);
1028
    }
1029
    */
1030
 
1031
    while ((timer2=__gettimer())<timer) {
1032
 
1033
      //cprintf("<%li>",timer2);
1034
 
1035
 
1036
      //if (timer2<timer3) break;      
1037
      //timer3=timer2;
1038
 
1039
      res=__b_sem_trywait(&idereq[req].wait);
1040
      if (!res) break;
1041
    }
1042
    printk3(ideif,"CC");
1043
    if (res) {
1044
      /* DANGER: if this is sent and an'interrupt occur
1045
       * the reqpending assertion of the server fail
1046
       */
1047
      printk3(ideif,"timer expired.. try to remove request");
1048
      ide_glue_send_request(ideif);
1049
      __b_sem_wait(&idereq[req].wait);
1050
      res=IDE_ERR_TIMEOUT;
1051
    } else {
1052
      res=idereq[req].result;
1053
      printk3(ideif,"server reply ok");
1054
    }
1055
  } else {
1056
    printk3(ideif,"waiting server reply");
1057
#ifdef TRACEWAIT
1058
    num=exec_shadow;
1059
    trc_logevent(TRC_USER1,&num);
1060
#endif
1061
    __b_sem_wait(&idereq[req].wait);
1062
#ifdef TRACEWAIT
1063
    trc_logevent(TRC_USER2,&num);
1064
#endif
1065
    printk3(ideif,"server reply ok");
1066
    res=idereq[req].result;
1067
  }
1068
  free_idereq(req);
1069
 
1070
  if (idereq[req].resetonerror==2) {
1071
    printk3(ideif,"SOFT RESET");
1072
    do_ide_softreset(ideif);
1073
    ret=releasequeue_idereq(ideif);
1074
    if (ret) {
1075
      /* there are request pending... */
1076
      ide_glue_send_request(ideif);
1077
    }
1078
  }
1079
 
1080
 
1081
  printk3(ideif,"END");
1082
  return res;
1083
}
1084
 
1085
#define REQ_EPILOG(ideif,drv,req) __REQ_EPILOG(ideif,drv,req,0)
1086
#define TIMED_REQ_EPILOG(ideif,drv,req) __REQ_EPILOG(ideif,drv,req,1)
1087
 
1088
/**/
1089
 
1090
static void fill_prologue(int req,
1091
                          int cmd,
1092
                          unsigned lsector,
1093
                          struct phdskinfo *pdisk)
1094
{
1095
  unsigned track;
1096
 
1097
  if (cmd==REQ_DUMMY) {
1098
    idereq[req].info.sector=0;
1099
    idereq[req].info.head=0;
1100
    idereq[req].info.cylinder=0;
1101
    idereq[req].info.nsectors=0;
1102
    idereq[req].info.operation=cmd;
1103
    return;
1104
  }
1105
  track=lsector/pdisk->pd_phgeom.sectors;
1106
  idereq[req].info.sector=lsector%pdisk->pd_phgeom.sectors+1;
1107
  idereq[req].info.head=track%pdisk->pd_phgeom.heads;
1108
  idereq[req].info.cylinder=track/pdisk->pd_phgeom.heads;
1109
  idereq[req].info.nsectors=1;
1110
  idereq[req].info.operation=cmd;
1111
}
1112
 
1113
int ide_identify(int ideif, int id, struct ata_diskid *buffer)
1114
{
1115
  int req,ret;
1116
 
1117
  printk1(ideif,"%s start",cmd2str(ATA_IDENTIFY));
1118
 
1119
  req=REQ_PROLOG();
1120
  if (req<0) {
1121
    printk1(ideif,"%s end=%i",cmd2str(ATA_IDENTIFY),req);
1122
    return req;
1123
  }
1124
 
1125
  idereq[req].cmd=ATA_IDENTIFY;
1126
  idereq[req].features=0;
1127
  idereq[req].cyllow=0;
1128
  idereq[req].cylhig=0;
1129
  idereq[req].seccou=0;
1130
  idereq[req].secnum=0;
1131
  idereq[req].devhead=0xa0|((id&0x01)<<4);
1132
  idereq[req].buffer=(BYTE*)buffer;
1133
  idereq[req].resetonerror=0;
1134
  fill_prologue(req,REQ_DUMMY,0,ide[ideif].pdisk[id]);
1135
 
1136
  ret=TIMED_REQ_EPILOG(ideif,id,req);
1137
 
1138
  if (ret==IDE_OK) ide_fixdiskid(buffer);
1139
 
1140
  printk1(ideif,"%s end=%i",cmd2str(ATA_IDENTIFY),ret);  
1141
  return ret;
1142
}
1143
 
1144
int ide_pidentify(int ideif, int id, struct atapi_diskid *buffer)
1145
{
1146
  int req,ret;
1147
 
1148
  printk1(ideif,"%s start",cmd2str(ATA_PIDENTIFY));
1149
 
1150
  req=REQ_PROLOG();
1151
  if (req<0) {
1152
    printk1(ideif,"%s end=%i",cmd2str(ATA_PIDENTIFY),req);
1153
    return req;
1154
  }
1155
 
1156
  idereq[req].cmd=ATA_PIDENTIFY;
1157
  idereq[req].features=0;
1158
  idereq[req].cyllow=0;
1159
  idereq[req].cylhig=0;
1160
  idereq[req].seccou=0;
1161
  idereq[req].secnum=0;
1162
  idereq[req].devhead=0xa0|((id&0x01)<<4);
1163
  idereq[req].buffer=(BYTE*)buffer;
1164
  idereq[req].resetonerror=0;
1165
  fill_prologue(req,REQ_DUMMY,0,ide[ideif].pdisk[id]);
1166
 
1167
  ret=TIMED_REQ_EPILOG(ideif,id,req);
1168
 
1169
  if (ret==IDE_OK) ide_fixatapidiskid(buffer);
1170
 
1171
  printk1(ideif,"%s end=%i",cmd2str(ATA_PIDENTIFY),ret);
1172
  return ret;
1173
}
1174
 
1175
#define IDE_READ_RETRIES  1
1176
#define IDE_SEEK_RETRIES  1
1177
#define IDE_WRITE_RETRIES 1
1178
 
1179
int ide_read(int ideif, int id, __blkcnt_t lsector, BYTE *buffer)
1180
{
1181
  int req,ret;
1182
  int i;
1183
 
1184
  printk1(ideif,"%s start",cmd2str(ATA_READ));
1185
 
1186
  for (i=0;i<IDE_READ_RETRIES;i++) {
1187
 
1188
    req=REQ_PROLOG();
1189
    if (req<0) {
1190
      printk1(ideif,"%s end(1)=%i",cmd2str(ATA_READ),req);
1191
      return req;
1192
    }
1193
 
1194
    idereq[req].cmd=ATA_READ;
1195
    assertk(ide[ideif].info[id].use_dma==0);
1196
    if (ide[ideif].info[id].use_bm_dma) idereq[req].cmd=ATA_DMAREAD;
1197
    lba2chs(ideif,id,lsector,req);
1198
    idereq[req].features=0;
1199
    idereq[req].seccou=1;
1200
    idereq[req].buffer=buffer;
1201
    idereq[req].resetonerror=1;
1202
    fill_prologue(req,REQ_READ,lsector,ide[ideif].pdisk[id]);
1203
 
1204
    ret=REQ_EPILOG(ideif,id,req);
1205
    if (ret==IDE_OK) break;
1206
    if (i!=0) printk1(ideif,"%s retry",cmd2str(ATA_READ));
1207
  }
1208
  printk1(ideif,"%s end(2)=%i",cmd2str(ATA_READ),ret);
1209
  return ret;
1210
}
1211
 
1212
int ide_seek(int ideif, int id, __blkcnt_t lsector)
1213
{  
1214
  int req,ret;
1215
  int i;
1216
 
1217
  printk1(ideif,"%s start",cmd2str(ATA_SEEK));
1218
 
1219
  for (i=0;i<IDE_SEEK_RETRIES;i++) {
1220
 
1221
    req=REQ_PROLOG();
1222
    if (req<0) {
1223
      printk1(ideif,"%s end=%i",cmd2str(ATA_SEEK),req);
1224
      return req;
1225
    }
1226
 
1227
    idereq[req].cmd=ATA_SEEK;
1228
    lba2chs(ideif,id,lsector,req);
1229
    idereq[req].features=0;
1230
    idereq[req].seccou=0;
1231
    idereq[req].buffer=NULL;
1232
    idereq[req].resetonerror=1;
1233
    fill_prologue(req,REQ_SEEK,lsector,ide[ideif].pdisk[id]);
1234
 
1235
    ret=REQ_EPILOG(ideif,id,req);
1236
    if (ret==IDE_OK) break;
1237
    if (i!=0) printk1(ideif,"%s retry",cmd2str(ATA_SEEK));
1238
  }
1239
  printk1(ideif,"%s end=%i",cmd2str(ATA_SEEK),ret);
1240
  return ret;
1241
}
1242
 
1243
int ide_enablelookahead(int ideif, int id)
1244
{  
1245
  int req,ret;
1246
 
1247
#ifndef IDE_ENABLESETFEATURES
1248
  printk(KERN_NOTICE "ide command 'enable look-ahead' not yet implementated");
1249
  return IDE_ERR_UNKNOWN;
1250
#endif
1251
 
1252
  printk1(ideif,"%s start (enable look a head)",cmd2str(ATA_SETFEATURE));
1253
 
1254
  req=REQ_PROLOG();
1255
  if (req<0) {
1256
    printk1(ideif,"%s end=%i",cmd2str(ATA_SETFEATURE),req);
1257
    return req;
1258
  }
1259
 
1260
  idereq[req].cmd=ATA_SETFEATURE;
1261
  idereq[req].features=ATA_FEATURE_ENABLELOOKAHEAD;
1262
  idereq[req].cyllow=0;
1263
  idereq[req].cylhig=0;
1264
  idereq[req].seccou=0;
1265
  idereq[req].secnum=0;
1266
  idereq[req].devhead=((id&0x01)<<4);
1267
  idereq[req].buffer=NULL;
1268
  idereq[req].resetonerror=1;
1269
  fill_prologue(req,REQ_DUMMY,0,ide[ideif].pdisk[id]);
1270
 
1271
  ret=REQ_EPILOG(ideif,id,req);
1272
 
1273
  //ide_dump_interface_status(ideif);
1274
 
1275
  __delayk(5);
1276
  outp(IDE_REG_DEVCTRL,DEVCTRL_NORMALOP);
1277
 
1278
  printk1(ideif,"%s end=%i",cmd2str(ATA_SETFEATURE),ret);
1279
  return ret;
1280
}
1281
 
1282
int ide_disablelookahead(int ideif, int id)
1283
{  
1284
  int req,ret;
1285
 
1286
#ifndef IDE_ENABLESETFEATURES
1287
  printk(KERN_NOTICE "ide command 'disable look-ahead' not yet implementated");
1288
  return IDE_ERR_UNKNOWN;
1289
#endif
1290
 
1291
  printk1(ideif,"%s start (enable look a head)",cmd2str(ATA_SETFEATURE));
1292
 
1293
  req=REQ_PROLOG();
1294
  if (req<0) {
1295
    printk1(ideif,"%s end=%i",cmd2str(ATA_SETFEATURE),req);
1296
    return req;
1297
  }
1298
 
1299
  idereq[req].cmd=ATA_SETFEATURE;
1300
  idereq[req].features=ATA_FEATURE_DISABLELOOKAHEAD;
1301
  idereq[req].cyllow=0;
1302
  idereq[req].cylhig=0;
1303
  idereq[req].seccou=0;
1304
  idereq[req].secnum=0;
1305
  idereq[req].devhead=((id&0x01)<<4);
1306
  idereq[req].buffer=NULL;
1307
  idereq[req].resetonerror=1;
1308
  fill_prologue(req,REQ_DUMMY,0,ide[ideif].pdisk[id]);
1309
 
1310
  ret=REQ_EPILOG(ideif,id,req);
1311
 
1312
  printk1(ideif,"%s end=%i",cmd2str(ATA_SETFEATURE),ret);
1313
  return ret;
1314
}
1315
 
1316
int ide_settransfertmode(int ideif, int id, int mode)
1317
{  
1318
  int req,ret;
1319
 
1320
#ifndef IDE_ENABLESETFEATURES
1321
  printk(KERN_NOTICE "ide command 'set transfert mode' not yet implementated");
1322
  return IDE_ERR_UNKNOWN;
1323
#endif
1324
 
1325
  printk1(ideif,"%s start (set transfert mode)",cmd2str(ATA_SETFEATURE));
1326
 
1327
  req=REQ_PROLOG();
1328
  if (req<0) {
1329
    printk1(ideif,"%s end=%i",cmd2str(ATA_SETFEATURE),req);
1330
    return req;
1331
  }
1332
 
1333
  idereq[req].cmd=ATA_SETFEATURE;
1334
  idereq[req].features=ATA_FEATURE_SETTRANSFERTMODE;
1335
  idereq[req].cyllow=0;
1336
  idereq[req].cylhig=0;
1337
  idereq[req].seccou=mode;
1338
  idereq[req].secnum=0;
1339
  idereq[req].devhead=((id&0x01)<<4);
1340
  idereq[req].buffer=NULL;
1341
  idereq[req].resetonerror=1;
1342
  fill_prologue(req,REQ_DUMMY,0,ide[ideif].pdisk[id]);
1343
 
1344
  ret=REQ_EPILOG(ideif,id,req);
1345
 
1346
  ide_dump_interface_status(ideif);
1347
 
1348
  printk1(ideif,"%s end=%i",cmd2str(ATA_SETFEATURE),ret);
1349
  return ret;
1350
}
1351
 
1352
int ide_write(int ideif, int id, __blkcnt_t lsector, BYTE *buffer)
1353
{  
1354
  int req,ret;
1355
  int i;
1356
 
1357
  printk1(ideif,"%s start",cmd2str(ATA_WRITE));
1358
 
1359
  for (i=0;i<IDE_WRITE_RETRIES;i++) {
1360
 
1361
    req=REQ_PROLOG();
1362
    if (req<0) {
1363
      printk1(ideif,"%s end=%i",cmd2str(ATA_WRITE),req);
1364
      return req;
1365
    }
1366
 
1367
    idereq[req].cmd=ATA_WRITE;    
1368
    assertk(ide[ideif].info[id].use_dma==0);
1369
    if (ide[ideif].info[id].use_bm_dma) idereq[req].cmd=ATA_DMAWRITE;
1370
    else {
1371
      panic("there is no support for polled write (only DMA allowed)!");
1372
    }
1373
    lba2chs(ideif,id,lsector,req);
1374
    idereq[req].features=0;
1375
    idereq[req].seccou=1;
1376
    idereq[req].buffer=buffer;
1377
    idereq[req].resetonerror=1;
1378
    fill_prologue(req,REQ_WRITE,lsector,ide[ideif].pdisk[id]);
1379
 
1380
    ret=REQ_EPILOG(ideif,id,req);
1381
    if (ret==IDE_OK) break;
1382
    if (i!=0) printk1(ideif,"%s retry",cmd2str(ATA_WRITE));
1383
  }
1384
  printk1(ideif,"%s end=%i",cmd2str(ATA_WRITE),ret);
1385
  return ret;
1386
}
1387
 
1388
/**/
1389
 
1390
void ide_service_request(int ideif)
1391
{
1392
  static int reqpending=0;
1393
  BYTE status,dma_status;
1394
  int res=0,req=0;
1395
  int n;
1396
 
1397
  printk0(ideif,"ACTIVATED");
1398
  //assertk(ide[ideif].reqhead!=NIL);
1399
 
1400
  if (!reqpending) {
1401
    printk0(ideif,"doing a new request");
1402
    reqpending=1;
1403
    goto DO_REQUEST;
1404
  }
1405
 
1406
  printk0(ideif,"start to serve %s request",cmd2str(idereq[req].cmd));
1407
  status=inp(IDE_REG_STATUS);    
1408
  //req=ide[ideif].reqhead;
1409
  req=actual_idereq(ideif);
1410
 
1411
  /*
1412
    if (req==NIL) {
1413
    printk(KERN_INFO "unaspceted INTR catch");
1414
    continue;
1415
    }
1416
   */
1417
 
1418
  if (status&STATUS_BUSY||status&STATUS_ERR) {
1419
    idereq[req].cmd=0;
1420
    /* to FIX! */
1421
  }
1422
 
1423
  switch (idereq[req].cmd) {
1424
 
1425
    /*
1426
     * DMA COMMANDS
1427
     *
1428
     * DMAREAD
1429
     */
1430
 
1431
    case ATA_DMAREAD:
1432
    case ATA_DMAWRITE:
1433
      /* from Linux 2.2.12 */
1434
 
1435
      /* stop DMA */      
1436
      outp(BM_REG_COMMAND,inp(BM_REG_COMMAND)&~1);
1437
 
1438
      /* get DMA status */    
1439
      dma_status = inp(BM_REG_STATUS);
1440
 
1441
      /* clear the INTR & ERROR bits */
1442
      outp(BM_REG_STATUS,dma_status|6);
1443
 
1444
      /* verify good DMA status (0 -> OK)*/
1445
      dma_status=(dma_status&7)!=4;    
1446
 
1447
      if (dma_status||status&STATUS_DRQ)
1448
        idereq[req].result=((status&STATUS_ERR)?
1449
                            decode_error_result(ideif):IDE_ERR_DMA
1450
                            );
1451
      else
1452
        idereq[req].result=IDE_OK;
1453
      break;
1454
 
1455
    /*
1456
     * NO DATA COMMANDS
1457
     *
1458
     * SEEK and SET FEATURE
1459
     */
1460
 
1461
    case ATA_SEEK:
1462
    case ATA_SETFEATURE:
1463
 
1464
      if (status&STATUS_DRQ) {
1465
        idereq[req].result=((status&STATUS_ERR)?
1466
                            decode_error_result(ideif):IDE_ERR_DATA
1467
                            );
1468
      } else
1469
        idereq[req].result=IDE_OK;
1470
 
1471
      break;
1472
 
1473
    case ATA_PIDENTIFY:
1474
    case ATA_IDENTIFY:
1475
    case ATA_READ:
1476
 
1477
      /*
1478
       * PIO IN COMMANDS
1479
       *
1480
       * PIDENTIFY, IDENTIFY and READ commands
1481
       */
1482
 
1483
      if (status&STATUS_DRQ) {
1484
        WORD *ptr=(WORD*)idereq[req].buffer;
1485
        for (n=0;n<IDE_SECTOR_SIZE>>1;n++)
1486
          *ptr++=inpw(IDE_REG_DATA);
1487
        status=inp(IDE_REG_ALTSTATUS);    
1488
 
1489
      } else {
1490
        idereq[req].result=((status&STATUS_ERR)?
1491
                            decode_error_result(ideif):IDE_ERR_NODATA
1492
                            );
1493
      }
1494
      status=inp(IDE_REG_STATUS);    
1495
      if (status&STATUS_DRQ) idereq[req].result=IDE_ERR_NODATA; /*fix*/
1496
      else idereq[req].result=IDE_OK;
1497
 
1498
      break;
1499
 
1500
      /*
1501
       * PIO OUT COMMANDS
1502
       *
1503
       * WRITE command
1504
       */
1505
 
1506
    case ATA_WRITE:
1507
      /* all work is done into do_io_request() */
1508
      idereq[req].result=IDE_OK;
1509
      break;
1510
 
1511
      /*
1512
       * BOH ?!?
1513
       */
1514
 
1515
    default:
1516
      /* an abort is more appropiate! */
1517
      inp(IDE_REG_ALTSTATUS);    
1518
      idereq[req].result=IDE_ERR_UNKNOWN;
1519
      break;      
1520
  }
1521
 
1522
#ifdef IDE_OLDATAPIDELAY
1523
  if (idereq[req].cmd==ATA_PIDENTIFY) {
1524
    /* delay for old ATAPI device */
1525
    /* on my old cdrom a n>700 is ok */
1526
    for (n=0;n<750;n++) {
1527
      status=inp(IDE_REG_ALTSTATUS);
1528
      if (status&0x100) break;
1529
    }
1530
  }
1531
#endif
1532
 
1533
  reqpending=remove_idereq(ideif);
1534
  printk0(ideif,"end to serve request (result=%i)",idereq[req].result);
1535
  __b_sem_signal(&idereq[req].wait);
1536
  if (reqpending) printk0(ideif,"another request into the queue");
1537
 
1538
DO_REQUEST:
1539
  /* if there are requests pending... */
1540
  if (reqpending)
1541
    /* loop until no request error! */
1542
    for (;;) {
1543
      /* made request! */
1544
      printk0(ideif,"made new request");
1545
      res=do_io_request(ideif);
1546
      if (res!=IDE_OK) {
1547
        /* if request fail... */
1548
 
1549
        /* update result */
1550
        printk0(ideif,"new request fail (code: %i)",res);
1551
 
1552
        //req=ide[ideif].reqhead;
1553
        req=actual_idereq(ideif);
1554
        idereq[req].result=res;
1555
 
1556
        /* if "request on error" ... */
1557
        if (idereq[req].resetonerror==1) {
1558
          /* request a soft error */
1559
          printk0(ideif,"ERROR: soft reset in progress..");
1560
          idereq[req].resetonerror=2;
1561
          ide[ideif].errors++;
1562
          /* remove request (blocking new ones) and wake up blocked thread */
1563
          reqpending=remove_idereq_blocking(ideif);    
1564
          __b_sem_signal(&idereq[req].wait);
1565
          break;
1566
        }
1567
 
1568
        /* remove request and wake up waiting thread */
1569
        reqpending=remove_idereq(ideif);       
1570
        __b_sem_signal(&idereq[req].wait);
1571
 
1572
        if (reqpending) printk0(ideif,"redoing a new request");
1573
        /* if no more request... go out of the loop! */
1574
        if (!reqpending) break;
1575
      } else
1576
        /* if request does not fail... */
1577
        /* go out of the loop */
1578
        printk0(ideif,"new request in progress");
1579
        break;
1580
    }
1581
}