> + * Called to enable the use of DMA based on kernel command line. > + */ > +void octeon_cf_enable_dma(void) > +{ > + use_cf_dma = 1; > +} Why not use the standard module parameter interface ? > + /* > + * PIO modes 0-4 all allow the device to deassert IORDY to slow down > + * the host. > + */ See ata_timing_compute() which also knows about master/slave timing, PIO5/6 rules and timing adjustments as well as doing bus clock quantisations and lengthenings for you. > + use_iordy = 1; This depends on the device as well and gets quite complicated. We have ata_pio_need_iordy() to do the work for you. > + t1 = (t1 * clocks_us) / 1000 / 2; > + if (t1) > + t1--; Even if you wanted to do it this way you could just use arrays and lookup tables as many other drivers do - ie pio = dev->pio_mode - XFER_PIO_0; t1 = data[pio]; > + mio_boot_reg_tim.s.wr_hld = t4; What guarantees the computation results always fit the bit fields. This is one reason the kerne strongly favours masks - it is a lot easier to check such things. > +static void octeon_cf_set_dmamode(struct ata_port *ap, struct ata_device *dev) > +{ > + case XFER_MW_DMA_0: > + dma_ackh = 20; /* Tj */ > + To = 480; > + Td = 215; > + Tkr = 50; > + break; Same comments apply as to PIO > + /* > + * Odd lengths are not supported. We should always be a > + * multiple of 512. > + */ > + BUG_ON(buflen & 1); If you get a request for an odd length you should write an extra word containing the last byte and one other. See how the standard methods handle this. > + if (ocd->is16bit) { Or you could have two methods and two transfer routines defined > + while (words--) { > + *(uint16_t *)buffer = ioread16(data_addr); > + buffer += sizeof(uint16_t); By definition tht is 2. Do you have an ioread16_rep ? > + > +/** > + * Get ready for a dma operation. We do nothing, as all DMA > + * operations are taken care of in octeon_cf_bmdma_start. > + */ > +void octeon_cf_qc_prep(struct ata_queued_cmd *qc) > +{ > +} ata_noop_qc_prep > +/** > + * Check if any queued commands have more DMAs, if so start the next > + * transfer, else do standard handling. > + */ > +irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance) A lot of these functions could be static it seems > > +static void octeon_cf_delayed_irq(unsigned long data) > +{ What stops the following occuring ATA irq BUSY still set Queue tasklet Other irq on same line ATA busy clear Handle command Tasklet runs but command was sorted out (or a reset of the ata controller in the gap) > + base = cs0 + ocd->base_region_bias; > + if (!ocd->is16bit) { ata_std_ > + ap->ioaddr.cmd_addr = base + ATA_REG_CMD; ata_sff_std_ports ? (at least for the 8bit case) Alan -- "Alan, I'm getting a bit worried about you." -- Linus Torvalds