Commit 9135f190 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (95 commits)
  ide-tape: remove idetape_config_t typedef
  ide-tape: remove mtio.h related comments
  ide-tape: make function name more accurate
  ide-tape: remove unused sense packet commands.
  ide-tape: use generic byteorder macros
  ide-tape: remove EXPERIMENTAL driver status
  ide-tape: use generic scsi commands
  ide-tape: remove struct idetape_block_size_page_t
  ide-tape: remove structs os_partition_t, os_dat_entry_t, os_dat_t
  ide-tape: remove struct idetape_parameter_block_descriptor_t
  ide-tape: remove struct idetape_medium_partition_page_t
  ide-tape: remove struct idetape_data_compression_page_t
  ide-tape: remove struct idetape_inquiry_result_t
  ide-tape: remove struct idetape_capabilities_page_t
  ide-tape: remove IDETAPE_DEBUG_BUGS
  ide-tape: remove IDETAPE_DEBUG_INFO
  ide-tape: dump gcw fields on error in idetape_identify_device()
  ide-tape: remove struct idetape_mode_parameter_header_t
  ide-tape: remove struct idetape_request_sense_result_t
  ide-tape: remove dead code
  ...
parents 124d3b70 d59823fa
/*
* Ver 0.1 Nov 1 95 Pre-working code :-)
* Ver 0.2 Nov 23 95 A short backup (few megabytes) and restore procedure
* was successful ! (Using tar cvf ... on the block
* device interface).
* A longer backup resulted in major swapping, bad
* overall Linux performance and eventually failed as
* we received non serial read-ahead requests from the
* buffer cache.
* Ver 0.3 Nov 28 95 Long backups are now possible, thanks to the
* character device interface. Linux's responsiveness
* and performance doesn't seem to be much affected
* from the background backup procedure.
* Some general mtio.h magnetic tape operations are
* now supported by our character device. As a result,
* popular tape utilities are starting to work with
* ide tapes :-)
* The following configurations were tested:
* 1. An IDE ATAPI TAPE shares the same interface
* and irq with an IDE ATAPI CDROM.
* 2. An IDE ATAPI TAPE shares the same interface
* and irq with a normal IDE disk.
* Both configurations seemed to work just fine !
* However, to be on the safe side, it is meanwhile
* recommended to give the IDE TAPE its own interface
* and irq.
* The one thing which needs to be done here is to
* add a "request postpone" feature to ide.c,
* so that we won't have to wait for the tape to finish
* performing a long media access (DSC) request (such
* as a rewind) before we can access the other device
* on the same interface. This effect doesn't disturb
* normal operation most of the time because read/write
* requests are relatively fast, and once we are
* performing one tape r/w request, a lot of requests
* from the other device can be queued and ide.c will
* service all of them after this single tape request.
* Ver 1.0 Dec 11 95 Integrated into Linux 1.3.46 development tree.
* On each read / write request, we now ask the drive
* if we can transfer a constant number of bytes
* (a parameter of the drive) only to its buffers,
* without causing actual media access. If we can't,
* we just wait until we can by polling the DSC bit.
* This ensures that while we are not transferring
* more bytes than the constant referred to above, the
* interrupt latency will not become too high and
* we won't cause an interrupt timeout, as happened
* occasionally in the previous version.
* While polling for DSC, the current request is
* postponed and ide.c is free to handle requests from
* the other device. This is handled transparently to
* ide.c. The hwgroup locking method which was used
* in the previous version was removed.
* Use of new general features which are provided by
* ide.c for use with atapi devices.
* (Programming done by Mark Lord)
* Few potential bug fixes (Again, suggested by Mark)
* Single character device data transfers are now
* not limited in size, as they were before.
* We are asking the tape about its recommended
* transfer unit and send a larger data transfer
* as several transfers of the above size.
* For best results, use an integral number of this
* basic unit (which is shown during driver
* initialization). I will soon add an ioctl to get
* this important parameter.
* Our data transfer buffer is allocated on startup,
* rather than before each data transfer. This should
* ensure that we will indeed have a data buffer.
* Ver 1.1 Dec 14 95 Fixed random problems which occurred when the tape
* shared an interface with another device.
* (poll_for_dsc was a complete mess).
* Removed some old (non-active) code which had
* to do with supporting buffer cache originated
* requests.
* The block device interface can now be opened, so
* that general ide driver features like the unmask
* interrupts flag can be selected with an ioctl.
* This is the only use of the block device interface.
* New fast pipelined operation mode (currently only on
* writes). When using the pipelined mode, the
* throughput can potentially reach the maximum
* tape supported throughput, regardless of the
* user backup program. On my tape drive, it sometimes
* boosted performance by a factor of 2. Pipelined
* mode is enabled by default, but since it has a few
* downfalls as well, you may want to disable it.
* A short explanation of the pipelined operation mode
* is available below.
* Ver 1.2 Jan 1 96 Eliminated pipelined mode race condition.
* Added pipeline read mode. As a result, restores
* are now as fast as backups.
* Optimized shared interface behavior. The new behavior
* typically results in better IDE bus efficiency and
* higher tape throughput.
* Pre-calculation of the expected read/write request
* service time, based on the tape's parameters. In
* the pipelined operation mode, this allows us to
* adjust our polling frequency to a much lower value,
* and thus to dramatically reduce our load on Linux,
* without any decrease in performance.
* Implemented additional mtio.h operations.
* The recommended user block size is returned by
* the MTIOCGET ioctl.
* Additional minor changes.
* Ver 1.3 Feb 9 96 Fixed pipelined read mode bug which prevented the
* use of some block sizes during a restore procedure.
* The character device interface will now present a
* continuous view of the media - any mix of block sizes
* during a backup/restore procedure is supported. The
* driver will buffer the requests internally and
* convert them to the tape's recommended transfer
* unit, making performance almost independent of the
* chosen user block size.
* Some improvements in error recovery.
* By cooperating with ide-dma.c, bus mastering DMA can
* now sometimes be used with IDE tape drives as well.
* Bus mastering DMA has the potential to dramatically
* reduce the CPU's overhead when accessing the device,
* and can be enabled by using hdparm -d1 on the tape's
* block device interface. For more info, read the
* comments in ide-dma.c.
* Ver 1.4 Mar 13 96 Fixed serialize support.
* Ver 1.5 Apr 12 96 Fixed shared interface operation, broken in 1.3.85.
* Fixed pipelined read mode inefficiency.
* Fixed nasty null dereferencing bug.
* Ver 1.6 Aug 16 96 Fixed FPU usage in the driver.
* Fixed end of media bug.
* Ver 1.7 Sep 10 96 Minor changes for the CONNER CTT8000-A model.
* Ver 1.8 Sep 26 96 Attempt to find a better balance between good
* interactive response and high system throughput.
* Ver 1.9 Nov 5 96 Automatically cross encountered filemarks rather
* than requiring an explicit FSF command.
* Abort pending requests at end of media.
* MTTELL was sometimes returning incorrect results.
* Return the real block size in the MTIOCGET ioctl.
* Some error recovery bug fixes.
* Ver 1.10 Nov 5 96 Major reorganization.
* Reduced CPU overhead a bit by eliminating internal
* bounce buffers.
* Added module support.
* Added multiple tape drives support.
* Added partition support.
* Rewrote DSC handling.
* Some portability fixes.
* Removed ide-tape.h.
* Additional minor changes.
* Ver 1.11 Dec 2 96 Bug fix in previous DSC timeout handling.
* Use ide_stall_queue() for DSC overlap.
* Use the maximum speed rather than the current speed
* to compute the request service time.
* Ver 1.12 Dec 7 97 Fix random memory overwriting and/or last block data
* corruption, which could occur if the total number
* of bytes written to the tape was not an integral
* number of tape blocks.
* Add support for INTERRUPT DRQ devices.
* Ver 1.13 Jan 2 98 Add "speed == 0" work-around for HP COLORADO 5GB
* Ver 1.14 Dec 30 98 Partial fixes for the Sony/AIWA tape drives.
* Replace cli()/sti() with hwgroup spinlocks.
* Ver 1.15 Mar 25 99 Fix SMP race condition by replacing hwgroup
* spinlock with private per-tape spinlock.
* Ver 1.16 Sep 1 99 Add OnStream tape support.
* Abort read pipeline on EOD.
* Wait for the tape to become ready in case it returns
* "in the process of becoming ready" on open().
* Fix zero padding of the last written block in
* case the tape block size is larger than PAGE_SIZE.
* Decrease the default disconnection time to tn.
* Ver 1.16e Oct 3 99 Minor fixes.
* Ver 1.16e1 Oct 13 99 Patches by Arnold Niessen,
* niessen@iae.nl / arnold.niessen@philips.com
* GO-1) Undefined code in idetape_read_position
* according to Gadi's email
* AJN-1) Minor fix asc == 11 should be asc == 0x11
* in idetape_issue_packet_command (did effect
* debugging output only)
* AJN-2) Added more debugging output, and
* added ide-tape: where missing. I would also
* like to add tape->name where possible
* AJN-3) Added different debug_level's
* via /proc/ide/hdc/settings
* "debug_level" determines amount of debugging output;
* can be changed using /proc/ide/hdx/settings
* 0 : almost no debugging output
* 1 : 0+output errors only
* 2 : 1+output all sensekey/asc
* 3 : 2+follow all chrdev related procedures
* 4 : 3+follow all procedures
* 5 : 4+include pc_stack rq_stack info
* 6 : 5+USE_COUNT updates
* AJN-4) Fixed timeout for retension in idetape_queue_pc_tail
* from 5 to 10 minutes
* AJN-5) Changed maximum number of blocks to skip when
* reading tapes with multiple consecutive write
* errors from 100 to 1000 in idetape_get_logical_blk
* Proposed changes to code:
* 1) output "logical_blk_num" via /proc
* 2) output "current_operation" via /proc
* 3) Either solve or document the fact that `mt rewind' is
* required after reading from /dev/nhtx to be
* able to rmmod the idetape module;
* Also, sometimes an application finishes but the
* device remains `busy' for some time. Same cause ?
* Proposed changes to release-notes:
* 4) write a simple `quickstart' section in the
* release notes; I volunteer if you don't want to
* 5) include a pointer to video4linux in the doc
* to stimulate video applications
* 6) release notes lines 331 and 362: explain what happens
* if the application data rate is higher than 1100 KB/s;
* similar approach to lower-than-500 kB/s ?
* 7) 6.6 Comparison; wouldn't it be better to allow different
* strategies for read and write ?
* Wouldn't it be better to control the tape buffer
* contents instead of the bandwidth ?
* 8) line 536: replace will by would (if I understand
* this section correctly, a hypothetical and unwanted situation
* is being described)
* Ver 1.16f Dec 15 99 Change place of the secondary OnStream header frames.
* Ver 1.17 Nov 2000 / Jan 2001 Marcel Mol, marcel@mesa.nl
* - Add idetape_onstream_mode_sense_tape_parameter_page
* function to get tape capacity in frames: tape->capacity.
* - Add support for DI-50 drives( or any DI- drive).
* - 'workaround' for read error/blank block around block 3000.
* - Implement Early warning for end of media for Onstream.
* - Cosmetic code changes for readability.
* - Idetape_position_tape should not use SKIP bit during
* Onstream read recovery.
* - Add capacity, logical_blk_num and first/last_frame_position
* to /proc/ide/hd?/settings.
* - Module use count was gone in the Linux 2.4 driver.
* Ver 1.17a Apr 2001 Willem Riede osst@riede.org
* - Get drive's actual block size from mode sense block descriptor
* - Limit size of pipeline
* Ver 1.17b Oct 2002 Alan Stern <stern@rowland.harvard.edu>
* Changed IDETAPE_MIN_PIPELINE_STAGES to 1 and actually used
* it in the code!
* Actually removed aborted stages in idetape_abort_pipeline
* instead of just changing the command code.
* Made the transfer byte count for Request Sense equal to the
* actual length of the data transfer.
* Changed handling of partial data transfers: they do not
* cause DMA errors.
* Moved initiation of DMA transfers to the correct place.
* Removed reference to unallocated memory.
* Made __idetape_discard_read_pipeline return the number of
* sectors skipped, not the number of stages.
* Replaced errant kfree() calls with __idetape_kfree_stage().
* Fixed off-by-one error in testing the pipeline length.
* Fixed handling of filemarks in the read pipeline.
* Small code optimization for MTBSF and MTBSFM ioctls.
* Don't try to unlock the door during device close if is
* already unlocked!
* Cosmetic fixes to miscellaneous debugging output messages.
* Set the minimum /proc/ide/hd?/settings values for "pipeline",
* "pipeline_min", and "pipeline_max" to 1.
*/
/*
* IDE ATAPI streaming tape driver.
*
* This driver is a part of the Linux ide driver.
*
* The driver, in co-operation with ide.c, basically traverses the
* request-list for the block device interface. The character device
* interface, on the other hand, creates new requests, adds them
* to the request-list of the block device, and waits for their completion.
*
* Pipelined operation mode is now supported on both reads and writes.
*
* The block device major and minor numbers are determined from the
* tape's relative position in the ide interfaces, as explained in ide.c.
*
* The character device interface consists of the following devices:
*
* ht0 major 37, minor 0 first IDE tape, rewind on close.
* ht1 major 37, minor 1 second IDE tape, rewind on close.
* ...
* nht0 major 37, minor 128 first IDE tape, no rewind on close.
* nht1 major 37, minor 129 second IDE tape, no rewind on close.
* ...
*
* The general magnetic tape commands compatible interface, as defined by
* include/linux/mtio.h, is accessible through the character device.
*
* General ide driver configuration options, such as the interrupt-unmask
* flag, can be configured by issuing an ioctl to the block device interface,
* as any other ide device.
*
* Our own ide-tape ioctl's can be issued to either the block device or
* the character device interface.
*
* Maximal throughput with minimal bus load will usually be achieved in the
* following scenario:
*
* 1. ide-tape is operating in the pipelined operation mode.
* 2. No buffering is performed by the user backup program.
*
* Testing was done with a 2 GB CONNER CTMA 4000 IDE ATAPI Streaming Tape Drive.
*
* Here are some words from the first releases of hd.c, which are quoted
* in ide.c and apply here as well:
*
* | Special care is recommended. Have Fun!
*
*
* An overview of the pipelined operation mode.
*
* In the pipelined write mode, we will usually just add requests to our
* pipeline and return immediately, before we even start to service them. The
* user program will then have enough time to prepare the next request while
* we are still busy servicing previous requests. In the pipelined read mode,
* the situation is similar - we add read-ahead requests into the pipeline,
* before the user even requested them.
*
* The pipeline can be viewed as a "safety net" which will be activated when
* the system load is high and prevents the user backup program from keeping up
* with the current tape speed. At this point, the pipeline will get
* shorter and shorter but the tape will still be streaming at the same speed.
* Assuming we have enough pipeline stages, the system load will hopefully
* decrease before the pipeline is completely empty, and the backup program
* will be able to "catch up" and refill the pipeline again.
*
* When using the pipelined mode, it would be best to disable any type of
* buffering done by the user program, as ide-tape already provides all the
* benefits in the kernel, where it can be done in a more efficient way.
* As we will usually not block the user program on a request, the most
* efficient user code will then be a simple read-write-read-... cycle.
* Any additional logic will usually just slow down the backup process.
*
* Using the pipelined mode, I get a constant over 400 KBps throughput,
* which seems to be the maximum throughput supported by my tape.
*
* However, there are some downfalls:
*
* 1. We use memory (for data buffers) in proportional to the number
* of pipeline stages (each stage is about 26 KB with my tape).
* 2. In the pipelined write mode, we cheat and postpone error codes
* to the user task. In read mode, the actual tape position
* will be a bit further than the last requested block.
*
* Concerning (1):
*
* 1. We allocate stages dynamically only when we need them. When
* we don't need them, we don't consume additional memory. In
* case we can't allocate stages, we just manage without them
* (at the expense of decreased throughput) so when Linux is
* tight in memory, we will not pose additional difficulties.
*
* 2. The maximum number of stages (which is, in fact, the maximum
* amount of memory) which we allocate is limited by the compile
* time parameter IDETAPE_MAX_PIPELINE_STAGES.
*
* 3. The maximum number of stages is a controlled parameter - We
* don't start from the user defined maximum number of stages
* but from the lower IDETAPE_MIN_PIPELINE_STAGES (again, we
* will not even allocate this amount of stages if the user
* program can't handle the speed). We then implement a feedback
* loop which checks if the pipeline is empty, and if it is, we
* increase the maximum number of stages as necessary until we
* reach the optimum value which just manages to keep the tape
* busy with minimum allocated memory or until we reach
* IDETAPE_MAX_PIPELINE_STAGES.
*
* Concerning (2):
*
* In pipelined write mode, ide-tape can not return accurate error codes
* to the user program since we usually just add the request to the
* pipeline without waiting for it to be serviced. In case an error
* occurs, I will report it on the next user request.
*
* In the pipelined read mode, subsequent read requests or forward
* filemark spacing will perform correctly, as we preserve all blocks
* and filemarks which we encountered during our excess read-ahead.
*
* For accurate tape positioning and error reporting, disabling
* pipelined mode might be the best option.
*
* You can enable/disable/tune the pipelined operation mode by adjusting
* the compile time parameters below.
*
*
* Possible improvements.
*
* 1. Support for the ATAPI overlap protocol.
*
* In order to maximize bus throughput, we currently use the DSC
* overlap method which enables ide.c to service requests from the
* other device while the tape is busy executing a command. The
* DSC overlap method involves polling the tape's status register
* for the DSC bit, and servicing the other device while the tape
* isn't ready.
*
* In the current QIC development standard (December 1995),
* it is recommended that new tape drives will *in addition*
* implement the ATAPI overlap protocol, which is used for the
* same purpose - efficient use of the IDE bus, but is interrupt
* driven and thus has much less CPU overhead.
*
* ATAPI overlap is likely to be supported in most new ATAPI
* devices, including new ATAPI cdroms, and thus provides us
* a method by which we can achieve higher throughput when
* sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
*/
...@@ -216,8 +216,7 @@ config BLK_DEV_IDECD_VERBOSE_ERRORS ...@@ -216,8 +216,7 @@ config BLK_DEV_IDECD_VERBOSE_ERRORS
memory, though. memory, though.
config BLK_DEV_IDETAPE config BLK_DEV_IDETAPE
tristate "Include IDE/ATAPI TAPE support (EXPERIMENTAL)" tristate "Include IDE/ATAPI TAPE support"
depends on EXPERIMENTAL
help help
If you have an IDE tape drive using the ATAPI protocol, say Y. If you have an IDE tape drive using the ATAPI protocol, say Y.
ATAPI is a newer protocol used by IDE tape and CD-ROM drives, ATAPI is a newer protocol used by IDE tape and CD-ROM drives,
......
...@@ -28,8 +28,10 @@ static int __init ...@@ -28,8 +28,10 @@ static int __init
bastide_register(unsigned int base, unsigned int aux, int irq, bastide_register(unsigned int base, unsigned int aux, int irq,
ide_hwif_t **hwif) ide_hwif_t **hwif)
{ {
ide_hwif_t *hwif;
hw_regs_t hw; hw_regs_t hw;
int i; int i;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
memset(&hw, 0, sizeof(hw)); memset(&hw, 0, sizeof(hw));
...@@ -44,8 +46,24 @@ bastide_register(unsigned int base, unsigned int aux, int irq, ...@@ -44,8 +46,24 @@ bastide_register(unsigned int base, unsigned int aux, int irq,
hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20); hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
hw.irq = irq; hw.irq = irq;
ide_register_hw(&hw, NULL, hwif); hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
if (hwif == NULL)
goto out;
i = hwif->index;
if (hwif->present)
ide_unregister(i, 0, 0);
else if (!hwif->hold)
ide_init_port_data(hwif, i);
ide_init_port_hw(hwif, &hw);
hwif->quirkproc = NULL;
idx[0] = i;
ide_device_add(idx, NULL);
out:
return 0; return 0;
} }
......
...@@ -377,9 +377,6 @@ static void icside_dma_lost_irq(ide_drive_t *drive) ...@@ -377,9 +377,6 @@ static void icside_dma_lost_irq(ide_drive_t *drive)
static void icside_dma_init(ide_hwif_t *hwif) static void icside_dma_init(ide_hwif_t *hwif)
{ {
hwif->mwdma_mask = 7; /* MW0..2 */
hwif->swdma_mask = 7; /* SW0..2 */
hwif->dmatable_cpu = NULL; hwif->dmatable_cpu = NULL;
hwif->dmatable_dma = 0; hwif->dmatable_dma = 0;
hwif->set_dma_mode = icside_set_dma_mode; hwif->set_dma_mode = icside_set_dma_mode;
...@@ -459,11 +456,19 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) ...@@ -459,11 +456,19 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
idx[0] = hwif->index; idx[0] = hwif->index;
ide_device_add(idx); ide_device_add(idx, NULL);
return 0; return 0;
} }
static const struct ide_port_info icside_v6_port_info __initdata = {
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
IDE_HFLAG_NO_AUTOTUNE,
.mwdma_mask = ATA_MWDMA2,
.swdma_mask = ATA_SWDMA2,
};
static int __init static int __init
icside_register_v6(struct icside_state *state, struct expansion_card *ec) icside_register_v6(struct icside_state *state, struct expansion_card *ec)
{ {
...@@ -472,6 +477,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) ...@@ -472,6 +477,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
unsigned int sel = 0; unsigned int sel = 0;
int ret; int ret;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
struct ide_port_info d = icside_v6_port_info;
ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (!ioc_base) { if (!ioc_base) {
...@@ -521,30 +527,25 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) ...@@ -521,30 +527,25 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
state->hwif[1] = mate; state->hwif[1] = mate;
hwif->maskproc = icside_maskproc; hwif->maskproc = icside_maskproc;
hwif->channel = 0;
hwif->hwif_data = state; hwif->hwif_data = state;
hwif->mate = mate;
hwif->serialized = 1;
hwif->config_data = (unsigned long)ioc_base; hwif->config_data = (unsigned long)ioc_base;
hwif->select_data = sel; hwif->select_data = sel;
mate->maskproc = icside_maskproc; mate->maskproc = icside_maskproc;
mate->channel = 1;
mate->hwif_data = state; mate->hwif_data = state;
mate->mate = hwif;
mate->serialized = 1;
mate->config_data = (unsigned long)ioc_base; mate->config_data = (unsigned long)ioc_base;
mate->select_data = sel | 1; mate->select_data = sel | 1;
if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) { if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
icside_dma_init(hwif); icside_dma_init(hwif);
icside_dma_init(mate); icside_dma_init(mate);
} } else
d.mwdma_mask = d.swdma_mask = 0;
idx[0] = hwif->index; idx[0] = hwif->index;
idx[1] = mate->index; idx[1] = mate->index;
ide_device_add(idx); ide_device_add(idx, &d);
return 0; return 0;
......
...@@ -39,7 +39,7 @@ static int __init ide_arm_init(void) ...@@ -39,7 +39,7 @@ static int __init ide_arm_init(void)
ide_init_port_hw(hwif, &hw); ide_init_port_hw(hwif, &hw);
idx[0] = hwif->index; idx[0] = hwif->index;
ide_device_add(idx); ide_device_add(idx, NULL);
} }
return 0; return 0;
......
...@@ -58,7 +58,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -58,7 +58,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
idx[0] = hwif->index; idx[0] = hwif->index;
ide_device_add(idx); ide_device_add(idx, NULL);
ecard_set_drvdata(ec, hwif); ecard_set_drvdata(ec, hwif);
goto out; goto out;
...@@ -76,7 +76,7 @@ static void __devexit rapide_remove(struct expansion_card *ec) ...@@ -76,7 +76,7 @@ static void __devexit rapide_remove(struct expansion_card *ec)
ecard_set_drvdata(ec, NULL); ecard_set_drvdata(ec, NULL);
ide_unregister(hwif->index); ide_unregister(hwif->index, 0, 0);
ecard_release_resources(ec); ecard_release_resources(ec);
} }
......
...@@ -753,6 +753,15 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed) ...@@ -753,6 +753,15 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
} }
static const struct ide_port_info cris_port_info __initdata = {
.chipset = ide_etrax100,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_NO_DMA, /* no SFF-style DMA */
.pio_mask = ATA_PIO4,
.udma_mask = cris_ultra_mask,
.mwdma_mask = ATA_MWDMA2,
};
static int __init init_e100_ide(void) static int __init init_e100_ide(void)
{ {
hw_regs_t hw; hw_regs_t hw;
...@@ -780,7 +789,6 @@ static int __init init_e100_ide(void) ...@@ -780,7 +789,6 @@ static int __init init_e100_ide(void)
ide_init_port_data(hwif, hwif->index); ide_init_port_data(hwif, hwif->index);
ide_init_port_hw(hwif, &hw); ide_init_port_hw(hwif, &hw);
hwif->mmio = 1; hwif->mmio = 1;
hwif->chipset = ide_etrax100;
hwif->set_pio_mode = &cris_set_pio_mode; hwif->set_pio_mode = &cris_set_pio_mode;
hwif->set_dma_mode = &cris_set_dma_mode; hwif->set_dma_mode = &cris_set_dma_mode;
hwif->ata_input_data = &cris_ide_input_data; hwif->ata_input_data = &cris_ide_input_data;
...@@ -799,12 +807,6 @@ static int __init init_e100_ide(void) ...@@ -799,12 +807,6 @@ static int __init init_e100_ide(void)
hwif->INB = &cris_ide_inb; hwif->INB = &cris_ide_inb;
hwif->INW = &cris_ide_inw; hwif->INW = &cris_ide_inw;
hwif->cbl = ATA_CBL_PATA40; hwif->cbl = ATA_CBL_PATA40;
hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
hwif->pio_mask = ATA_PIO4,
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
hwif->ultra_mask = cris_ultra_mask;
hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
idx[h] = hwif->index; idx[h] = hwif->index;
} }
...@@ -820,7 +822,7 @@ static int __init init_e100_ide(void) ...@@ -820,7 +822,7 @@ static int __init init_e100_ide(void)
cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD); cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD);
cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0); cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
ide_device_add(idx); ide_device_add(idx, &cris_port_info);
return 0; return 0;
} }
...@@ -1032,11 +1034,7 @@ static int cris_dma_setup(ide_drive_t *drive) ...@@ -1032,11 +1034,7 @@ static int cris_dma_setup(ide_drive_t *drive)
static void cris_dma_exec_cmd(ide_drive_t *drive, u8 command) static void cris_dma_exec_cmd(ide_drive_t *drive, u8 command)
{ {
/* set the irq handler which will finish the request when DMA is done */ ide_execute_command(drive, command, &cris_dma_intr, WAIT_CMD, NULL);
ide_set_handler(drive, &cris_dma_intr, WAIT_CMD, NULL);
/* issue cmd to drive */
cris_ide_outb(command, IDE_COMMAND_REG);
} }
static void cris_dma_start(ide_drive_t *drive) static void cris_dma_start(ide_drive_t *drive)
......
...@@ -114,7 +114,7 @@ static int __init h8300_ide_init(void) ...@@ -114,7 +114,7 @@ static int __init h8300_ide_init(void)
idx[0] = index; idx[0] = index;
ide_device_add(idx); ide_device_add(idx, NULL);
return 0; return 0;
......
...@@ -39,7 +39,6 @@ struct GTM_buffer { ...@@ -39,7 +39,6 @@ struct GTM_buffer {
}; };
struct ide_acpi_drive_link { struct ide_acpi_drive_link {
ide_drive_t *drive;
acpi_handle obj_handle; acpi_handle obj_handle;
u8 idbuff[512]; u8 idbuff[512];
}; };
...@@ -280,16 +279,6 @@ static int do_drive_get_GTF(ide_drive_t *drive, ...@@ -280,16 +279,6 @@ static int do_drive_get_GTF(ide_drive_t *drive,
port = hwif->channel ? drive->dn - 2: drive->dn; port = hwif->channel ? drive->dn - 2: drive->dn;
if (!drive->acpidata) {
if (port == 0) {
drive->acpidata = &hwif->acpidata->master;
hwif->acpidata->master.drive = drive;
} else {
drive->acpidata = &hwif->acpidata->slave;
hwif->acpidata->slave.drive = drive;
}
}
DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n", DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
hwif->name, dev->bus_id, port, hwif->channel); hwif->name, dev->bus_id, port, hwif->channel);
...@@ -494,7 +483,6 @@ int ide_acpi_exec_tfs(ide_drive_t *drive) ...@@ -494,7 +483,6 @@ int ide_acpi_exec_tfs(ide_drive_t *drive)
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(ide_acpi_exec_tfs);
/** /**
* ide_acpi_get_timing - get the channel (controller) timings * ide_acpi_get_timing - get the channel (controller) timings
...@@ -580,7 +568,6 @@ void ide_acpi_get_timing(ide_hwif_t *hwif) ...@@ -580,7 +568,6 @@ void ide_acpi_get_timing(ide_hwif_t *hwif)
kfree(output.pointer); kfree(output.pointer);
} }
EXPORT_SYMBOL_GPL(ide_acpi_get_timing);
/** /**
* ide_acpi_push_timing - set the channel (controller) timings * ide_acpi_push_timing - set the channel (controller) timings
...@@ -634,7 +621,6 @@ void ide_acpi_push_timing(ide_hwif_t *hwif) ...@@ -634,7 +621,6 @@ void ide_acpi_push_timing(ide_hwif_t *hwif)
} }
DEBPRINT("_STM status: %d\n", status); DEBPRINT("_STM status: %d\n", status);
} }
EXPORT_SYMBOL_GPL(ide_acpi_push_timing);
/** /**
* ide_acpi_set_state - set the channel power state * ide_acpi_set_state - set the channel power state
...@@ -688,11 +674,6 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) ...@@ -688,11 +674,6 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
*/ */
void ide_acpi_init(ide_hwif_t *hwif) void ide_acpi_init(ide_hwif_t *hwif)
{ {
int unit;
int err;
struct ide_acpi_drive_link *master;
struct ide_acpi_drive_link *slave;
ide_acpi_blacklist(); ide_acpi_blacklist();
hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL); hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
...@@ -704,40 +685,38 @@ void ide_acpi_init(ide_hwif_t *hwif) ...@@ -704,40 +685,38 @@ void ide_acpi_init(ide_hwif_t *hwif)
DEBPRINT("no ACPI object for %s found\n", hwif->name); DEBPRINT("no ACPI object for %s found\n", hwif->name);
kfree(hwif->acpidata); kfree(hwif->acpidata);
hwif->acpidata = NULL; hwif->acpidata = NULL;
return;
} }
}
void ide_acpi_port_init_devices(ide_hwif_t *hwif)
{
ide_drive_t *drive;
int i, err;
if (hwif->acpidata == NULL)
return;
/* /*
* The ACPI spec mandates that we send information * The ACPI spec mandates that we send information
* for both drives, regardless whether they are connected * for both drives, regardless whether they are connected
* or not. * or not.
*/ */
hwif->acpidata->master.drive = &hwif->drives[0];
hwif->drives[0].acpidata = &hwif->acpidata->master; hwif->drives[0].acpidata = &hwif->acpidata->master;
master = &hwif->acpidata->master;
hwif->acpidata->slave.drive = &hwif->drives[1];
hwif->drives[1].acpidata = &hwif->acpidata->slave; hwif->drives[1].acpidata = &hwif->acpidata->slave;
slave = &hwif->acpidata->slave;
/* /*
* Send IDENTIFY for each drive * Send IDENTIFY for each drive
*/ */
if (master->drive->present) { for (i = 0; i < MAX_DRIVES; i++) {
err = taskfile_lib_get_identify(master->drive, master->idbuff); drive = &hwif->drives[i];
if (err) {
DEBPRINT("identify device %s failed (%d)\n", if (!drive->present)
master->drive->name, err); continue;
}
}
if (slave->drive->present) { err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
err = taskfile_lib_get_identify(slave->drive, slave->idbuff); if (err)
if (err) {
DEBPRINT("identify device %s failed (%d)\n", DEBPRINT("identify device %s failed (%d)\n",
slave->drive->name, err); drive->name, err);
}
} }
if (ide_noacpionboot) { if (ide_noacpionboot) {
...@@ -753,13 +732,11 @@ void ide_acpi_init(ide_hwif_t *hwif) ...@@ -753,13 +732,11 @@ void ide_acpi_init(ide_hwif_t *hwif)
ide_acpi_get_timing(hwif); ide_acpi_get_timing(hwif);
ide_acpi_push_timing(hwif); ide_acpi_push_timing(hwif);
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (i = 0; i < MAX_DRIVES; i++) {
ide_drive_t *drive = &hwif->drives[unit]; drive = &hwif->drives[i];
if (drive->present) { if (drive->present)
/* Execute ACPI startup code */ /* Execute ACPI startup code */
ide_acpi_exec_tfs(drive); ide_acpi_exec_tfs(drive);
}
} }
} }
EXPORT_SYMBOL_GPL(ide_acpi_init);
...@@ -604,8 +604,6 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive, ...@@ -604,8 +604,6 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
* Block read functions. * Block read functions.
*/ */
typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len) static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len)
{ {
while (len > 0) { while (len > 0) {
......
...@@ -819,6 +819,26 @@ int ide_set_dma(ide_drive_t *drive) ...@@ -819,6 +819,26 @@ int ide_set_dma(ide_drive_t *drive)
return 0; return 0;
} }
void ide_check_dma_crc(ide_drive_t *drive)
{
u8 mode;
ide_dma_off_quietly(drive);
drive->crc_count = 0;
mode = drive->current_speed;
/*
* Don't try non Ultra-DMA modes without iCRC's. Force the
* device to PIO and make the user enable SWDMA/MWDMA modes.
*/
if (mode > XFER_UDMA_0 && mode <= XFER_UDMA_7)
mode--;
else
mode = XFER_PIO_4;
ide_set_xfer_rate(drive, mode);
if (drive->current_speed >= XFER_SW_DMA_0)
ide_dma_on(drive);
}
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
void ide_dma_lost_irq (ide_drive_t *drive) void ide_dma_lost_irq (ide_drive_t *drive)
{ {
......
This diff is collapsed.
...@@ -23,7 +23,7 @@ static int __init ide_generic_init(void) ...@@ -23,7 +23,7 @@ static int __init ide_generic_init(void)
for (i = 0; i < MAX_HWIFS; i++) for (i = 0; i < MAX_HWIFS; i++)
idx[i] = ide_hwifs[i].present ? 0xff : i; idx[i] = ide_hwifs[i].present ? 0xff : i;
ide_device_add_all(idx); ide_device_add_all(idx, NULL);
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
ide_release_lock(); /* for atari only */ ide_release_lock(); /* for atari only */
......
...@@ -163,8 +163,6 @@ void SELECT_DRIVE (ide_drive_t *drive) ...@@ -163,8 +163,6 @@ void SELECT_DRIVE (ide_drive_t *drive)
HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG); HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG);
} }
EXPORT_SYMBOL(SELECT_DRIVE);
void SELECT_MASK (ide_drive_t *drive, int mask) void SELECT_MASK (ide_drive_t *drive, int mask)
{ {
if (HWIF(drive)->maskproc) if (HWIF(drive)->maskproc)
...@@ -614,66 +612,6 @@ u8 eighty_ninty_three (ide_drive_t *drive) ...@@ -614,66 +612,6 @@ u8 eighty_ninty_three (ide_drive_t *drive)
return 0; return 0;
} }
int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
{
if (args->tf.command == WIN_SETFEATURES &&
args->tf.nsect > XFER_UDMA_2 &&
args->tf.feature == SETFEATURES_XFER) {
if (eighty_ninty_three(drive) == 0) {
printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
"be set\n", drive->name);
return 1;
}
}
return 0;
}
/*
* Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER.
* 1 : Safe to update drive->id DMA registers.
* 0 : OOPs not allowed.
*/
int set_transfer (ide_drive_t *drive, ide_task_t *args)
{
if (args->tf.command == WIN_SETFEATURES &&
args->tf.nsect >= XFER_SW_DMA_0 &&
args->tf.feature == SETFEATURES_XFER &&
(drive->id->dma_ultra ||
drive->id->dma_mword ||
drive->id->dma_1word))
return 1;
return 0;
}
#ifdef CONFIG_BLK_DEV_IDEDMA
static u8 ide_auto_reduce_xfer (ide_drive_t *drive)
{
if (!drive->crc_count)
return drive->current_speed;
drive->crc_count = 0;
switch(drive->current_speed) {
case XFER_UDMA_7: return XFER_UDMA_6;
case XFER_UDMA_6: return XFER_UDMA_5;
case XFER_UDMA_5: return XFER_UDMA_4;
case XFER_UDMA_4: return XFER_UDMA_3;
case XFER_UDMA_3: return XFER_UDMA_2;
case XFER_UDMA_2: return XFER_UDMA_1;
case XFER_UDMA_1: return XFER_UDMA_0;
/*
* OOPS we do not goto non Ultra DMA modes
* without iCRC's available we force
* the system to PIO and make the user
* invoke the ATA-1 ATA-2 DMA modes.
*/
case XFER_UDMA_0:
default: return XFER_PIO_4;
}
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
int ide_driveid_update(ide_drive_t *drive) int ide_driveid_update(ide_drive_t *drive)
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
...@@ -882,22 +820,17 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, ...@@ -882,22 +820,17 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
unsigned long flags; unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
BUG_ON(hwgroup->handler); BUG_ON(hwgroup->handler);
hwgroup->handler = handler; __ide_set_handler(drive, handler, timeout, expiry);
hwgroup->expiry = expiry;
hwgroup->timer.expires = jiffies + timeout;
hwgroup->req_gen_timer = hwgroup->req_gen;
add_timer(&hwgroup->timer);
hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG); hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG);
/* Drive takes 400nS to respond, we must avoid the IRQ being /*
serviced before that. * Drive takes 400nS to respond, we must avoid the IRQ being
* serviced before that.
FIXME: we could skip this delay with care on non shared *
devices * FIXME: we could skip this delay with care on non shared devices
*/ */
ndelay(400); ndelay(400);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
} }
...@@ -1005,19 +938,6 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) ...@@ -1005,19 +938,6 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
return ide_stopped; return ide_stopped;
} }
static void check_dma_crc(ide_drive_t *drive)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->crc_count) {
ide_dma_off_quietly(drive);
ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
if (drive->current_speed >= XFER_SW_DMA_0)
ide_dma_on(drive);
} else
ide_dma_off(drive);
#endif
}
static void ide_disk_pre_reset(ide_drive_t *drive) static void ide_disk_pre_reset(ide_drive_t *drive)
{ {
int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1; int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;
...@@ -1039,17 +959,20 @@ static void pre_reset(ide_drive_t *drive) ...@@ -1039,17 +959,20 @@ static void pre_reset(ide_drive_t *drive)
else else
drive->post_reset = 1; drive->post_reset = 1;
if (drive->using_dma) {
if (drive->crc_count)
ide_check_dma_crc(drive);
else
ide_dma_off(drive);
}
if (!drive->keep_settings) { if (!drive->keep_settings) {
if (drive->using_dma) { if (!drive->using_dma) {
check_dma_crc(drive);
} else {
drive->unmask = 0; drive->unmask = 0;
drive->io_32bit = 0; drive->io_32bit = 0;
} }
return; return;
} }
if (drive->using_dma)
check_dma_crc(drive);
if (HWIF(drive)->pre_reset != NULL) if (HWIF(drive)->pre_reset != NULL)
HWIF(drive)->pre_reset(drive); HWIF(drive)->pre_reset(drive);
......
...@@ -49,7 +49,7 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id ...@@ -49,7 +49,7 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
pnp_set_drvdata(dev,hwif); pnp_set_drvdata(dev,hwif);
ide_device_add(idx); ide_device_add(idx, NULL);
return 0; return 0;
} }
...@@ -60,9 +60,10 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id ...@@ -60,9 +60,10 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
static void idepnp_remove(struct pnp_dev * dev) static void idepnp_remove(struct pnp_dev * dev)
{ {
ide_hwif_t *hwif = pnp_get_drvdata(dev); ide_hwif_t *hwif = pnp_get_drvdata(dev);
if (hwif) {
ide_unregister(hwif->index); if (hwif)
} else ide_unregister(hwif->index, 0, 0);
else
printk(KERN_ERR "idepnp: Unable to remove device, please report.\n"); printk(KERN_ERR "idepnp: Unable to remove device, please report.\n");
} }
......
...@@ -423,8 +423,9 @@ static int ide_busy_sleep(ide_hwif_t *hwif) ...@@ -423,8 +423,9 @@ static int ide_busy_sleep(ide_hwif_t *hwif)
static int do_probe (ide_drive_t *drive, u8 cmd) static int do_probe (ide_drive_t *drive, u8 cmd)
{ {
int rc;
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
int rc;
u8 stat;
if (drive->present) { if (drive->present) {
/* avoid waiting for inappropriate probes */ /* avoid waiting for inappropriate probes */
...@@ -461,15 +462,17 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -461,15 +462,17 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
/* failed: try again */ /* failed: try again */
rc = try_to_identify(drive,cmd); rc = try_to_identify(drive,cmd);
} }
if (hwif->INB(IDE_STATUS_REG) == (BUSY_STAT|READY_STAT))
stat = hwif->INB(IDE_STATUS_REG);
if (stat == (BUSY_STAT | READY_STAT))
return 4; return 4;
if ((rc == 1 && cmd == WIN_PIDENTIFY) && if ((rc == 1 && cmd == WIN_PIDENTIFY) &&
((drive->autotune == IDE_TUNE_DEFAULT) || ((drive->autotune == IDE_TUNE_DEFAULT) ||
(drive->autotune == IDE_TUNE_AUTO))) { (drive->autotune == IDE_TUNE_AUTO))) {
printk("%s: no response (status = 0x%02x), " printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, "resetting drive\n", drive->name, stat);
hwif->INB(IDE_STATUS_REG));
msleep(50); msleep(50);
hwif->OUTB(drive->select.all, IDE_SELECT_REG); hwif->OUTB(drive->select.all, IDE_SELECT_REG);
msleep(50); msleep(50);
...@@ -477,11 +480,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -477,11 +480,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
(void)ide_busy_sleep(hwif); (void)ide_busy_sleep(hwif);
rc = try_to_identify(drive, cmd); rc = try_to_identify(drive, cmd);
} }
/* ensure drive IRQ is clear */
stat = hwif->INB(IDE_STATUS_REG);
if (rc == 1) if (rc == 1)
printk("%s: no response (status = 0x%02x)\n", printk(KERN_ERR "%s: no response (status = 0x%02x)\n",
drive->name, hwif->INB(IDE_STATUS_REG)); drive->name, stat);
/* ensure drive irq is clear */
(void) hwif->INB(IDE_STATUS_REG);
} else { } else {
/* not present or maybe ATAPI */ /* not present or maybe ATAPI */
rc = 3; rc = 3;
...@@ -502,6 +507,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -502,6 +507,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
static void enable_nest (ide_drive_t *drive) static void enable_nest (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
u8 stat;
printk("%s: enabling %s -- ", hwif->name, drive->id->model); printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
...@@ -515,11 +521,12 @@ static void enable_nest (ide_drive_t *drive) ...@@ -515,11 +521,12 @@ static void enable_nest (ide_drive_t *drive)
msleep(50); msleep(50);
if (!OK_STAT((hwif->INB(IDE_STATUS_REG)), 0, BAD_STAT)) { stat = hwif->INB(IDE_STATUS_REG);
printk("failed (status = 0x%02x)\n", hwif->INB(IDE_STATUS_REG));
} else { if (!OK_STAT(stat, 0, BAD_STAT))
printk("success\n"); printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
} else
printk(KERN_CONT "success\n");
/* if !(success||timed-out) */ /* if !(success||timed-out) */
if (do_probe(drive, WIN_IDENTIFY) >= 2) { if (do_probe(drive, WIN_IDENTIFY) >= 2) {
...@@ -822,7 +829,7 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) ...@@ -822,7 +829,7 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
if (hwif->no_io_32bit) if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
drive->no_io_32bit = 1; drive->no_io_32bit = 1;
else else
drive->no_io_32bit = drive->id->dword_io ? 1 : 0; drive->no_io_32bit = drive->id->dword_io ? 1 : 0;
...@@ -881,13 +888,6 @@ static int ide_init_queue(ide_drive_t *drive) ...@@ -881,13 +888,6 @@ static int ide_init_queue(ide_drive_t *drive)
q->queuedata = drive; q->queuedata = drive;
blk_queue_segment_boundary(q, 0xffff); blk_queue_segment_boundary(q, 0xffff);
if (!hwif->rqsize) {
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
(hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
hwif->rqsize = 256;
else
hwif->rqsize = 65536;
}
if (hwif->rqsize < max_sectors) if (hwif->rqsize < max_sectors)
max_sectors = hwif->rqsize; max_sectors = hwif->rqsize;
blk_queue_max_sectors(q, max_sectors); blk_queue_max_sectors(q, max_sectors);
...@@ -918,6 +918,48 @@ static int ide_init_queue(ide_drive_t *drive) ...@@ -918,6 +918,48 @@ static int ide_init_queue(ide_drive_t *drive)
return 0; return 0;
} }
static void ide_add_drive_to_hwgroup(ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
spin_lock_irq(&ide_lock);
if (!hwgroup->drive) {
/* first drive for hwgroup. */
drive->next = drive;
hwgroup->drive = drive;
hwgroup->hwif = HWIF(hwgroup->drive);
} else {
drive->next = hwgroup->drive->next;
hwgroup->drive->next = drive;
}
spin_unlock_irq(&ide_lock);
}
/*
* For any present drive:
* - allocate the block device queue
* - link drive into the hwgroup
*/
static void ide_port_setup_devices(ide_hwif_t *hwif)
{
int i;
for (i = 0; i < MAX_DRIVES; i++) {
ide_drive_t *drive = &hwif->drives[i];
if (!drive->present)
continue;
if (ide_init_queue(drive)) {
printk(KERN_ERR "ide: failed to init %s\n",
drive->name);
continue;
}
ide_add_drive_to_hwgroup(drive);
}
}
/* /*
* This routine sets up the irq for an ide interface, and creates a new * This routine sets up the irq for an ide interface, and creates a new
* hwgroup for the irq/hwif if none was previously assigned. * hwgroup for the irq/hwif if none was previously assigned.
...@@ -1019,30 +1061,12 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -1019,30 +1061,12 @@ static int init_irq (ide_hwif_t *hwif)
goto out_unlink; goto out_unlink;
} }
/* if (!hwif->rqsize) {
* For any present drive: if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
* - allocate the block device queue (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
* - link drive into the hwgroup hwif->rqsize = 256;
*/ else
for (index = 0; index < MAX_DRIVES; ++index) { hwif->rqsize = 65536;
ide_drive_t *drive = &hwif->drives[index];
if (!drive->present)
continue;
if (ide_init_queue(drive)) {
printk(KERN_ERR "ide: failed to init %s\n",drive->name);
continue;
}
spin_lock_irq(&ide_lock);
if (!hwgroup->drive) {
/* first drive for hwgroup. */
drive->next = drive;
hwgroup->drive = drive;
hwgroup->hwif = HWIF(hwgroup->drive);
} else {
drive->next = hwgroup->drive->next;
hwgroup->drive->next = drive;
}
spin_unlock_irq(&ide_lock);
} }
#if !defined(__mc68000__) && !defined(CONFIG_APUS) #if !defined(__mc68000__) && !defined(CONFIG_APUS)
...@@ -1058,6 +1082,9 @@ static int init_irq (ide_hwif_t *hwif) ...@@ -1058,6 +1082,9 @@ static int init_irq (ide_hwif_t *hwif)
printk(" (%sed with %s)", printk(" (%sed with %s)",
hwif->sharing_irq ? "shar" : "serializ", match->name); hwif->sharing_irq ? "shar" : "serializ", match->name);
printk("\n"); printk("\n");
ide_port_setup_devices(hwif);
mutex_unlock(&ide_cfg_mtx); mutex_unlock(&ide_cfg_mtx);
return 0; return 0;
out_unlink: out_unlink:
...@@ -1182,30 +1209,6 @@ static void drive_release_dev (struct device *dev) ...@@ -1182,30 +1209,6 @@ static void drive_release_dev (struct device *dev)
complete(&drive->gendev_rel_comp); complete(&drive->gendev_rel_comp);
} }
/*
* init_gendisk() (as opposed to ide_geninit) is called for each major device,
* after probing for drives, to allocate partition tables and other data
* structures needed for the routines in genhd.c. ide_geninit() gets called
* somewhat later, during the partition check.
*/
static void init_gendisk (ide_hwif_t *hwif)
{
unsigned int unit;
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t * drive = &hwif->drives[unit];
ide_add_generic_settings(drive);
snprintf(drive->gendev.bus_id,BUS_ID_SIZE,"%u.%u",
hwif->index,unit);
drive->gendev.parent = &hwif->gendev;
drive->gendev.bus = &ide_bus_type;
drive->gendev.driver_data = drive;
drive->gendev.release = drive_release_dev;
}
blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
THIS_MODULE, ata_probe, ata_lock, hwif);
}
static int hwif_init(ide_hwif_t *hwif) static int hwif_init(ide_hwif_t *hwif)
{ {
int old_irq; int old_irq;
...@@ -1262,8 +1265,8 @@ static int hwif_init(ide_hwif_t *hwif) ...@@ -1262,8 +1265,8 @@ static int hwif_init(ide_hwif_t *hwif)
hwif->name, hwif->irq); hwif->name, hwif->irq);
done: done:
init_gendisk(hwif); blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
ide_acpi_init(hwif); THIS_MODULE, ata_probe, ata_lock, hwif);
return 1; return 1;
out: out:
...@@ -1277,23 +1280,118 @@ static void hwif_register_devices(ide_hwif_t *hwif) ...@@ -1277,23 +1280,118 @@ static void hwif_register_devices(ide_hwif_t *hwif)
for (i = 0; i < MAX_DRIVES; i++) { for (i = 0; i < MAX_DRIVES; i++) {
ide_drive_t *drive = &hwif->drives[i]; ide_drive_t *drive = &hwif->drives[i];
struct device *dev = &drive->gendev;
int ret;
if (drive->present) { if (!drive->present)
int ret = device_register(&drive->gendev); continue;
if (ret < 0) ide_add_generic_settings(drive);
printk(KERN_WARNING "IDE: %s: "
"device_register error: %d\n", snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i);
__FUNCTION__, ret); dev->parent = &hwif->gendev;
} dev->bus = &ide_bus_type;
dev->driver_data = drive;
dev->release = drive_release_dev;
ret = device_register(dev);
if (ret < 0)
printk(KERN_WARNING "IDE: %s: device_register error: "
"%d\n", __func__, ret);
}
}
static void ide_port_init_devices(ide_hwif_t *hwif)
{
int i;
for (i = 0; i < MAX_DRIVES; i++) {
ide_drive_t *drive = &hwif->drives[i];
if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
drive->io_32bit = 1;
if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
drive->unmask = 1;
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
drive->no_unmask = 1;
if ((hwif->host_flags & IDE_HFLAG_NO_AUTOTUNE) == 0)
drive->autotune = 1;
}
if (hwif->port_init_devs)
hwif->port_init_devs(hwif);
}
static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
const struct ide_port_info *d)
{
if (d->chipset != ide_etrax100)
hwif->channel = port;
if (d->chipset)
hwif->chipset = d->chipset;
if (d->init_iops)
d->init_iops(hwif);
if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
ide_hwif_setup_dma(hwif, d);
if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
(d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
hwif->irq = port ? 15 : 14;
hwif->host_flags = d->host_flags;
hwif->pio_mask = d->pio_mask;
if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
hwif->mate->serialized = hwif->serialized = 1;
hwif->swdma_mask = d->swdma_mask;
hwif->mwdma_mask = d->mwdma_mask;
hwif->ultra_mask = d->udma_mask;
/* reset DMA masks only for SFF-style DMA controllers */
if ((d->host_flags && IDE_HFLAG_NO_DMA) == 0 && hwif->dma_base == 0)
hwif->swdma_mask = hwif->mwdma_mask = hwif->ultra_mask = 0;
if (d->host_flags & IDE_HFLAG_RQSIZE_256)
hwif->rqsize = 256;
/* call chipset specific routine for each enabled port */
if (d->init_hwif)
d->init_hwif(hwif);
if (hwif->cable_detect && (hwif->ultra_mask & 0x78)) {
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = hwif->cable_detect(hwif);
} }
} }
int ide_device_add_all(u8 *idx) int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
{ {
ide_hwif_t *hwif; ide_hwif_t *hwif, *mate = NULL;
int i, rc = 0; int i, rc = 0;
for (i = 0; i < MAX_HWIFS; i++) {
if (d == NULL || idx[i] == 0xff) {
mate = NULL;
continue;
}
hwif = &ide_hwifs[idx[i]];
if (d->chipset != ide_etrax100 && (i & 1) && mate) {
hwif->mate = mate;
mate->mate = hwif;
}
mate = (i & 1) ? NULL : hwif;
ide_init_port(hwif, i & 1, d);
ide_port_init_devices(hwif);
}
for (i = 0; i < MAX_HWIFS; i++) { for (i = 0; i < MAX_HWIFS; i++) {
if (idx[i] == 0xff) if (idx[i] == 0xff)
continue; continue;
...@@ -1337,6 +1435,9 @@ int ide_device_add_all(u8 *idx) ...@@ -1337,6 +1435,9 @@ int ide_device_add_all(u8 *idx)
rc = -1; rc = -1;
continue; continue;
} }
ide_acpi_init(hwif);
ide_acpi_port_init_devices(hwif);
} }
for (i = 0; i < MAX_HWIFS; i++) { for (i = 0; i < MAX_HWIFS; i++) {
...@@ -1354,15 +1455,22 @@ int ide_device_add_all(u8 *idx) ...@@ -1354,15 +1455,22 @@ int ide_device_add_all(u8 *idx)
} }
for (i = 0; i < MAX_HWIFS; i++) { for (i = 0; i < MAX_HWIFS; i++) {
if (idx[i] != 0xff) if (idx[i] == 0xff)
ide_proc_register_port(&ide_hwifs[idx[i]]); continue;
hwif = &ide_hwifs[idx[i]];
if (hwif->present) {
ide_proc_register_port(hwif);
ide_proc_port_register_devices(hwif);
}
} }
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ide_device_add_all); EXPORT_SYMBOL_GPL(ide_device_add_all);
int ide_device_add(u8 idx[4]) int ide_device_add(u8 idx[4], const struct ide_port_info *d)
{ {
u8 idx_all[MAX_HWIFS]; u8 idx_all[MAX_HWIFS];
int i; int i;
...@@ -1370,6 +1478,6 @@ int ide_device_add(u8 idx[4]) ...@@ -1370,6 +1478,6 @@ int ide_device_add(u8 idx[4])
for (i = 0; i < MAX_HWIFS; i++) for (i = 0; i < MAX_HWIFS; i++)
idx_all[i] = (i < 4) ? idx[i] : 0xff; idx_all[i] = (i < 4) ? idx[i] : 0xff;
return ide_device_add_all(idx_all); return ide_device_add_all(idx_all, d);
} }
EXPORT_SYMBOL_GPL(ide_device_add); EXPORT_SYMBOL_GPL(ide_device_add);
...@@ -739,7 +739,7 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) ...@@ -739,7 +739,7 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
EXPORT_SYMBOL(ide_proc_unregister_driver); EXPORT_SYMBOL(ide_proc_unregister_driver);
static void create_proc_ide_drives(ide_hwif_t *hwif) void ide_proc_port_register_devices(ide_hwif_t *hwif)
{ {
int d; int d;
struct proc_dir_entry *ent; struct proc_dir_entry *ent;
...@@ -793,9 +793,6 @@ static ide_proc_entry_t hwif_entries[] = { ...@@ -793,9 +793,6 @@ static ide_proc_entry_t hwif_entries[] = {
void ide_proc_register_port(ide_hwif_t *hwif) void ide_proc_register_port(ide_hwif_t *hwif)
{ {
if (!hwif->present)
return;
if (!hwif->proc) { if (!hwif->proc) {
hwif->proc = proc_mkdir(hwif->name, proc_ide_root); hwif->proc = proc_mkdir(hwif->name, proc_ide_root);
...@@ -804,8 +801,6 @@ void ide_proc_register_port(ide_hwif_t *hwif) ...@@ -804,8 +801,6 @@ void ide_proc_register_port(ide_hwif_t *hwif)
ide_add_proc_entries(hwif->proc, hwif_entries, hwif); ide_add_proc_entries(hwif->proc, hwif_entries, hwif);
} }
create_proc_ide_drives(hwif);
} }
#ifdef CONFIG_BLK_DEV_IDEPCI #ifdef CONFIG_BLK_DEV_IDEPCI
......
This diff is collapsed.
...@@ -755,6 +755,7 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -755,6 +755,7 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
u8 args[4], xfer_rate = 0; u8 args[4], xfer_rate = 0;
ide_task_t tfargs; ide_task_t tfargs;
struct ide_taskfile *tf = &tfargs.tf; struct ide_taskfile *tf = &tfargs.tf;
struct hd_driveid *id = drive->id;
if (NULL == (void *) arg) { if (NULL == (void *) arg) {
struct request rq; struct request rq;
...@@ -792,10 +793,16 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) ...@@ -792,10 +793,16 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
return -ENOMEM; return -ENOMEM;
} }
if (set_transfer(drive, &tfargs)) { if (tf->command == WIN_SETFEATURES &&
tf->feature == SETFEATURES_XFER &&
tf->nsect >= XFER_SW_DMA_0 &&
(id->dma_ultra || id->dma_mword || id->dma_1word)) {
xfer_rate = args[1]; xfer_rate = args[1];
if (ide_ata66_check(drive, &tfargs)) if (tf->nsect > XFER_UDMA_2 && !eighty_ninty_three(drive)) {
printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
"be set\n", drive->name);
goto abort; goto abort;
}
} }
err = ide_raw_taskfile(drive, &tfargs, buf, args[3]); err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment