.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Generic Macintosh NCR5380 driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
24 | 25 | |
---|
25 | 26 | #include <asm/hwtest.h> |
---|
26 | 27 | #include <asm/io.h> |
---|
| 28 | +#include <asm/macintosh.h> |
---|
27 | 29 | #include <asm/macints.h> |
---|
28 | 30 | #include <asm/setup.h> |
---|
29 | 31 | |
---|
.. | .. |
---|
262 | 264 | return addr - start; |
---|
263 | 265 | } |
---|
264 | 266 | |
---|
| 267 | +/* The "SCSI DMA" chip on the IIfx implements this register. */ |
---|
| 268 | +#define CTRL_REG 0x8 |
---|
| 269 | +#define CTRL_INTERRUPTS_ENABLE BIT(1) |
---|
| 270 | +#define CTRL_HANDSHAKE_MODE BIT(3) |
---|
| 271 | + |
---|
| 272 | +static inline void write_ctrl_reg(struct NCR5380_hostdata *hostdata, u32 value) |
---|
| 273 | +{ |
---|
| 274 | + out_be32(hostdata->io + (CTRL_REG << 4), value); |
---|
| 275 | +} |
---|
| 276 | + |
---|
265 | 277 | static inline int macscsi_pread(struct NCR5380_hostdata *hostdata, |
---|
266 | 278 | unsigned char *dst, int len) |
---|
267 | 279 | { |
---|
268 | 280 | u8 __iomem *s = hostdata->pdma_io + (INPUT_DATA_REG << 4); |
---|
269 | 281 | unsigned char *d = dst; |
---|
| 282 | + int result = 0; |
---|
270 | 283 | |
---|
271 | 284 | hostdata->pdma_residual = len; |
---|
272 | 285 | |
---|
.. | .. |
---|
274 | 287 | BASR_DRQ | BASR_PHASE_MATCH, |
---|
275 | 288 | BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) { |
---|
276 | 289 | int bytes; |
---|
| 290 | + |
---|
| 291 | + if (macintosh_config->ident == MAC_MODEL_IIFX) |
---|
| 292 | + write_ctrl_reg(hostdata, CTRL_HANDSHAKE_MODE | |
---|
| 293 | + CTRL_INTERRUPTS_ENABLE); |
---|
277 | 294 | |
---|
278 | 295 | bytes = mac_pdma_recv(s, d, min(hostdata->pdma_residual, 512)); |
---|
279 | 296 | |
---|
.. | .. |
---|
283 | 300 | } |
---|
284 | 301 | |
---|
285 | 302 | if (hostdata->pdma_residual == 0) |
---|
286 | | - return 0; |
---|
| 303 | + goto out; |
---|
287 | 304 | |
---|
288 | 305 | if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ, |
---|
289 | 306 | BUS_AND_STATUS_REG, BASR_ACK, |
---|
.. | .. |
---|
291 | 308 | scmd_printk(KERN_DEBUG, hostdata->connected, |
---|
292 | 309 | "%s: !REQ and !ACK\n", __func__); |
---|
293 | 310 | if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) |
---|
294 | | - return 0; |
---|
| 311 | + goto out; |
---|
295 | 312 | |
---|
296 | 313 | if (bytes == 0) |
---|
297 | 314 | udelay(MAC_PDMA_DELAY); |
---|
.. | .. |
---|
302 | 319 | dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host, |
---|
303 | 320 | "%s: bus error (%d/%d)\n", __func__, d - dst, len); |
---|
304 | 321 | NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host); |
---|
305 | | - return -1; |
---|
| 322 | + result = -1; |
---|
| 323 | + goto out; |
---|
306 | 324 | } |
---|
307 | 325 | |
---|
308 | 326 | scmd_printk(KERN_ERR, hostdata->connected, |
---|
309 | 327 | "%s: phase mismatch or !DRQ\n", __func__); |
---|
310 | 328 | NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host); |
---|
311 | | - return -1; |
---|
| 329 | + result = -1; |
---|
| 330 | +out: |
---|
| 331 | + if (macintosh_config->ident == MAC_MODEL_IIFX) |
---|
| 332 | + write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE); |
---|
| 333 | + return result; |
---|
312 | 334 | } |
---|
313 | 335 | |
---|
314 | 336 | static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata, |
---|
.. | .. |
---|
316 | 338 | { |
---|
317 | 339 | unsigned char *s = src; |
---|
318 | 340 | u8 __iomem *d = hostdata->pdma_io + (OUTPUT_DATA_REG << 4); |
---|
| 341 | + int result = 0; |
---|
319 | 342 | |
---|
320 | 343 | hostdata->pdma_residual = len; |
---|
321 | 344 | |
---|
.. | .. |
---|
323 | 346 | BASR_DRQ | BASR_PHASE_MATCH, |
---|
324 | 347 | BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) { |
---|
325 | 348 | int bytes; |
---|
| 349 | + |
---|
| 350 | + if (macintosh_config->ident == MAC_MODEL_IIFX) |
---|
| 351 | + write_ctrl_reg(hostdata, CTRL_HANDSHAKE_MODE | |
---|
| 352 | + CTRL_INTERRUPTS_ENABLE); |
---|
326 | 353 | |
---|
327 | 354 | bytes = mac_pdma_send(s, d, min(hostdata->pdma_residual, 512)); |
---|
328 | 355 | |
---|
.. | .. |
---|
334 | 361 | if (hostdata->pdma_residual == 0) { |
---|
335 | 362 | if (NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG, |
---|
336 | 363 | TCR_LAST_BYTE_SENT, |
---|
337 | | - TCR_LAST_BYTE_SENT, HZ / 64) < 0) |
---|
| 364 | + TCR_LAST_BYTE_SENT, |
---|
| 365 | + HZ / 64) < 0) { |
---|
338 | 366 | scmd_printk(KERN_ERR, hostdata->connected, |
---|
339 | 367 | "%s: Last Byte Sent timeout\n", __func__); |
---|
340 | | - return 0; |
---|
| 368 | + result = -1; |
---|
| 369 | + } |
---|
| 370 | + goto out; |
---|
341 | 371 | } |
---|
342 | 372 | |
---|
343 | 373 | if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ, |
---|
.. | .. |
---|
346 | 376 | scmd_printk(KERN_DEBUG, hostdata->connected, |
---|
347 | 377 | "%s: !REQ and !ACK\n", __func__); |
---|
348 | 378 | if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) |
---|
349 | | - return 0; |
---|
| 379 | + goto out; |
---|
350 | 380 | |
---|
351 | 381 | if (bytes == 0) |
---|
352 | 382 | udelay(MAC_PDMA_DELAY); |
---|
.. | .. |
---|
357 | 387 | dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host, |
---|
358 | 388 | "%s: bus error (%d/%d)\n", __func__, s - src, len); |
---|
359 | 389 | NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host); |
---|
360 | | - return -1; |
---|
| 390 | + result = -1; |
---|
| 391 | + goto out; |
---|
361 | 392 | } |
---|
362 | 393 | |
---|
363 | 394 | scmd_printk(KERN_ERR, hostdata->connected, |
---|
364 | 395 | "%s: phase mismatch or !DRQ\n", __func__); |
---|
365 | 396 | NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host); |
---|
366 | | - return -1; |
---|
| 397 | + result = -1; |
---|
| 398 | +out: |
---|
| 399 | + if (macintosh_config->ident == MAC_MODEL_IIFX) |
---|
| 400 | + write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE); |
---|
| 401 | + return result; |
---|
367 | 402 | } |
---|
368 | 403 | |
---|
369 | 404 | static int macscsi_dma_xfer_len(struct NCR5380_hostdata *hostdata, |
---|
.. | .. |
---|
398 | 433 | .this_id = 7, |
---|
399 | 434 | .sg_tablesize = 1, |
---|
400 | 435 | .cmd_per_lun = 2, |
---|
401 | | - .use_clustering = DISABLE_CLUSTERING, |
---|
| 436 | + .dma_boundary = PAGE_SIZE - 1, |
---|
402 | 437 | .cmd_size = NCR5380_CMD_SIZE, |
---|
403 | 438 | .max_sectors = 128, |
---|
404 | 439 | }; |
---|