source: rtems/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c @ 39d08d55

4.104.114.9
Last change on this file since 39d08d55 was 39d08d55, checked in by Ralf Corsepius <ralf.corsepius@…>, on Sep 6, 2008 at 5:36:55 PM

Convert to "bool".

  • Property mode set to 100644
File size: 21.5 KB
Line 
1/*===============================================================*\
2| Project: RTEMS generic MPC5200 BSP                              |
3+-----------------------------------------------------------------+
4| Partially based on the code references which are named below.   |
5| Adaptions, modifications, enhancements and any recent parts of  |
6| the code are:                                                   |
7|                    Copyright (c) 2005                           |
8|                    Embedded Brains GmbH                         |
9|                    Obere Lagerstr. 30                           |
10|                    D-82178 Puchheim                             |
11|                    Germany                                      |
12|                    rtems@embedded-brains.de                     |
13+-----------------------------------------------------------------+
14| The license and distribution terms for this file may be         |
15| found in the file LICENSE in this distribution or at            |
16|                                                                 |
17| http://www.rtems.com/license/LICENSE.                           |
18|                                                                 |
19+-----------------------------------------------------------------+
20| this file contains the PCMCIA IDE access functions              |
21\*===============================================================*/
22/***********************************************************************/
23/*                                                                     */
24/*   Module:       pcmcia_ide.c                                        */
25/*   Date:         07/17/2003                                          */
26/*   Purpose:      RTEMS MPC5x00 PCMCIA IDE harddisk driver            */
27/*                                                                     */
28/*---------------------------------------------------------------------*/
29/*                                                                     */
30/*   Description:                                                      */
31/*                                                                     */
32/*---------------------------------------------------------------------*/
33/*                                                                     */
34/*   Code                                                              */
35/*   References:   RTEMS MBX8xx PCMCIA IDE harddisc driver             */
36/*   Module:       pcmcia_ide.c                                        */
37/*   Project:      RTEMS 4.6.0pre1 / Mbx8xx BSP                        */
38/*   Version                                                           */
39/*   Date:         01/14/2003                                          */
40/*                                                                     */
41/*   Author(s) / Copyright(s):                                         */
42/*                                                                     */
43/*                    Copyright (c) 2003 IMD                           */
44/*      Ingenieurbuero fuer Microcomputertechnik Th. Doerfler          */
45/*               <Thomas.Doerfler@imd-systems.de>                      */
46/*                       all rights reserved                           */
47/*                                                                     */
48/*  this file contains the BSP layer for PCMCIA IDE access below the   */
49/*  libchip IDE harddisc driver based on a board specific driver from  */
50/*  Eugeny S. Mints, Oktet                                             */
51/*                                                                     */
52/*  The license and distribution terms for this file may be            */
53/*  found in the file LICENSE in this distribution or at               */
54/*  http://www.rtems.com/license/LICENSE.                         */
55/*                                                                     */
56/*---------------------------------------------------------------------*/
57/*                                                                     */
58/*   Partially based on the code references which are named above.     */
59/*   Adaptions, modifications, enhancements and any recent parts of    */
60/*   the code are under the right of                                   */
61/*                                                                     */
62/*         IPR Engineering, Dachauer Straße 38, D-80335 MÃŒnchen        */
63/*                        Copyright(C) 2003                            */
64/*                                                                     */
65/*---------------------------------------------------------------------*/
66/*                                                                     */
67/*   IPR Engineering makes no representation or warranties with        */
68/*   respect to the performance of this computer program, and          */
69/*   specifically disclaims any responsibility for any damages,        */
70/*   special or consequential, connected with the use of this program. */
71/*                                                                     */
72/*---------------------------------------------------------------------*/
73/*                                                                     */
74/*   Version history:  1.0                                             */
75/*                                                                     */
76/***********************************************************************/
77
78#include <rtems.h>
79#include <rtems/error.h>
80#include <bsp.h>
81#include <bsp/irq.h>
82#include "../include/mpc5200.h"
83#include "./pcmcia_ide.h"
84
85#include <libchip/ide_ctrl.h>
86#include <libchip/ide_ctrl_cfg.h>
87#include <libchip/ide_ctrl_io.h>
88#include <string.h>
89
90#ifndef MIN
91#define MIN(a,b) (((a)<(b))?(a):(b))
92#endif
93#define IDE_DMA_TEST            FALSE
94
95#ifdef BRS5L
96#define IDE_USE_INT             TRUE
97#define IDE_READ_USE_DMA        TRUE
98#define IDE_USE_READ_PIO_OPT    FALSE
99#define IDE_WRITE_USE_DMA       TRUE
100#define IDE_USE_WRITE_PIO_OPT   TRUE
101/* #define IDE_USE_DMA (IDE_READ_USE_DMA||IDE_WRITE_USE_DMA) */
102#define IDE_USE_DMA             TRUE
103#else
104#define IDE_USE_INT             TRUE
105#define IDE_READ_USE_DMA        FALSE
106#define IDE_USE_READ_PIO_OPT    FALSE
107#define IDE_WRITE_USE_DMA       FALSE
108#define IDE_USE_WRITE_PIO_OPT   FALSE
109/* #define IDE_USE_DMA (IDE_READ_USE_DMA||IDE_WRITE_USE_DMA) */
110#define IDE_USE_DMA             FALSE
111#endif
112
113#define IDE_USE_STATISTICS      TRUE
114
115#if IDE_USE_DMA
116#define PCMCIA_IDE_DMA_WR_BD_CNT 2
117#define PCMCIA_IDE_DMA_RD_BD_CNT 2
118#define PCMCIA_IDE_INTERRUPT_EVENT RTEMS_EVENT_2
119/* Task number assignment */
120#include "../bestcomm/bestcomm_glue.h"
121#include "../bestcomm/bestcomm_api.h"
122#include "../bestcomm/task_api/bestcomm_cntrl.h"
123#include "../bestcomm/task_api/tasksetup_bdtable.h"
124
125#define IDE_RECV_TASK_NO            TASK_GEN_DP_BD_0
126#define TASK_GEN_DP_BD_1            TASK_GEN_DP_BD_1
127static TaskId pcmcia_ide_rxTaskId;      /* SDMA RX task ID */
128static TaskId pcmcia_ide_txTaskId;      /* SDMA TX task ID */
129#define PCMCIA_IDE_RD_SECTOR_SIZE 512   /* FIXME: make this better... */
130#define PCMCIA_IDE_WR_SECTOR_SIZE 512   /* FIXME: make this better... */
131
132bool mpc5200_dma_task_started[2] = {false,false};
133#endif /* IDE_USE_DMA */
134
135#if IDE_USE_STATISTICS
136uint32_t mpc5200_pcmciaide_write_block_call_cnt  = 0;
137uint32_t mpc5200_pcmciaide_write_block_block_cnt = 0;
138uint32_t mpc5200_pcmciaide_read_block_call_cnt   = 0;
139uint32_t mpc5200_pcmciaide_read_block_block_cnt  = 0;
140#endif
141
142extern volatile uint32_t * mpc5200_ata_drive_regs[];
143extern uint32_t ata_pio_timings[2][6];
144
145void mpc5200_pcmciaide_dma_blockop(
146  bool, int, uint16_t, rtems_blkdev_sg_buffer *, uint32_t *, uint32_t *);
147/*
148 * support functions for PCMCIA IDE IF
149 */
150bool mpc5200_pcmciaide_probe(int minor)
151  {
152  bool ide_card_plugged = false; /* assume: we don't have a card plugged in */
153  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT2]);
154
155  /* enable card detection on GPT2 */
156  gpt->emsel = (GPT_EMSEL_GPIO_IN | GPT_EMSEL_TIMER_MS_GPIO);
157
158#if defined (BRS5L)
159  /* Check for card detection (-CD0) */
160  if((gpt->status) & GPT_STATUS_PIN)
161    ide_card_plugged = false;
162  else
163#endif
164    ide_card_plugged = true;
165
166  return ide_card_plugged;
167
168  }
169
170
171rtems_status_code mpc5200_pcmciaide_config_io_speed(int minor, uint16_t modes_avail)
172  {
173  uint8_t pio_t0, pio_t2_8, pio_t2_16, pio_t4, pio_t1, pio_ta;
174
175  if((modes_avail & ATA_MODES_PIO4) != 0)
176    {
177
178    pio_t0    = ata_pio_timings[PIO_4][T0];
179    pio_t2_8  = ata_pio_timings[PIO_4][T2_8];
180    pio_t2_16 = ata_pio_timings[PIO_4][T2_16];
181    pio_t4    = ata_pio_timings[PIO_4][T4];
182    pio_t1    = ata_pio_timings[PIO_4][T1];
183    pio_ta    = ata_pio_timings[PIO_4][TA];
184
185    }
186  else
187    {
188
189    pio_t0    = ata_pio_timings[PIO_3][T0];
190    pio_t2_8  = ata_pio_timings[PIO_3][T2_8];
191    pio_t2_16 = ata_pio_timings[PIO_3][T2_16];
192    pio_t4    = ata_pio_timings[PIO_3][T4];
193    pio_t1    = ata_pio_timings[PIO_3][T1];
194    pio_ta    = ata_pio_timings[PIO_3][TA];
195
196    }
197
198  /* set timings according according to selected ATA mode */
199  mpc5200.ata_pio1 = ATA_PIO_TIMING_1(pio_t0, pio_t2_8, pio_t2_16);
200  mpc5200.ata_pio2 = ATA_PIO_TIMING_2(pio_t4, pio_t1, pio_ta);
201
202  return RTEMS_SUCCESSFUL;
203
204  }
205
206
207
208void mpc5200_pcmciaide_read_reg(int minor, int reg, uint16_t *value)
209  {
210  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[reg];
211
212  if(reg == IDE_REGISTER_DATA_WORD)
213    *value = *(volatile uint16_t *)(ata_reg);
214  else
215    *value = *(volatile uint8_t  *)(ata_reg);
216  }
217
218
219void mpc5200_pcmciaide_write_reg(int minor, int reg, uint16_t value)
220  {
221  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[reg];
222
223  if(reg == IDE_REGISTER_DATA_WORD)
224    *(volatile uint16_t *)(ata_reg) = value;
225  else
226    *(volatile uint8_t  *)(ata_reg) = value;
227  }
228
229#if IDE_USE_DMA
230
231
232uint32_t pcmcia_ide_rxInterrupts;
233uint32_t pcmcia_ide_txInterrupts;
234volatile rtems_id pcmcia_ide_hdl_task = 0;
235/*
236 * MPC5200 BestComm interrupt handlers
237 */
238static void pcmcia_ide_recv_dmairq_hdl(rtems_irq_hdl_param unused)
239{
240  SDMA_CLEAR_IEVENT(&mpc5200.IntPend,TASK_GEN_DP_BD_0);
241
242/*Disable receive ints*/
243  bestcomm_glue_irq_disable(TASK_GEN_DP_BD_0);
244
245  pcmcia_ide_rxInterrupts++;            /* Rx int has occurred */
246     
247  if (pcmcia_ide_hdl_task != 0) {
248    rtems_event_send(pcmcia_ide_hdl_task,PCMCIA_IDE_INTERRUPT_EVENT);
249  }
250}
251
252static void pcmcia_ide_xmit_dmairq_hdl(rtems_irq_hdl_param unused)
253{
254
255  SDMA_CLEAR_IEVENT(&mpc5200.IntPend,TASK_GEN_DP_BD_1);
256
257  /*Disable transmit ints*/
258  bestcomm_glue_irq_disable(TASK_GEN_DP_BD_1);
259
260  pcmcia_ide_txInterrupts++;            /* Tx int has occurred */
261     
262  if (pcmcia_ide_hdl_task != 0) {
263    rtems_event_send(pcmcia_ide_hdl_task,PCMCIA_IDE_INTERRUPT_EVENT);
264  }
265}
266
267
268void mpc5200_pcmciaide_dma_init(int minor)
269{
270  TaskSetupParamSet_t   rxParam;        /* RX task setup parameters     */
271  TaskSetupParamSet_t   txParam;        /* TX task setup parameters     */
272  /*
273   * Init Bestcomm system
274   */
275  bestcomm_glue_init();
276  /*
277   * Setup the SDMA RX task.
278   */
279  rxParam.NumBD        = PCMCIA_IDE_DMA_RD_BD_CNT;
280  rxParam.Size.MaxBuf  = PCMCIA_IDE_RD_SECTOR_SIZE;
281  rxParam.Initiator    = INITIATOR_ALWAYS;
282  rxParam.StartAddrSrc = 
283    (uint32)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
284  rxParam.IncrSrc      = 0;
285  rxParam.SzSrc        = sizeof(uint16_t);
286  rxParam.StartAddrDst = (uint32)NULL;
287  rxParam.IncrDst      = sizeof(uint16_t);
288  rxParam.SzDst        = sizeof(uint16_t);  /* XXX: set this to 32 bit? */
289
290  pcmcia_ide_rxTaskId  = TaskSetup(TASK_GEN_DP_BD_0,&rxParam );
291
292  /*
293   * Setup the TX task.
294   */
295  txParam.NumBD        = PCMCIA_IDE_DMA_WR_BD_CNT;
296  txParam.Size.MaxBuf  = PCMCIA_IDE_WR_SECTOR_SIZE;
297  txParam.Initiator    = INITIATOR_ALWAYS;
298  txParam.StartAddrSrc = (uint32)NULL;
299  txParam.IncrSrc      = sizeof(uint16_t);
300  txParam.SzSrc        = sizeof(uint16_t); /* do not set this to 32 bit! */
301  txParam.StartAddrDst =
302    (uint32)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
303  txParam.IncrDst      = 0;
304  txParam.SzDst        = sizeof(uint16_t);
305 
306  pcmcia_ide_txTaskId  = TaskSetup( TASK_GEN_DP_BD_1, &txParam );
307  /*
308   * FIXME: Init BD rings
309   */
310  /*
311   * Enable the SmartDMA transmit/receive task.
312   * do not enable interrupts to CPU
313   */
314  /*
315   * connect interrupt handlers
316   */ 
317  bestcomm_glue_irq_install(TASK_GEN_DP_BD_1,pcmcia_ide_xmit_dmairq_hdl,NULL);
318  bestcomm_glue_irq_install(TASK_GEN_DP_BD_0,pcmcia_ide_recv_dmairq_hdl,NULL);
319}
320
321void mpc5200_pcmciaide_dma_blockop(bool is_write,
322                                   int minor, 
323                                   uint16_t block_size, 
324                                   rtems_blkdev_sg_buffer *bufs,
325                                   uint32_t *cbuf, 
326                                   uint32_t *pos)
327
328{
329  /*
330   * Nameing:
331   * - a block is one unit of data on disk (multiple sectors)
332   * - a buffer is a contignuous chunk of data in memory
333   * a block on disk may be filled with data from several buffers
334   */
335  uint32_t buf_idx,bufs_from_dma, bufs_to_dma,bufs_total;
336  uint32_t bds_free;
337  uint32_t llength;
338  rtems_status_code rc = RTEMS_SUCCESSFUL;
339  rtems_event_set events;
340  BDIdx nxt_bd_idx;
341  bool use_irq = (_System_state_Current == SYSTEM_STATE_UP);
342  /*
343   * determine number of blocks
344   */
345  llength = 0;
346  buf_idx = 0;
347  bufs += *cbuf; /* *cbuf is the index of the next buffer to send in this transaction */
348  while (llength < block_size) {
349    llength += bufs[buf_idx++].length;
350  }
351  bufs_from_dma = 0;
352  bufs_to_dma   = 0;
353  bufs_total    = buf_idx;
354  /*
355   * here all BDs should be unused
356   */
357  bds_free = is_write ? PCMCIA_IDE_DMA_WR_BD_CNT : PCMCIA_IDE_DMA_RD_BD_CNT;
358  /*
359   * repeat, until all bufs are transferred
360   */
361  while ((rc == RTEMS_SUCCESSFUL) &&
362         (bufs_from_dma < bufs_total)) {
363   
364    while ((rc == RTEMS_SUCCESSFUL) && 
365           (bufs_to_dma < bufs_total) && 
366           (bds_free > 0)) {
367      /*
368       * fill in BD, set interrupt if needed
369       */
370    SDMA_CLEAR_IEVENT(&mpc5200.IntPend,(is_write
371                                          ? TASK_GEN_DP_BD_1
372                                          : TASK_GEN_DP_BD_0)); 
373      if (is_write) {
374        TaskBDAssign(pcmcia_ide_txTaskId ,
375                     (void *)bufs[bufs_to_dma].buffer,
376                     (void *)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD],
377                     bufs[bufs_to_dma].length,
378                     0/* flags */);
379#if IDE_USE_STATISTICS
380        mpc5200_pcmciaide_write_block_block_cnt++;
381#endif
382      }
383      else {
384        TaskBDAssign(pcmcia_ide_rxTaskId ,
385                     (void *)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD],
386                     (void *)bufs[bufs_to_dma].buffer,
387                     bufs[bufs_to_dma].length,
388                     0/* flags */);
389#if IDE_USE_STATISTICS
390        mpc5200_pcmciaide_read_block_block_cnt++;
391#endif
392      }
393      bufs_to_dma ++;
394      bds_free    --;
395    }
396    if (is_write) {
397      TaskStart( pcmcia_ide_txTaskId, TASK_AUTOSTART_DISABLE, 
398                 pcmcia_ide_txTaskId, TASK_INTERRUPT_DISABLE );
399    }
400    else {
401      TaskStart( pcmcia_ide_rxTaskId, TASK_AUTOSTART_DISABLE,
402                 pcmcia_ide_rxTaskId, TASK_INTERRUPT_DISABLE );
403    }
404    if (use_irq) {
405
406      /*
407       * enable interrupts, wait for interrupt event
408       */
409      rtems_task_ident(RTEMS_SELF,0,(rtems_id *)&pcmcia_ide_hdl_task);
410      bestcomm_glue_irq_enable((is_write
411                                ? TASK_GEN_DP_BD_1 
412                                : TASK_GEN_DP_BD_0));
413
414      rtems_event_receive(PCMCIA_IDE_INTERRUPT_EVENT, 
415                          RTEMS_WAIT | RTEMS_EVENT_ANY, 
416                          RTEMS_NO_TIMEOUT, &events);
417
418      pcmcia_ide_hdl_task = 0;
419    }
420    else {
421      /*
422       * HACK: just wait some time...
423       */
424      /*
425       * FIXME: poll, until SDMA is finished
426       */
427      volatile int32_t i;
428      for (i = 0;i < 10000;i++) {};
429    }
430
431    do {
432          nxt_bd_idx = TaskBDRelease(is_write
433                                                     ? pcmcia_ide_txTaskId 
434                                                     : pcmcia_ide_rxTaskId);
435      if ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) &&
436          (nxt_bd_idx != TASK_ERR_BD_BUSY)) {
437        (*cbuf)++;     
438        (*pos) += bufs[bufs_from_dma].length;     
439        bufs_from_dma++;
440          }
441    } while ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) &&
442             (nxt_bd_idx != TASK_ERR_BD_BUSY)       &&
443                 (bufs_from_dma < bufs_to_dma));
444  }
445}
446#endif /* IDE_USE_DMA */
447
448
449void mpc5200_pcmciaide_read_block(int minor, uint16_t block_size, rtems_blkdev_sg_buffer *bufs,
450                                  uint32_t *cbuf, uint32_t *pos)
451{
452
453  volatile uint32_t *ata_reg=mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
454  uint16_t  cnt = 0;
455  uint16_t *lbuf = (uint16_t*)((uint8_t*)(bufs[(*cbuf)].buffer)+(*pos));
456  uint32_t  llength = bufs[(*cbuf)].length;
457  bool      use_dma;
458 
459#if IDE_USE_STATISTICS
460      mpc5200_pcmciaide_read_block_call_cnt++;
461#endif
462#if IDE_READ_USE_DMA
463  /*
464   * FIXME: walk through buffer list. If any buffer has other size than default,
465   * then do not use DMA
466   * Is this needed?
467   */
468  use_dma = true;
469  /* use_dma = false; */
470#else
471  use_dma = false;
472#endif
473  if (use_dma) {
474    /*
475     * FIXME: wait for DRQ ready
476     * check, that once DRQ is ready, we really can send ALL data for this
477     * type of transfer mode
478     */
479    while ((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)
480                                                 (mpc5200.ata_dctr_dasr)) & 
481            IDE_REGISTER_STATUS_DRQ) == 0);
482    /*
483     * translate (part of) buffer list into DMA BDs
484     * only last (available) DMA BD sends interrupt
485     * DMA BDs may get ready as soon as possible
486     */
487    mpc5200_pcmciaide_dma_blockop(FALSE, /* read operation */
488                                  minor,
489                                  block_size,bufs,cbuf,pos);
490  }
491  else {
492#if IDE_USE_READ_PIO_OPT
493    while(cnt < block_size) {
494
495      *lbuf++ = GET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(*(volatile uint32_t *)(ata_reg)); /* only 16 bit data port */
496      cnt += 2;
497      (*pos) += 2;
498     
499      if((*pos) == llength) {
500         
501          (*pos) = 0;
502          (*cbuf)++;
503          lbuf = bufs[(*cbuf)].buffer;
504          llength = bufs[(*cbuf)].length;
505         
506      }
507    }
508#else
509
510    while((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)(mpc5200.ata_dctr_dasr)) & IDE_REGISTER_STATUS_DRQ) && (cnt < block_size)) {
511
512      *lbuf++ = *(volatile uint16_t *)(ata_reg); /* only 16 bit data port */
513      cnt += 2;
514      (*pos) += 2;
515     
516      if((*pos) == llength) {
517        (*pos) = 0;
518        (*cbuf)++;
519        lbuf = bufs[(*cbuf)].buffer;
520        llength = bufs[(*cbuf)].length; 
521      }
522    }
523#endif
524    while (cnt < block_size) {
525      *lbuf++ = 0; /* fill buffer with dummy data */
526      cnt += 2;
527      (*pos) += 2;
528     
529      if((*pos) == llength) {
530        (*pos) = 0;
531        (*cbuf)++;
532        lbuf = bufs[(*cbuf)].buffer;
533        llength = bufs[(*cbuf)].length; 
534      }
535    }
536  }
537}
538
539void mpc5200_pcmciaide_write_block(int minor, uint16_t block_size,
540                                   rtems_blkdev_sg_buffer *bufs, uint32_t *cbuf,
541                                   uint32_t *pos)
542
543{
544
545
546  volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD];
547  uint16_t  cnt = 0;
548  uint16_t *lbuf = (uint16_t *)((uint8_t *)(bufs[(*cbuf)].buffer) + (*pos));
549  uint32_t  llength = bufs[(*cbuf)].length;
550  bool use_dma;
551
552#if IDE_USE_STATISTICS
553  mpc5200_pcmciaide_write_block_call_cnt++;
554#endif
555#if IDE_WRITE_USE_DMA
556  /*
557   * FIXME: walk through buffer list. If any buffer has other size than default,
558   * then do not use DMA
559   * Is this needed?
560   */
561  use_dma = true;
562#else
563  use_dma = false;
564#endif
565
566  if (use_dma) {
567    /*
568     * wait for DRQ ready
569     * FIXME: check, that once DRQ is ready, we really can send ALL data for this
570     * type of transfer mode
571     */
572    while ((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)
573                                                 (mpc5200.ata_dctr_dasr)) & 
574            IDE_REGISTER_STATUS_DRQ) == 0);
575    /*
576     * translate (part of) buffer list into DMA BDs
577     * only last (available) DMA BD sends interrupt
578     * DMA BDs may get ready as soon as possible
579     */
580    mpc5200_pcmciaide_dma_blockop(true, /* write opeartion */
581                                  minor,
582                                  block_size,bufs,cbuf,pos);
583  }
584  else {
585#if IDE_USE_WRITE_PIO_OPT
586    while(cnt < block_size) {
587      int32_t loop_cnt,loop_max;
588
589#if IDE_USE_STATISTICS
590      mpc5200_pcmciaide_write_block_block_cnt++;
591#endif
592
593      loop_max = llength - (*pos) ;
594      if (loop_max > (block_size - cnt)) {
595        loop_max = (block_size - cnt);
596      }
597      for (loop_cnt = loop_max/2;loop_cnt > 0;loop_cnt--) {
598        *(volatile uint32_t *)(ata_reg) = 
599          SET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(*lbuf++); /* only 16 bit data port */
600      }
601      cnt += loop_max;
602      (*pos) += loop_max;
603     
604      if((*pos) == llength) {
605       
606        (*pos) = 0;
607        (*cbuf)++;
608        lbuf = bufs[(*cbuf)].buffer;
609        llength = bufs[(*cbuf)].length; 
610      }
611    }
612#else
613    while((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)(mpc5200.ata_dctr_dasr)) 
614           & IDE_REGISTER_STATUS_DRQ) 
615          && (cnt < block_size)) {
616      *(volatile uint16_t *)(ata_reg) = *lbuf++; /* only 16 bit data port */
617      cnt += 2;
618      (*pos) += 2;
619     
620      if((*pos) == llength) {
621        (*pos) = 0;
622        (*cbuf)++;
623        lbuf = bufs[(*cbuf)].buffer;
624        llength = bufs[(*cbuf)].length;
625      }
626    }
627#endif
628  }
629}
630
631int mpc5200_pcmciaide_control(int  minor, uint32_t cmd, void * arg)
632  {
633  return RTEMS_SUCCESSFUL;
634  }
635
636void mpc5200_pcmciaide_initialize(int minor)
637  {
638#if defined (BRS5L)
639  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT7]);
640
641  /* invert ATA reset on GPT7 */
642  gpt->emsel = (GPT_EMSEL_GPIO_OUT_HIGH | GPT_EMSEL_TIMER_MS_GPIO);
643#endif
644  /* reset ata host contr. and FIFO */
645  mpc5200.ata_hcfg |= (ATA_HCFG_SMR | ATA_HCFG_FR);
646  mpc5200.ata_hcfg &= ~(ATA_HCFG_SMR | ATA_HCFG_FR);
647
648  /* for the first access set lowest performance transfer mode to PIO3 */
649  mpc5200_pcmciaide_config_io_speed(minor, ATA_MODES_PIO3);
650
651  /* enable PIO operations (PIO 3/4) */
652  mpc5200.ata_hcfg |= ATA_HCFG_IORDY;
653
654#ifdef IDE_USE_INT
655  mpc5200.ata_hcfg |= ATA_HCFG_IE ;
656#endif
657
658#if IDE_USE_DMA
659  mpc5200_pcmciaide_dma_init(minor);
660#endif 
661  }
662
663
664/*
665 * The following table configures the functions used for IDE drivers
666 * in this BSP.
667 */
668ide_ctrl_fns_t mpc5200_pcmciaide_ctrl_fns =
669  {
670  mpc5200_pcmciaide_probe,
671  mpc5200_pcmciaide_initialize,
672  mpc5200_pcmciaide_control,
673  mpc5200_pcmciaide_read_reg,
674  mpc5200_pcmciaide_write_reg,
675  mpc5200_pcmciaide_read_block,
676  mpc5200_pcmciaide_write_block,
677  mpc5200_pcmciaide_config_io_speed
678  };
679
Note: See TracBrowser for help on using the repository browser.